package rajawali;
import rajawali.math.AngleAxis;
import rajawali.math.Number3D;
import rajawali.math.Number3D.Axis;
import rajawali.math.Quaternion;
import android.opengl.Matrix;
public abstract class ATransformable3D {
protected Number3D mPosition, mRotation, mScale;
protected Quaternion mOrientation;
protected Quaternion mTmpOrientation;
protected Number3D mRotationAxis;
protected Number3D mAxisX, mAxisY, mAxisZ;
protected boolean mRotationDirty;
protected Number3D mLookAt;
protected Number3D mTmpAxis, mTmpVec;
protected boolean mIsCamera, mQuatWasSet;
protected AngleAxis mAngleAxis;
public ATransformable3D() {
mPosition = new Number3D();
mRotation = new Number3D();
mScale = new Number3D(1, 1, 1);
mOrientation = new Quaternion();
mTmpOrientation = new Quaternion();
mAxisX = Number3D.getAxisVector(Axis.X);
mAxisY = Number3D.getAxisVector(Axis.Y);
mAxisZ = Number3D.getAxisVector(Axis.Z);
mTmpAxis = new Number3D();
mTmpVec = new Number3D();
mAngleAxis = new AngleAxis();
mRotationDirty = true;
}
public void setPosition(Number3D position) {
mPosition.setAllFrom(position);
}
public void setPosition(float x, float y, float z) {
mPosition.setAll(x, y, z);
}
public Number3D getPosition() {
return mPosition;
}
public void setX(float x) {
mPosition.x = x;
}
public float getX() {
return mPosition.x;
}
public void setY(float y) {
mPosition.y = y;
}
public float getY() {
return mPosition.y;
}
public void setZ(float z) {
mPosition.z = z;
}
public float getZ() {
return mPosition.z;
}
Number3D mTmpRotX = new Number3D();
Number3D mTmpRotY = new Number3D();
Number3D mTmpRotZ = new Number3D();
float[] mLookAtMatrix = new float[16];
public void setOrientation() {
if(!mRotationDirty && mLookAt == null) return;
mOrientation.setIdentity();
if(mLookAt != null) {
mTmpRotZ.setAllFrom(mLookAt);
mTmpRotZ.subtract(mPosition);
mTmpRotZ.normalize();
if(mTmpRotZ.length() == 0)
mTmpRotZ.z = 1;
mTmpRotX.setAllFrom(mAxisY);
mTmpRotX.cross(mTmpRotZ);
mTmpRotX.normalize();
if(mTmpRotX.length() == 0) {
mTmpRotZ.x += .0001f;
mTmpRotX.cross(mTmpRotZ);
mTmpRotX.normalize();
}
mTmpRotY.setAllFrom(mTmpRotZ);
mTmpRotY.cross(mTmpRotX);
Matrix.setIdentityM(mLookAtMatrix, 0);
mLookAtMatrix[0] = mTmpRotX.x;
mLookAtMatrix[1] = mTmpRotX.y;
mLookAtMatrix[2] = mTmpRotX.z;
mLookAtMatrix[4] = mTmpRotY.x;
mLookAtMatrix[5] = mTmpRotY.y;
mLookAtMatrix[6] = mTmpRotY.z;
mLookAtMatrix[8] = mTmpRotZ.x;
mLookAtMatrix[9] = mTmpRotZ.y;
mLookAtMatrix[10] = mTmpRotZ.z;
} else {
mOrientation.multiply(mTmpOrientation.fromAngleAxis(mIsCamera ? mRotation.y : mRotation.y, mAxisY));
mOrientation.multiply(mTmpOrientation.fromAngleAxis(mIsCamera ? mRotation.z : mRotation.z, mAxisZ));
mOrientation.multiply(mTmpOrientation.fromAngleAxis(mIsCamera ? mRotation.x : mRotation.x, mAxisX));
if(mIsCamera)
mOrientation.inverseSelf();
}
}
public void rotateAround(Number3D axis, float angle) {
rotateAround(axis, angle, true);
}
public void rotateAround(Number3D axis, float angle, boolean append) {
if(append) {
mTmpOrientation.fromAngleAxis(angle, axis);
mOrientation.multiply(mTmpOrientation);
} else {
mOrientation.fromAngleAxis(angle, axis);
}
mRotationDirty = false;
}
public Quaternion getOrientation() {
setOrientation(); // Force mOrientation to be recalculated
return new Quaternion(mOrientation);
}
public void setOrientation(Quaternion quat) {
mOrientation.setAllFrom(quat);
mRotationDirty = false;
}
public void setRotation(float rotX, float rotY, float rotZ) {
mRotation.x = rotX;
mRotation.y = rotY;
mRotation.z = rotZ;
mRotationDirty = true;
}
public void setRotX(float rotX) {
mRotation.x = rotX;
mRotationDirty = true;
}
public float getRotX() {
return mRotation.x;
}
public void setRotY(float rotY) {
mRotation.y = rotY;
mRotationDirty = true;
}
public float getRotY() {
return mRotation.y;
}
public void setRotZ(float rotZ) {
mRotation.z = rotZ;
mRotationDirty = true;
}
public float getRotZ() {
return mRotation.z;
}
public Number3D getRotation() {
return mRotation;
}
public void setRotation(Number3D rotation) {
mRotation.setAllFrom(rotation);
mRotationDirty = true;
}
public void setScale(float scale) {
mScale.x = scale;
mScale.y = scale;
mScale.z = scale;
}
public void setScale(float scaleX, float scaleY, float scaleZ) {
mScale.x = scaleX;
mScale.y = scaleY;
mScale.z = scaleZ;
}
public void setScaleX(float scaleX) {
mScale.x = scaleX;
}
public float getScaleX() {
return mScale.x;
}
public void setScaleY(float scaleY) {
mScale.y = scaleY;
}
public float getScaleY() {
return mScale.y;
}
public void setScaleZ(float scaleZ) {
mScale.z = scaleZ;
}
public float getScaleZ() {
return mScale.z;
}
public Number3D getScale() {
return mScale;
}
public void setScale(Number3D scale) {
mScale = scale;
}
public Number3D getLookAt() {
return mLookAt;
}
public void setLookAt(float x, float y, float z) {
if(mLookAt == null) mLookAt = new Number3D();
mLookAt.x = x;
mLookAt.y = y;
mLookAt.z = z;
mRotationDirty = true;
}
public void setLookAt(Number3D lookAt) {
if(lookAt == null) {
mLookAt = null;
return;
}
setLookAt(lookAt.x, lookAt.y, lookAt.z);
}
}