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));

            // convert the final animation to righthanded coords
            var finalEuler = ModelExporter.ConvertQuaternionToXYZEuler(fbxFinalAnimation);

            return(ModelExporter.EulerToQuaternion(finalEuler));
        }
Exemple #2
0
        public void TestBasics()
        {
            Assert.That(!string.IsNullOrEmpty(ModelExporter.GetVersionFromReadme()));

            // Test GetOrCreateLayer
            using (var fbxManager = FbxManager.Create()) {
                var fbxMesh = FbxMesh.Create(fbxManager, "name");
                var layer0  = ModelExporter.GetOrCreateLayer(fbxMesh);
                Assert.That(layer0, Is.Not.Null);
                Assert.That(ModelExporter.GetOrCreateLayer(fbxMesh), Is.EqualTo(layer0));
                var layer5 = ModelExporter.GetOrCreateLayer(fbxMesh, layer: 5);
                Assert.That(layer5, Is.Not.Null);
                Assert.That(layer5, Is.Not.EqualTo(layer0));
            }

            // Test axis conversion: a x b in left-handed is the same as b x a
            // in right-handed (that's why we need to flip the winding order).
            var a         = new Vector3(1, 0, 0);
            var b         = new Vector3(0, 0, 1);
            var crossLeft = Vector3.Cross(a, b);

            var afbx = ModelExporter.ConvertToRightHanded(a);
            var bfbx = ModelExporter.ConvertToRightHanded(b);

            Assert.AreEqual(ModelExporter.ConvertToRightHanded(crossLeft), bfbx.CrossProduct(afbx));

            // Test scale conversion. Nothing complicated here...
            var afbxPosition = ModelExporter.ConvertToRightHanded(a, ModelExporter.UnitScaleFactor);

            Assert.AreEqual(100, afbxPosition.Length());

            // Test rotation conversion.
            var q         = Quaternion.Euler(new Vector3(0, 90, 0));
            var fbxAngles = ModelExporter.ConvertQuaternionToXYZEuler(q);

            Assert.AreEqual(fbxAngles.X, 0);
            Assert.That(fbxAngles.Y, Is.InRange(-90.001, -89.999));
            Assert.AreEqual(fbxAngles.Z, 0);

            Assert.That(ModelExporter.DefaultMaterial);

            // Test non-static functions.
            using (var fbxManager = FbxManager.Create()) {
                var fbxScene = FbxScene.Create(fbxManager, "scene");
                var fbxNode  = FbxNode.Create(fbxScene, "node");
                var exporter = new ModelExporter();

                // Test ExportMaterial: it exports and it re-exports
                bool result = exporter.ExportMaterial(ModelExporter.DefaultMaterial, fbxScene, fbxNode);
                Assert.IsTrue(result);
                var fbxMaterial = fbxNode.GetMaterial(0);
                Assert.That(fbxMaterial, Is.Not.Null);

                result = exporter.ExportMaterial(ModelExporter.DefaultMaterial, fbxScene, fbxNode);
                var fbxMaterial2 = fbxNode.GetMaterial(1);
                Assert.AreEqual(fbxMaterial, fbxMaterial2);

                // Test ExportTexture: it finds the same texture for the default-material (it doesn't create a new one)
                var fbxMaterialNew = FbxSurfaceLambert.Create(fbxScene, "lambert");
                exporter.ExportTexture(ModelExporter.DefaultMaterial, "_MainTex",
                                       fbxMaterialNew, FbxSurfaceLambert.sBump);
                Assert.AreEqual(
                    fbxMaterial.FindProperty(FbxSurfaceLambert.sDiffuse).GetSrcObject(),
                    fbxMaterialNew.FindProperty(FbxSurfaceLambert.sBump).GetSrcObject()
                    );

                // Test ExportMesh: make sure we exported a mesh with welded vertices.
                var cube     = GameObject.CreatePrimitive(PrimitiveType.Cube);
                var cubeNode = FbxNode.Create(fbxScene, "cube");
                exporter.ExportMesh(cube.GetComponent <MeshFilter>().sharedMesh, cubeNode);
                Assert.That(cubeNode.GetMesh(), Is.Not.Null);
                Assert.That(cubeNode.GetMesh().GetControlPointsCount(), Is.EqualTo(8));
            }

            // Test exporting a skinned-mesh. Make sure it doesn't leak (it did at one point)
            {
                var cube      = GameObject.CreatePrimitive(PrimitiveType.Cube);
                var character = new GameObject();
                var smr       = character.AddComponent <SkinnedMeshRenderer>();
                smr.sharedMesh = cube.GetComponent <MeshFilter>().sharedMesh;
                var meshCount = Object.FindObjectsOfType <Mesh>().Length;
                ModelExporter.ExportObject(GetRandomFbxFilePath(), character);
                Assert.AreEqual(meshCount, Object.FindObjectsOfType <Mesh>().Length);
            }
        }