Added marker positioning and rendering. Not tested yet.

This commit is contained in:
2014-05-13 18:29:25 -04:30
parent 82e95ed0f7
commit fbb25ead08
14 changed files with 351 additions and 69 deletions

View File

@@ -15,9 +15,9 @@
*/ */
package ve.ucv.ciens.ccg.nxtar; package ve.ucv.ciens.ccg.nxtar;
import ve.ucv.ciens.ccg.nxtar.interfaces.CVProcessor; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor;
import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener; import ve.ucv.ciens.ccg.nxtar.interfaces.ApplicationEventsListener;
import ve.ucv.ciens.ccg.nxtar.interfaces.OSFunctionalityProvider; import ve.ucv.ciens.ccg.nxtar.interfaces.AndroidFunctionalityWrapper;
import ve.ucv.ciens.ccg.nxtar.network.RobotControlThread; import ve.ucv.ciens.ccg.nxtar.network.RobotControlThread;
import ve.ucv.ciens.ccg.nxtar.network.SensorReportThread; import ve.ucv.ciens.ccg.nxtar.network.SensorReportThread;
import ve.ucv.ciens.ccg.nxtar.network.ServiceDiscoveryThread; import ve.ucv.ciens.ccg.nxtar.network.ServiceDiscoveryThread;
@@ -116,12 +116,12 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
/** /**
* <p>The OpenCV wrapper.</p> * <p>The OpenCV wrapper.</p>
*/ */
public CVProcessor cvProc; public ImageProcessor cvProc;
/** /**
* <p>Wrapper around the Operating System methods.</p> * <p>Wrapper around the Operating System methods.</p>
*/ */
private OSFunctionalityProvider osFunction; private AndroidFunctionalityWrapper osFunction;
// Networking related fields. // Networking related fields.
/** /**
@@ -206,14 +206,14 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
// Check if the concrete application implements all required interfaces. // Check if the concrete application implements all required interfaces.
try{ try{
this.osFunction = (OSFunctionalityProvider)concreteApp; this.osFunction = (AndroidFunctionalityWrapper)concreteApp;
}catch(ClassCastException cc){ }catch(ClassCastException cc){
Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the Toaster interface. Toasting disabled."); Gdx.app.debug(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the Toaster interface. Toasting disabled.");
this.osFunction = null; this.osFunction = null;
} }
try{ try{
this.cvProc = (CVProcessor)concreteApp; this.cvProc = (ImageProcessor)concreteApp;
}catch(ClassCastException cc){ }catch(ClassCastException cc){
Gdx.app.error(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the CVProcessor interface. Quitting."); Gdx.app.error(TAG, CLASS_NAME + ".Main() :: concreteApp does not implement the CVProcessor interface. Quitting.");
Gdx.app.exit(); Gdx.app.exit();

View File

@@ -16,35 +16,23 @@
package ve.ucv.ciens.ccg.nxtar.components; package ve.ucv.ciens.ccg.nxtar.components;
import com.artemis.Component; import com.artemis.Component;
import com.badlogic.gdx.math.Quaternion; import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.Vector3;
public class GeometryComponent extends Component { public class GeometryComponent extends Component {
public Vector3 position; public Vector3 position;
public Quaternion rotation; public Matrix3 rotation;
public Vector3 scaling; public Vector3 scaling;
public GeometryComponent(){ public GeometryComponent(){
this.position = new Vector3(); this.position = new Vector3();
this.rotation = new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0.0f); this.rotation = new Matrix3();
this.scaling = new Vector3(1.0f, 1.0f, 1.0f); this.scaling = new Vector3(1.0f, 1.0f, 1.0f);
} }
public GeometryComponent(Vector3 position){ public GeometryComponent(Vector3 position, Matrix3 rotation, Vector3 scaling){
this.position = new Vector3(position); this.position = new Vector3(position);
this.rotation = new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0.0f); this.rotation = new Matrix3(rotation);
this.scaling = new Vector3(1.0f, 1.0f, 1.0f);
}
public GeometryComponent(Quaternion rotation){
this.position = new Vector3();
this.rotation = new Quaternion(rotation);
this.scaling = new Vector3(1.0f, 1.0f, 1.0f);
}
public GeometryComponent(Vector3 position, Quaternion rotation, Vector3 scaling){
this.position = new Vector3(position);
this.rotation = new Quaternion(rotation);
this.scaling = new Vector3(scaling); this.scaling = new Vector3(scaling);
} }
} }

View File

@@ -0,0 +1,28 @@
/*
* 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;
public class MarkerCodeComponent extends Component {
public int code;
public MarkerCodeComponent(int code) throws IllegalArgumentException{
if(code < 0 || code > 1024)
throw new IllegalArgumentException("Marker code must be between [0, 1024].");
this.code = code;
}
}

View File

@@ -18,10 +18,10 @@ package ve.ucv.ciens.ccg.nxtar.components;
import com.artemis.Component; import com.artemis.Component;
import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.Mesh;
public class ModelComponent extends Component { public class MeshComponent extends Component {
public Mesh model; public Mesh model;
public ModelComponent(Mesh model){ public MeshComponent(Mesh model){
this.model = model; this.model = model;
} }
} }

View File

@@ -0,0 +1,32 @@
/*
* 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.entities;
public class BombGameEntityCreator extends EntityCreatorBase {
public BombGameEntityCreator(){
// TODO: Empty constructor.
}
@Override
public void createAllEntities() {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
}

View File

@@ -15,8 +15,8 @@
*/ */
package ve.ucv.ciens.ccg.nxtar.entities; package ve.ucv.ciens.ccg.nxtar.entities;
import ve.ucv.ciens.ccg.nxtar.components.ModelComponent;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException; import ve.ucv.ciens.ccg.nxtar.exceptions.ShaderFailedToLoadException;
import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase; import ve.ucv.ciens.ccg.nxtar.graphics.shaders.CustomShaderBase;
@@ -30,7 +30,7 @@ import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.VertexAttributes; import com.badlogic.gdx.graphics.VertexAttributes;
import com.badlogic.gdx.graphics.VertexAttributes.Usage; import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder; import com.badlogic.gdx.graphics.g3d.utils.MeshBuilder;
import com.badlogic.gdx.math.Quaternion; import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.Vector3;
public class TestGameEntityCreator extends EntityCreatorBase { public class TestGameEntityCreator extends EntityCreatorBase {
@@ -45,6 +45,7 @@ public class TestGameEntityCreator extends EntityCreatorBase {
@Override @Override
public void createAllEntities() { public void createAllEntities() {
Matrix3 identity = new Matrix3();
Entity sphere; Entity sphere;
Entity cube; Entity cube;
Entity capsule1; Entity capsule1;
@@ -52,6 +53,8 @@ public class TestGameEntityCreator extends EntityCreatorBase {
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Started."); Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Started.");
identity.idt();
// Create the sphere. // Create the sphere.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the meshes."); Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the meshes.");
builder = new MeshBuilder(); builder = new MeshBuilder();
@@ -84,23 +87,23 @@ public class TestGameEntityCreator extends EntityCreatorBase {
// Create the entities. // Create the entities.
Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites."); Gdx.app.log(TAG, CLASS_NAME + ".createAllEntities(): Creating the enitites.");
sphere = world.createEntity(); sphere = world.createEntity();
sphere.addComponent(new GeometryComponent(new Vector3(0.5f, 0.5f, 0.0f))); sphere.addComponent(new GeometryComponent(new Vector3(0.5f, 0.5f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f)));
sphere.addComponent(new ModelComponent(sphereMesh)); sphere.addComponent(new MeshComponent(sphereMesh));
sphere.addComponent(new ShaderComponent(singleLightPhongShader)); sphere.addComponent(new ShaderComponent(singleLightPhongShader));
cube = world.createEntity(); cube = world.createEntity();
cube.addComponent(new GeometryComponent(new Vector3(-0.5f, -0.5f, 0.0f), new Quaternion(new Vector3(1.0f, 1.0f, 0.0f), 0.0f), new Vector3(1.0f, 1.0f, 1.0f))); cube.addComponent(new GeometryComponent(new Vector3(-0.5f, -0.5f, 0.0f), identity, new Vector3(1.0f, 1.0f, 1.0f)));
cube.addComponent(new ModelComponent(cubeMesh)); cube.addComponent(new MeshComponent(cubeMesh));
cube.addComponent(new ShaderComponent(singleLightPhongShader)); cube.addComponent(new ShaderComponent(singleLightPhongShader));
capsule1 = world.createEntity(); capsule1 = world.createEntity();
capsule1.addComponent(new GeometryComponent(new Vector3(-0.5f, 0.5f, 0.0f), new Quaternion(new Vector3(1.0f, 0.0f, 0.0f), 0.0f), new Vector3(1.5f, 1.0f, 1.0f))); capsule1.addComponent(new GeometryComponent(new Vector3(-0.5f, 0.5f, 0.0f), identity, new Vector3(1.5f, 1.0f, 1.0f)));
capsule1.addComponent(new ModelComponent(capsuleMesh)); capsule1.addComponent(new MeshComponent(capsuleMesh));
capsule1.addComponent(new ShaderComponent(singleLightPhongShader)); capsule1.addComponent(new ShaderComponent(singleLightPhongShader));
capsule2 = world.createEntity(); capsule2 = world.createEntity();
capsule2.addComponent(new GeometryComponent(new Vector3(0.5f, -0.5f, 0.0f), new Quaternion(new Vector3(0.0f, 1.0f, 0.0f), 0.0f), new Vector3(1.0f, 1.5f, 1.0f))); capsule2.addComponent(new GeometryComponent(new Vector3(0.5f, -0.5f, 0.0f), identity, new Vector3(1.0f, 1.5f, 1.0f)));
capsule2.addComponent(new ModelComponent(capsuleMesh)); capsule2.addComponent(new MeshComponent(capsuleMesh));
capsule2.addComponent(new ShaderComponent(singleLightPhongShader)); capsule2.addComponent(new ShaderComponent(singleLightPhongShader));
// Add the entities to the world. // Add the entities to the world.

View File

@@ -15,7 +15,7 @@
*/ */
package ve.ucv.ciens.ccg.nxtar.interfaces; package ve.ucv.ciens.ccg.nxtar.interfaces;
public interface OSFunctionalityProvider{ public interface AndroidFunctionalityWrapper{
public void showShortToast(String msg); public void showShortToast(String msg);
public void showLongToast(String msg); public void showLongToast(String msg);
public void enableMulticast(); public void enableMulticast();

View File

@@ -15,21 +15,25 @@
*/ */
package ve.ucv.ciens.ccg.nxtar.interfaces; package ve.ucv.ciens.ccg.nxtar.interfaces;
public interface CVProcessor{ import com.badlogic.gdx.math.Matrix3;
public class CVMarkerData{ import com.badlogic.gdx.math.Vector3;
public interface ImageProcessor{
public class MarkerData{
public byte[] outFrame; public byte[] outFrame;
public int[] markerCodes; public int[] markerCodes;
// TODO: Add marker location data. public Vector3[] translationVectors;
public Matrix3[] rotationMatrices;
} }
public class CVCalibrationData{ public class CalibrationData{
public byte[] outFrame; public byte[] outFrame;
public float[] calibrationPoints; public float[] calibrationPoints;
} }
public CVMarkerData findMarkersInFrame(byte[] frame); public MarkerData findMarkersInFrame(byte[] frame);
public CVCalibrationData findCalibrationPattern(byte[] frame); public CalibrationData findCalibrationPattern(byte[] frame);
public void calibrateCamera(float[][] calibrationSamples, byte[] frame); public void calibrateCamera(float[][] calibrationSamples, byte[] frame);
public byte[] undistortFrame(byte[] frame); public byte[] undistortFrame(byte[] frame);
public boolean cameraIsCalibrated(); public boolean isCameraCalibrated();
} }

View File

@@ -19,7 +19,7 @@ import java.util.Arrays;
import ve.ucv.ciens.ccg.nxtar.NxtARCore; import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t; import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
import ve.ucv.ciens.ccg.nxtar.interfaces.CVProcessor.CVCalibrationData; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.CalibrationData;
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor; import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import ve.ucv.ciens.ccg.nxtar.utils.Size; import ve.ucv.ciens.ccg.nxtar.utils.Size;
@@ -210,22 +210,22 @@ public class CameraCalibrationState extends BaseState{
frame = frameMonitor.getCurrentFrame(); frame = frameMonitor.getCurrentFrame();
// Apply the undistortion method if the camera has been calibrated already. // Apply the undistortion method if the camera has been calibrated already.
if(core.cvProc.cameraIsCalibrated()){ if(core.cvProc.isCameraCalibrated()){
frame = core.cvProc.undistortFrame(frame); frame = core.cvProc.undistortFrame(frame);
} }
// Find the calibration points in the video frame. // Find the calibration points in the video frame.
CVCalibrationData data = core.cvProc.findCalibrationPattern(frame); CalibrationData data = core.cvProc.findCalibrationPattern(frame);
// Disable the sampling button if the calibration pattern was not found. // Disable the sampling button if the calibration pattern was not found.
if(data.calibrationPoints != null && !core.cvProc.cameraIsCalibrated()){ if(data.calibrationPoints != null && !core.cvProc.isCameraCalibrated()){
takeSampleButton.setDisabled(false); takeSampleButton.setDisabled(false);
}else{ }else{
takeSampleButton.setDisabled(true); takeSampleButton.setDisabled(true);
} }
// If the user requested a sample be taken. // If the user requested a sample be taken.
if(takeSample && !core.cvProc.cameraIsCalibrated() && data.calibrationPoints != null){ if(takeSample && !core.cvProc.isCameraCalibrated() && data.calibrationPoints != null){
// Disable sample taking. // Disable sample taking.
takeSample = false; takeSample = false;
Gdx.app.log(TAG, CLASS_NAME + ".render(): Sample taken."); Gdx.app.log(TAG, CLASS_NAME + ".render(): Sample taken.");

View File

@@ -22,10 +22,12 @@ import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase; import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase;
import ve.ucv.ciens.ccg.nxtar.entities.TestGameEntityCreator; import ve.ucv.ciens.ccg.nxtar.entities.TestGameEntityCreator;
import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters;
import ve.ucv.ciens.ccg.nxtar.interfaces.CVProcessor.CVMarkerData; import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue; import ve.ucv.ciens.ccg.nxtar.network.monitors.MotorEventQueue;
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor; import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
import ve.ucv.ciens.ccg.nxtar.systems.RenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants; import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import com.artemis.World; import com.artemis.World;
@@ -173,7 +175,9 @@ public class InGameState extends BaseState{
entityCreator.setWorld(gameWorld); entityCreator.setWorld(gameWorld);
entityCreator.createAllEntities(); entityCreator.createAllEntities();
gameWorld.setSystem(new RenderingSystem(), true); gameWorld.setSystem(new MarkerPositioningSystem());
gameWorld.setSystem(new MarkerRenderingSystem(), true);
gameWorld.setSystem(new ObjectRenderingSystem(), true);
gameWorld.initialize(); gameWorld.initialize();
} }
@@ -186,13 +190,9 @@ public class InGameState extends BaseState{
public void render(float delta){ public void render(float delta){
int w, h; int w, h;
byte[] frame; byte[] frame;
CVMarkerData data; MarkerData data;
TextureRegion region; TextureRegion region;
// Update the game state.
gameWorld.setDelta(Gdx.graphics.getDeltaTime() * 1000);
gameWorld.process();
// Clear the screen. // Clear the screen.
Gdx.gl.glClearColor(1, 1, 1, 1); Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
@@ -227,7 +227,7 @@ public class InGameState extends BaseState{
} }
// Apply the undistortion method if the camera has been calibrated already. // Apply the undistortion method if the camera has been calibrated already.
if(core.cvProc.cameraIsCalibrated()){ if(core.cvProc.isCameraCalibrated()){
frame = core.cvProc.undistortFrame(frame); frame = core.cvProc.undistortFrame(frame);
} }
@@ -236,6 +236,11 @@ public class InGameState extends BaseState{
// If a valid frame was fetched. // If a valid frame was fetched.
if(data != null && data.outFrame != null){ if(data != null && data.outFrame != null){
// Update the game state.
gameWorld.setDelta(Gdx.graphics.getDeltaTime() * 1000);
gameWorld.getSystem(MarkerPositioningSystem.class).setMarkerData(data);
gameWorld.process();
// Decode the video frame. // Decode the video frame.
videoFrame = new Pixmap(data.outFrame, 0, w * h); videoFrame = new Pixmap(data.outFrame, 0, w * h);
videoFrameTexture = new Texture(videoFrame); videoFrameTexture = new Texture(videoFrame);
@@ -260,7 +265,9 @@ public class InGameState extends BaseState{
// Render the current state of the game. // Render the current state of the game.
RenderParameters.setModelViewProjectionMatrix(camera3D.combined); RenderParameters.setModelViewProjectionMatrix(camera3D.combined);
RenderParameters.setEyePosition(camera3D.position); RenderParameters.setEyePosition(camera3D.position);
gameWorld.getSystem(RenderingSystem.class).process(); gameWorld.getSystem(MarkerRenderingSystem.class).setMarkerData(data);
gameWorld.getSystem(MarkerRenderingSystem.class).process();
gameWorld.getSystem(ObjectRenderingSystem.class).process();
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST); Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
}frameBuffer.end(); }frameBuffer.end();
@@ -325,6 +332,8 @@ public class InGameState extends BaseState{
headC.draw(core.batch); headC.draw(core.batch);
}core.batch.end(); }core.batch.end();
} }
data = null;
} }
@Override @Override

View File

@@ -0,0 +1,77 @@
/*
* 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.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
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;
public class MarkerPositioningSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
private static final String TAG = "MARKER_POSITIONING_SYSTEM";
private static final String CLASS_NAME = MarkerPositioningSystem.class.getSimpleName();
private MarkerData markers;
@SuppressWarnings("unchecked")
public MarkerPositioningSystem(){
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class));
markers = null;
}
public void setMarkerData(MarkerData markers){
this.markers = markers;
}
@Override
protected void process(Entity e) {
MarkerCodeComponent marker;
GeometryComponent geometry;
if(markers == null)
return;
Gdx.app.log(TAG, CLASS_NAME + ".process(): Getting components.");
marker = markerMapper.get(e);
geometry = geometryMapper.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(): Processing marker code " + Integer.toString(markers.markerCodes[i]) + ".");
geometry.position.set(markers.translationVectors[i]);
geometry.rotation.set(markers.rotationMatrices[i]);
}
}else{
Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + ".");
}
}
markers = null;
}
}

View File

@@ -0,0 +1,108 @@
package ve.ucv.ciens.ccg.nxtar.systems;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters;
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.GL20;
import com.badlogic.gdx.math.Matrix4;
public class MarkerRenderingSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<ShaderComponent> shaderMapper;
@Mapper ComponentMapper<MeshComponent> meshMapper;
private static final String TAG = "MARKER_RENDERING_SYSTEM";
private static final String CLASS_NAME = MarkerRenderingSystem.class.getSimpleName();
/**
* <p>A matrix representing 3D translations.</p>
*/
private Matrix4 translationMatrix;
/**
* <p>A matrix representing 3D rotations.</p>
*/
private Matrix4 rotationMatrix;
/**
* <p>A matrix representing 3D scalings.</p>
*/
private Matrix4 scalingMatrix;
/**
* <p>The total transformation to be applied to an entity.</p>
*/
private Matrix4 combinedTransformationMatrix;
MarkerData markers;
@SuppressWarnings("unchecked")
public MarkerRenderingSystem(){
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, ShaderComponent.class, MeshComponent.class));
markers = null;
translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f);
rotationMatrix = new Matrix4().idt();
scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f);
combinedTransformationMatrix = new Matrix4();
}
public void setMarkerData(MarkerData markers){
this.markers = markers;
}
@Override
protected void process(Entity e) {
MarkerCodeComponent marker;
GeometryComponent geometry;
ShaderComponent shaderComp;
MeshComponent meshComp;
if(markers == null)
return;
Gdx.app.log(TAG, CLASS_NAME + ".process(): Getting components.");
marker = markerMapper.get(e);
geometry = geometryMapper.get(e);
shaderComp = shaderMapper.get(e);
meshComp = meshMapper.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.set(geometry.rotation);
scalingMatrix.setToScaling(geometry.scaling);
combinedTransformationMatrix.idt().mul(scalingMatrix).mul(rotationMatrix).mul(translationMatrix);
RenderParameters.setTransformationMatrix(combinedTransformationMatrix);
// Render the marker;
shaderComp.shader.getShaderProgram().begin();{
shaderComp.shader.setUniforms();
meshComp.model.render(shaderComp.shader.getShaderProgram(), GL20.GL_TRIANGLES);
}shaderComp.shader.getShaderProgram().end();
}
}else{
Gdx.app.log(TAG, CLASS_NAME + ".process(): Skipping marker number " + Integer.toString(i) + ".");
}
}
markers = null;
}
}

