summaryrefslogtreecommitdiff
path: root/NET/worlds
diff options
context:
space:
mode:
Diffstat (limited to 'NET/worlds')
-rw-r--r--NET/worlds/scape/Transform.java567
1 files changed, 541 insertions, 26 deletions
diff --git a/NET/worlds/scape/Transform.java b/NET/worlds/scape/Transform.java
index 8b7bc26..59f2b27 100644
--- a/NET/worlds/scape/Transform.java
+++ b/NET/worlds/scape/Transform.java
@@ -12,22 +12,26 @@ public class Transform extends SuperRoot {
private float yScale;
private float zScale;
private static Object classCookie = new Object();
+ private float[] matrix = new float[16];
static {
nativeInit();
}
- public static native void nativeInit();
+ public static void nativeInit() { }
public static Transform make() {
assert Main.isMainThread();
int last = recycled.size() - 1;
+
if (last == -1) {
return new Transform();
} else {
Transform ret = recycled.elementAt(last);
+
recycled.removeElementAt(last);
+
return ret;
}
}
@@ -40,14 +44,26 @@ public class Transform extends SuperRoot {
}
protected Transform() {
- this.makeIdentity();
+ for (int elementIndex = 0; elementIndex < 16; elementIndex++) {
+ matrix[elementIndex] = (elementIndex % 5 == 0) ? 1.0F : 0.0F;
+ }
+
+ this.xScale = 1.0F;
+ this.yScale = 1.0F;
+ this.zScale = 1.0F;
}
- public native float getX();
+ public float getX() {
+ return matrix[12];
+ }
- public native float getY();
+ public float getY() {
+ return matrix[13];
+ }
- public native float getZ();
+ public float getZ() {
+ return matrix[14];
+ }
public Point3Temp getPosition() {
return Point3Temp.make(this.getX(), this.getY(), this.getZ());
@@ -77,15 +93,206 @@ public class Transform extends SuperRoot {
return (this.getScaleX() + this.getScaleY() + this.getScaleZ()) / 3.0F;
}
- public native float getYaw();
+ public float getYaw() {
+ float[] normalized = getScaleRemovedOrthoNormalized();
+ float transformedX = normalized[4];
+ float transformedY = normalized[5];
+ float horizontalLengthSquared = transformedX * transformedX + transformedY * transformedY;
+
+ if (horizontalLengthSquared == 0.0f) {
+ return 0.0f;
+ }
+
+ float horizontalLength = (float)Math.sqrt(horizontalLengthSquared);
+ float cosineRatio = transformedX / horizontalLength;
+ float bearingDegrees;
+
+ if (cosineRatio >= 1.0f) {
+ bearingDegrees = 0.0f;
+ } else if (cosineRatio <= -1.0f) {
+ bearingDegrees = 180.0f;
+ } else {
+ bearingDegrees = (float)(180.0 * (0.5 * Math.PI - Math.asin(cosineRatio)) / Math.PI);
+ }
+
+ if (transformedY < 0.0f) {
+ bearingDegrees = -bearingDegrees;
+ }
+
+ float yawResult = 90.0f - bearingDegrees;
+
+ if (yawResult < 0.0f) {
+ yawResult += 360.0f;
+ }
+
+ return yawResult;
+ }
+
+ public float getPitch() {
+ float[] normalized = getScaleRemovedOrthoNormalized();
+ float transformedX = normalized[4];
+ float transformedY = normalized[5];
+ float transformedZ = normalized[6];
+ float horizontalLengthSquared = transformedX * transformedX + transformedY * transformedY;
+ float totalLengthSquared = transformedZ * transformedZ + horizontalLengthSquared;
+
+ if (totalLengthSquared == 0.0f) {
+ return 0.0f;
+ }
+
+ float pitchResult = 0.0f;
+
+ if (horizontalLengthSquared > 0.0f) {
+ float horizontalLength = (float)Math.sqrt(horizontalLengthSquared);
+ float totalLength = (float)Math.sqrt(transformedZ * transformedZ + horizontalLengthSquared);
+ float cosElevation = horizontalLength / totalLength;
+
+ if (cosElevation < 1.0f) {
+ pitchResult = (float)(180.0 * (0.5 * Math.PI - Math.asin(cosElevation)) / Math.PI);
+ }
+ }
+
+ if (transformedZ < 0.0f) {
+ pitchResult = -pitchResult;
+ }
+
+ return pitchResult;
+ }
+
+ public float getSpin(Point3Temp axis) {
+ float[] normalized = getScaleRemovedOrthoNormalized();
+ float axisX = 0.0f, axisY = 0.0f, axisZ = 0.0f;
+
+ if (axis != null) {
+ axisX = axis.x;
+ axisY = axis.y;
+ axisZ = axis.z;
+ }
+
+ float[] queryResult = queryRotateMatrix(normalized, axisX, axisY, axisZ);
+
+ axisX = queryResult[0];
+ axisY = queryResult[1];
+ axisZ = queryResult[2];
+
+ float angleDegrees = queryResult[3];
+
+ if (axisZ > 0.0f) {
+ angleDegrees = 360.0f - angleDegrees;
+ axisX = -axisX;
+ axisY = -axisY;
+ axisZ = -axisZ;
+ }
+
+ if (angleDegrees == 0.0f) {
+ axisX = 0.0f;
+ axisY = 0.0f;
+ axisZ = -1.0f;
+ }
+
+ if (axis != null) {
+ axis.x = axisX;
+ axis.y = axisY;
+ axis.z = axisZ;
+ }
+
+ return angleDegrees;
+ }
+
+ private float[] getScaleRemovedOrthoNormalized() {
+ float[] result = new float[16];
+
+ System.arraycopy(this.matrix, 0, result, 0, 16);
+
+ float inverseScaleX = xScale != 0.0f ? 1.0f / xScale : 1.0f;
+ float inverseScaleY = yScale != 0.0f ? 1.0f / yScale : 1.0f;
+ float inverseScaleZ = zScale != 0.0f ? 1.0f / zScale : 1.0f;
+
+ result[0] *= inverseScaleX; result[1] *= inverseScaleX; result[2] *= inverseScaleX; result[3] *= inverseScaleX;
+ result[4] *= inverseScaleY; result[5] *= inverseScaleY; result[6] *= inverseScaleY; result[7] *= inverseScaleY;
+ result[8] *= inverseScaleZ; result[9] *= inverseScaleZ; result[10] *= inverseScaleZ; result[11] *= inverseScaleZ;
+
+ orthoNormalize(result);
+
+ return result;
+ }
+
+ private static void orthoNormalize(float[] matrix) {
+ float row0Length = (float)Math.sqrt(matrix[0]*matrix[0] + matrix[1]*matrix[1] + matrix[2]*matrix[2]);
+
+ if (row0Length > 0.0f) {
+ matrix[0] /= row0Length;
+ matrix[1] /= row0Length;
+ matrix[2] /= row0Length;
+ }
+
+ float row0DotRow1 = matrix[0]*matrix[4] + matrix[1]*matrix[5] + matrix[2]*matrix[6];
+
+ matrix[4] -= row0DotRow1 * matrix[0];
+ matrix[5] -= row0DotRow1 * matrix[1];
+ matrix[6] -= row0DotRow1 * matrix[2];
+
+ float row1Length = (float)Math.sqrt(matrix[4]*matrix[4] + matrix[5]*matrix[5] + matrix[6]*matrix[6]);
+
+ if (row1Length > 0.0f) {
+ matrix[4] /= row1Length;
+ matrix[5] /= row1Length;
+ matrix[6] /= row1Length;
+ }
+
+ matrix[8] = matrix[1]*matrix[6] - matrix[2]*matrix[5];
+ matrix[9] = matrix[2]*matrix[4] - matrix[0]*matrix[6];
+ matrix[10] = matrix[0]*matrix[5] - matrix[1]*matrix[4];
+ }
+
+ private static float[] queryRotateMatrix(float[] rotationMatrix, float hintAxisX, float hintAxisY, float hintAxisZ) {
+ float trace = rotationMatrix[0] + rotationMatrix[5] + rotationMatrix[10];
+ float cosAngle = (trace - 1.0f) * 0.5f;
+
+ if (cosAngle > 1.0f) cosAngle = 1.0f;
+ if (cosAngle < -1.0f) cosAngle = -1.0f;
- public native float getPitch();
+ float angleRadians = (float)Math.acos(cosAngle);
+ float angleDegrees = (float)(angleRadians * 180.0 / Math.PI);
+ float axisX, axisY, axisZ;
- public native float getSpin(Point3Temp var1);
+ if (angleRadians > 0.0001f) {
+ float sinAngle = (float)Math.sin(angleRadians);
- protected void noteTransformChange() {
+ if (Math.abs(sinAngle) > 0.0001f) {
+ float inverseDoubleSin = 1.0f / (2.0f * sinAngle);
+
+ axisX = (rotationMatrix[9] - rotationMatrix[6]) * inverseDoubleSin;
+ axisY = (rotationMatrix[2] - rotationMatrix[8]) * inverseDoubleSin;
+ axisZ = (rotationMatrix[4] - rotationMatrix[1]) * inverseDoubleSin;
+ } else {
+ axisX = (float)Math.sqrt(Math.max(0, (rotationMatrix[0] + 1.0f) * 0.5f));
+ axisY = (float)Math.sqrt(Math.max(0, (rotationMatrix[5] + 1.0f) * 0.5f));
+ axisZ = (float)Math.sqrt(Math.max(0, (rotationMatrix[10] + 1.0f) * 0.5f));
+
+ if (rotationMatrix[1] + rotationMatrix[4] < 0) axisY = -axisY;
+ if (rotationMatrix[2] + rotationMatrix[8] < 0) axisZ = -axisZ;
+ }
+
+ float axisLength = (float)Math.sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);
+
+ if (axisLength > 0.0001f) {
+ axisX /= axisLength;
+ axisY /= axisLength;
+ axisZ /= axisLength;
+ }
+ } else {
+ axisX = hintAxisX;
+ axisY = hintAxisY;
+ axisZ = hintAxisZ;
+ angleDegrees = 0.0f;
+ }
+
+ return new float[] { axisX, axisY, axisZ, angleDegrees };
}
+ protected void noteTransformChange() {}
+
public Transform raise(float z) {
return this.moveBy(0.0F, 0.0F, z);
}
@@ -116,16 +323,40 @@ public class Transform extends SuperRoot {
super.finalize();
}
- public native Transform pre(Transform var1);
+ public Transform pre(Transform other) {
+ if (other == null) return this;
+
+ boolean nonUniform = !(xScale == yScale && yScale == zScale);
+
+ if (nonUniform) {
+ preScaleMatrix(1.0f / xScale, 1.0f / yScale, 1.0f / zScale);
+ }
+
+ preTransformMatrix(other.matrix);
+
+ if (nonUniform) {
+ preScaleMatrix(xScale, yScale, zScale);
+ }
+
+ this.xScale *= other.xScale;
+ this.yScale *= other.yScale;
+ this.zScale *= other.zScale;
+
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform post(Transform t) {
Point3Temp v = t.getScale();
+
if (!this.checkPostScale(v)) {
return this;
} else {
this.xScale = this.xScale * v.x;
this.yScale = this.yScale * v.y;
this.zScale = this.zScale * v.z;
+
return this.postHelper(t);
}
}
@@ -133,31 +364,86 @@ public class Transform extends SuperRoot {
private boolean checkPostScale(Point3Temp v) {
if (this.getSpin(Point3Temp.make()) != 0.0F && (v.x != v.y || v.y != v.z)) {
Console.println(Console.message("non-uniform"));
+
return false;
} else {
return true;
}
}
- private native Transform postHelper(Transform var1);
+ private Transform postHelper(Transform t) {
+ if (t == null) return this;
+
+ postTransformMatrix(t.matrix);
+ this.noteTransformChange();
+
+ return this;
+ }
- public native Transform makeIdentity();
+ public Transform makeIdentity() {
+ for (int elementIndex = 0; elementIndex < 16; elementIndex++) {
+ matrix[elementIndex] = (elementIndex % 5 == 0) ? 1.0F : 0.0F;
+ }
+
+ this.xScale = 1.0F;
+ this.yScale = 1.0F;
+ this.zScale = 1.0F;
+
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform moveBy(Point3Temp p) {
return this.moveBy(p.x, p.y, p.z);
}
- public native Transform moveBy(float var1, float var2, float var3);
+ public Transform moveBy(float x, float y, float z) {
+ matrix[12] += x;
+ matrix[13] += y;
+ matrix[14] += z;
+
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform moveTo(Point3Temp p) {
return this.moveTo(p.x, p.y, p.z);
}
- public native Transform moveTo(float var1, float var2, float var3);
+ public Transform moveTo(float x, float y, float z) {
+ matrix[12] = x;
+ matrix[13] = y;
+ matrix[14] = z;
+
+ this.noteTransformChange();
+
+ return this;
+ }
- public native Transform premoveBy(float var1, float var2, float var3);
+ public Transform premoveBy(float x, float y, float z) {
+ matrix[12] += matrix[0] * x + matrix[4] * y + matrix[8] * z;
+ matrix[13] += matrix[1] * x + matrix[5] * y + matrix[9] * z;
+ matrix[14] += matrix[2] * x + matrix[6] * y + matrix[10] * z;
+
+ this.noteTransformChange();
+
+ return this;
+ }
- public native Transform scale(float var1, float var2, float var3);
+ public Transform scale(float scaleX, float scaleY, float scaleZ) {
+ this.xScale *= scaleX;
+ this.yScale *= scaleY;
+ this.zScale *= scaleZ;
+ matrix[0] *= scaleX; matrix[1] *= scaleX; matrix[2] *= scaleX; matrix[3] *= scaleX;
+ matrix[4] *= scaleY; matrix[5] *= scaleY; matrix[6] *= scaleY; matrix[7] *= scaleY;
+ matrix[8] *= scaleZ; matrix[9] *= scaleZ; matrix[10] *= scaleZ; matrix[11] *= scaleZ;
+
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform scale(Point3Temp s) {
return this.scale(s.x, s.y, s.z);
@@ -182,11 +468,20 @@ public class Transform extends SuperRoot {
this.xScale = this.xScale * s.x;
this.yScale = this.yScale * s.y;
this.zScale = this.zScale * s.z;
+
return this.postscaleHelper(s.x, s.y, s.z);
}
}
- private native Transform postscaleHelper(float var1, float var2, float var3);
+ private Transform postscaleHelper(float scaleX, float scaleY, float scaleZ) {
+ matrix[0] *= scaleX; matrix[4] *= scaleX; matrix[8] *= scaleX; matrix[12] *= scaleX;
+ matrix[1] *= scaleY; matrix[5] *= scaleY; matrix[9] *= scaleY; matrix[13] *= scaleY;
+ matrix[2] *= scaleZ; matrix[6] *= scaleZ; matrix[10] *= scaleZ; matrix[14] *= scaleZ;
+
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform worldScale(float x, float y, float z) {
return this.worldScale(Point3Temp.make(x, y, z));
@@ -196,7 +491,101 @@ public class Transform extends SuperRoot {
return !this.checkPostScale(s) ? this : this.scale(s);
}
- public native Transform spin(float var1, float var2, float var3, float var4);
+ public Transform spin(float axisX, float axisY, float axisZ, float angleDeg) {
+ boolean nonUniform = !(xScale == yScale && yScale == zScale);
+
+ if (nonUniform) {
+ preScaleMatrix(1.0f / xScale, 1.0f / yScale, 1.0f / zScale);
+ }
+
+ preRotateMatrix(axisX, axisY, axisZ, angleDeg);
+
+ if (nonUniform) {
+ preScaleMatrix(xScale, yScale, zScale);
+ }
+
+ this.noteTransformChange();
+
+ return this;
+ }
+
+ private void preScaleMatrix(float scaleX, float scaleY, float scaleZ) {
+ matrix[0] *= scaleX; matrix[1] *= scaleX; matrix[2] *= scaleX; matrix[3] *= scaleX;
+ matrix[4] *= scaleY; matrix[5] *= scaleY; matrix[6] *= scaleY; matrix[7] *= scaleY;
+ matrix[8] *= scaleZ; matrix[9] *= scaleZ; matrix[10] *= scaleZ; matrix[11] *= scaleZ;
+ }
+
+ private void preRotateMatrix(float axisX, float axisY, float axisZ, float angleDeg) {
+ float angleRadians = (float)Math.toRadians(angleDeg);
+ float cosine = (float)Math.cos(angleRadians);
+ float sine = (float)Math.sin(angleRadians);
+ float axisLength = (float)Math.sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ);
+
+ if (axisLength < 0.0001f) return;
+
+ axisX /= axisLength;
+ axisY /= axisLength;
+ axisZ /= axisLength;
+
+ float oneMinusCos = 1.0f - cosine;
+ float[] rotation = new float[9];
+
+ rotation[0] = oneMinusCos * axisX * axisX + cosine;
+ rotation[1] = oneMinusCos * axisX * axisY + sine * axisZ;
+ rotation[2] = oneMinusCos * axisX * axisZ - sine * axisY;
+ rotation[3] = oneMinusCos * axisX * axisY - sine * axisZ;
+ rotation[4] = oneMinusCos * axisY * axisY + cosine;
+ rotation[5] = oneMinusCos * axisY * axisZ + sine * axisX;
+ rotation[6] = oneMinusCos * axisX * axisZ + sine * axisY;
+ rotation[7] = oneMinusCos * axisY * axisZ - sine * axisX;
+ rotation[8] = oneMinusCos * axisZ * axisZ + cosine;
+
+ for (int columnIndex = 0; columnIndex < 4; columnIndex++) {
+ float row0Value = matrix[columnIndex];
+ float row1Value = matrix[4 + columnIndex];
+ float row2Value = matrix[8 + columnIndex];
+
+ matrix[columnIndex] = rotation[0] * row0Value + rotation[1] * row1Value + rotation[2] * row2Value;
+ matrix[4 + columnIndex] = rotation[3] * row0Value + rotation[4] * row1Value + rotation[5] * row2Value;
+ matrix[8 + columnIndex] = rotation[6] * row0Value + rotation[7] * row1Value + rotation[8] * row2Value;
+ }
+ }
+
+ private void preTransformMatrix(float[] other) {
+ float[] result = new float[16];
+
+ for (int rowIndex = 0; rowIndex < 4; rowIndex++) {
+ for (int columnIndex = 0; columnIndex < 4; columnIndex++) {
+ float elementSum = 0;
+
+ for (int innerIndex = 0; innerIndex < 4; innerIndex++) {
+ elementSum += other[rowIndex * 4 + innerIndex] * matrix[innerIndex * 4 + columnIndex];
+ }
+
+ result[rowIndex * 4 + columnIndex] = elementSum;
+ }
+ }
+
+ System.arraycopy(result, 0, this.matrix, 0, 16);
+ }
+
+ private void postTransformMatrix(float[] other) {
+ float[] result = new float[16];
+
+ for (int rowIndex = 0; rowIndex < 4; rowIndex++) {
+ for (int columnIndex = 0; columnIndex < 4; columnIndex++) {
+ float elementSum = 0;
+
+ for (int innerIndex = 0; innerIndex < 4; innerIndex++) {
+ elementSum += matrix[rowIndex * 4 + innerIndex] * other[innerIndex * 4 + columnIndex];
+ }
+
+ result[rowIndex * 4 + columnIndex] = elementSum;
+ }
+ }
+
+ System.arraycopy(result, 0, this.matrix, 0, 16);
+ }
public Transform spin(Point3Temp p, float a) {
return this.spin(p.x, p.y, p.z, a);
@@ -206,23 +595,115 @@ public class Transform extends SuperRoot {
return this.postspin(axis.x, axis.y, axis.z, a);
}
- public native Transform postspin(float var1, float var2, float var3, float var4);
+ public Transform postspin(float axisX, float axisY, float axisZ, float angleDeg) {
+ float angleRadians = (float)Math.toRadians(angleDeg);
+ float cosine = (float)Math.cos(angleRadians);
+ float sine = (float)Math.sin(angleRadians);
+ float axisLength = (float)Math.sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ);
+
+ if (axisLength < 0.0001f) return this;
+
+ axisX /= axisLength;
+ axisY /= axisLength;
+ axisZ /= axisLength;
+
+ float oneMinusCos = 1.0f - cosine;
+ float[] rotation = new float[16];
+
+ rotation[0] = oneMinusCos * axisX * axisX + cosine;
+ rotation[1] = oneMinusCos * axisX * axisY + sine * axisZ;
+ rotation[2] = oneMinusCos * axisX * axisZ - sine * axisY;
+ rotation[3] = 0;
+ rotation[4] = oneMinusCos * axisX * axisY - sine * axisZ;
+ rotation[5] = oneMinusCos * axisY * axisY + cosine;
+ rotation[6] = oneMinusCos * axisY * axisZ + sine * axisX;
+ rotation[7] = 0;
+ rotation[8] = oneMinusCos * axisX * axisZ + sine * axisY;
+ rotation[9] = oneMinusCos * axisY * axisZ - sine * axisX;
+ rotation[10] = oneMinusCos * axisZ * axisZ + cosine;
+ rotation[11] = 0;
+ rotation[12] = 0; rotation[13] = 0; rotation[14] = 0; rotation[15] = 1;
+
+ postTransformMatrix(rotation);
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform worldSpin(float x, float y, float z, float a) {
return this.spin(this.worldVecToObjectVec(Point3Temp.make(x, y, z)), a);
}
- private native void nativeFinalize();
+ private void nativeFinalize() {}
public Transform getTransform() {
Transform t = make();
+
t.setTransform(this);
+
return t;
}
- public native void setTransform(Transform var1);
+ public void setTransform(Transform other) {
+ if (other != null) {
+ System.arraycopy(other.matrix, 0, this.matrix, 0, 16);
+
+ this.xScale = other.xScale;
+ this.yScale = other.yScale;
+ this.zScale = other.zScale;
+
+ this.noteTransformChange();
+ }
+ }
- public native Transform invert();
+ public Transform invert() {
+ float[] source = this.matrix;
+ float[] inverse = new float[16];
+ float[] cofactor = new float[16];
+
+ cofactor[0] = (source[5]*(source[10]*source[15]-source[11]*source[14]) - source[6]*(source[9]*source[15]-source[11]*source[13]) + source[7]*(source[9]*source[14]-source[10]*source[13]));
+ cofactor[1] = -(source[4]*(source[10]*source[15]-source[11]*source[14]) - source[6]*(source[8]*source[15]-source[11]*source[12]) + source[7]*(source[8]*source[14]-source[10]*source[12]));
+ cofactor[2] = (source[4]*(source[9]*source[15]-source[11]*source[13]) - source[5]*(source[8]*source[15]-source[11]*source[12]) + source[7]*(source[8]*source[13]-source[9]*source[12]));
+ cofactor[3] = -(source[4]*(source[9]*source[14]-source[10]*source[13]) - source[5]*(source[8]*source[14]-source[10]*source[12]) + source[6]*(source[8]*source[13]-source[9]*source[12]));
+ cofactor[4] = -(source[1]*(source[10]*source[15]-source[11]*source[14]) - source[2]*(source[9]*source[15]-source[11]*source[13]) + source[3]*(source[9]*source[14]-source[10]*source[13]));
+ cofactor[5] = (source[0]*(source[10]*source[15]-source[11]*source[14]) - source[2]*(source[8]*source[15]-source[11]*source[12]) + source[3]*(source[8]*source[14]-source[10]*source[12]));
+ cofactor[6] = -(source[0]*(source[9]*source[15]-source[11]*source[13]) - source[1]*(source[8]*source[15]-source[11]*source[12]) + source[3]*(source[8]*source[13]-source[9]*source[12]));
+ cofactor[7] = (source[0]*(source[9]*source[14]-source[10]*source[13]) - source[1]*(source[8]*source[14]-source[10]*source[12]) + source[2]*(source[8]*source[13]-source[9]*source[12]));
+ cofactor[8] = (source[1]*(source[6]*source[15]-source[7]*source[14]) - source[2]*(source[5]*source[15]-source[7]*source[13]) + source[3]*(source[5]*source[14]-source[6]*source[13]));
+ cofactor[9] = -(source[0]*(source[6]*source[15]-source[7]*source[14]) - source[2]*(source[4]*source[15]-source[7]*source[12]) + source[3]*(source[4]*source[14]-source[6]*source[12]));
+ cofactor[10] = (source[0]*(source[5]*source[15]-source[7]*source[13]) - source[1]*(source[4]*source[15]-source[7]*source[12]) + source[3]*(source[4]*source[13]-source[5]*source[12]));
+ cofactor[11] = -(source[0]*(source[5]*source[14]-source[6]*source[13]) - source[1]*(source[4]*source[14]-source[6]*source[12]) + source[2]*(source[4]*source[13]-source[5]*source[12]));
+ cofactor[12] = -(source[1]*(source[6]*source[11]-source[7]*source[10]) - source[2]*(source[5]*source[11]-source[7]*source[9]) + source[3]*(source[5]*source[10]-source[6]*source[9]));
+ cofactor[13] = (source[0]*(source[6]*source[11]-source[7]*source[10]) - source[2]*(source[4]*source[11]-source[7]*source[8]) + source[3]*(source[4]*source[10]-source[6]*source[8]));
+ cofactor[14] = -(source[0]*(source[5]*source[11]-source[7]*source[9]) - source[1]*(source[4]*source[11]-source[7]*source[8]) + source[3]*(source[4]*source[9]-source[5]*source[8]));
+ cofactor[15] = (source[0]*(source[5]*source[10]-source[6]*source[9]) - source[1]*(source[4]*source[10]-source[6]*source[8]) + source[2]*(source[4]*source[9]-source[5]*source[8]));
+
+ float determinant = source[0]*cofactor[0] + source[1]*cofactor[1] + source[2]*cofactor[2] + source[3]*cofactor[3];
+
+ if (determinant != 0.0f) {
+ float inverseDeterminant = 1.0f / determinant;
+
+ for (int rowIndex = 0; rowIndex < 4; rowIndex++) {
+ for (int columnIndex = 0; columnIndex < 4; columnIndex++) {
+ inverse[rowIndex * 4 + columnIndex] = cofactor[columnIndex * 4 + rowIndex] * inverseDeterminant;
+ }
+ }
+ } else {
+ for (int elementIndex = 0; elementIndex < 16; elementIndex++) {
+ inverse[elementIndex] = (elementIndex % 5 == 0) ? 1.0f : 0.0f;
+ }
+ }
+
+ System.arraycopy(inverse, 0, this.matrix, 0, 16);
+
+ this.xScale = 1.0f / this.xScale;
+ this.yScale = 1.0f / this.yScale;
+ this.zScale = 1.0f / this.zScale;
+
+ this.noteTransformChange();
+
+ return this;
+ }
public Transform getObjectToWorldMatrix() {
return this.getTransform();
@@ -231,13 +712,16 @@ public class Transform extends SuperRoot {
private Point3Temp worldVecToObjectVec(Point3Temp worldVec) {
Transform inv = this.getObjectToWorldMatrix().invert();
Point3Temp p = Point3Temp.make(worldVec).vectorTimes(inv).times(this.getScale());
+
inv.recycle();
+
return p;
}
@Override
public Object properties(int index, int offset, int mode, Object value) throws NoSuchPropertyException {
Object ret = null;
+
switch (index - offset) {
case 0:
if (mode == 0) {
@@ -247,6 +731,7 @@ public class Transform extends SuperRoot {
} else if (mode == 2) {
this.setTransform((Transform)value);
}
+
break;
default:
ret = super.properties(index, offset + 1, mode, value);
@@ -262,6 +747,7 @@ public class Transform extends SuperRoot {
s.saveFloat(this.xScale);
s.saveFloat(this.yScale);
s.saveFloat(this.zScale);
+
float[] guts = this.getGuts();
for (int i = 0; i < 16; i++) {
@@ -276,6 +762,7 @@ public class Transform extends SuperRoot {
super.restoreState(r);
case 0:
this.xScale = this.yScale = this.zScale = r.restoreFloat();
+
float[] guts = new float[16];
for (int i = 0; i < 16; i++) {
@@ -283,35 +770,62 @@ public class Transform extends SuperRoot {
}
this.setGuts(guts);
+
break;
case 2:
super.restoreState(r);
this.xScale = r.restoreFloat();
this.yScale = r.restoreFloat();
this.zScale = r.restoreFloat();
- float[] guts = new float[16];
+ guts = new float[16];
for (int i = 0; i < 16; i++) {
guts[i] = r.restoreFloat();
}
this.setGuts(guts);
+
break;
default:
throw new TooNewException();
}
}
- private native float[] getGuts();
+ private float[] getGuts() {
+ float[] guts = new float[16];
+
+ System.arraycopy(this.matrix, 0, guts, 0, 16);
+
+ return guts;
+ }
+
+ public float[] getGutsPublic() {
+ return this.matrix;
+ }
- public native boolean isTransformEqual(Transform var1);
+ public boolean isTransformEqual(Transform other) {
+ if (other == null) return false;
+
+ for (int rowIndex = 0; rowIndex < 4; rowIndex++) {
+ for (int columnIndex = 0; columnIndex < 3; columnIndex++) {
+ if (this.matrix[rowIndex * 4 + columnIndex] != other.matrix[rowIndex * 4 + columnIndex]) return false;
+ }
+ }
+
+ return true;
+ }
- private native void setGuts(float[] var1);
+ private void setGuts(float[] guts) {
+ if (guts != null && guts.length == 16) {
+ System.arraycopy(guts, 0, this.matrix, 0, 16);
+ }
+ }
public String toTransformSubstring() {
Point3Temp axis = Point3Temp.make();
float angle = this.getSpin(axis);
Point3Temp pos = this.getPosition();
+
return angle == 0.0F && this.xScale == 1.0F && this.yScale == 1.0F && this.zScale == 1.0F && pos.x == 0.0F && pos.y == 0.0F && pos.z == 0.0F
? "[identity]"
: "[pos ("
@@ -347,6 +861,7 @@ public class Transform extends SuperRoot {
for (int k = 0; k < 4; k++) {
String s = strs[j * 4 + k];
int pad = maxStr - s.length() + 1;
+
System.out.print(s);
while (pad-- != 0) {