diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/EnvironmentComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/EnvironmentComponent.java new file mode 100644 index 0000000..dfea86c --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/EnvironmentComponent.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ve.ucv.ciens.ccg.nxtar.components; + +import com.artemis.Component; +import com.badlogic.gdx.graphics.g3d.Environment; + +public class EnvironmentComponent extends Component { + public Environment environment; + + public EnvironmentComponent(Environment environment) throws IllegalArgumentException{ + if(environment == null) + throw new IllegalArgumentException("Environment is null."); + + this.environment = environment; + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java b/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java new file mode 100644 index 0000000..e630fca --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/components/ModelComponent.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ve.ucv.ciens.ccg.nxtar.components; + +import com.artemis.Component; +import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.ModelInstance; + +public class ModelComponent extends Component { + public ModelInstance instance; + + public ModelComponent(Model model) throws IllegalArgumentException{ + if(model == null) + throw new IllegalArgumentException("Model is null."); + + this.instance = new ModelInstance(model); + } +} diff --git a/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java b/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java index 82f718d..ac65472 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java +++ b/src/ve/ucv/ciens/ccg/nxtar/entities/MarkerTestEntityCreator.java @@ -15,6 +15,8 @@ */ package ve.ucv.ciens.ccg.nxtar.entities; +import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent; +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent; @@ -25,12 +27,17 @@ import ve.ucv.ciens.ccg.nxtar.graphics.shaders.SingleLightPhongShader; import com.artemis.Entity; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes; import com.badlogic.gdx.graphics.VertexAttributes.Usage; +import com.badlogic.gdx.graphics.g3d.Environment; import com.badlogic.gdx.graphics.g3d.Model; +import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute; +import com.badlogic.gdx.graphics.g3d.attributes.DepthTestAttribute; +import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight; import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader; import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder; import com.badlogic.gdx.math.Matrix3; @@ -50,8 +57,9 @@ public class MarkerTestEntityCreator extends EntityCreatorBase { @Override public void createAllEntities() { MeshBuilder builder; - Entity bomb, sphere, box; + Entity bomb, sphere, box, bombModelBatch; G3dModelLoader loader; + Environment environment; // Create mesh. Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the meshes."); @@ -77,7 +85,7 @@ public class MarkerTestEntityCreator extends EntityCreatorBase { }boxMesh = builder.end(); loader = new G3dModelLoader(new JsonReader()); - bombModel = loader.loadModel(Gdx.files.internal("models/Bomb_test_1.g3dj")); + bombModel = loader.loadModel(Gdx.files.internal("models/Bomb_test_2.g3dj")); bombMesh = bombModel.meshes.get(0); Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): " + bombMesh.getVertexAttributes().toString()); @@ -91,13 +99,24 @@ public class MarkerTestEntityCreator extends EntityCreatorBase { Gdx.app.exit(); } + environment = new Environment(); + environment.set(new DepthTestAttribute(GL20.GL_LEQUAL, true)); + environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.3f, 0.3f, 0.3f, 1.0f)); + environment.add(new DirectionalLight().set(new Color(1, 1, 1, 1), new Vector3(-2, -2, -2))); + // Create the entities. Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites."); bomb = world.createEntity(); bomb.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), new Matrix3().idt(), new Vector3(1.0f, 1.0f, 1.0f))); bomb.addComponent(new MeshComponent(bombMesh)); bomb.addComponent(new ShaderComponent(phongShader)); - bomb.addComponent(new MarkerCodeComponent(213)); + bomb.addComponent(new MarkerCodeComponent(1023)); + + bombModelBatch = world.createEntity(); + bombModelBatch.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), new Matrix3().idt(), new Vector3(1.0f, 1.0f, 1.0f))); + bombModelBatch.addComponent(new ModelComponent(bombModel)); + bombModelBatch.addComponent(new EnvironmentComponent(environment)); + bombModelBatch.addComponent(new MarkerCodeComponent(89)); sphere = world.createEntity(); sphere.addComponent(new GeometryComponent(new Vector3(0.0f, 0.0f, 0.0f), new Matrix3().idt(), new Vector3(1.0f, 1.0f, 1.0f))); @@ -114,6 +133,7 @@ public class MarkerTestEntityCreator extends EntityCreatorBase { Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Adding entities to the world."); //sphere.addToWorld(); bomb.addToWorld(); + bombModelBatch.addToWorld(); sphere.addToWorld(); box.addToWorld(); } diff --git a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java index ca148ac..95fefa6 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java +++ b/src/ve/ucv/ciens/ccg/nxtar/states/InGameState.java @@ -29,6 +29,7 @@ import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue; import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor; import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem; +import ve.ucv.ciens.ccg.nxtar.systems.ModelBatchMarkerRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem; import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; @@ -191,6 +192,7 @@ public class InGameState extends BaseState{ entityCreator.createAllEntities(); gameWorld.setSystem(new MarkerPositioningSystem()); gameWorld.setSystem(new MarkerRenderingSystem(), true); + gameWorld.setSystem(new ModelBatchMarkerRenderingSystem(), true); gameWorld.setSystem(new ObjectRenderingSystem(), true); gameWorld.initialize(); } @@ -306,6 +308,11 @@ public class InGameState extends BaseState{ // Call rendering systems. gameWorld.getSystem(MarkerRenderingSystem.class).setMarkerData(data); gameWorld.getSystem(MarkerRenderingSystem.class).process(); + + gameWorld.getSystem(ModelBatchMarkerRenderingSystem.class).begin(perspectiveCamera, data); + gameWorld.getSystem(ModelBatchMarkerRenderingSystem.class).process(); + gameWorld.getSystem(ModelBatchMarkerRenderingSystem.class).end(); + gameWorld.getSystem(ObjectRenderingSystem.class).process(); Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); @@ -377,6 +384,8 @@ public class InGameState extends BaseState{ @Override public void dispose(){ + gameWorld.getSystem(ModelBatchMarkerRenderingSystem.class).dispose(); + if(entityCreator != null) entityCreator.dispose(); diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java index 8d3f80e..874baa6 100644 --- a/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/MarkerRenderingSystem.java @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package ve.ucv.ciens.ccg.nxtar.systems; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; @@ -116,15 +131,11 @@ public class MarkerRenderingSystem extends EntityProcessingSystem { shaderComp.shader.setUniforms(); meshComp.model.render(shaderComp.shader.getShaderProgram(), GL20.GL_TRIANGLES); }shaderComp.shader.getShaderProgram().end(); - - break; } }else{ Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + "."); } } - - markers = null; } } diff --git a/src/ve/ucv/ciens/ccg/nxtar/systems/ModelBatchMarkerRenderingSystem.java b/src/ve/ucv/ciens/ccg/nxtar/systems/ModelBatchMarkerRenderingSystem.java new file mode 100644 index 0000000..26cb501 --- /dev/null +++ b/src/ve/ucv/ciens/ccg/nxtar/systems/ModelBatchMarkerRenderingSystem.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2014 Miguel Angel Astor Romero + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ve.ucv.ciens.ccg.nxtar.systems; + +import ve.ucv.ciens.ccg.nxtar.components.EnvironmentComponent; +import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; +import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent; +import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; +import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; +import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; + +import com.artemis.Aspect; +import com.artemis.ComponentMapper; +import com.artemis.Entity; +import com.artemis.annotations.Mapper; +import com.artemis.systems.EntityProcessingSystem; +import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.graphics.PerspectiveCamera; +import com.badlogic.gdx.graphics.g3d.ModelBatch; +import com.badlogic.gdx.math.Matrix4; + +public class ModelBatchMarkerRenderingSystem extends EntityProcessingSystem { + @Mapper ComponentMapper markerMapper; + @Mapper ComponentMapper geometryMapper; + @Mapper ComponentMapper modelMapper; + @Mapper ComponentMapper environmentMapper; + + private static final String TAG = "MODEL_BATCH_MARKER_RENDERING_SYSTEM"; + private static final String CLASS_NAME = ModelBatchMarkerRenderingSystem.class.getSimpleName(); + + /** + *

A matrix representing 3D translations.

+ */ + private Matrix4 translationMatrix; + + /** + *

A matrix representing 3D rotations.

+ */ + private Matrix4 rotationMatrix; + + /** + *

A matrix representing 3D scalings.

+ */ + private Matrix4 scalingMatrix; + + private MarkerData markers; + + private PerspectiveCamera camera; + + private ModelBatch batch; + + @SuppressWarnings("unchecked") + public ModelBatchMarkerRenderingSystem(){ + super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, EnvironmentComponent.class, ModelComponent.class)); + + markers = null; + camera = null; + batch = new ModelBatch(); + translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f); + rotationMatrix = new Matrix4().idt(); + scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); + } + + public void dispose(){ + batch.dispose(); + } + + public void begin(PerspectiveCamera camera, MarkerData markers) throws RuntimeException{ + if(this.camera != null) + throw new RuntimeException("Begin called twice without calling end."); + + if(this.markers != null) + throw new RuntimeException("Begin called twice without calling end."); + + this.markers = markers; + this.camera = camera; + batch.begin(camera); + } + + public void end(){ + batch.end(); + camera = null; + markers = null; + } + + @Override + protected void process(Entity e) { + MarkerCodeComponent marker; + GeometryComponent geometry; + EnvironmentComponent environment; + ModelComponent model; + + if(markers == null || camera == null) + return; + + Gdx.app.log(TAG, CLASS_NAME + ".process(): Getting components."); + marker = markerMapper.get(e); + geometry = geometryMapper.get(e); + model = modelMapper.get(e); + environment = environmentMapper.get(e); + + Gdx.app.log(TAG, CLASS_NAME + ".process(): Processing markers."); + for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ + if(markers.markerCodes[i] != 1){ + if(markers.markerCodes[i] == marker.code){ + Gdx.app.log(TAG, CLASS_NAME + ".process(): Rendering marker code " + Integer.toString(markers.markerCodes[i]) + "."); + // Set the geometric transformations. + translationMatrix.setToTranslation(geometry.position); + + rotationMatrix.val[Matrix4.M00] = geometry.rotation.val[0]; + rotationMatrix.val[Matrix4.M10] = geometry.rotation.val[1]; + rotationMatrix.val[Matrix4.M20] = geometry.rotation.val[2]; + rotationMatrix.val[Matrix4.M30] = 0; + + rotationMatrix.val[Matrix4.M01] = geometry.rotation.val[3]; + rotationMatrix.val[Matrix4.M11] = geometry.rotation.val[4]; + rotationMatrix.val[Matrix4.M21] = geometry.rotation.val[5]; + rotationMatrix.val[Matrix4.M31] = 0; + + rotationMatrix.val[Matrix4.M02] = geometry.rotation.val[6]; + rotationMatrix.val[Matrix4.M12] = geometry.rotation.val[7]; + rotationMatrix.val[Matrix4.M22] = geometry.rotation.val[8]; + rotationMatrix.val[Matrix4.M32] = 0; + + rotationMatrix.val[Matrix4.M03] = 0; + rotationMatrix.val[Matrix4.M13] = 0; + rotationMatrix.val[Matrix4.M23] = 0; + rotationMatrix.val[Matrix4.M33] = 1; + + scalingMatrix.setToScaling(geometry.scaling); + + // Apply the geometric transformations to the model. + model.instance.transform.idt().mul(translationMatrix).mul(rotationMatrix).mul(scalingMatrix); + model.instance.calculateTransforms(); + + // Render the marker; + batch.render(model.instance, environment.environment); + } + }else{ + Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + "."); + } + } + } + +}