Fixed device orientation calculation. Other assorted fixes.

This commit is contained in:
2014-06-20 11:32:02 -04:30
parent 6a392856ee
commit 99236420d1
9 changed files with 650 additions and 140 deletions

View File

@@ -238,7 +238,15 @@ public class NxtARCore extends Game implements ApplicationEventsListener{
states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this); states[game_states_t.MAIN_MENU.getValue()] = new OuyaMainMenuState(this);
else else
states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this); states[game_states_t.MAIN_MENU.getValue()] = new TabletMainMenuState(this);
try{
states[game_states_t.IN_GAME.getValue()] = new InGameState(this); states[game_states_t.IN_GAME.getValue()] = new InGameState(this);
}catch(IllegalStateException e){
Gdx.app.error(TAG, CLASS_NAME + ".create(): Illegal state: " + e.getMessage());
Gdx.app.exit();
return;
}
states[game_states_t.CALIBRATION.getValue()] = new CameraCalibrationState(this); states[game_states_t.CALIBRATION.getValue()] = new CameraCalibrationState(this);
// Register controller listeners. // Register controller listeners.

View File

@@ -20,12 +20,19 @@ import aurelienribon.tweenengine.TweenEquations;
import aurelienribon.tweenengine.primitives.MutableFloat; import aurelienribon.tweenengine.primitives.MutableFloat;
import com.artemis.Component; import com.artemis.Component;
import com.badlogic.gdx.graphics.Color;
public class FadeEffectComponent extends Component{ public class FadeEffectComponent extends Component{
private MutableFloat alpha; private MutableFloat alpha;
private Tween fadeIn; private Tween fadeIn;
private Tween fadeOut; private Tween fadeOut;
public Color color;
/**
* <p>Creates a fade to/from white depending on the parameter.</p>
*
* @param fadeIn True to create a fade FROM white, false for a fade TO white.
*/
public FadeEffectComponent(boolean fadeIn){ public FadeEffectComponent(boolean fadeIn){
if(fadeIn){ if(fadeIn){
this.alpha = new MutableFloat(1.0f); this.alpha = new MutableFloat(1.0f);
@@ -36,12 +43,50 @@ public class FadeEffectComponent extends Component{
this.fadeOut = Tween.to(alpha, 0, 2.5f).target(1.0f).ease(TweenEquations.easeInQuint); this.fadeOut = Tween.to(alpha, 0, 2.5f).target(1.0f).ease(TweenEquations.easeInQuint);
this.fadeIn = null; this.fadeIn = null;
} }
color = new Color(Color.WHITE);
} }
/**
* <p>Creates a fade effect with the desired parameters.</p>
*
* @param fadeIn True to create a fade FROM color, false for a fade TO color.
* @param color The color of the effect.
*/
public FadeEffectComponent(boolean fadeIn, Color color){
this(fadeIn);
this.color.set(color);
}
/**
* <p>Creates a fade out effect of the desired color.</p>
*
* @param color The color of the effect.
*/
public FadeEffectComponent(Color color){
this(false, color);
}
/**
* <p>Creates a white fade out effect.</p>
*/
public FadeEffectComponent(){
this(false);
}
/**
* <p>The current transparency of the effect.</p>
*
* @return The transparency.
*/
public float getFloatValue(){ public float getFloatValue(){
return alpha.floatValue(); return alpha.floatValue();
} }
/**
* <p>Interpolates the transparency of the effect by the given delta time in seconds.</p>
*
* @param delta
*/
public void update(float delta){ public void update(float delta){
if(fadeIn != null) if(fadeIn != null)
fadeIn.update(delta); fadeIn.update(delta);
@@ -50,6 +95,9 @@ public class FadeEffectComponent extends Component{
fadeOut.update(delta); fadeOut.update(delta);
} }
/**
* <p>Initializes the effect.</p>
*/
public void startEffect(){ public void startEffect(){
if(fadeIn != null) if(fadeIn != null)
fadeIn.start(); fadeIn.start();
@@ -58,14 +106,23 @@ public class FadeEffectComponent extends Component{
fadeOut.start(); fadeOut.start();
} }
/**
* @return True if the effect has been initialized. False otherwise.
*/
public boolean isEffectStarted(){ public boolean isEffectStarted(){
return fadeIn != null ? fadeIn.isStarted() : fadeOut.isStarted(); return fadeIn != null ? fadeIn.isStarted() : fadeOut.isStarted();
} }
/**
* @return True if this effect is a fade in. False if it is a fade out.
*/
public boolean isEffectFadeIn(){ public boolean isEffectFadeIn(){
return fadeIn != null; return fadeIn != null;
} }
/**
* @return True if the effect's interpolation is over. False otherwise.
*/
public boolean isEffectFinished(){ public boolean isEffectFinished(){
return fadeIn != null ? fadeIn.isFinished() : fadeOut.isFinished(); return fadeIn != null ? fadeIn.isFinished() : fadeOut.isFinished();
} }

View File

@@ -0,0 +1,432 @@
/*
* 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.states;
import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.NxtARCore.game_states_t;
import ve.ucv.ciens.ccg.nxtar.graphics.CustomPerspectiveCamera;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData;
import ve.ucv.ciens.ccg.nxtar.network.monitors.VideoFrameMonitor;
import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem;
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.systems.RobotArmPositioningSystem;
import ve.ucv.ciens.ccg.nxtar.utils.GameSettings;
import ve.ucv.ciens.ccg.nxtar.utils.ProjectConstants;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import com.artemis.World;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.controllers.Controller;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.Texture.TextureWrap;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
public class AutomaticActionState extends BaseState{
private static final String TAG = "IN_GAME_STATE";
private static final String CLASS_NAME = AutomaticActionState.class.getSimpleName();
private static final String BACKGROUND_SHADER_PATH = "shaders/bckg/bckg";
private static final float NEAR = 0.01f;
private static final float FAR = 100.0f;
// Background related fields.
private Sprite background;
private float uScaling[];
private Texture backgroundTexture;
private ShaderProgram backgroundShader;
// 3D rendering fields.
private ModelBatch modelBatch;
private FrameBuffer frameBuffer;
private Sprite frameBufferSprite;
// Game related fields.
private World gameWorld;
private MarkerRenderingSystem markerRenderingSystem;
private ObjectRenderingSystem objectRenderingSystem;
private RobotArmPositioningSystem robotArmPositioningSystem;
private FadeEffectRenderingSystem fadeEffectRenderingSystem;
// Cameras.
private OrthographicCamera unitaryOrthographicCamera;
private OrthographicCamera pixelPerfectOrthographicCamera;
private CustomPerspectiveCamera perspectiveCamera;
// Video stream graphics.
private Texture videoFrameTexture;
private Sprite renderableVideoFrame;
private Pixmap videoFrame;
// Button touch helper fields.
private boolean[] buttonsTouched;
private int[] buttonPointers;
private boolean[] gamepadButtonPressed;
// Monitors.
private VideoFrameMonitor frameMonitor;
// private MotorEventQueue queue;
// private SensorReportThread sensorThread;
public AutomaticActionState(final NxtARCore core){
this.core = core;
frameMonitor = VideoFrameMonitor.getInstance();
// queue = MotorEventQueue.getInstance();
// sensorThread = SensorReportThread.getInstance();
// Set up rendering fields;
videoFrame = null;
// Set up the cameras.
pixelPerfectOrthographicCamera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
unitaryOrthographicCamera = new OrthographicCamera(1.0f, Gdx.graphics.getHeight() / Gdx.graphics.getWidth());
// Set up input handling support fields.
win2world = new Vector3(0.0f, 0.0f, 0.0f);
touchPointWorldCoords = new Vector2();
buttonsTouched = new boolean[1];
buttonsTouched[0] = false;
buttonPointers = new int[1];
buttonPointers[0] = -1;
gamepadButtonPressed = new boolean[1];
gamepadButtonPressed[0] = false;
// Set up the background.
backgroundTexture = new Texture(Gdx.files.internal("data/gfx/textures/tile_aqua.png"));
backgroundTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
backgroundTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
background = new Sprite(backgroundTexture);
background.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
background.setPosition(-(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));
// Set up the shader.
backgroundShader = new ShaderProgram(Gdx.files.internal(BACKGROUND_SHADER_PATH + "_vert.glsl"), Gdx.files.internal(BACKGROUND_SHADER_PATH + "_frag.glsl"));
if(!backgroundShader.isCompiled()){
Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the background shader.");
Gdx.app.error(TAG, CLASS_NAME + backgroundShader.getLog());
backgroundShader = null;
}
uScaling = new float[2];
uScaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f;
uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f;
// Set up the 3D rendering.
modelBatch = new ModelBatch();
frameBuffer = null;
perspectiveCamera = null;
frameBufferSprite = null;
// Set up the game world.
gameWorld = GameSettings.getGameWorld();
robotArmPositioningSystem = new RobotArmPositioningSystem();
markerRenderingSystem = new MarkerRenderingSystem(modelBatch);
objectRenderingSystem = new ObjectRenderingSystem(modelBatch);
fadeEffectRenderingSystem = new FadeEffectRenderingSystem();
gameWorld.setSystem(new MarkerPositioningSystem());
gameWorld.setSystem(robotArmPositioningSystem, Ouya.runningOnOuya);
gameWorld.setSystem(new GeometrySystem());
gameWorld.setSystem(new AnimationSystem());
gameWorld.setSystem(new CollisionDetectionSystem());
gameWorld.setSystem(GameSettings.getGameLogicSystem());
gameWorld.setSystem(markerRenderingSystem, true);
gameWorld.setSystem(objectRenderingSystem, true);
gameWorld.setSystem(fadeEffectRenderingSystem, true);
gameWorld.initialize();
}
/*;;;;;;;;;;;;;;;;;;;;;;
; BASE STATE METHODS ;
;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public void render(float delta){
int w, h;
byte[] frame;
MarkerData data;
TextureRegion region;
float focalPointX, focalPointY, cameraCenterX, cameraCenterY;
// Clear the screen.
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// Render the background.
core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined);
core.batch.begin();{
if(backgroundShader != null){
core.batch.setShader(backgroundShader);
backgroundShader.setUniform2fv("u_scaling", uScaling, 0, 2);
}
background.draw(core.batch);
if(backgroundShader != null) core.batch.setShader(null);
}core.batch.end();
// Fetch the current video frame.
frame = frameMonitor.getCurrentFrame();
w = frameMonitor.getFrameDimensions().getWidth();
h = frameMonitor.getFrameDimensions().getHeight();
// Create the 3D perspective camera and the frame buffer object if they don't exist.
if(perspectiveCamera == null && frameBuffer == null){
frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true);
frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
perspectiveCamera = new CustomPerspectiveCamera(67, w, h);
perspectiveCamera.translate(0.0f, 0.0f, 0.0f);
perspectiveCamera.near = NEAR;
perspectiveCamera.far = FAR;
perspectiveCamera.lookAt(0.0f, 0.0f, -1.0f);
perspectiveCamera.update();
}
// Attempt to find the markers in the current video frame.
data = core.cvProc.findMarkersInFrame(frame);
// If a valid frame was fetched.
if(data != null && data.outFrame != null){
// Set the camera to the correct projection.
focalPointX = core.cvProc.getFocalPointX();
focalPointY = core.cvProc.getFocalPointY();
cameraCenterX = core.cvProc.getCameraCenterX();
cameraCenterY = core.cvProc.getCameraCenterY();
perspectiveCamera.setCustomARProjectionMatrix(focalPointX, focalPointY, cameraCenterX, cameraCenterY, NEAR, FAR, w, h);
perspectiveCamera.update(perspectiveCamera.projection);
// Update the game state.
gameWorld.setDelta(Gdx.graphics.getDeltaTime() * 1000);
gameWorld.getSystem(MarkerPositioningSystem.class).setMarkerData(data);
gameWorld.process();
// Decode the video frame.
videoFrame = new Pixmap(data.outFrame, 0, w * h);
videoFrameTexture = new Texture(videoFrame);
videoFrameTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
videoFrame.dispose();
// Convert the decoded frame into a renderable texture.
region = new TextureRegion(videoFrameTexture, 0, 0, w, h);
if(renderableVideoFrame == null)
renderableVideoFrame = new Sprite(region);
else
renderableVideoFrame.setRegion(region);
renderableVideoFrame.setOrigin(renderableVideoFrame.getWidth() / 2, renderableVideoFrame.getHeight() / 2);
renderableVideoFrame.setPosition(0, 0);
// Set the 3D frame buffer for rendering.
frameBuffer.begin();{
// Set OpenGL state.
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glDisable(GL20.GL_TEXTURE_2D);
// Call rendering systems.
markerRenderingSystem.begin(perspectiveCamera);
markerRenderingSystem.process();
markerRenderingSystem.end();
}frameBuffer.end();
// Set the frame buffer object texture to a renderable sprite.
region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
region.flip(false, true);
if(frameBufferSprite == null)
frameBufferSprite = new Sprite(region);
else
frameBufferSprite.setRegion(region);
frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2);
frameBufferSprite.setPosition(0, 0);
// Set the position and orientation of the renderable video frame and the frame buffer.
if(!Ouya.runningOnOuya){
renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() );
renderableVideoFrame.rotate90(true);
renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, 0.5f - renderableVideoFrame.getHeight());
frameBufferSprite.setSize(1.0f, frameBufferSprite.getHeight() / frameBufferSprite.getWidth() );
frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight());
}else{
float xSize = Gdx.graphics.getHeight() * (w / h);
renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight());
renderableVideoFrame.rotate90(true);
renderableVideoFrame.translate(-renderableVideoFrame.getWidth() / 2, -renderableVideoFrame.getHeight() / 2);
frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight());
frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2);
}
// Set the correct camera for the device.
if(!Ouya.runningOnOuya){
core.batch.setProjectionMatrix(unitaryOrthographicCamera.combined);
}else{
core.batch.setProjectionMatrix(pixelPerfectOrthographicCamera.combined);
}
// Render the video frame and the frame buffer.
core.batch.begin();{
renderableVideoFrame.draw(core.batch);
frameBufferSprite.draw(core.batch);
}core.batch.end();
// Clear the video frame from memory.
videoFrameTexture.dispose();
}
data = null;
}
@Override
public void dispose(){
if(modelBatch != null)
modelBatch.dispose();
if(videoFrameTexture != null)
videoFrameTexture.dispose();
if(backgroundTexture != null)
backgroundTexture.dispose();
if(backgroundShader != null)
backgroundShader.dispose();
if(frameBuffer != null)
frameBuffer.dispose();
fadeEffectRenderingSystem.dispose();
}
/*;;;;;;;;;;;;;;;;;;
; HELPER METHODS ;
;;;;;;;;;;;;;;;;;;*/
@Override
public void onStateSet(){
stateActive = true;
Gdx.input.setInputProcessor(this);
Gdx.input.setCatchBackKey(true);
Gdx.input.setCatchMenuKey(true);
}
@Override
public void onStateUnset(){
stateActive = false;
Gdx.input.setInputProcessor(null);
Gdx.input.setCatchBackKey(false);
Gdx.input.setCatchMenuKey(false);
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;
; INPUT PROCESSOR METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean touchDown(int screenX, int screenY, int pointer, int button){
if(!Ouya.runningOnOuya){
win2world.set(screenX, screenY, 0.0f);
unitaryOrthographicCamera.unproject(win2world);
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
}
return false;
}
@Override
public boolean touchUp(int screenX, int screenY, int pointer, int button){
if(!Ouya.runningOnOuya){
win2world.set(screenX, screenY, 0.0f);
unitaryOrthographicCamera.unproject(win2world);
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
}
return false;
}
@Override
public boolean touchDragged(int screenX, int screenY, int pointer){
if(!Ouya.runningOnOuya){
win2world.set(screenX, screenY, 0.0f);
unitaryOrthographicCamera.unproject(win2world);
touchPointWorldCoords.set(win2world.x * Gdx.graphics.getWidth(), win2world.y * Gdx.graphics.getHeight());
}
return false;
}
@Override
public boolean keyDown(int keycode){
if(keycode == Input.Keys.BACK){
core.nextState = game_states_t.MAIN_MENU;
return true;
}
return false;
}
/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONTROLLER LISTENER METHODS ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
@Override
public boolean buttonDown(Controller controller, int buttonCode){
if(stateActive){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown() :: " + controller.getName() + " :: " + Integer.toString(buttonCode));
if(buttonCode == Ouya.BUTTON_O){
}
return true;
}else{
return false;
}
}
@Override
public boolean buttonUp(Controller controller, int buttonCode){
if(stateActive){
Gdx.app.log(TAG, CLASS_NAME + ".buttonDown() :: " + controller.getName() + " :: " + Integer.toString(buttonCode));
if(buttonCode == Ouya.BUTTON_O){ }
return true;
}else{
return false;
}
}
}

View File

@@ -27,10 +27,7 @@ import ve.ucv.ciens.ccg.nxtar.input.UserInput;
import ve.ucv.ciens.ccg.nxtar.interfaces.ImageProcessor.MarkerData; 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.AnimationSystem;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerPositioningSystem;
import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.MarkerRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem; import ve.ucv.ciens.ccg.nxtar.systems.ObjectRenderingSystem;
@@ -94,9 +91,6 @@ public class InGameState extends BaseState{
private ModelBatch modelBatch; private ModelBatch modelBatch;
private FrameBuffer frameBuffer; private FrameBuffer frameBuffer;
private Sprite frameBufferSprite; private Sprite frameBufferSprite;
// private FrameBuffer robotArmFrameBuffer;
// private Sprite robotArmFrameBufferSprite;
// private ShaderProgram alphaShader;
// Game related fields. // Game related fields.
private World gameWorld; private World gameWorld;
@@ -126,7 +120,7 @@ public class InGameState extends BaseState{
private Texture armControlButtonTexture; private Texture armControlButtonTexture;
private Texture correctAngleLedOnTexture; private Texture correctAngleLedOnTexture;
private Texture correctAngleLedOffTexture; private Texture correctAngleLedOffTexture;
private Texture crossSectionFloorTexture; private Texture orientationSliderTexture;
// Gui renderable sprites. // Gui renderable sprites.
private Sprite motorAButton; private Sprite motorAButton;
@@ -144,9 +138,7 @@ public class InGameState extends BaseState{
private Sprite armControlButton; private Sprite armControlButton;
private Sprite correctAngleLedOnSprite; private Sprite correctAngleLedOnSprite;
private Sprite correctAngleLedOffSprite; private Sprite correctAngleLedOffSprite;
private Sprite crossSectionFloorLed; private Sprite orientationSlider;
private Sprite normalFloorLed;
private Sprite itemNearbyFloorLed;
// Button touch helper fields. // Button touch helper fields.
private boolean[] buttonsTouched; private boolean[] buttonsTouched;
@@ -156,14 +148,12 @@ public class InGameState extends BaseState{
// Monitors. // Monitors.
private VideoFrameMonitor frameMonitor; private VideoFrameMonitor frameMonitor;
private MotorEventQueue queue; private MotorEventQueue queue;
// private SensorReportThread sensorThread;
public InGameState(final NxtARCore core){ public InGameState(final NxtARCore core) throws IllegalStateException{
this.core = core; this.core = core;
frameMonitor = VideoFrameMonitor.getInstance(); frameMonitor = VideoFrameMonitor.getInstance();
queue = MotorEventQueue.getInstance(); queue = MotorEventQueue.getInstance();
controlMode = robot_control_mode_t.WHEEL_CONTROL; controlMode = robot_control_mode_t.WHEEL_CONTROL;
// sensorThread = SensorReportThread.getInstance();
// Set up rendering fields; // Set up rendering fields;
videoFrame = null; videoFrame = null;
@@ -225,61 +215,26 @@ public class InGameState extends BaseState{
uScaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f; uScaling[0] = Gdx.graphics.getWidth() > Gdx.graphics.getHeight() ? 16.0f : 9.0f;
uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f; uScaling[1] = Gdx.graphics.getHeight() > Gdx.graphics.getWidth() ? 16.0f : 9.0f;
// Set up the alpha shader.
// alphaShader = new ShaderProgram(Gdx.files.internal(ALPHA_SHADER_PREFIX + "_vert.glsl"), Gdx.files.internal(ALPHA_SHADER_PREFIX + "_frag.glsl"));
// if(!alphaShader.isCompiled()){
// Gdx.app.error(TAG, CLASS_NAME + ".InGameState() :: Failed to compile the alpha shader.");
// Gdx.app.error(TAG, CLASS_NAME + alphaShader.getLog());
// alphaShader = null;
// }
// Set up the 3D rendering. // Set up the 3D rendering.
modelBatch = new ModelBatch(); modelBatch = new ModelBatch();
frameBuffer = null; frameBuffer = null;
perspectiveCamera = null; perspectiveCamera = null;
frameBufferSprite = null; frameBufferSprite = null;
// robotArmFrameBuffer = null;
// robotArmFrameBufferSprite = null;
// Set up floor leds and possibly the buttons.
correctAngleLedOnTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Green.png"));
correctAngleLedOffTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Red.png"));
crossSectionFloorTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Cyan.png"));
crossSectionFloorLed = new Sprite(crossSectionFloorTexture);
normalFloorLed = new Sprite(correctAngleLedOffTexture);
itemNearbyFloorLed = new Sprite(correctAngleLedOnTexture);
crossSectionFloorLed.setSize(crossSectionFloorLed.getWidth() * 0.25f, crossSectionFloorLed.getHeight() * 0.25f);
normalFloorLed.setSize(normalFloorLed.getWidth() * 0.25f, normalFloorLed.getHeight() * 0.25f);
itemNearbyFloorLed.setSize(itemNearbyFloorLed.getWidth() * 0.25f, itemNearbyFloorLed.getHeight() * 0.25f);
crossSectionFloorLed.setPosition(-(crossSectionFloorLed.getWidth() / 2), (Utils.getScreenHeight() / 2) - crossSectionFloorLed.getHeight() - 5);
normalFloorLed.setPosition(-(normalFloorLed.getWidth() / 2), (Utils.getScreenHeight() / 2) - normalFloorLed.getHeight() - 5);
itemNearbyFloorLed.setPosition(-(itemNearbyFloorLed.getWidth() / 2), (Utils.getScreenHeight() / 2) - itemNearbyFloorLed.getHeight() - 5);
// Set up he buttons.
if(!Ouya.runningOnOuya) if(!Ouya.runningOnOuya)
setUpButtons(); setUpButtons();
// Set up the game world. // Set up the game world.
gameWorld = GameSettings.getGameWorld(); gameWorld = GameSettings.getGameWorld();
robotArmPositioningSystem = new RobotArmPositioningSystem(); robotArmPositioningSystem = gameWorld.getSystem(RobotArmPositioningSystem.class);
markerRenderingSystem = new MarkerRenderingSystem(modelBatch); markerRenderingSystem = gameWorld.getSystem(MarkerRenderingSystem.class);
objectRenderingSystem = new ObjectRenderingSystem(modelBatch); objectRenderingSystem = gameWorld.getSystem(ObjectRenderingSystem.class);
fadeEffectRenderingSystem = new FadeEffectRenderingSystem(); fadeEffectRenderingSystem = gameWorld.getSystem(FadeEffectRenderingSystem.class);
gameWorld.setSystem(new MarkerPositioningSystem()); if(robotArmPositioningSystem == null || markerRenderingSystem == null || objectRenderingSystem == null || fadeEffectRenderingSystem == null)
gameWorld.setSystem(robotArmPositioningSystem, Ouya.runningOnOuya); throw new IllegalStateException("One or more essential systems are null.");
gameWorld.setSystem(new GeometrySystem());
gameWorld.setSystem(new AnimationSystem());
gameWorld.setSystem(new CollisionDetectionSystem());
gameWorld.setSystem(GameSettings.getGameLogicSystem());
gameWorld.setSystem(markerRenderingSystem, true);
gameWorld.setSystem(objectRenderingSystem, true);
gameWorld.setSystem(fadeEffectRenderingSystem, true);
gameWorld.initialize();
} }
/*;;;;;;;;;;;;;;;;;;;;;; /*;;;;;;;;;;;;;;;;;;;;;;
@@ -288,7 +243,10 @@ public class InGameState extends BaseState{
@Override @Override
public void render(float delta){ public void render(float delta){
final float MIN_SLIDER_X = correctAngleLedOnSprite != null ? -(Utils.getScreenWidth() / 2) + 5 + correctAngleLedOnSprite.getWidth() : -(Utils.getScreenWidth() / 2) + 5;
final float MAX_SLIDER_X = correctAngleLedOnSprite != null ? (Utils.getScreenWidth() / 2) - 5 - correctAngleLedOnSprite.getWidth(): (Utils.getScreenWidth() / 2) - 5;
int w, h; int w, h;
float t, xSliderPos;
byte[] frame; byte[] frame;
MarkerData data; MarkerData data;
TextureRegion region; TextureRegion region;
@@ -319,9 +277,6 @@ public class InGameState extends BaseState{
frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true); frameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true);
frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear); frameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
// robotArmFrameBuffer = new FrameBuffer(Format.RGBA8888, w, h, true);
// robotArmFrameBuffer.getColorBufferTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
perspectiveCamera = new CustomPerspectiveCamera(67, w, h); perspectiveCamera = new CustomPerspectiveCamera(67, w, h);
perspectiveCamera.translate(0.0f, 0.0f, 0.0f); perspectiveCamera.translate(0.0f, 0.0f, 0.0f);
perspectiveCamera.near = NEAR; perspectiveCamera.near = NEAR;
@@ -382,18 +337,6 @@ public class InGameState extends BaseState{
} }
}frameBuffer.end(); }frameBuffer.end();
// robotArmFrameBuffer.begin();{
// // Set OpenGL state.
// Gdx.gl.glClearColor(0, 0, 0, 0);
// Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
// Gdx.gl.glDisable(GL20.GL_TEXTURE_2D);
//
// // Call rendering systems.
// objectRenderingSystem.begin(perspectiveCamera);
// objectRenderingSystem.process();
// objectRenderingSystem.end();
// }robotArmFrameBuffer.end();
// Set the frame buffer object texture to a renderable sprite. // Set the frame buffer object texture to a renderable sprite.
region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight()); region = new TextureRegion(frameBuffer.getColorBufferTexture(), 0, 0, frameBuffer.getWidth(), frameBuffer.getHeight());
region.flip(false, true); region.flip(false, true);
@@ -404,16 +347,6 @@ public class InGameState extends BaseState{
frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2); frameBufferSprite.setOrigin(frameBufferSprite.getWidth() / 2, frameBufferSprite.getHeight() / 2);
frameBufferSprite.setPosition(0, 0); frameBufferSprite.setPosition(0, 0);
// Set the other frame buffer object texture to a renderable sprite.
// region = new TextureRegion(robotArmFrameBuffer.getColorBufferTexture(), 0, 0, robotArmFrameBuffer.getWidth(), robotArmFrameBuffer.getHeight());
// region.flip(false, true);
// if(robotArmFrameBufferSprite == null)
// robotArmFrameBufferSprite = new Sprite(region);
// else
// robotArmFrameBufferSprite.setRegion(region);
// robotArmFrameBufferSprite.setOrigin(robotArmFrameBuffer.getWidth() / 2, robotArmFrameBuffer.getHeight() / 2);
// robotArmFrameBufferSprite.setPosition(0, 0);
// Set the position and orientation of the renderable video frame and the frame buffer. // Set the position and orientation of the renderable video frame and the frame buffer.
if(!Ouya.runningOnOuya){ if(!Ouya.runningOnOuya){
renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() ); renderableVideoFrame.setSize(1.0f, renderableVideoFrame.getHeight() / renderableVideoFrame.getWidth() );
@@ -424,9 +357,6 @@ public class InGameState extends BaseState{
frameBufferSprite.rotate90(true); frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight()); frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, 0.5f - frameBufferSprite.getHeight());
// robotArmFrameBufferSprite.setSize(1.0f, robotArmFrameBufferSprite.getHeight() / robotArmFrameBufferSprite.getWidth() );
// robotArmFrameBufferSprite.rotate90(true);
// robotArmFrameBufferSprite.translate(-robotArmFrameBufferSprite.getWidth() / 2, 0.5f - robotArmFrameBufferSprite.getHeight());
}else{ }else{
float xSize = Gdx.graphics.getHeight() * (w / h); float xSize = Gdx.graphics.getHeight() * (w / h);
renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); renderableVideoFrame.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight());
@@ -436,10 +366,6 @@ public class InGameState extends BaseState{
frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight()); frameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Utils.getScreenHeight());
frameBufferSprite.rotate90(true); frameBufferSprite.rotate90(true);
frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2); frameBufferSprite.translate(-frameBufferSprite.getWidth() / 2, -frameBufferSprite.getHeight() / 2);
// robotArmFrameBufferSprite.setSize(xSize * ProjectConstants.OVERSCAN, Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
// robotArmFrameBufferSprite.rotate90(true);
// robotArmFrameBufferSprite.translate(-robotArmFrameBufferSprite.getWidth() / 2, -robotArmFrameBufferSprite.getHeight() / 2);
} }
// Set the correct camera for the device. // Set the correct camera for the device.
@@ -453,16 +379,6 @@ public class InGameState extends BaseState{
core.batch.begin();{ core.batch.begin();{
renderableVideoFrame.draw(core.batch); renderableVideoFrame.draw(core.batch);
frameBufferSprite.draw(core.batch); frameBufferSprite.draw(core.batch);
// Render the robot arm only when in the corresponding control mode. Always render it on the OUYA.
// if(controlMode.getValue() == robot_control_mode_t.ARM_CONTROL.getValue() || Ouya.runningOnOuya){
// if(alphaShader != null){
// core.batch.setShader(alphaShader);
// }
// robotArmFrameBufferSprite.draw(core.batch);
// if(alphaShader != null) core.batch.setShader(null);
// }
}core.batch.end(); }core.batch.end();
// Clear the video frame from memory. // Clear the video frame from memory.
@@ -497,13 +413,21 @@ public class InGameState extends BaseState{
headCButton.draw(core.batch); headCButton.draw(core.batch);
// Draw device rotation led. // Draw device rotation led.
if(Utils.isDeviceRollValid() && Math.abs(Gdx.input.getRoll()) < ProjectConstants.MAX_ABS_ROLL){ if(Utils.isDeviceRollValid()){
if(Math.abs(Gdx.input.getRoll()) < ProjectConstants.MAX_ABS_ROLL)
correctAngleLedOnSprite.draw(core.batch); correctAngleLedOnSprite.draw(core.batch);
else
correctAngleLedOffSprite.draw(core.batch);
t = (Gdx.input.getRoll() + 60.0f) / 120.0f;
xSliderPos = (MIN_SLIDER_X * t) + (MAX_SLIDER_X * (1.0f - t));
xSliderPos = xSliderPos < MIN_SLIDER_X ? MIN_SLIDER_X : (xSliderPos > MAX_SLIDER_X ? MAX_SLIDER_X : xSliderPos);
orientationSlider.setPosition(xSliderPos, orientationSlider.getY());
orientationSlider.draw(core.batch);
}else{ }else{
correctAngleLedOffSprite.draw(core.batch); correctAngleLedOffSprite.draw(core.batch);
orientationSlider.draw(core.batch);
} }
// TODO: Draw rotation slider.
}core.batch.end(); }core.batch.end();
} }
@@ -544,8 +468,8 @@ public class InGameState extends BaseState{
if(backgroundTexture != null) if(backgroundTexture != null)
backgroundTexture.dispose(); backgroundTexture.dispose();
if(crossSectionFloorTexture != null) if(orientationSliderTexture != null)
crossSectionFloorTexture.dispose(); orientationSliderTexture.dispose();
if(backgroundShader != null) if(backgroundShader != null)
backgroundShader.dispose(); backgroundShader.dispose();
@@ -553,16 +477,11 @@ public class InGameState extends BaseState{
if(frameBuffer != null) if(frameBuffer != null)
frameBuffer.dispose(); frameBuffer.dispose();
// if(robotArmFrameBuffer != null)
// robotArmFrameBuffer.dispose();
if(correctAngleLedOffTexture != null) if(correctAngleLedOffTexture != null)
correctAngleLedOffTexture.dispose(); correctAngleLedOffTexture.dispose();
if(correctAngleLedOnTexture != null) if(correctAngleLedOnTexture != null)
correctAngleLedOnTexture.dispose(); correctAngleLedOnTexture.dispose();
fadeEffectRenderingSystem.dispose();
} }
/*;;;;;;;;;;;;;;;;;; /*;;;;;;;;;;;;;;;;;;
@@ -657,6 +576,9 @@ public class InGameState extends BaseState{
armControlButton.setPosition(-(armControlButton.getWidth() / 2), headCButton.getY() - headCButton.getHeight() - 15); armControlButton.setPosition(-(armControlButton.getWidth() / 2), headCButton.getY() - headCButton.getHeight() - 15);
// Set up the correct angle leds. // Set up the correct angle leds.
correctAngleLedOnTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Green.png"));
correctAngleLedOffTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_Button_Red.png"));
correctAngleLedOnSprite = new Sprite(correctAngleLedOnTexture); correctAngleLedOnSprite = new Sprite(correctAngleLedOnTexture);
correctAngleLedOffSprite = new Sprite(correctAngleLedOffTexture); correctAngleLedOffSprite = new Sprite(correctAngleLedOffTexture);
@@ -665,6 +587,12 @@ public class InGameState extends BaseState{
correctAngleLedOnSprite.setPosition((Gdx.graphics.getWidth() / 2) - correctAngleLedOnSprite.getWidth() - 5, (Gdx.graphics.getHeight() / 2) - correctAngleLedOnSprite.getHeight() - 5); correctAngleLedOnSprite.setPosition((Gdx.graphics.getWidth() / 2) - correctAngleLedOnSprite.getWidth() - 5, (Gdx.graphics.getHeight() / 2) - correctAngleLedOnSprite.getHeight() - 5);
correctAngleLedOffSprite.setPosition((Gdx.graphics.getWidth() / 2) - correctAngleLedOffSprite.getWidth() - 5, (Gdx.graphics.getHeight() / 2) - correctAngleLedOffSprite.getHeight() - 5); correctAngleLedOffSprite.setPosition((Gdx.graphics.getWidth() / 2) - correctAngleLedOffSprite.getWidth() - 5, (Gdx.graphics.getHeight() / 2) - correctAngleLedOffSprite.getHeight() - 5);
// Set up orientation slider.
orientationSliderTexture = new Texture(Gdx.files.internal("data/gfx/gui/slider_black.png"));
orientationSlider = new Sprite(orientationSliderTexture);
orientationSlider.setSize(orientationSlider.getWidth() * 0.25f, orientationSlider.getHeight() * 0.25f);
orientationSlider.setPosition(-(orientationSlider.getWidth() / 2), (Utils.getScreenHeight() / 2) - orientationSlider.getHeight() - 5);
} }
/*;;;;;;;;;;;;;;;;;;;;;;;;;;; /*;;;;;;;;;;;;;;;;;;;;;;;;;;;

View File

@@ -18,22 +18,47 @@ package ve.ucv.ciens.ccg.nxtar.systems;
import ve.ucv.ciens.ccg.nxtar.NxtARCore; import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.components.BombGamePlayerComponent; import ve.ucv.ciens.ccg.nxtar.components.BombGamePlayerComponent;
import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator; import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator;
import ve.ucv.ciens.ccg.nxtar.utils.Utils;
import com.artemis.ComponentMapper; import com.artemis.ComponentMapper;
import com.artemis.Entity; import com.artemis.Entity;
import com.artemis.annotations.Mapper; import com.artemis.annotations.Mapper;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.utils.Disposable;
public class BombGamePlayerSystem extends PlayerSystemBase{ public class BombGamePlayerSystem extends PlayerSystemBase implements Disposable{
private static final float HEART_Y_POS = (Utils.getScreenHeight() / 2) - 69;
@Mapper ComponentMapper<BombGamePlayerComponent> playerMapper; @Mapper ComponentMapper<BombGamePlayerComponent> playerMapper;
private SpriteBatch batch;
private Texture heartTexture;
private Sprite heart;
public BombGamePlayerSystem(NxtARCore core){ public BombGamePlayerSystem(NxtARCore core){
super(BombGamePlayerComponent.class, core); super(BombGamePlayerComponent.class, core);
batch = new SpriteBatch();
heartTexture = new Texture(Gdx.files.internal("data/gfx/gui/Anonymous_heart_1.png"));
heart = new Sprite(heartTexture);
heart.setSize(heart.getWidth() * 0.5f, heart.getHeight() * 0.5f);
} }
@Override @Override
protected void process(Entity e) { protected void process(Entity e) {
float heartXPos;
BombGamePlayerComponent player = playerMapper.get(e); BombGamePlayerComponent player = playerMapper.get(e);
// Render remaining lives.
heartXPos = -(Utils.getScreenWidth() / 2) + 5;
for(int i = 0; i < player.lives; ++i){
heart.setPosition(heartXPos, HEART_Y_POS);
heart.draw(batch);
heartXPos += heart.getWidth() + 5;
}
// Check ending conditions.
if(player.lives == 0){ if(player.lives == 0){
player.gameFinished = true; player.gameFinished = true;
player.victory = false; player.victory = false;
@@ -42,7 +67,17 @@ public class BombGamePlayerSystem extends PlayerSystemBase{
player.victory = true; player.victory = true;
} }
// If met ending conditions then end the game.
if(player.gameFinished) if(player.gameFinished)
finishGame(player.victory); finishGame(player.victory);
} }
@Override
public void dispose() {
if(batch != null)
batch.dispose();
if(heartTexture != null)
heartTexture.dispose();
}
} }

View File

@@ -45,11 +45,16 @@ public class FadeEffectRenderingSystem extends EntityProcessingSystem implements
@Override @Override
protected void process(Entity e) { protected void process(Entity e) {
float r, g, b;
FadeEffectComponent fade = fadeMapper.get(e); FadeEffectComponent fade = fadeMapper.get(e);
r = fade.color.r;
g = fade.color.g;
b = fade.color.b;
this.batch.setProjectionMatrix(this.camera.combined); this.batch.setProjectionMatrix(this.camera.combined);
this.batch.begin();{ this.batch.begin();{
this.batch.setColor(1, 1, 1, fade.getFloatValue()); this.batch.setColor(r, g, b, fade.getFloatValue());
this.batch.draw(fadeTexture, -(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2)); this.batch.draw(fadeTexture, -(Gdx.graphics.getWidth() / 2), -(Gdx.graphics.getHeight() / 2));
this.batch.setColor(1, 1, 1, 1); this.batch.setColor(1, 1, 1, 1);
}this.batch.end(); }this.batch.end();

View File

@@ -26,10 +26,6 @@ import com.artemis.ComponentMapper;
import com.artemis.Entity; import com.artemis.Entity;
import com.artemis.annotations.Mapper; import com.artemis.annotations.Mapper;
import com.artemis.systems.EntityProcessingSystem; import com.artemis.systems.EntityProcessingSystem;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Matrix3;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Quaternion;
public class MarkerPositioningSystem extends EntityProcessingSystem { public class MarkerPositioningSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<MarkerCodeComponent> markerMapper; @Mapper ComponentMapper<MarkerCodeComponent> markerMapper;
@@ -37,18 +33,12 @@ public class MarkerPositioningSystem extends EntityProcessingSystem {
@Mapper ComponentMapper<VisibilityComponent> visibilityMapper; @Mapper ComponentMapper<VisibilityComponent> visibilityMapper;
private MarkerData markers; private MarkerData markers;
private Quaternion qAux;
private Matrix4 correctedRotation;
private Matrix3 mAux;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public MarkerPositioningSystem(){ public MarkerPositioningSystem(){
super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, VisibilityComponent.class)); super(Aspect.getAspectForAll(MarkerCodeComponent.class, GeometryComponent.class, VisibilityComponent.class));
markers = null; markers = null;
qAux = new Quaternion();
mAux = new Matrix3();
correctedRotation = new Matrix4();
} }
public void setMarkerData(MarkerData markers){ public void setMarkerData(MarkerData markers){
@@ -71,25 +61,8 @@ public class MarkerPositioningSystem extends EntityProcessingSystem {
for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){ for(int i = 0; i < ProjectConstants.MAXIMUM_NUMBER_OF_MARKERS; i++){
if(markers.markerCodes[i] != 1){ if(markers.markerCodes[i] != 1){
if(markers.markerCodes[i] == marker.code){ if(markers.markerCodes[i] == marker.code){
qAux.setFromMatrix(markers.rotationMatrices[i]).nor();
if(Math.abs(qAux.getRoll()) > 10.0f){
// qAux.setEulerAngles(qAux.getYaw(), qAux.getPitch(), 0.0f);
// qAux.toMatrix(correctedRotation.val);
// mAux.set(correctedRotation);
mAux.set(markers.rotationMatrices[i]);
Gdx.app.log("ROTATION", "YAW : " + Float.toString(qAux.getYaw()));
Gdx.app.log("ROTATION", "PITCH: " + Float.toString(qAux.getPitch()));
Gdx.app.log("ROTATION", "ROLL : " + Float.toString(qAux.getRoll()));
Gdx.app.log("ROTATION", "------------------------------------------");
}else{
mAux.set(markers.rotationMatrices[i]);
}
geometry.position.set(markers.translationVectors[i]); geometry.position.set(markers.translationVectors[i]);
geometry.rotation.set(mAux); geometry.rotation.set(markers.rotationMatrices[i]);
visibility.visible = true; visibility.visible = true;
break; break;
}else{ }else{

View File

@@ -18,21 +18,38 @@ package ve.ucv.ciens.ccg.nxtar.utils;
import ve.ucv.ciens.ccg.nxtar.NxtARCore; import ve.ucv.ciens.ccg.nxtar.NxtARCore;
import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator; import ve.ucv.ciens.ccg.nxtar.entities.BombGameEntityCreator;
import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase; import ve.ucv.ciens.ccg.nxtar.entities.EntityCreatorBase;
import ve.ucv.ciens.ccg.nxtar.systems.AnimationSystem;
import ve.ucv.ciens.ccg.nxtar.systems.BombGameLogicSystem; import ve.ucv.ciens.ccg.nxtar.systems.BombGameLogicSystem;
import ve.ucv.ciens.ccg.nxtar.systems.CollisionDetectionSystem;
import ve.ucv.ciens.ccg.nxtar.systems.FadeEffectRenderingSystem;
import ve.ucv.ciens.ccg.nxtar.systems.GameLogicSystemBase; import ve.ucv.ciens.ccg.nxtar.systems.GameLogicSystemBase;
import ve.ucv.ciens.ccg.nxtar.systems.GeometrySystem;
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.systems.RobotArmPositioningSystem;
import com.artemis.EntitySystem;
import com.artemis.World; import com.artemis.World;
import com.artemis.managers.GroupManager; import com.artemis.managers.GroupManager;
import com.artemis.utils.ImmutableBag;
import com.badlogic.gdx.controllers.mappings.Ouya;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.utils.Disposable;
public abstract class GameSettings{ public abstract class GameSettings{
private static EntityCreatorBase entityCreator = null; private static EntityCreatorBase entityCreator = null;
private static GameLogicSystemBase gameLogicSystem = null; private static GameLogicSystemBase gameLogicSystem = null;
private static World gameWorld = null; private static World gameWorld = null;
private static ModelBatch modelBatch = null;
public static void initGameSettings(NxtARCore core) throws IllegalArgumentException{ public static void initGameSettings(NxtARCore core) throws IllegalArgumentException{
if(core == null) if(core == null)
throw new IllegalArgumentException("Core is null."); throw new IllegalArgumentException("Core is null.");
if(modelBatch == null)
modelBatch = new ModelBatch();
if(getGameWorld() == null){ if(getGameWorld() == null){
gameWorld = new World(); gameWorld = new World();
gameWorld.setManager(new GroupManager()); gameWorld.setManager(new GroupManager());
@@ -46,9 +63,29 @@ public abstract class GameSettings{
if(getGameLogicSystem() == null) if(getGameLogicSystem() == null)
gameLogicSystem = new BombGameLogicSystem(); gameLogicSystem = new BombGameLogicSystem();
gameWorld.setSystem(new MarkerPositioningSystem());
gameWorld.setSystem(new RobotArmPositioningSystem(), Ouya.runningOnOuya);
gameWorld.setSystem(new GeometrySystem());
gameWorld.setSystem(new AnimationSystem());
gameWorld.setSystem(new CollisionDetectionSystem());
gameWorld.setSystem(gameLogicSystem);
gameWorld.setSystem(new MarkerRenderingSystem(modelBatch), true);
gameWorld.setSystem(new ObjectRenderingSystem(modelBatch), true);
gameWorld.setSystem(new FadeEffectRenderingSystem(), true);
gameWorld.initialize();
} }
public static void clearGameSettings(){ public static void clearGameSettings(){
ImmutableBag<EntitySystem> systems = gameWorld.getSystems();
for(int i = 0; i < systems.size(); i++){
if(systems.get(i) instanceof Disposable){
((Disposable)systems.get(i)).dispose();
}
}
entityCreator.dispose(); entityCreator.dispose();
entityCreator = null; entityCreator = null;
gameLogicSystem = null; gameLogicSystem = null;

View File

@@ -19,23 +19,58 @@ import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Peripheral; import com.badlogic.gdx.Input.Peripheral;
import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.math.Vector3;
/**
* Assorted common auxiliary functions.
*/
public abstract class Utils{ public abstract class Utils{
private static final float MIN_PITCH = -80.0f;
private static final float MAX_PITCH = 5.0f;
private static final float MIN_AZIMUTH = -155.0f;
private static final float MAX_AZIMUTH = -40.0f;
/**
* <p>Converts a libGDX {@link Vector3} to a String representation form easy logging.</p>
*
* @param v The vector to convert.
* @return A string representation of the form "(v.x, v.y, v.z)".
*/
public static String vector2String(Vector3 v){ public static String vector2String(Vector3 v){
return "(" + Float.toString(v.x) + ", " + Float.toString(v.y) + ", " + Float.toString(v.z) + ")"; return "(" + Float.toString(v.x) + ", " + Float.toString(v.y) + ", " + Float.toString(v.z) + ")";
} }
/**
* @return The width of the screen accounting for screen overscan.
*/
public static int getScreenWidth(){ public static int getScreenWidth(){
return (int)(Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN); return (int)(Gdx.graphics.getWidth() * ProjectConstants.OVERSCAN);
} }
/**
* @return The height of the screen accounting for screen overscan.
*/
public static int getScreenHeight(){ public static int getScreenHeight(){
return (int)(Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN); return (int)(Gdx.graphics.getHeight() * ProjectConstants.OVERSCAN);
} }
/**
* <p>Checks if the device's orientation is available and wihtin some arbitrary ranges.</p>
*
* @return True if the device can detect it's orientation and it's within range. False otherwise.
*/
public static boolean isDeviceRollValid(){ public static boolean isDeviceRollValid(){
boolean rollValid = Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer) && Gdx.input.isPeripheralAvailable(Peripheral.Compass); boolean rollValid = Gdx.input.isPeripheralAvailable(Peripheral.Accelerometer) && Gdx.input.isPeripheralAvailable(Peripheral.Compass);
float azimuth, pitch;
// TODO: Check device orientation for limits. if(rollValid){
azimuth = Gdx.input.getAzimuth();
pitch = Gdx.input.getPitch();
if(pitch < MIN_PITCH || pitch > MAX_PITCH)
rollValid = false;
if(rollValid && (azimuth < MIN_AZIMUTH || azimuth > MAX_AZIMUTH))
rollValid = false;
}
return rollValid; return rollValid;
} }