PlayerModel.java

/*
 * Copyright © 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

package com.nokia.example.spacemission;

import javax.microedition.m3g.*;

public class PlayerModel {

    // initial camera position
    private static final float X_POS = 0.0f;
    private static final float Y_POS = 0.4f;
    private static final float Z_POS = 2.0f;
    //     translation and rotation increments
    private static final float ANGLE_INCR = 5.0f; // degrees
    private static final float MOVE_INCR = 0.1f;
    //for examining the camera's (x,y,z) position
    private Transform trans = new Transform();
    private float[] transMat = new float[16];
    private float xCoord, yCoord, zCoord;
    //for storing the camera's current y- rotations
    private float yAngle;
    private Transform rotTrans = new Transform();
    private Group transGroup;
    private Camera cam;
    //     booleans for remembering key presses
    private boolean upPressed = false;
    private boolean downPressed = false;
    private boolean leftPressed = false;
    private boolean rightPressed = false;

    public PlayerModel(int width, int height) {
        cam = new Camera();
        float aspectRatio = ((float) width) / ((float) height);
        cam.setPerspective(70.0f, aspectRatio, 0.1f, 50.0f);
        cam.postRotate(-2.0f, 1.0f, 0, 0); // apply x-axis rotations to camera
        // transGroup handles both camera translation and y-axis rotations
        transGroup = new Group(); // no initial rotation
        trans.postTranslate(X_POS, Y_POS, Z_POS);
        transGroup.setTransform(trans);
        transGroup.addChild(cam);
        // store initial rotation
        yAngle = 0.0f;
    }

    public Group getCameraGroup() {
        return transGroup;
    }

    public Camera getCamera() {
        return cam;
    }

    public void setKeysPressed(boolean leftPressed, boolean rightPressed,
                               boolean upPressed, boolean downPressed) {
        this.upPressed = upPressed;
        this.downPressed = downPressed;
        this.leftPressed = leftPressed;
        this.rightPressed = rightPressed;
    }

    public void updatePosition() {
        if (upPressed || downPressed) {
            updateMove();
        }
        else if (leftPressed || rightPressed) {
            updateRotation();
        }
    }

    private void updateMove() {

        transGroup.getTransform(trans);
        if (upPressed) { // move forward
            trans.postTranslate(0, 0, -MOVE_INCR);
        }
        else { // move backwards
            trans.postTranslate(0, 0, MOVE_INCR);
        }
        transGroup.setTransform(trans);

    }

    private void updateRotation() {
        if (leftPressed) { // rotate left around the y-axis
            rotTrans.postRotate(ANGLE_INCR, 0, 1.0f, 0);
            yAngle += ANGLE_INCR;
        }
        else { // rotate right around the y-axis
            rotTrans.postRotate(-ANGLE_INCR, 0, 1.0f, 0);
            yAngle -= ANGLE_INCR;
        }

        // angle values are modulo 360 degrees
        if (yAngle >= 360.0f) {
            yAngle -= 360.0f;
        }
        else if (yAngle <= -360.0f) {
            yAngle += 360.0f;
        }

        // apply the y-axis rotation to transGroup
        storePosition();
        trans.setIdentity();
        trans.postTranslate(xCoord, yCoord, zCoord);
        trans.postRotate(yAngle, 0, 1.0f, 0);
        transGroup.setTransform(trans);
    }

    private void storePosition() {
        // extract the current (x,y,z) position from transGroup
        transGroup.getCompositeTransform(trans);

        trans.get(transMat);
        xCoord = transMat[3];
        yCoord = transMat[7];
        zCoord = transMat[11];
    } // end of storePosition()

    public float[] getDirection() {
        float[] zVec = {0, 0, -1.0f, 0};
        rotTrans.transform(zVec);
        return new float[]{zVec[0], zVec[1], zVec[2]};
    }

    public float[] getPosition() {
        storePosition();
        return new float[]{xCoord, yCoord, zCoord};
    }
}