|
@@ -1722,6 +1722,7 @@
|
|
|
* Given three orthogonal normalized left-handed oriented Vector3 axis in space (target system),
|
|
|
* RotationFromAxis() returns the rotation Euler angles (ex : rotation.x, rotation.y, rotation.z) to apply
|
|
|
* to something in order to rotate it from its local system to the given target system.
|
|
|
+ * Note : axis1, axis2 and axis3 are normalized during this operation.
|
|
|
* Returns a new Vector3.
|
|
|
*/
|
|
|
public static RotationFromAxis(axis1: Vector3, axis2: Vector3, axis3: Vector3): Vector3 {
|
|
@@ -1734,121 +1735,13 @@
|
|
|
* The same than RotationFromAxis but updates the passed ref Vector3 parameter instead of returning a new Vector3.
|
|
|
*/
|
|
|
public static RotationFromAxisToRef(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Vector3): void {
|
|
|
- var u = axis1.normalize();
|
|
|
- var w = axis3.normalize();
|
|
|
-
|
|
|
- // world axis
|
|
|
- var X = Axis.X;
|
|
|
- var Y = Axis.Y;
|
|
|
-
|
|
|
- // equation unknowns and vars
|
|
|
- var yaw = 0.0;
|
|
|
- var pitch = 0.0;
|
|
|
- var roll = 0.0;
|
|
|
- var x = 0.0;
|
|
|
- var y = 0.0;
|
|
|
- var z = 0.0;
|
|
|
- var t = 0.0;
|
|
|
- var sign = -1.0;
|
|
|
- var nbRevert = 0;
|
|
|
- var cross: Vector3 = Tmp.Vector3[0];
|
|
|
- var dot = 0.0;
|
|
|
-
|
|
|
- // step 1 : rotation around w
|
|
|
- // Rv3(u) = u1, and u1 belongs to plane xOz
|
|
|
- // Rv3(w) = w1 = w invariant
|
|
|
- var u1: Vector3 = Tmp.Vector3[1];
|
|
|
- if (MathTools.WithinEpsilon(w.z, 0, Epsilon)) {
|
|
|
- z = 1.0;
|
|
|
- }
|
|
|
- else if (MathTools.WithinEpsilon(w.x, 0, Epsilon)) {
|
|
|
- x = 1.0;
|
|
|
- }
|
|
|
- else {
|
|
|
- t = w.z / w.x;
|
|
|
- x = - t * Math.sqrt(1 / (1 + t * t));
|
|
|
- z = Math.sqrt(1 / (1 + t * t));
|
|
|
- }
|
|
|
-
|
|
|
- u1.x = x;
|
|
|
- u1.y = y;
|
|
|
- u1.z = z;
|
|
|
- u1.normalize();
|
|
|
- Vector3.CrossToRef(u, u1, cross); // returns same direction as w (=local z) if positive angle : cross(source, image)
|
|
|
- cross.normalize();
|
|
|
- if (Vector3.Dot(w, cross) < 0) {
|
|
|
- sign = 1.0;
|
|
|
- }
|
|
|
-
|
|
|
- dot = Vector3.Dot(u, u1);
|
|
|
- dot = (Math.min(1.0, Math.max(-1.0, dot))); // to force dot to be in the range [-1, 1]
|
|
|
- roll = Math.acos(dot) * sign;
|
|
|
-
|
|
|
- if (Vector3.Dot(u1, X) < 0) { // checks X orientation
|
|
|
- roll = Math.PI + roll;
|
|
|
- u1 = u1.scaleInPlace(-1);
|
|
|
- nbRevert++;
|
|
|
- }
|
|
|
-
|
|
|
- // step 2 : rotate around u1
|
|
|
- // Ru1(w1) = Ru1(w) = w2, and w2 belongs to plane xOz
|
|
|
- // u1 is yet in xOz and invariant by Ru1, so after this step u1 and w2 will be in xOz
|
|
|
- var w2: Vector3 = Tmp.Vector3[2];
|
|
|
- var v2: Vector3 = Tmp.Vector3[3];
|
|
|
- x = 0.0;
|
|
|
- y = 0.0;
|
|
|
- z = 0.0;
|
|
|
- sign = -1.0;
|
|
|
- if (MathTools.WithinEpsilon(w.z, 0, Epsilon)) {
|
|
|
- x = 1.0;
|
|
|
- }
|
|
|
- else {
|
|
|
- t = u1.z / u1.x;
|
|
|
- x = - t * Math.sqrt(1 / (1 + t * t));
|
|
|
- z = Math.sqrt(1 / (1 + t * t));
|
|
|
- }
|
|
|
-
|
|
|
- w2.x = x;
|
|
|
- w2.y = y;
|
|
|
- w2.z = z;
|
|
|
- w2.normalize();
|
|
|
- Vector3.CrossToRef(w2, u1, v2); // v2 image of v1 through rotation around u1
|
|
|
- v2.normalize();
|
|
|
- Vector3.CrossToRef(w, w2, cross); // returns same direction as u1 (=local x) if positive angle : cross(source, image)
|
|
|
- cross.normalize();
|
|
|
- if (Vector3.Dot(u1, cross) < 0) {
|
|
|
- sign = 1.0;
|
|
|
- }
|
|
|
-
|
|
|
- dot = Vector3.Dot(w, w2);
|
|
|
- dot = (Math.min(1.0, Math.max(-1.0, dot))); // to force dot to be in the range [-1, 1]
|
|
|
- pitch = Math.acos(dot) * sign;
|
|
|
- if (Vector3.Dot(v2, Y) < 0) { // checks for Y orientation
|
|
|
- pitch = Math.PI + pitch;
|
|
|
- nbRevert++;
|
|
|
- }
|
|
|
-
|
|
|
- // step 3 : rotate around v2
|
|
|
- // Rv2(u1) = X, same as Rv2(w2) = Z, with X=(1,0,0) and Z=(0,0,1)
|
|
|
- sign = -1.0;
|
|
|
- Vector3.CrossToRef(X, u1, cross); // returns same direction as Y if positive angle : cross(source, image)
|
|
|
- cross.normalize();
|
|
|
- if (Vector3.Dot(cross, Y) < 0) {
|
|
|
- sign = 1.0;
|
|
|
- }
|
|
|
- dot = Vector3.Dot(u1, X);
|
|
|
- dot = (Math.min(1.0, Math.max(-1.0, dot))); // to force dot to be in the range [-1, 1]
|
|
|
- yaw = - Math.acos(dot) * sign; // negative : plane zOx oriented clockwise
|
|
|
- if (dot < 0 && nbRevert < 2) {
|
|
|
- yaw = Math.PI + yaw;
|
|
|
- }
|
|
|
-
|
|
|
- ref.x = pitch;
|
|
|
- ref.y = yaw;
|
|
|
- ref.z = roll;
|
|
|
+ var quat = BABYLON.Tmp.Quaternion[1];
|
|
|
+ Quaternion.QuaternionRotationFromAxisToRef(axis1, axis2, axis3, quat);
|
|
|
+ quat.toEulerAnglesToRef(ref);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
//Vector4 class created for EulerAngle class conversion to Quaternion
|
|
|
export class Vector4 {
|
|
|
/**
|
|
@@ -2795,6 +2688,27 @@
|
|
|
result.w = Math.cos(halfGammaPlusAlpha) * Math.cos(halfBeta);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Returns a new Quaternion as the quaternion rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system.
|
|
|
+ * cf to Vector3.RotationFromAxis() documentation.
|
|
|
+ * Note : axis1, axis2 and axis3 are normalized during this operation.
|
|
|
+ */
|
|
|
+ public static QuaternionRotationFromAxis(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Quaternion): Quaternion {
|
|
|
+ var quat = new Quaternion(0.0, 0.0, 0.0, 0.0);
|
|
|
+ Quaternion.QuaternionRotationFromAxisToRef(axis1, axis2, axis3, quat);
|
|
|
+ return quat;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Sets the passed quaternion "ref" with the quaternion rotation value to reach the target (axis1, axis2, axis3) orientation as a rotated XYZ system.
|
|
|
+ * cf to Vector3.RotationFromAxis() documentation.
|
|
|
+ * Note : axis1, axis2 and axis3 are normalized during this operation.
|
|
|
+ */
|
|
|
+ public static QuaternionRotationFromAxisToRef(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Quaternion): void {
|
|
|
+ var rotMat = Tmp.Matrix[0];
|
|
|
+ BABYLON.Matrix.FromXYZAxesToRef(axis1.normalize(), axis2.normalize(), axis3.normalize(), rotMat);
|
|
|
+ BABYLON.Quaternion.FromRotationMatrixToRef(rotMat, ref);
|
|
|
+ }
|
|
|
+
|
|
|
public static Slerp(left: Quaternion, right: Quaternion, amount: number): Quaternion {
|
|
|
|
|
|
var result = Quaternion.Identity();
|