package javax.microedition.m3g;
class Constants {
public static final float EPSILON = 0.0000001f;
public static final float DEG2RAD = 0.017453292519943295769236907684886f;
public static final float RAD2DEG = 57.295779513082320876798154814105f;
}
class Tools {
public static boolean isPowerOfTwo(int x) {
return (x & (x - 1)) == 0;
}
}
class Vector3 {
public float x;
public float y;
public float z;
public Vector3() {
x = y = z = 0;
}
public Vector3(float[] vec) {
if (vec == null)
throw new NullPointerException();
if (vec.length < 3)
throw new IllegalArgumentException();
x = vec[0];
y = vec[1];
z = vec[2];
}
public Vector3(float vx, float vy, float vz) {
x = vx;
y = vy;
z = vz;
}
public Vector3(Vector3 vec) {
x = vec.x;
y = vec.y;
z = vec.z;
}
public Vector3(QVec4 q) {
x = q.x;
y = q.y;
z = q.z;
}
public void logQuat(QVec4 quat) {
float sinTheta = (float) Math.sqrt(QVec4.norm3(quat));
if (sinTheta > Constants.EPSILON) {
float s = (float) (Math.atan2(sinTheta, quat.w) / sinTheta);
x = s * quat.x;
y = s * quat.y;
z = s * quat.z;
} else
x = y = z = 0.0f;
}
public void assign(Vector3 other) {
x = other.x;
y = other.y;
z = other.z;
}
public void setVec3(float val) {
x = val;
y = val;
z = val;
}
public void setVec3(float[] vec) {
if (vec == null)
throw new NullPointerException();
if (vec.length < 3)
throw new IllegalArgumentException();
x = vec[0];
y = vec[1];
z = vec[2];
}
public void setVec3(float vx, float vy, float vz) {
x = vx;
y = vy;
z = vz;
}
public void logDiffQuat(QVec4 from, QVec4 to) {
QVec4 temp = new QVec4();
temp.x = -from.x;
temp.y = -from.y;
temp.z = -from.z;
temp.w = from.w;
temp.mulQuat(to);
this.logQuat(temp);
}
public void addVec3(Vector3 other) {
x += other.x;
y += other.y;
z += other.z;
}
public void subVec3(Vector3 other) {
x -= other.x;
y -= other.y;
z -= other.z;
}
public static void scale3(float[] v, float s) {
v[0] *= s;
v[1] *= s;
v[2] *= s;
}
public void scaleVec3(float s) {
x *= s;
y *= s;
z *= s;
}
public static void lerp(int size, float[] vec, float s, float[] start, float[] end) {
float sCompl = 1.f - s;
for (int i = 0; i < size; i++)
vec[i] = (sCompl * start[i]) + (s * end[i]);
}
public float lengthVec3() {
return (float) Math.sqrt(x * x + y * y + z * z);
}
public static float norm3(float[] v) {
return (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
public void normalizeVec3() {
float norm = norm3(new float[]{x, y, z});
if (norm > Constants.EPSILON) {
norm = (float) (1.0d / Math.sqrt(norm));
scaleVec3(norm);
} else {
x = y = z = 0;
}
}
public void cross(Vector3 a, Vector3 b) {
x = a.y * b.z - a.z * b.y;
y = a.z * b.x - a.x * b.z;
z = a.x * b.y - a.y * b.x;
}
public static float dot3(Vector3 a, Vector3 b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
public static boolean intersectTriangle(Vector3 orig, Vector3 dir, Vector3 vert0, Vector3 vert1, Vector3 vert2, Vector3 tuv, int cullMode) {
Vector3 edge1 = new Vector3();
Vector3 edge2 = new Vector3();
Vector3 tvec = new Vector3();
Vector3 pvec = new Vector3();
Vector3 qvec = new Vector3();
edge1.assign(vert1);
edge2.assign(vert2);
edge1.subVec3(vert0);
edge2.subVec3(vert0);
pvec.cross(dir, edge2);
float det = dot3(edge1, pvec);
if (cullMode == 0 && det <= 0) return false;
if (cullMode == 1 && det >= 0) return false;
if (det > -Constants.EPSILON && det < Constants.EPSILON)
return false;
float inv_det = (float) (1.0d / det);
tvec.assign(orig);
tvec.subVec3(vert0);
tuv.y = inv_det * dot3(tvec, pvec);
if (tuv.y < 0.0f || tuv.y > 1.0f)
return false;
qvec.cross(tvec, edge1);
tuv.z = inv_det * dot3(dir, qvec);
if (tuv.z < 0.0f || (tuv.y + tuv.z) > 1.0f)
return false;
tuv.x = inv_det * dot3(edge2, qvec);
return true;
}
}
class QVec4 {
public static final int[] Vec4_X_AXIS = new int[]{1, 0, 0, 0};
public static final int[] Vec4_Y_AXIS = new int[]{0, 1, 0, 0};
public static final int[] Vec4_Z_AXIS = new int[]{0, 0, 1, 0};
public static final int[] Vec4_ORIGIN = new int[]{0, 0, 0, 1};
public float x;
public float y;
public float z;
public float w;
public QVec4() {
x = y = z = w = 0;
}
public QVec4(float[] q) {
if (q == null)
throw new NullPointerException();
if (q.length < 4)
throw new IllegalArgumentException();
x = q[0];
y = q[1];
z = q[2];
w = q[3];
}
public QVec4(QVec4 q) {
x = q.x;
y = q.y;
z = q.z;
w = q.w;
}
public QVec4(float qx, float qy, float qz, float qw) {
x = qx;
y = qy;
z = qz;
w = qw;
}
public void setQuat(float[] vec) {
if (vec.length < 4)
throw new IllegalArgumentException();
x = vec[0];
y = vec[1];
z = vec[2];
w = vec[3];
}
public void setVec4(float x, float y, float z, float w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public void assign(QVec4 other) {
x = other.x;
y = other.y;
z = other.z;
w = other.w;
}
public void mulQuat(QVec4 other) {
QVec4 q = new QVec4();
q.assign(other);
w = q.w * other.w - q.x * other.x - q.y * other.y - q.z * other.z;
x = q.w * other.x + q.x * other.w + q.y * other.z - q.z * other.y;
y = q.w * other.y - q.x * other.z + q.y * other.w + q.z * other.x;
z = q.w * other.z + q.x * other.y - q.y * other.x + q.z * other.w;
}
public static float norm3(QVec4 quat) {
return (quat.x * quat.x + quat.y * quat.y + quat.z * quat.z);
}
public void expQuat(Vector3 qExp) {
float theta = (float) (Math.sqrt(qExp.x * qExp.x + qExp.y * qExp.y + qExp.z * qExp.z));
if (theta > Constants.EPSILON) {
float s = (float) (Math.sin(theta) * (1.0d / (double) theta));
x = qExp.x * s;
y = qExp.y * s;
z = qExp.z * s;
w = (float) Math.cos(theta);
} else {
x = y = z = 0.0f;
w = 1.0f;
}
}
public static float dot4(QVec4 a, QVec4 b) {
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
public void slerpQuat(float s, QVec4 q0, QVec4 q1) {
float s0, s1;
float cosTheta = QVec4.dot4(q0, q1);
float oneMinusS = 1.0f - s;
if (cosTheta > (Constants.EPSILON - 1.0f)) {
if (cosTheta < (1.0f - Constants.EPSILON)) {
float theta = (float) Math.acos((double) cosTheta);
float sinTheta = (float) Math.sin(theta);
s0 = (float) (Math.sin(oneMinusS * theta) / sinTheta);
s1 = (float) (Math.sin(s * theta) / sinTheta);
} else {
s0 = oneMinusS;
s1 = s;
}
x = s0 * q0.x + s1 * q1.x;
y = s0 * q0.y + s1 * q1.y;
z = s0 * q0.z + s1 * q1.z;
w = s0 * q0.w + s1 * q1.w;
} else {
x = -q0.y;
y = q0.x;
z = -q0.w;
w = q0.z;
s0 = (float) Math.sin(oneMinusS * (Math.PI / 2));
s1 = (float) Math.sin(s * (Math.PI / 2));
x = s0 * q0.x + s1 * x;
y = s0 * q0.y + s1 * y;
z = s0 * q0.z + s1 * z;
}
}
public void scaleVec4(float s) {
x *= s;
y *= s;
z *= s;
w *= s;
}
public float norm4() {
return (x * x + y * y + z * z + w * w);
}
public static float norm4(float[] v) {
return v[0] * v[0] + v[1] * v[1] + v[2] * v[2] + v[3] * v[3];
}
public void identityQuat() {
x = y = z = 0.0f;
w = 1.0f;
}
public void normalizeQuat() {
float norm = (x * x + y * y + z * z + w * w);
if (norm > Constants.EPSILON) {
norm = (float) (1.0d / Math.sqrt(norm));
scaleVec4(norm);
} else
identityQuat();
}
public void setAngleAxis(float angle, float ax, float ay, float az) {
setAngleAxisRad(angle * Constants.DEG2RAD, ax, ay, az);
}
public void setAngleAxisRad(float angleRad, float ax, float