View File

@@ -16,7 +16,8 @@
package ve.ucv.ciens.ccg.nxtar.systems; package ve.ucv.ciens.ccg.nxtar.systems;
import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent; import ve.ucv.ciens.ccg.nxtar.components.GeometryComponent;
import ve.ucv.ciens.ccg.nxtar.components.ModelComponent; import ve.ucv.ciens.ccg.nxtar.components.MarkerCodeComponent;
import ve.ucv.ciens.ccg.nxtar.components.MeshComponent;
import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent; import ve.ucv.ciens.ccg.nxtar.components.ShaderComponent;
import ve.ucv.ciens.ccg.nxtar.graphics.LightSource; import ve.ucv.ciens.ccg.nxtar.graphics.LightSource;
import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters; import ve.ucv.ciens.ccg.nxtar.graphics.RenderParameters;
@@ -31,42 +32,73 @@ import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.Vector3;
public class RenderingSystem extends EntityProcessingSystem { /**
* <p>Entity processing system in charge of rendering 3D objects using OpenGL. The
* entities to be rendered must have a geometry, shader and mesh component associated.</p>
*/
public class ObjectRenderingSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<GeometryComponent> geometryMapper; @Mapper ComponentMapper<GeometryComponent> geometryMapper;
@Mapper ComponentMapper<ShaderComponent> shaderMapper; @Mapper ComponentMapper<ShaderComponent> shaderMapper;
@Mapper ComponentMapper<ModelComponent> modelMapper; @Mapper ComponentMapper<MeshComponent> modelMapper;
private static final Vector3 LIGHT_POSITION = new Vector3(2.0f, 2.0f, 4.0f);
private static final Color AMBIENT_COLOR = new Color(0.0f, 0.1f, 0.2f, 1.0f);
private static final Color DIFFUSE_COLOR = new Color(1.0f, 1.0f, 1.0f, 1.0f);
private static final Color SPECULAR_COLOR = new Color(1.0f, 0.8f, 0.0f, 1.0f);
private static final float SHINYNESS = 50.0f;
/**
* <p>A matrix representing 3D translations.</p>
*/
private Matrix4 translationMatrix; private Matrix4 translationMatrix;
/**
* <p>A matrix representing 3D rotations.</p>
*/
private Matrix4 rotationMatrix; private Matrix4 rotationMatrix;
/**
* <p>A matrix representing 3D scalings.</p>
*/
private Matrix4 scalingMatrix; private Matrix4 scalingMatrix;
/**
* <p>The total transformation to be applied to an entity.</p>
*/
private Matrix4 combinedTransformationMatrix; private Matrix4 combinedTransformationMatrix;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public RenderingSystem() { public ObjectRenderingSystem() {
super(Aspect.getAspectForAll(GeometryComponent.class, ShaderComponent.class, ModelComponent.class)); super(Aspect.getAspectForAll(GeometryComponent.class, ShaderComponent.class, MeshComponent.class).exclude(MarkerCodeComponent.class));
RenderParameters.setLightSource1(new LightSource(new Vector3(2.0f, 2.0f, 4.0f), new Color(0.0f, 0.1f, 0.2f, 1.0f), new Color(1.0f, 1.0f, 1.0f, 1.0f), new Color(1.0f, 0.8f, 0.0f, 1.0f), 50.0f)); RenderParameters.setLightSource1(new LightSource(LIGHT_POSITION, AMBIENT_COLOR, DIFFUSE_COLOR, SPECULAR_COLOR, SHINYNESS));
translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f); translationMatrix = new Matrix4().setToTranslation(0.0f, 0.0f, 0.0f);
rotationMatrix = new Matrix4().setToRotation(1.0f, 0.0f, 0.0f, 0.0f); rotationMatrix = new Matrix4().idt();
scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f); scalingMatrix = new Matrix4().setToScaling(0.0f, 0.0f, 0.0f);
combinedTransformationMatrix = new Matrix4(); combinedTransformationMatrix = new Matrix4();
} }
/**
* <p>Renders the entity passed by parameter, calculating it's corresponding geometric
* transformation and setting and calling it's associated shader program.</p>
*
* @param e The entity to be processed.
*/
@Override @Override
protected void process(Entity e) { protected void process(Entity e) {
GeometryComponent geometryComponent; GeometryComponent geometryComponent;
ShaderComponent shaderComponent; ShaderComponent shaderComponent;
ModelComponent modelComponent; MeshComponent meshComponent;
// Get the necessary components. // Get the necessary components.
geometryComponent = geometryMapper.get(e); geometryComponent = geometryMapper.get(e);
modelComponent = modelMapper.get(e); meshComponent = modelMapper.get(e);
shaderComponent = shaderMapper.get(e); shaderComponent = shaderMapper.get(e);
// Calculate the geometric transformation for this entity. // Calculate the geometric transformation for this entity.
translationMatrix.setToTranslation(geometryComponent.position); translationMatrix.setToTranslation(geometryComponent.position);
rotationMatrix.rotate(geometryComponent.rotation); rotationMatrix.set(geometryComponent.rotation);
scalingMatrix.setToScaling(geometryComponent.scaling); scalingMatrix.setToScaling(geometryComponent.scaling);
combinedTransformationMatrix.idt().mul(scalingMatrix).mul(rotationMatrix).mul(translationMatrix); combinedTransformationMatrix.idt().mul(scalingMatrix).mul(rotationMatrix).mul(translationMatrix);
@@ -76,7 +108,7 @@ public class RenderingSystem extends EntityProcessingSystem {
// Render this entity. // Render this entity.
shaderComponent.shader.getShaderProgram().begin();{ shaderComponent.shader.getShaderProgram().begin();{
shaderComponent.shader.setUniforms(); shaderComponent.shader.setUniforms();
modelComponent.model.render(shaderComponent.shader.getShaderProgram(), GL20.GL_TRIANGLES); meshComponent.model.render(shaderComponent.shader.getShaderProgram(), GL20.GL_TRIANGLES);
}shaderComponent.shader.getShaderProgram().end(); }shaderComponent.shader.getShaderProgram().end();
} }
} }

View File

@@ -36,6 +36,7 @@ public abstract class ProjectConstants{
public static final int MENU_BUTTON_FONT_SIZE; public static final int MENU_BUTTON_FONT_SIZE;
public static final String FONT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; public static final String FONT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
public static final int MAXIMUM_NUMBER_OF_MARKERS = 5;
public static final int CALIBRATION_PATTERN_POINTS = 54; public static final int CALIBRATION_PATTERN_POINTS = 54;
public static final int CALIBRATION_SAMPLES = 10; public static final int CALIBRATION_SAMPLES = 10;