public FbxQuaternion GetQ() { FbxQuaternion ret = new FbxQuaternion(NativeMethods.FbxAMatrix_GetQ(swigCPtr), true); if (NativeMethods.SWIGPendingException.Pending) { throw NativeMethods.SWIGPendingException.Retrieve(); } return(ret); }
public double DotProduct(FbxQuaternion pQuaternion) { double ret = FbxWrapperNativePINVOKE.FbxQuaternion_DotProduct(swigCPtr, FbxQuaternion.getCPtr(pQuaternion)); if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending) { throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
public FbxQuaternion Product(FbxQuaternion pOther) { FbxQuaternion ret = new FbxQuaternion(FbxWrapperNativePINVOKE.FbxQuaternion_Product(swigCPtr, FbxQuaternion.getCPtr(pOther)), true); if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending) { throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
public FbxQuaternion div_assign(FbxQuaternion pOther) { FbxQuaternion ret = new FbxQuaternion(FbxWrapperNativePINVOKE.FbxQuaternion_div_assign__SWIG_1(swigCPtr, FbxQuaternion.getCPtr(pOther)), false); if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending) { throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
public FbxQuaternion sub(FbxQuaternion pQuaternion) { FbxQuaternion ret = new FbxQuaternion(FbxWrapperNativePINVOKE.FbxQuaternion_sub__SWIG_1(swigCPtr, FbxQuaternion.getCPtr(pQuaternion)), true); if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending) { throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
public FbxQuaternion MultQ(FbxQuaternion pQuaternion) { FbxQuaternion ret = new FbxQuaternion(NativeMethods.FbxAMatrix_MultQ(swigCPtr, FbxQuaternion.getCPtr(pQuaternion)), true); if (NativeMethods.SWIGPendingException.Pending) { throw NativeMethods.SWIGPendingException.Retrieve(); } return(ret); }
// FbxQuaternion public static Quaternion ToUQuaternion(this FbxQuaternion fbx) { var q = new Quaternion(); // the indexing order of FbxQuaternion is undocumented; w=3 // was determined empirically. q.x = (float)fbx.GetAt(0); q.y = (float)fbx.GetAt(1); q.z = (float)fbx.GetAt(2); q.w = (float)fbx.GetAt(3); return(q); }
protected override FbxQuaternion GetConvertedQuaternionRotation(float seconds, Quaternion restRotation) { AnimationCurve x = GetCurves()[0], y = GetCurves()[1], z = GetCurves()[2], w = GetCurves()[3]; // The final animation, including the effect of pre-rotation. // If we have no curve, assume the node has the correct rotation right now. // We need to evaluate since we might only have keys in one of the axes. var fbxFinalAnimation = new FbxQuaternion( (x == null) ? restRotation[0] : x.Evaluate(seconds), (y == null) ? restRotation[1] : y.Evaluate(seconds), (z == null) ? restRotation[2] : z.Evaluate(seconds), (w == null) ? restRotation[3] : w.Evaluate(seconds)); return(fbxFinalAnimation); }
public static FbxDouble3 XYZEulerFromQuaternion(Quaternion rotation) { // Unity wrappers don't have FbxVector4::SetXYZ(FbxQuaternion) to convert quat -> xyz euler. // We can abuse FbxAMatrix to do the same thing. FbxQuaternion fbxQuaternion = new FbxQuaternion(rotation.x, rotation.y, rotation.z, rotation.w); // We're using the FBX API to do the conversion to XYZ eulers. var mat = new FbxAMatrix(); mat.SetIdentity(); mat.SetQ(fbxQuaternion); // "The returned rotation vector is in Euler angle and the rotation order is XYZ." FbxVector4 v4 = mat.GetR(); return(new FbxDouble3(v4.X, v4.Y, v4.Z)); }
public void TestFbxQuaternion() { var uq = new Quaternion(1, 2, 3, 4); var fq = uq.ToFbxQuaternion(); // Basic round-tripping var uq2 = fq.ToUQuaternion(); MathTestUtils.AssertAlmostEqual(uq, uq2); // Check that [3] is w, the real part (docs don't say anything about this) var fqc = new FbxQuaternion(fq); fqc.Conjugate(); // [3] is the real part MathTestUtils.AssertAlmostEqual((float)fq.GetAt(3), (float)fqc.GetAt(3)); // and 0-2 are the imaginary part MathTestUtils.AssertAlmostEqual((float)fq.GetAt(1), -(float)fqc.GetAt(1)); }
/// <summary> /// Check that two quaternions represent a similar rotation. /// /// Either they're equal (within tolerance) or they're exactly opposite. /// Note that a slerp will go opposite directions if they're opposite. /// /// If you want to use the boolean result, pass in 'nothrow' as true. /// Otherwise a failed comparision will throw an exception. /// </summary> public static bool AssertSimilar(FbxQuaternion expected, FbxQuaternion actual, double tolerance = 1e-10, bool nothrow = false) { // Are they bitwise equal? if (expected == actual) { return(true); } // Compute the dot product. It'll be +1 or -1 if they're the same rotation. if (System.Math.Abs(expected.DotProduct(actual)) >= 1 - tolerance) { return(true); } // Fail. Print it out nicely. if (!nothrow) { Assert.AreEqual(expected, actual); } return(false); }
/// <summary> /// Check that two vectors are similar, interpreting them as XYZ euler angles, /// ignoring W. /// /// Pass 'nothrow' as true if you want a bool yes/no. By default we /// throw an NUnit exception if the vectors don't match. /// </summary> public static bool AssertSimilarEuler(FbxVector4 expected, FbxVector4 actual, double tolerance = 1e-10, bool nothrow = false) { if (expected == actual) { return(true); } var q1 = new FbxQuaternion(); q1.ComposeSphericalXYZ(expected); var q2 = new FbxQuaternion(); q2.ComposeSphericalXYZ(actual); // Check if the quaternions match. if (FbxQuaternionTest.AssertSimilar(q1, q2, System.Math.Sqrt(tolerance), nothrow: true)) { return(true); } if (!nothrow) { Assert.AreEqual(expected, actual, "Quaternions don't match: " + q1 + " versus " + q2); } return(false); }
public FbxQuaternion GetRotation() { FbxQuaternion ret = new FbxQuaternion(fbx_wrapperPINVOKE.FbxDualQuaternion_GetRotation(swigCPtr), true); return(ret); }
public FbxMatrix(FbxVector4 pT, FbxQuaternion pQ, FbxVector4 pS) : this(FbxWrapperNativePINVOKE.new_FbxMatrix__SWIG_4(FbxVector4.getCPtr(pT), FbxQuaternion.getCPtr(pQ), FbxVector4.getCPtr(pS)), true) { if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending) { throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve(); } }
public void BasicTests() { FbxQuaternion u, v; // make sure the no-arg constructor doesn't crash new FbxQuaternion(); // test dispose using (new FbxQuaternion()) { } DisposeTester.TestDispose(new FbxQuaternion()); // Test other constructors v = new FbxQuaternion(0.1, 0.2, 0.3, 0.4); u = new FbxQuaternion(v); Assert.AreEqual(v, u); u[0] = 0.5; Assert.AreEqual(0.5, u[0]); Assert.AreEqual(0.1, v[0]); // check that setting u doesn't set v // axis-angle constructor and setter v = new FbxQuaternion(new FbxVector4(1, 2, 3), 90); u = new FbxQuaternion(); u.SetAxisAngle(new FbxVector4(1, 2, 3), 90); Assert.AreEqual(u, v); // euler v = new FbxQuaternion(); v.ComposeSphericalXYZ(new FbxVector4(20, 30, 40)); var euler = v.DecomposeSphericalXYZ(); Assert.That(euler.X, Is.InRange(19.99, 20.01)); Assert.That(euler.Y, Is.InRange(29.99, 30.01)); Assert.That(euler.Z, Is.InRange(39.99, 40.01)); Assert.AreEqual(0, euler.W); v = new FbxQuaternion(0.1, 0.2, 0.3); Assert.AreEqual(0.1, v[0]); Assert.AreEqual(0.2, v[1]); Assert.AreEqual(0.3, v[2]); Assert.AreEqual(1, v[3]); // w is assumed to be a homogenous coordinate v.Set(0.9, 0.8, 0.7, 0.6); Assert.AreEqual(0.9, v[0]); Assert.AreEqual(0.8, v[1]); Assert.AreEqual(0.7, v[2]); Assert.AreEqual(0.6, v[3]); v.Set(0.9, 0.8, 0.7); Assert.AreEqual(0.9, v[0]); Assert.AreEqual(0.8, v[1]); Assert.AreEqual(0.7, v[2]); v.SetAt(1, 2); Assert.AreEqual(2, v.GetAt(1)); // Test operator[] v = new FbxQuaternion(); v[0] = 0.1; Assert.AreEqual(0.1, v[0]); v[1] = 0.2; Assert.AreEqual(0.2, v[1]); v[2] = 0.3; Assert.AreEqual(0.3, v[2]); v[3] = 0.4; Assert.AreEqual(0.4, v[3]); v.SetAt(3, 0.5); Assert.AreEqual(0.5, v.GetAt(3)); Assert.That(() => v[-1], Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v[4], Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v.GetAt(-1), Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v.GetAt(4), Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v[-1] = 0.5, Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v[4] = 0.5, Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v.SetAt(-1, 0.5), Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); Assert.That(() => v.SetAt(4, 0.5), Throws.Exception.TypeOf <System.ArgumentOutOfRangeException>()); // Test W/X/Y/Z v.X = 0.1; Assert.AreEqual(0.1, v.X); v.Y = 0.2; Assert.AreEqual(0.2, v.Y); v.Z = 0.3; Assert.AreEqual(0.3, v.Z); v.W = 0.4; Assert.AreEqual(0.4, v.W); // call the multiply/divide/add/sub operators, make sure they're vaguely sane u = new FbxQuaternion(v); v = v * v; Assert.AreNotEqual(0, u.Compare(v, 1e-15)); // test compare can return false v = v * 9; v = 9 * v; v = v + 5; v = v - 5; // undo v + 5 v = v + u; v = v - u; // undo v + u v = v / 81; // undo 9 * (v * 9) v = v / u; // undo v*v Assert.AreEqual(0, u.Compare(v)); // u and v are the same up to rounding Assert.AreEqual(u * u, u.Product(u)); // unary negate and dot product Assert.AreEqual(0, (-u).Compare(-v)); Assert.AreEqual(-0.3, v.DotProduct(-v), 1e-6); Assert.AreEqual(System.Math.Sqrt(0.3), v.Length(), 1e-6); v.Normalize(); Assert.AreEqual(1, v.DotProduct(v), 1e-6); // various others where we assume that FBX works, just test that they don't crash v.Conjugate(); v.Inverse(); v.Slerp(u, 0.5); }
public FbxAMatrix(FbxVector4 pT, FbxQuaternion pQ, FbxVector4 pS) : this(fbx_wrapperPINVOKE.new_FbxAMatrix__SWIG_3(FbxVector4.getCPtr(pT), FbxQuaternion.getCPtr(pQ), FbxVector4.getCPtr(pS)), true) { if (fbx_wrapperPINVOKE.SWIGPendingException.Pending) { throw fbx_wrapperPINVOKE.SWIGPendingException.Retrieve(); } }
/// <summary> /// Process transformation data and setup Transform component /// </summary> private void ProcessTransform(FbxNode fbxNode, GameObject unityGo) { FbxVector4 lclTrs = new FbxVector4(); FbxQuaternion lclRot = new FbxQuaternion(); FbxVector4 lclScl = new FbxVector4(1.0f, 1.0f, 1.0f); #if UNI_18844 // Construct rotation matrices FbxVector4 fbxRotation = new FbxVector4(fbxNode.LclRotation.Get()); FbxAMatrix fbxRotationM = new FbxAMatrix(); fbxRotationM.SetR(fbxRotation); FbxVector4 fbxPreRotation = new FbxVector4(fbxNode.PreRotation.Get()); FbxAMatrix fbxPreRotationM = new FbxAMatrix(); fbxPreRotationM.SetR(fbxPreRotation); FbxVector4 fbxPostRotation = new FbxVector4(fbxNode.PostRotation.Get()); FbxAMatrix fbxPostRotationM = new FbxAMatrix(); fbxPostRotationM.SetR(fbxPostRotation); // Construct translation matrix FbxAMatrix fbxTranslationM = new FbxAMatrix(); FbxVector4 fbxTranslation = new FbxVector4(fbxNode.LclTranslation.Get()); fbxTranslationM.SetT(fbxTranslation); // Construct scaling matrix FbxAMatrix fbxScalingM = new FbxAMatrix(); FbxVector4 fbxScaling = new FbxVector4(fbxNode.LclScaling.Get()); fbxScalingM.SetS(fbxScaling); // Construct offset and pivot matrices FbxAMatrix fbxRotationOffsetM = new FbxAMatrix(); FbxVector4 fbxRotationOffset = fbxNode.RotationOffset.Get(); fbxRotationOffsetM.SetT(fbxRotationOffset); FbxAMatrix fbxRotationPivotM = new FbxAMatrix(); FbxVector4 fbxRotationPivot = fbxNode.RotationPivot.Get(); fbxRotationPivotM.SetT(fbxRotationPivot); FbxAMatrix fbxScalingOffsetM = new FbxAMatrix(); FbxVector4 fbxScalingOffset = fbxNode.ScalingOffset.Get(); fbxScalingOffsetM.SetT(fbxScalingOffset); FbxAMatrix fbxScalingPivotM = new FbxAMatrix(); FbxVector4 fbxScalingPivot = fbxNode.ScalingPivot.Get(); fbxScalingPivotM.SetT(fbxScalingPivot); FbxAMatrix fbxTransform = fbxTranslationM * fbxRotationOffsetM * fbxRotationPivotM * fbxPreRotationM * fbxRotationM * fbxPostRotationM * fbxRotationPivotM.Inverse() * fbxScalingOffsetM * fbxScalingPivotM * fbxScalingM * fbxScalingPivotM.Inverse(); FbxVector4 lclTrs = fbxTransform.GetT(); FbxQuaternion lclRot = fbxTransform.GetQ(); FbxVector4 lclScl = fbxTransform.GetS(); #endif Debug.Log(string.Format("processing {3} Lcl : T({0}) R({1}) S({2})", lclTrs.ToString(), lclRot.ToString(), lclScl.ToString(), fbxNode.GetName())); unityGo.transform.localPosition = new Vector3((float)lclTrs[0], (float)lclTrs[1], (float)lclTrs[2]); unityGo.transform.localRotation = new Quaternion((float)lclRot[0], (float)lclRot[1], (float)lclRot[2], (float)lclRot[3]); unityGo.transform.localScale = new Vector3((float)lclScl[0], (float)lclScl[1], (float)lclScl[2]); }
/// <summary> /// Process fbx scene by doing nothing /// </summary> public void ProcessNode(FbxNode fbxNode, GameObject unityParentObj = null, bool constructTransform = false) { string name = fbxNode.GetName(); GameObject unityGo = new GameObject(name); NumNodes++; if (unityParentObj != null) { unityGo.transform.parent = unityParentObj.transform; } FbxAMatrix fbxTransform = null; if (constructTransform) { #if UNI_18844 // Construct rotation matrices FbxVector4 fbxRotation = new FbxVector4(fbxNode.LclRotation.Get()); FbxAMatrix fbxRotationM = new FbxAMatrix(); fbxRotationM.SetR(fbxRotation); FbxVector4 fbxPreRotation = new FbxVector4(fbxNode.PreRotation.Get()); FbxAMatrix fbxPreRotationM = new FbxAMatrix(); fbxPreRotationM.SetR(fbxPreRotation); FbxVector4 fbxPostRotation = new FbxVector4(fbxNode.PostRotation.Get()); FbxAMatrix fbxPostRotationM = new FbxAMatrix(); fbxPostRotationM.SetR(fbxPostRotation); // Construct translation matrix FbxAMatrix fbxTranslationM = new FbxAMatrix(); FbxVector4 fbxTranslation = new FbxVector4(fbxNode.LclTranslation.Get()); fbxTranslationM.SetT(fbxTranslation); // Construct scaling matrix FbxAMatrix fbxScalingM = new FbxAMatrix(); FbxVector4 fbxScaling = new FbxVector4(fbxNode.LclScaling.Get()); fbxScalingM.SetS(fbxScaling); // Construct offset and pivot matrices FbxAMatrix fbxRotationOffsetM = new FbxAMatrix(); FbxVector4 fbxRotationOffset = fbxNode.RotationOffset.Get(); fbxRotationOffsetM.SetT(fbxRotationOffset); FbxAMatrix fbxRotationPivotM = new FbxAMatrix(); FbxVector4 fbxRotationPivot = fbxNode.RotationPivot.Get(); fbxRotationPivotM.SetT(fbxRotationPivot); FbxAMatrix fbxScalingOffsetM = new FbxAMatrix(); FbxVector4 fbxScalingOffset = fbxNode.ScalingOffset.Get(); fbxScalingOffsetM.SetT(fbxScalingOffset); FbxAMatrix fbxScalingPivotM = new FbxAMatrix(); FbxVector4 fbxScalingPivot = fbxNode.ScalingPivot.Get(); fbxScalingPivotM.SetT(fbxScalingPivot); fbxTransform = fbxTranslationM * fbxRotationOffsetM * fbxRotationPivotM * fbxPreRotationM * fbxRotationM * fbxPostRotationM * fbxRotationPivotM.Inverse() * fbxScalingOffsetM * fbxScalingPivotM * fbxScalingM * fbxScalingPivotM.Inverse(); lclTrs = fbxTransform.GetT(); lclRot = fbxTransform.GetQ(); lclScl = fbxTransform.GetS(); #endif } else { fbxTransform = fbxNode.EvaluateLocalTransform(); } if (fbxTransform == null) { Debug.LogError(string.Format("failed to retrieve transform for node : {0}", fbxNode.GetName())); return; } FbxVector4 lclTrs = fbxTransform.GetT(); FbxQuaternion lclRot = fbxTransform.GetQ(); FbxVector4 lclScl = fbxTransform.GetS(); Debug.Log(string.Format("processing {3} Lcl : T({0}) R({1}) S({2})", lclTrs.ToString(), lclRot.ToString(), lclScl.ToString(), fbxNode.GetName())); // check we can handle translation value Debug.Assert(lclTrs.X <= float.MaxValue && lclTrs.X >= float.MinValue); Debug.Assert(lclTrs.Y <= float.MaxValue && lclTrs.Y >= float.MinValue); Debug.Assert(lclTrs.Z <= float.MaxValue && lclTrs.Z >= float.MinValue); unityGo.transform.localPosition = new Vector3((float)lclTrs.X, (float)lclTrs.Y, (float)lclTrs.Z); unityGo.transform.localRotation = new Quaternion((float)lclRot[0], (float)lclRot[1], (float)lclRot[2], (float)lclRot[3]); unityGo.transform.localScale = new Vector3((float)lclScl.X, (float)lclScl.Y, (float)lclScl.Z); for (int i = 0; i < fbxNode.GetChildCount(); ++i) { ProcessNode(fbxNode.GetChild(i), unityGo); } }
public void GetElements(FbxVector4 pTranslation, FbxQuaternion pRotation, FbxVector4 pShearing, FbxVector4 pScaling, SWIGTYPE_p_double pSign) { fbx_wrapperPINVOKE.FbxMatrix_GetElements__SWIG_0(swigCPtr, FbxVector4.getCPtr(pTranslation), FbxQuaternion.getCPtr(pRotation), FbxVector4.getCPtr(pShearing), FbxVector4.getCPtr(pScaling), SWIGTYPE_p_double.getCPtr(pSign)); if (fbx_wrapperPINVOKE.SWIGPendingException.Pending) { throw fbx_wrapperPINVOKE.SWIGPendingException.Retrieve(); } }
public FbxDualQuaternion(FbxQuaternion pV1, FbxQuaternion pV2) : this(fbx_wrapperPINVOKE.new_FbxDualQuaternion__SWIG_1(FbxQuaternion.getCPtr(pV1), FbxQuaternion.getCPtr(pV2)), true) { if (fbx_wrapperPINVOKE.SWIGPendingException.Pending) { throw fbx_wrapperPINVOKE.SWIGPendingException.Retrieve(); } }
Key [] ComputeKeys(UnityEngine.Quaternion restRotation, FbxNode node) { // Get the source pivot pre-rotation if any, so we can // remove it from the animation we get from Unity. var fbxPreRotationEuler = node.GetRotationActive() ? node.GetPreRotation(FbxNode.EPivotSet.eSourcePivot) : new FbxVector4(); var fbxPreRotationInverse = new FbxQuaternion(); fbxPreRotationInverse.ComposeSphericalXYZ(fbxPreRotationEuler); fbxPreRotationInverse.Inverse(); // If we're only animating along certain coords for some // reason, we'll need to fill in the other coords with the // rest-pose value. var lclQuaternion = new FbxQuaternion(restRotation.x, restRotation.y, restRotation.z, restRotation.w); // Find when we have keys set. var keyTimes = new HashSet <float>(); if (x != null) { foreach (var key in x.keys) { keyTimes.Add(key.time); } } if (y != null) { foreach (var key in y.keys) { keyTimes.Add(key.time); } } if (z != null) { foreach (var key in z.keys) { keyTimes.Add(key.time); } } if (w != null) { foreach (var key in w.keys) { keyTimes.Add(key.time); } } // Convert to the Key type. var keys = new Key[keyTimes.Count]; int i = 0; foreach (var seconds in keyTimes) { // The final animation, including the effect of pre-rotation. // If we have no curve, assume the node has the correct rotation right now. // We need to evaluate since we might only have keys in one of the axes. var fbxFinalAnimation = new FbxQuaternion( (x == null) ? lclQuaternion[0] : x.Evaluate(seconds), (y == null) ? lclQuaternion[1] : y.Evaluate(seconds), (z == null) ? lclQuaternion[2] : z.Evaluate(seconds), (w == null) ? lclQuaternion[3] : w.Evaluate(seconds)); // Cancel out the pre-rotation. Order matters. FBX reads left-to-right. // When we run animation we will apply: // pre-rotation // then pre-rotation inverse // then animation. var fbxAnimation = fbxPreRotationInverse * fbxFinalAnimation; // Store the key so we can sort them later. Key key; key.time = FbxTime.FromSecondDouble(seconds); key.euler = fbxAnimation.DecomposeSphericalXYZ(); keys[i++] = key; } // Sort the keys by time System.Array.Sort(keys, (Key a, Key b) => a.time.CompareTo(b.time)); return(keys); }
public FbxDualQuaternion(FbxQuaternion pRotation, FbxVector4 pTranslation) : this(fbx_wrapperPINVOKE.new_FbxDualQuaternion__SWIG_3(FbxQuaternion.getCPtr(pRotation), FbxVector4.getCPtr(pTranslation)), true) { if (fbx_wrapperPINVOKE.SWIGPendingException.Pending) { throw fbx_wrapperPINVOKE.SWIGPendingException.Retrieve(); } }
public void BasicTests() { base.TestElementAccessAndDispose(new FbxMatrix()); FbxMatrix mx; // make sure the constructors compile and don't crash mx = new FbxMatrix(); mx = new FbxMatrix(new FbxMatrix()); mx = new FbxMatrix(new FbxAMatrix()); mx = new FbxMatrix(new FbxVector4(), new FbxVector4(), new FbxVector4(1, 1, 1)); mx = new FbxMatrix(new FbxVector4(), new FbxQuaternion(), new FbxVector4(1, 1, 1)); mx = new FbxMatrix(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); /* Check the values we typed in match up. */ for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(x + 4 * y, mx.Get(y, x)); } } Assert.AreEqual(new FbxVector4(4, 5, 6, 7), mx.GetRow(1)); Assert.AreEqual(new FbxVector4(1, 5, 9, 13), mx.GetColumn(1)); /* Check that set and get work (silly transpose operation). */ FbxMatrix mx2 = new FbxMatrix(); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { mx2.Set(y, x, y + 4 * x); Assert.AreEqual(mx.Get(x, y), mx2.Get(y, x)); } } /* normal transpose operation */ Assert.AreEqual(mx, mx2.Transpose()); // Test SetIdentity Assert.IsFalse(AssertIsIdentity(mx, nothrow: true)); AssertIsIdentity(mx, 15); // squint very, very, very hard mx.SetIdentity(); AssertIsIdentity(mx); // Test getting the elements from a matrix built by TRS var translate = new FbxVector4(1, 2, 3); var rotate = new FbxVector4(0, 90, 0); var scale = new FbxVector4(1, 2, .5); mx = new FbxMatrix(translate, rotate, scale); FbxVector4 t, r, s, shear; double sign; mx.GetElements(out t, out r, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxVector4Test.AssertSimilarEuler(rotate, r); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); FbxQuaternion q = new FbxQuaternion(); mx.GetElements(out r, q, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxQuaternionTest.AssertSimilar(rotate, q); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); // Try SetTRS and SetTQS with the same arguments. using (var X = new FbxMatrix()) { X.SetTRS(translate, rotate, scale); X.GetElements(out r, q, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxQuaternionTest.AssertSimilar(rotate, q); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); } using (var X = new FbxMatrix()) { FbxQuaternion qRotate = new FbxQuaternion(); qRotate.ComposeSphericalXYZ(rotate); X.SetTQS(translate, q, scale); X.GetElements(out r, q, out shear, out s, out sign); Assert.AreEqual(1, sign); FbxVector4Test.AssertSimilarXYZ(translate, t); FbxQuaternionTest.AssertSimilar(rotate, q); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(), shear); FbxVector4Test.AssertSimilarXYZ(scale, s); // While we're at it, transform a vertex. // Verify also that w turns out normalized. var v = new FbxVector4(1, 2, 3, 4); var v2 = X.MultNormalize(v); FbxVector4Test.AssertSimilarXYZW(new FbxVector4(2.5, 6, 2, 1), v2); // While we're at it, test that we can invert the matrix. // This matrix is invertible (since it's an affine transformation), // and the inversion turns out to be exact. AssertIsIdentity(X.Inverse() * X); using (var inv = new FbxMatrix( 0, 0, 2, 0, 0, 0.5, 0, 0, -1, 0, 0, 0, 3, -1, -2, 1)) { Assert.AreEqual(inv, X.Inverse()); } } // Test set column + set row mx = new FbxMatrix(); mx.SetColumn(1, new FbxVector4(1, 2, 3, 4)); mx.SetRow(2, new FbxVector4(5, 6, 7, 8)); //check that the column is what we expect Assert.AreEqual(1, mx.Get(0, 1)); Assert.AreEqual(2, mx.Get(1, 1)); Assert.AreEqual(6, mx.Get(2, 1)); // this value got changed by SetRow Assert.AreEqual(4, mx.Get(3, 1)); // check that the row is what we expect Assert.AreEqual(new FbxDouble4(5, 6, 7, 8), mx [2]); // Test operators on two matrices. using (var a = new FbxMatrix( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) { using (var b = new FbxMatrix( 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)) { using (var sum = new FbxMatrix( 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15)) { Assert.AreEqual(sum, a + b); } using (var diff = new FbxMatrix( -15, -13, -11, -9, -7, -5, -3, -1, 1, 3, 5, 7, 9, 11, 13, 15)) { Assert.AreEqual(diff, a - b); } using (var prod = new FbxMatrix( 304, 358, 412, 466, 208, 246, 284, 322, 112, 134, 156, 178, 16, 22, 28, 34)) { Assert.AreEqual(prod, a * b); } using (var neg = new FbxMatrix( 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15)) { Assert.AreEqual(neg, -a); } } } var eyePosition = new FbxVector4(1, 2, 3); var eyeDirection = new FbxVector4(-1, -1, -1); var eyeUp = new FbxVector4(0, 1, 0); using (mx = new FbxMatrix()) { mx.SetLookToRH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( 0.707, -0.408, 0.577, 0, 0, 0.816, 0.577, 0, -0.707, -0.408, 0.577, 0, 1.414, 0, -3.464, 1), mx, 1e-2); mx.SetLookToLH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( -0.707, -0.408, -0.577, 0, 0, 0.816, -0.577, 0, 0.707, -0.408, -0.577, 0, -1.414, 0, 3.464, 1), mx, 1e-2); mx.SetLookAtRH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( 0.894, -0.249, 0.371, 0, 0, 0.834, 0.557, 0, -0.447, -0.498, 0.742, 0, 0.447, 0.083, -3.713, 1), mx, 1e-2); mx.SetLookAtLH(eyePosition, eyeDirection, eyeUp); AssertSimilar(new FbxMatrix( -0.894, -0.249, -0.371, 0, 0, 0.834, -0.557, 0, 0.447, -0.498, -0.742, 0, -0.447, 0.083, 3.713, 1), mx, 1e-2); } }
public FbxQuaternion GetFirstQuaternion() { FbxQuaternion ret = new FbxQuaternion(fbx_wrapperPINVOKE.FbxDualQuaternion_GetFirstQuaternion__SWIG_0(swigCPtr), false); return(ret); }
public FbxMatrix(FbxVector4 pT, FbxQuaternion pQ, FbxVector4 pS) : this(NativeMethods.new_FbxMatrix__SWIG_4(pT, FbxQuaternion.getCPtr(pQ), pS), true) { if (NativeMethods.SWIGPendingException.Pending) { throw NativeMethods.SWIGPendingException.Retrieve(); } }
public void BasicTests() { base.TestElementAccessAndDispose(new FbxAMatrix()); // make sure the constructors compile and don't crash new FbxAMatrix(); new FbxAMatrix(new FbxAMatrix()); var mx = new FbxAMatrix(new FbxVector4(), new FbxVector4(), new FbxVector4(1, 1, 1)); // check that the matrix is the id matrix Assert.IsTrue(mx.IsIdentity()); for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(x == y ? 1 : 0, mx.Get(y, x)); } } // Test that all the operations work. // In particular, test that they don't return the default element // when they aren't supposed to. var translate = new FbxVector4(5, 3, 1); var euler = new FbxVector4(-135, -90, 0); var scale = new FbxVector4(1, 2, .5); var quat = new FbxQuaternion(); quat.ComposeSphericalXYZ(euler); mx = new FbxAMatrix(translate, euler, scale); Assert.IsFalse(mx.IsIdentity()); Assert.IsTrue(mx.IsIdentity(10)); // squint very, very, very hard FbxVector4Test.AssertSimilarXYZ(translate, mx.GetT()); FbxVector4Test.AssertSimilarEuler(euler, mx.GetR()); FbxQuaternionTest.AssertSimilar(quat, mx.GetQ()); FbxVector4Test.AssertSimilarXYZ(scale, mx.GetS()); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(0.354, 0.354, 0), mx.GetRow(2), 1e-2); FbxVector4Test.AssertSimilarXYZ(new FbxVector4(1, 0, 0), mx.GetColumn(2)); mx.SetT(translate * 2); FbxVector4Test.AssertSimilarXYZ(2 * translate, mx.GetT()); mx.SetR(euler * 2); FbxVector4Test.AssertSimilarEuler(2 * euler, mx.GetR()); mx.SetQ(quat * 2); FbxQuaternionTest.AssertSimilar(2 * quat, mx.GetQ()); mx.SetS(scale * 2); FbxVector4Test.AssertSimilarXYZ(2 * scale, mx.GetS()); mx.SetTRS(translate, euler, scale); FbxVector4Test.AssertSimilarXYZ(translate, mx.GetT()); mx.SetTQS(2 * translate, 2 * quat, 2 * scale); FbxVector4Test.AssertSimilarXYZ(2 * translate, mx.GetT()); // Test Inverse. var mxInv = mx.Inverse(); Assert.AreNotEqual(mx.GetT(), mxInv.GetT()); Assert.IsTrue((mx * mxInv).IsIdentity()); // Test multiplying by a translation. Really we just want to make sure we got a result // different than doing nothing. FbxVector4Test.AssertSimilarXYZ(new FbxVector4(17.778175, 2.464466, 4), mx.MultT(new FbxVector4(1, 2, 3)), 1e-5); // Test multiplying by a rotation. FbxVector4Test.AssertSimilarEuler(new FbxVector4(-180, 0, 45), mx.MultR(new FbxVector4(0, -90, 0))); quat.ComposeSphericalXYZ(new FbxVector4(0, -90, 0)); quat = mx.MultQ(quat); var quatExpected = new FbxQuaternion(); quatExpected.ComposeSphericalXYZ(new FbxVector4(-180, 0, 45)); FbxQuaternionTest.AssertSimilar(quatExpected, quat); // Test multiplying a scale. FbxVector4Test.AssertSimilarXYZ(new FbxVector4(4, 6, .5), mx.MultS(new FbxVector4(2, 1.5, .5))); // Test scaling. Multiply/divide by powers of two so there's no roundoff. // The scale/rotate is scaled, the translation is cleared to (0,0,0,1). AssertScaled(mx, mx * 2, 2); AssertScaled(mx, 2 * mx, 2); AssertScaled(mx, mx / 2, 0.5); // Test negating. This is different from scaling by -1. using (var mxNegated = -mx) { for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(-mx.Get(x, y), mxNegated.Get(x, y), string.Format("Index {0} {1}", x, y)); } } } // Test transpose. using (var mxTranspose = mx.Transpose()) { for (int y = 0; y < 4; ++y) { for (int x = 0; x < 4; ++x) { Assert.AreEqual(mx.Get(y, x), mxTranspose.Get(x, y), string.Format("Index {0} {1}", x, y)); } } } // Test setting to identity. mx.SetIdentity(); Assert.IsTrue(mx.IsIdentity()); // Slerp between two rotation matrices. var q1 = new FbxQuaternion(); q1.ComposeSphericalXYZ(new FbxVector4(0, -90, 0)); var q2 = new FbxQuaternion(); q2.ComposeSphericalXYZ(new FbxVector4(0, 90, 0)); var m1 = new FbxAMatrix(); m1.SetQ(q1); var m2 = new FbxAMatrix(); m2.SetQ(q2); var m12 = m1.Slerp(m2, 0.25); var q12 = new FbxQuaternion(); q12.ComposeSphericalXYZ(new FbxVector4(0, -45, 0)); FbxQuaternionTest.AssertSimilar(q12, m12.GetQ()); }
public FbxQuaternion MultQ(FbxQuaternion pQuaternion) { FbxQuaternion ret = new FbxQuaternion(fbx_wrapperPINVOKE.FbxAMatrix_MultQ(swigCPtr, FbxQuaternion.getCPtr(pQuaternion)), true); if (fbx_wrapperPINVOKE.SWIGPendingException.Pending) { throw fbx_wrapperPINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
public void SetTQS(FbxVector4 pT, FbxQuaternion pQ, FbxVector4 pS) { FbxWrapperNativePINVOKE.FbxAMatrix_SetTQS(swigCPtr, FbxVector4.getCPtr(pT), FbxQuaternion.getCPtr(pQ), FbxVector4.getCPtr(pS)); if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending) { throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve(); } }
public FbxQuaternion GetQ() { FbxQuaternion ret = new FbxQuaternion(fbx_wrapperPINVOKE.FbxAMatrix_GetQ(swigCPtr), true); return(ret); }
public FbxQuaternion GetQ() { FbxQuaternion ret = new FbxQuaternion(FbxWrapperNativePINVOKE.FbxAMatrix_GetQ(swigCPtr), true); return(ret); }