public class Player extends MyObject { private VertexArray vertexArray; private final int POSITION_COMPONENT_COUNT = 3; private final int TEXTURE_COMPONENT_COUNT = 2; private final int STRIDE = (POSITION_COMPONENT_COUNT + TEXTURE_COMPONENT_COUNT) * Constants.BYTES_PER_FLOAT; private int indicesCount; private final ShortBuffer indices; private Vector3 worldMidPoint; private Vector3 timeBasedVelocity; private Vector3 initialVelocity; private Vector3 radius; private boolean playerRunningStatus; private float[] translationMatrix; private float[] incrementalRotationMatrix; private float incrementalRotationAngle; private float[] directRotationMatrix; private float directRotationAngle; public Player(Context context, int fileId) { InputStream path = context.getResources().openRawResource(fileId); LoadOBJ OBJLoader = new LoadOBJ(true, false); OBJFileData objFileData = OBJLoader.LoadData(path); radius = new Vector3((max.x - min.x)/2, (max.y - min.y)/2, (max.z - min.z)/2); worldMidPoint = new Vector3(0, radius.y, 0); initialVelocity = new Vector3(0, 0, -2.0f); //If I didn't multiply this vector with the time variable later on and set it to like -0.002f on the z axis it works fine. timeBasedVelocity = new Vector3(0, 0, -2.0f); playerRunningStatus = false; VerticesAndIndices VAI = RestructureData.GetVerticesAndIndices(objFileData); indicesCount = VAI.Indices.length; vertexArray = new VertexArray(VAI.Vertices); indices = ByteBuffer. allocateDirect(VAI.Indices.length * Constants.BYTES_PER_SHORT). order(ByteOrder.nativeOrder()). asShortBuffer(); indices.put(VAI.Indices); indices.position(0); translationMatrix = new float[16]; directRotationMatrix = new float[16]; directRotationAngle = 0; incrementalRotationMatrix = new float[16]; incrementalRotationAngle = 0; } public void bindData(TextureShaderProgram program) { int dataOffset = 0; vertexArray.setVertexAttribPointer(dataOffset, program.getPositionAttributeLocation(), POSITION_COMPONENT_COUNT, STRIDE); dataOffset += POSITION_COMPONENT_COUNT; vertexArray.setVertexAttribPointer(dataOffset, program.getTextureCoordinatesAttributeLocation(), TEXTURE_COMPONENT_COUNT, STRIDE); } public void draw() { GLES20.glDrawElements(GLES20.GL_TRIANGLES, indicesCount, GLES20.GL_UNSIGNED_SHORT, indices); } public Vector3 getWorldMidPoint() { return new Vector3(worldMidPoint.x, worldMidPoint.y, worldMidPoint.z); } public Vector3 getPlayerRadius() { return new Vector3(radius.x, radius.y, radius.z); } public Vector3 getPlayerTimeBasedVelocity() { return new Vector3(timeBasedVelocity.x, timeBasedVelocity.y, timeBasedVelocity.z); } public boolean getPlayerRunningStatus() { return playerRunningStatus; } public float[] getIncrementalRotationMatrix() { return incrementalRotationMatrix; } public float getIncrementalRotationAngle() { return incrementalRotationAngle; } private void setIncrementalRotationMatrix(float angle) { incrementalRotationAngle += angle; Matrix.setIdentityM(incrementalRotationMatrix, 0); Matrix.rotateM(incrementalRotationMatrix, 0, -incrementalRotationAngle, 0, 1, 0); } private void setDirectRotationMatrix(float angle) { directRotationAngle = angle; Matrix.setIdentityM(directRotationMatrix, 0); Matrix.rotateM(directRotationMatrix, 0, -directRotationAngle, 0, 1, 0); } private void setPlayerTimeBasedVelocity(float elapsedTime) { timeBasedVelocity.x = initialVelocity.x * elapsedTime; timeBasedVelocity.y = initialVelocity.y * elapsedTime; timeBasedVelocity.z = initialVelocity.z * elapsedTime; } public void updatePlayerPosition(float elapsedTime) { float angle = MyOnTouchListener.getdx() / 5.0f; setIncrementalRotationMatrix(angle); setDirectRotationMatrix(angle); //Rotating the velocity vector initialVelocity.rotateVectorBy4x4Matrix(directRotationMatrix); setPlayerTimeBasedVelocity(elapsedTime); if(MyOnTouchListener.getRunningStatus()) { playerRunningStatus = true; worldMidPoint.addVector(timeBasedVelocity); } else { playerRunningStatus = false; } MyOnTouchListener.resetdx(); updatePlayerMinMax(); } }