Пример #1
0
        public virtual void TestSetConstrainedObject()
        {
            if (ConstraintType == FbxConstraint.EType.eUnknown)
            {
                return;
            }

            using (var constraint = CreateObject("constraint")) {
                Assert.That(() => SetConstrainedObject(constraint, null), Throws.Exception.TypeOf <System.ArgumentNullException> ());

                var fbxNode = FbxNode.Create(Manager, "rootnode");

                SetConstrainedObject(constraint, fbxNode);
                Assert.That(constraint.GetConstrainedObject(), Is.EqualTo(fbxNode));
            }
        }
Пример #2
0
        // Returns the root, or a node right under the root.
        // Either way, the transform stack is guaranteed to be identity.
        static FbxNode GetGroupNode(FbxManager manager, FbxScene scene, UInt32 group)
        {
            FbxNode root = scene.GetRootNode();

            if (group == 0)
            {
                return(root);
            }
            string  childName = $"group_{group}";
            FbxNode child     = root.FindChild(childName, false);

            if (child == null)
            {
                child = FbxNode.Create(manager, childName);
                root.AddChild(child);
            }
            return(child);
        }
Пример #3
0
        public virtual void TestAddConstraintSource()
        {
            using (var constraint = CreateObject("constraint")) {
                Assert.That(() => AddConstraintSource(constraint, null), Throws.Exception.TypeOf <System.ArgumentNullException> ());
                Assert.That(constraint.GetConstraintSourceCount(), Is.EqualTo(0));

                var fbxNode = FbxNode.Create(Manager, "rootnode");

                AddConstraintSource(constraint, fbxNode);
                Assert.That(constraint.GetConstraintSource(0), Is.EqualTo(fbxNode));
                Assert.That(constraint.GetConstraintSourceCount(), Is.EqualTo(1));

                fbxNode = FbxNode.Create(Manager, "node2");
                AddConstraintSourceDouble(constraint, fbxNode, 2.0);
                Assert.That(constraint.GetConstraintSource(1), Is.EqualTo(fbxNode));
                Assert.That(constraint.GetConstraintSourceCount(), Is.EqualTo(2));
            }
        }
Пример #4
0
    public FbxNode CreateSkeleton(List <FMeshBoneInfo> boneInfos, ref List <FbxNode> BoneNodes)
    {
        if (boneInfos == null || boneInfos.Count == 0)
        {
            return(null);
        }

        for (int BoneIndex = 0; BoneIndex < boneInfos.Count; BoneIndex++)
        {
            FMeshBoneInfo CurrentBone       = boneInfos[BoneIndex];
            FbxSkeleton   SkeletonAttribute = FbxSkeleton.Create(Scene, CurrentBone.Name);
            if (BoneIndex != 0)
            {
                SkeletonAttribute.SetSkeletonType(FbxSkeleton.EType.eLimbNode);
                //SkeletonAttribute.Size.Set(1.0);
            }
            else
            {
                SkeletonAttribute.SetSkeletonType(FbxSkeleton.EType.eRoot);
                //SkeletonAttribute.Size.Set(1.0);
            }

            // Create the node
            FbxNode BoneNode = FbxNode.Create(Scene, CurrentBone.Name);
            BoneNode.SetNodeAttribute(SkeletonAttribute);

            FbxDouble3 LocalPos   = FbxDataConverter.ConvertToFbxPos(CurrentBone.BoneTransform.position);
            FbxDouble3 LocalRot   = FbxDataConverter.ConvertToFbxRot(CurrentBone.BoneTransform.rotation);
            FbxDouble3 LocalScale = FbxDataConverter.ConvertToFbxScale(CurrentBone.BoneTransform.scale);

            BoneNode.LclTranslation.Set(LocalPos);
            BoneNode.LclRotation.Set(LocalRot);
            BoneNode.LclScaling.Set(LocalScale);

            if (BoneIndex != 0)
            {
                BoneNodes[CurrentBone.ParentIndex].AddChild(BoneNode);
            }

            BoneNodes.Add(BoneNode);
        }

        return(BoneNodes[0]);
    }
Пример #5
0
            /// <summary>
            /// Exports the game object has a light component
            /// </summary>
            protected void ExportComponents(GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent)
            {
                // create an node and add it as a child of parent
                FbxNode fbxNode = FbxNode.Create(fbxScene, unityGo.name);

                NumNodes++;

                ExportTransform(unityGo.transform, fbxNode);

                var fbxMesh = ExportMesh(unityGo, fbxScene);

                if (fbxMesh != null)
                {
                    // set the fbxNode containing the mesh
                    fbxNode.SetNodeAttribute(fbxMesh);
                    fbxNode.SetShadingMode(FbxNode.EShadingMode.eWireFrame);
                }

                FbxLight fbxLight = ExportLight(unityGo, fbxScene, fbxNode);

                if (fbxLight != null)
                {
                    fbxNode.SetNodeAttribute(fbxLight);
                }

                if (Verbose)
                {
                    Debug.Log(string.Format("exporting {0}", fbxNode.GetName()));
                }

                fbxNodeParent.AddChild(fbxNode);

                // add mapping between fbxnode for light
                // and unity game object for animation export
                MapUnityObjectToFbxNode [unityGo] = fbxNode;

                // now  unityGo  through our children and recurse
                foreach (Transform childT in  unityGo.transform)
                {
                    ExportComponents(childT.gameObject, fbxScene, fbxNode);
                }

                return;
            }
        protected override FbxScene CreateScene(FbxManager manager)
        {
            // Create a cube as a static mesh

            FbxScene scene = FbxScene.Create(manager, "myScene");

            FbxNode meshNode = FbxNode.Create(scene, "MeshNode");
            FbxMesh cubeMesh = FbxMesh.Create(scene, "cube");

            meshNode.SetNodeAttribute(cubeMesh);

            scene.GetRootNode().AddChild(meshNode);

            cubeMesh.InitControlPoints(24);

            for (int i = 0; i < cubeMesh.GetControlPointsCount(); i++)
            {
                cubeMesh.SetControlPointAt(m_controlPoints [i], i);
            }

            // A cube: 6 polygons with 4 vertices each
            int[] vertices =
            {
                0,   1,  2,  3,
                4,   5,  6,  7,
                8,   9, 10, 11,
                12, 13, 14, 15,
                16, 17, 18, 19,
                20, 21, 22, 23
            };

            for (int i = 0; i < 6; i++)
            {
                cubeMesh.BeginPolygon(pGroup: -1);
                for (int j = 0; j < 4; j++)
                {
                    cubeMesh.AddPolygon(vertices[i * 4 + j]);
                }

                cubeMesh.EndPolygon();
            }

            return(scene);
        }
Пример #7
0
            /// <summary>
            /// Exports the game object has a camera component
            /// </summary>
            protected void ExportComponents(GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent)
            {
                Camera unityCamera = unityGo.GetComponent <Camera> ();

                if (unityCamera == null)
                {
                    return;
                }

                // create an node and add it as a child of parent
                FbxNode fbxNode = FbxNode.Create(fbxScene, unityGo.name);

                NumNodes++;

                FbxNodeAttribute fbxNodeAttr = ExportCamera(unityCamera, fbxScene, fbxNode);

                if (fbxNodeAttr != null)
                {
                    fbxNode.SetNodeAttribute(fbxNodeAttr);

                    // make the last camera exported the default camera
                    DefaultCamera = fbxNode.GetName();
                }

                if (Verbose)
                {
                    Debug.Log(string.Format("exporting {0}", fbxNode.GetName()));
                }

                fbxNodeParent.AddChild(fbxNode);

                // add mapping between fbxnode for light
                // and unity game object for animation export
                MapUnityObjectToFbxNode [unityGo] = fbxNode;

                // now  unityGo  through our children and recurse
                foreach (Transform childT in  unityGo.transform)
                {
                    ExportComponents(childT.gameObject, fbxScene, fbxNode);
                }

                return;
            }
Пример #8
0
            protected void ExportComponents(GameObject unityGo, FbxScene fbxScene, FbxNode fbxParentNode)
            {
                // create an sketelon root
                FbxNode fbxRootNode = FbxNode.Create(fbxScene, unityGo.name);

                // create node hierarchy
                ExportNodeHierarchy(unityGo, fbxRootNode);

                // create skeleton bones
                if (ExportSkeleton(unityGo, fbxScene))
                {
                    fbxParentNode.AddChild(fbxRootNode);
                }

                // create animation takes
                ExportAnimationClips(unityGo, fbxScene);

                return;
            }
Пример #9
0
        protected override FbxScene CreateScene(FbxManager manager)
        {
            // Create a scene with a single node that has an animation clip
            // attached to it
            FbxScene scene = FbxScene.Create(manager, "myScene");

            FbxNode sourceNode      = FbxNode.Create(scene, "source");
            FbxNode constrainedNode = FbxNode.Create(scene, "constrained");

            scene.GetRootNode().AddChild(sourceNode);
            scene.GetRootNode().AddChild(constrainedNode);

            FbxConstraint posConstraint = CreatePositionConstraint(scene, sourceNode, constrainedNode);

            Assert.That(posConstraint, Is.Not.Null);

            bool result = posConstraint.ConnectDstObject(scene);

            Assert.That(result, Is.True);

            // animate weight + active
            // setup anim stack
            FbxAnimStack fbxAnimStack = CreateAnimStack(scene);

            // add an animation layer
            FbxAnimLayer fbxAnimLayer = FbxAnimLayer.Create(scene, "animBaseLayer");

            fbxAnimStack.AddMember(fbxAnimLayer);

            // set up the translation
            CreateAnimCurves(
                posConstraint, fbxAnimLayer, PropertyComponentList, (index) => { return(index * 2.0); }, (index) => { return(index * 3 - 2); }
                );

            // TODO: avoid needing to do this by creating typemaps for
            //       FbxObject::GetSrcObjectCount and FbxCast.
            //       Not trivial to do as both fbxobject.i and fbxemitter.i
            //       have to be moved up before the ignore all statement
            //       to allow use of templates.
            scene.SetCurrentAnimationStack(fbxAnimStack);
            return(scene);
        }
Пример #10
0
            /// <summary>
            /// Unconditionally export components on this game object
            /// </summary>
            protected void ExportComponents(GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent)
            {
                // create an node and add it as a child of parent
                FbxNode fbxNode = FbxNode.Create(fbxScene, unityGo.name);

                NumNodes++;

                if (Verbose)
                {
                    Debug.Log(string.Format("exporting {0}", fbxNode.GetName()));
                }

                fbxNodeParent.AddChild(fbxNode);

                // now  unityGo  through our children and recurse
                foreach (Transform childT in  unityGo.transform)
                {
                    ExportComponents(childT.gameObject, fbxScene, fbxNode);
                }

                return;
            }
Пример #11
0
        protected override FbxScene CreateScene(FbxManager manager)
        {
            // Create a cube as a static mesh

            FbxScene scene = FbxScene.Create(manager, "myScene");

            FbxNode meshNode = FbxNode.Create(scene, "MeshNode");
            FbxMesh cubeMesh = FbxMesh.Create(scene, "cube");

            meshNode.SetNodeAttribute(cubeMesh);

            scene.GetRootNode().AddChild(meshNode);

            cubeMesh.InitControlPoints(24);

            for (int i = 0; i < cubeMesh.GetControlPointsCount(); i++)
            {
                cubeMesh.SetControlPointAt(m_controlPoints [i], i);
            }

            return(scene);
        }
Пример #12
0
        protected override FbxScene CreateScene(FbxManager manager)
        {
            // create the following node hierarchy to test:
            //       Root
            //      /    \
            // Child0    Child1
            //              |
            //            Child2
            //         /    |     \
            //    Child3  Child4  Child5
            FbxScene scene = FbxScene.Create(manager, "myScene");

            FbxNode root = FbxNode.Create(scene, "Root");

            // set the root invisible
            root.SetVisibility(false);

            // don't let children inherit visibility of invisible root node
            root.VisibilityInheritance.Set(false);

            FbxNode[] children = new FbxNode[6];
            for (int i = 0; i < children.Length; i++)
            {
                children [i] = FbxNode.Create(scene, "Child" + i);
                // set even nodes visible, and odd nodes invisible
                children [i].SetVisibility(i % 2 == 0);
            }

            scene.GetRootNode().AddChild(root);
            root.AddChild(children [0]);
            root.AddChild(children [1]);
            children [1].AddChild(children [2]);
            children [2].AddChild(children [3]);
            children [2].AddChild(children [4]);
            children [2].AddChild(children [5]);

            return(scene);
        }
Пример #13
0
            static FbxScene BuildScene(FbxManager fbxManager)
            {
                // Create a scene
                var fbxScene = FbxScene.Create(fbxManager, "Scene");

                // Create 5000 nulls. Show progress on this task from [0,0.5]
                EditorUtility.DisplayProgressBar(ProgressBarTitle, "Creating the scene", 0);
                int percent = 1 + NumNulls / 100;

                for (int i = 0; i < NumNulls; ++i)
                {
                    FbxNode.Create(fbxScene, "node_" + i);
                    if (i % percent == 0)
                    {
                        if (EditorUtility.DisplayCancelableProgressBar(ProgressBarTitle, "Creating the scene", 0.5f * (float)i / (float)NumNulls))
                        {
                            // cancel silently
                            return(null);
                        }
                    }
                }
                return(fbxScene);
            }
Пример #14
0
            /// <summary>
            /// Unconditionally export components on this game object
            /// </summary>
            protected void ExportComponents(GameObject unityGo, FbxScene fbxScene, FbxNode fbxParentNode)
            {
                // create an FbxNode and add it as a child of fbxParentNode
                FbxNode fbxNode = FbxNode.Create(fbxScene, unityGo.name);

                NumNodes++;

                ExportTransform(unityGo.transform, fbxNode);
                ExportMesh(GetMeshInfo(unityGo), fbxNode, fbxScene);
#if UNI_16194
                // if this GameObject is at the root of the scene,
                // make it invisible, but leave all its children as is

                // set the node visibility
                fbxNode.SetVisibility(unityGo.transform.parent ? unityGo.activeSelf : false);

                // don't inherit visibility of invisible root node
                if (unityGo.transform.parent == null)
                {
                    fbxNode.VisibilityInheritance.Set(false);
                }
#endif
                if (Verbose)
                {
                    Debug.Log(string.Format("exporting {0}", fbxNode.GetName()));
                }

                fbxParentNode.AddChild(fbxNode);

                // now  unityGo  through our children and recurse
                foreach (Transform uniChildT in  unityGo.transform)
                {
                    ExportComponents(uniChildT.gameObject, fbxScene, fbxNode);
                }

                return;
            }
Пример #15
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);
            }
        }
        protected override FbxScene CreateScene(FbxManager manager)
        {
            FbxScene scene = FbxScene.Create(manager, "myScene");

            // Create the following node hierarchy with transforms:
            //          Root
            //        (t: 0,10,4)
            //        (r: 0,0,0)
            //        (s: 1,1,1)
            //         /    \
            //   child0      child1
            // (t: 1,1,1)    (t: 0,0,0)
            // (r: 0,0,90)   (r: 180,5,0)
            // (s: 2,2,2)    (s: 3,2,1)
            //                  |
            //                child2
            //               (t: 5,6,20)
            //               (r: 0,10,0)
            //               (s: 1,0.5,1)

            FbxNode root = FbxNode.Create(scene, "Root");

            root.SetNodeAttribute(ExportNull(scene));
            root.SetShadingMode(FbxNode.EShadingMode.eWireFrame);

            // Set the transform values
            root.LclTranslation.Set(new FbxDouble3(0, 10, 4));
            root.LclRotation.Set(new FbxDouble3(0, 0, 0));
            root.LclScaling.Set(new FbxDouble3(1, 1, 1));

            // Set the pre/post rotation, pivots and offsets
            // NOTE: For some reason when using PreRotation.Set() instead of SetPreRotation(),
            //       the PreRotation does not get imported properly. Same is true for the other properties.
            //       Also only works if EPivot set is SourcePivot.
            //       TODO: figure out why the other ways don't work.
            root.SetPreRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(30, 10, 45));
            root.SetPostRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(9, 10, 5));
            root.SetRotationPivot(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(5, 6, 7));
            root.SetScalingPivot(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(1, 2, 1));
            root.SetRotationOffset(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(0.6, 8, 0.3));
            root.SetScalingOffset(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(10, 4, 3));

            FbxNode[]      children   = new FbxNode[3];
            FbxDouble3[][] transforms =
            {
                new FbxDouble3[] { new FbxDouble3(1, 1,  1), new FbxDouble3(0,    0, 90), new FbxDouble3(2,   2, 2) },
                new FbxDouble3[] { new FbxDouble3(0, 0,  0), new FbxDouble3(180,  5,  0), new FbxDouble3(3,   2, 1) },
                new FbxDouble3[] { new FbxDouble3(5, 6, 20), new FbxDouble3(0,   10,  0), new FbxDouble3(1, 0.5, 1) }
            };

            for (int i = 0; i < children.Length; i++)
            {
                children [i] = FbxNode.Create(scene, "Child" + i);

                // set the fbxNode's node attribute
                children[i].SetNodeAttribute(ExportNull(scene));
                children[i].SetShadingMode(FbxNode.EShadingMode.eWireFrame);

                // set the transform
                children [i].LclTranslation.Set(transforms [i] [0]);
                children [i].LclRotation.Set(transforms [i] [1]);
                children [i].LclScaling.Set(transforms [i] [2]);

                // set some values to check against later (doesn't really matter what the values are)
                children [i].SetPreRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(i, i * 2, i % 3));
                children [i].SetPostRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(i - 1, i + 5, i));
                children [i].SetRotationPivot(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(i / 2, i, i + 3));
                children [i].SetScalingPivot(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(i * 5, i - 1, i / 4));
                children [i].SetRotationOffset(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(0.6 * i, 8, i / 2.0f));
                children [i].SetScalingOffset(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(i, i, i));
            }

            // Create the hierarchy
            scene.GetRootNode().AddChild(root);
            root.AddChild(children [0]);
            root.AddChild(children [1]);
            children [1].AddChild(children [2]);

            return(scene);
        }
Пример #17
0
        // outputFile must be a full path.
        static void WriteObjectsAndConnections2(FbxExportGlobals G)
        {
            var payload = ExportCollector.GetExportPayload(
                AxisConvention.kFbxAccordingToUnity,
                includeLocalMediaContent: true);

            // Write out each brush entry's geometry.
            foreach (var brushMeshPayload in payload.groups.SelectMany(g => g.brushMeshes))
            {
                // This code used to not set the transform; check that it didn't cause issues
                Debug.Assert(brushMeshPayload.xform.isIdentity);
                FbxNode parentNode = GetGroupNode(G.m_manager, G.m_scene, brushMeshPayload.group);
                ExportMeshPayload_Global(G, brushMeshPayload, parentNode);
            }

            // Models with exportable meshes.
            foreach (var sameInstance in payload.modelMeshes.GroupBy(m => (m.model, m.modelId)))
            {
                var modelMeshPayloads = sameInstance.ToList();
                if (modelMeshPayloads.Count == 0)
                {
                    continue;
                }

                // All of these pieces will come from the same Widget and therefore will have
                // the same group id, root transform, etc
                var     first            = modelMeshPayloads[0];
                FbxNode parentParentNode = GetGroupNode(G.m_manager, G.m_scene, first.group);
                string  rootNodeName     = $"model_{first.model.GetExportName()}_{first.modelId}";
                if (modelMeshPayloads.Count == 1 && first.localXform.isIdentity)
                {
                    // Condense the two nodes into one; give the top-level node the same name
                    // it would have had had it been multi-level.
                    FbxNode newNode = ExportMeshPayload_Global(G, first, parentParentNode);
                    newNode.SetName(rootNodeName);
                }
                else
                {
                    FbxNode parentNode = FbxNode.Create(G.m_manager, rootNodeName);
                    parentNode.SetLocalTransform(first.parentXform);
                    parentParentNode.AddChild(parentNode);
                    foreach (var modelMeshPayload in modelMeshPayloads)
                    {
                        ExportMeshPayload_Local(G, modelMeshPayload, parentNode);
                    }
                }
            }

            foreach (ImageQuadPayload meshPayload in payload.imageQuads)
            {
                FbxNode groupNode = GetGroupNode(G.m_manager, G.m_scene, meshPayload.group);
                ExportMeshPayload_Global(G, meshPayload, groupNode);
            }

            // Things that can only be exported as transforms (videos, images, models, ...)
            foreach (var referenceThing in payload.referenceThings)
            {
                FbxNode node = FbxNode.Create(G.m_manager, "reference_" + referenceThing.name);
                node.SetLocalTransform(referenceThing.xform);
                GetGroupNode(G.m_manager, G.m_scene, referenceThing.group).AddChild(node);
            }
        }
Пример #18
0
            /// <summary>
            /// Export GameObject's as a skinned mesh with bones
            /// </summary>
            protected void ExportSkinnedMesh(Animator unityAnimator, FbxScene fbxScene, FbxNode fbxParentNode)
            {
                GameObject unityGo = unityAnimator.gameObject;

                SkinnedMeshRenderer unitySkin
                    = unityGo.GetComponentInChildren <SkinnedMeshRenderer> ();

                if (unitySkin == null)
                {
                    Debug.LogError("could not find skinned mesh");
                    return;
                }

                var meshInfo = GetSkinnedMeshInfo(unityGo);

                if (meshInfo.renderer == null)
                {
                    Debug.LogError("mesh has no renderer");
                    return;
                }

                // create an FbxNode and add it as a child of fbxParentNode
                FbxNode fbxNode = FbxNode.Create(fbxScene, unityAnimator.name);


                Dictionary <Transform, FbxNode> boneNodes
                    = new Dictionary <Transform, FbxNode> ();

                // export skeleton
                if (ExportSkeleton(meshInfo, fbxScene, fbxNode, ref boneNodes))
                {
                    // export skin
                    FbxNode fbxMeshNode = ExportMesh(meshInfo, fbxScene, fbxNode);

                    FbxMesh fbxMesh = fbxMeshNode.GetMesh();

                    if (fbxMesh == null)
                    {
                        Debug.LogError("Could not find mesh");
                        return;
                    }

                    // bind mesh to skeleton
                    ExportSkin(meshInfo, fbxScene, fbxMesh, fbxMeshNode, boneNodes);

                    // add bind pose
                    ExportBindPose(fbxNode, fbxMeshNode, fbxScene, boneNodes);

                    fbxParentNode.AddChild(fbxNode);
                    NumNodes++;

                    if (Verbose)
                    {
                        Debug.Log(string.Format("exporting {0} {1}", "Skin", fbxNode.GetName()));
                    }
                }
                else
                {
                    Debug.LogError("failed to export skeleton");
                }
            }
Пример #19
0
        public void BasicTests()
        {
            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<FbxBool> example: VisibilityInheritance on a node
                var node = FbxNode.Create(manager, "node");
                GenericPropertyTests <FbxPropertyBool> (node.VisibilityInheritance, node, "Visibility Inheritance", Globals.FbxVisibilityInheritanceDT);

                var property = node.VisibilityInheritance;
                property.Set(false);
                Assert.AreEqual(false, property.Get());
                Assert.AreEqual(false, property.EvaluateValue());
                Assert.AreEqual(false, property.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(false, property.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<FbxDouble> example: several of them on a Lambert shader
                var obj = FbxSurfaceLambert.Create(manager, "lambert");
                GenericPropertyTests <FbxPropertyDouble> (obj.EmissiveFactor, obj, "EmissiveFactor", Globals.FbxDoubleDT);

                var property = obj.EmissiveFactor;
                property.Set(5.0); // bool Set<float> is not accessible here!
                Assert.AreEqual(5.0, property.Get());
                Assert.AreEqual(5.0, property.EvaluateValue());
                Assert.AreEqual(5.0, property.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(5.0, property.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<Double3> example: the LclTranslation on a node
                var node = FbxNode.Create(manager, "node");
                GenericPropertyTests <FbxPropertyDouble3> (node.LclTranslation, node, "Lcl Translation", Globals.FbxLocalTranslationDT);

                var property = node.LclTranslation;
                property.Set(new FbxDouble3(1, 2, 3));
                Assert.AreEqual(new FbxDouble3(1, 2, 3), property.Get());
                Assert.AreEqual(new FbxDouble3(1, 2, 3), property.EvaluateValue());
                Assert.AreEqual(new FbxDouble3(1, 2, 3), property.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(new FbxDouble3(1, 2, 3), property.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<float> example: the LeftBarnDoor on a light
                var light = FbxLight.Create(manager, "light");
                GenericPropertyTests(light.LeftBarnDoor, light, "LeftBarnDoor", Globals.FbxFloatDT);

                var property = light.LeftBarnDoor;
                light.LeftBarnDoor.Set(5.0f);
                Assert.AreEqual(5.0f, light.LeftBarnDoor.Get());
                Assert.AreEqual(5.0f, property.EvaluateValue());
                Assert.AreEqual(5.0f, property.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(5.0f, property.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<int> example: the WorldUpType on an aim constraint
                var constraint = FbxConstraintAim.Create(manager, "constraint");
                GenericPropertyTests(constraint.WorldUpType, constraint, "WorldUpType", Globals.FbxEnumDT);

                var property = constraint.WorldUpType;
                int value    = (int)FbxConstraintAim.EWorldUp.eAimAtObjectUp;
                constraint.WorldUpType.Set(value);
                Assert.That(constraint.WorldUpType.Get(), Is.EqualTo(value));
                Assert.That(property.EvaluateValue(), Is.EqualTo(value));
                Assert.That(property.EvaluateValue(FbxTime.FromSecondDouble(5)), Is.EqualTo(value));
                Assert.That(property.EvaluateValue(FbxTime.FromSecondDouble(5), true), Is.EqualTo(value));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<FbxString> example: the description of a shader implementation
                var impl = FbxImplementation.Create(manager, "name");
                GenericPropertyTests <FbxPropertyString> (impl.RenderAPI, impl, "RenderAPI", Globals.FbxStringDT);

                var property = impl.RenderAPI;
                property.Set("a value");
                Assert.AreEqual("a value", property.Get());

                // animated strings come out as empty-string
                Assert.AreEqual("", property.EvaluateValue());
                Assert.AreEqual("", property.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual("", property.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT for FbxTexture enums EBlendMode and EWrapMode
                var tex = FbxTexture.Create(manager, "tex");

                FbxPropertyTest.GenericPropertyTests(tex.CurrentTextureBlendMode, tex, "CurrentTextureBlendMode", Globals.FbxEnumDT);
                tex.CurrentTextureBlendMode.Set(FbxTexture.EBlendMode.eAdditive);
                Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.Get());
                Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.EvaluateValue());
                Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxTexture.EBlendMode.eAdditive, tex.CurrentTextureBlendMode.EvaluateValue(FbxTime.FromSecondDouble(5), true));

                FbxPropertyTest.GenericPropertyTests(tex.WrapModeU, tex, "WrapModeU", Globals.FbxEnumDT);
                tex.WrapModeU.Set(FbxTexture.EWrapMode.eClamp);
                Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.Get());
                Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.EvaluateValue());
                Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxTexture.EWrapMode.eClamp, tex.WrapModeU.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<FbxNull.ELook>
                var null1 = FbxNull.Create(manager, "null1");

                FbxPropertyTest.GenericPropertyTests(null1.Look, null1, "Look", Globals.FbxEnumDT);
                null1.Look.Set(FbxNull.ELook.eCross);
                Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.Get());
                Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.EvaluateValue());
                Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxNull.ELook.eCross, null1.Look.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<FbxMarker.ELook>
                var marker1 = FbxMarker.Create(manager, "marker1");

                FbxPropertyTest.GenericPropertyTests(marker1.Look, marker1, "Look", Globals.FbxEnumDT);
                marker1.Look.Set(FbxMarker.ELook.eCapsule);
                Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.Get());
                Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.EvaluateValue());
                Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxMarker.ELook.eCapsule, marker1.Look.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT for FbxCamera enum EProjectionType
                var camera = FbxCamera.Create(manager, "camera");

                FbxPropertyTest.GenericPropertyTests(camera.ProjectionType, camera, "CameraProjectionType", Globals.FbxEnumDT);
                camera.ProjectionType.Set(FbxCamera.EProjectionType.ePerspective);
                Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.Get());
                Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.EvaluateValue());
                Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxCamera.EProjectionType.ePerspective, camera.ProjectionType.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT for FbxCamera enum EGateFit
                var camera = FbxCamera.Create(manager, "camera");

                FbxPropertyTest.GenericPropertyTests(camera.GateFit, camera, "GateFit", Globals.FbxEnumDT);
                camera.GateFit.Set(FbxCamera.EGateFit.eFitHorizontal);
                Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.Get());
                Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.EvaluateValue());
                Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxCamera.EGateFit.eFitHorizontal, camera.GateFit.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT<EInheritType>
                var node = FbxNode.Create(manager, "node");

                FbxPropertyTest.GenericPropertyTests(node.InheritType, node, "InheritType", Globals.FbxEnumDT);
                node.InheritType.Set(FbxTransform.EInheritType.eInheritRSrs);
                Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.Get());
                Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.EvaluateValue());
                Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxTransform.EInheritType.eInheritRSrs, node.InheritType.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // FbxPropertyT for FbxLight enums
                var light = FbxLight.Create(manager, "light");

                FbxPropertyTest.GenericPropertyTests(light.LightType, light, "LightType", Globals.FbxEnumDT);
                light.LightType.Set(FbxLight.EType.eSpot);
                Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.Get());
                Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.EvaluateValue());
                Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxLight.EType.eSpot, light.LightType.EvaluateValue(FbxTime.FromSecondDouble(5), true));

                FbxPropertyTest.GenericPropertyTests(light.AreaLightShape, light, "AreaLightShape", Globals.FbxEnumDT);
                light.AreaLightShape.Set(FbxLight.EAreaLightShape.eSphere);
                Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.Get());
                Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.EvaluateValue());
                Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxLight.EAreaLightShape.eSphere, light.AreaLightShape.EvaluateValue(FbxTime.FromSecondDouble(5), true));

                FbxPropertyTest.GenericPropertyTests(light.DecayType, light, "DecayType", Globals.FbxEnumDT);
                light.DecayType.Set(FbxLight.EDecayType.eCubic);
                Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.Get());
                Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.EvaluateValue());
                Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.EvaluateValue(FbxTime.FromSecondDouble(5)));
                Assert.AreEqual(FbxLight.EDecayType.eCubic, light.DecayType.EvaluateValue(FbxTime.FromSecondDouble(5), true));
            }

            using (var manager = FbxManager.Create()) {
                // Test all the create and destroy operations
                FbxProperty root, child;
                var         obj = FbxObject.Create(manager, "obj");

                Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "a"));
                Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "b", "label"));
                Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "c", "label", false));
                bool didFind;
                Assert.IsNotNull(FbxProperty.Create(obj, Globals.FbxStringDT, "c", "label", true, out didFind));
                Assert.IsTrue(didFind);

                root = FbxProperty.Create(obj, Globals.FbxCompoundDT, "root");

                child = FbxProperty.Create(root, Globals.FbxStringDT, "a");
                Assert.IsNotNull(child);
                Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "b", "label"));
                Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "c", "label", false));
                Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "c", "label", true, out didFind));
                Assert.IsTrue(didFind);

                child.Destroy();

                root.DestroyChildren();
                Assert.IsNotNull(FbxProperty.Create(root, Globals.FbxStringDT, "c", "label", true, out didFind));
                Assert.IsFalse(didFind);

                root.DestroyRecursively();
            }
        }
        public void TestBasics()
        {
            // create a curve we can unroll.
            var fbxScene = FbxScene.Create(Manager, "scene");
            var fbxNode  = FbxNode.Create(fbxScene, "node");

            var fbxAnimNode = FbxAnimCurveNode.CreateTypedCurveNode(fbxNode.LclRotation, fbxScene);

            FbxAnimCurve[] fbxAnimCurves =
            {
                fbxAnimNode.CreateCurve(fbxAnimNode.GetName(), Globals.FBXSDK_CURVENODE_COMPONENT_X),
                fbxAnimNode.CreateCurve(fbxAnimNode.GetName(), Globals.FBXSDK_CURVENODE_COMPONENT_Y),
                fbxAnimNode.CreateCurve(fbxAnimNode.GetName(), Globals.FBXSDK_CURVENODE_COMPONENT_Z)
            };

            FbxAnimCurveFilterUnroll filter = new FbxAnimCurveFilterUnroll();

            Assert.That(filter.NeedApply(fbxAnimNode), Is.False, "expected not to need to unroll curves");
            Assert.That(filter.Apply(fbxAnimNode), Is.False, "expected to have nothing to do");

            // ensure coverage for function that takes an FbxStatus
            Assert.That(filter.NeedApply(fbxAnimNode, new FbxStatus()), Is.False);
            Assert.That(filter.Apply(fbxAnimNode, new FbxStatus()), Is.False);

            // configure the unroll condition
            foreach (float[] keydata in KeyTimeValues)
            {
                double seconds = keydata[0];

                foreach (var fbxAnimCurve in fbxAnimCurves)
                {
                    fbxAnimCurve.KeyModifyBegin();
                }

                using (var fbxTime = FbxTime.FromSecondDouble(seconds))
                {
                    for (int ci = 0; ci < fbxAnimCurves.Length; ci++)
                    {
                        int ki = fbxAnimCurves[ci].KeyAdd(fbxTime);
                        fbxAnimCurves[ci].KeySet(ki, fbxTime, keydata[ci + 1]);
                    }
                }

                foreach (var fbxAnimCurve in fbxAnimCurves)
                {
                    fbxAnimCurve.KeyModifyEnd();
                }
            }

            Assert.That(filter.NeedApply(fbxAnimNode), Is.True, "expected to need to unroll curves");
            Assert.That(filter.Apply(fbxAnimNode), Is.True, "expected to have unroll");

            IEnumerator origKeydata = KeyTimeValues.GetEnumerator();

            for (int ki = 0; ki < fbxAnimCurves[0].KeyGetCount(); ki++)
            {
                List <float> result = new List <float>()
                {
                    (float)fbxAnimCurves[0].KeyGetTime(ki).GetSecondDouble()
                };

                result = result.Concat((from ac in fbxAnimCurves select ac.KeyGetValue(ki))).ToList();

                origKeydata.MoveNext();
                if (ki == 0 || ki == 3 || ki == 4)
                {
                    Assert.That(result, Is.EqualTo(origKeydata.Current));
                }
                else
                {
                    Assert.That(result, Is.Not.EqualTo(origKeydata.Current));
                }
            }

            filter.Reset();
            filter.Dispose();
        }
Пример #21
0
        public void TestAdd()
        {
            using (var fbxPose = CreateObject("pose")){
                using (var fbxNode = FbxNode.Create(Manager, "node"))
                    using (var fbxMatrix = new FbxMatrix()){
                        Assert.AreEqual(0, fbxPose.GetCount());

                        // test basic use
                        int index = fbxPose.Add(fbxNode, fbxMatrix); // returns -1 if it fails
                        Assert.Greater(index, -1);
                        Assert.AreEqual(fbxPose.GetNode(index), fbxNode);
                        Assert.AreEqual(fbxPose.GetMatrix(index), fbxMatrix);

                        Assert.AreEqual(1, fbxPose.GetCount());

                        // test adding null
                        Assert.That(() => {
                            fbxPose.Add(null, null);
                        }, Throws.Exception.TypeOf <System.ArgumentNullException> ());

                        fbxPose.Add(FbxNode.Create(Manager, "node1"), fbxMatrix);
                        Assert.AreEqual(2, fbxPose.GetCount());
                    }

                var node = FbxNode.Create(Manager, "node1");
                using (var fbxMatrix = new FbxMatrix()) {
                    // test adding invalid node
                    node.Destroy();
                    Assert.That(() => {
                        fbxPose.Add(node, fbxMatrix);
                    }, Throws.Exception.TypeOf <System.ArgumentNullException> ());
                }

                using (var fbxNode = FbxNode.Create(Manager, "node2")){
                    var fbxMatrix = new FbxMatrix();
                    // test adding invalid matrix
                    fbxMatrix.Dispose();
                    Assert.That(() => {
                        fbxPose.Add(fbxNode, fbxMatrix);
                    }, Throws.Exception.TypeOf <System.ArgumentNullException> ());
                }

                using (var fbxNode = FbxNode.Create(Manager, "node3"))
                    using (var fbxMatrix = new FbxMatrix()) {
                        // test with local matrix arg
                        int index = fbxPose.Add(fbxNode, fbxMatrix, true); // false is default
                        Assert.Greater(index, -1);
                        Assert.AreEqual(fbxPose.GetNode(index), fbxNode);
                        Assert.AreEqual(fbxPose.GetMatrix(index), fbxMatrix);
                    }

                using (var fbxNode = FbxNode.Create(Manager, "node4"))
                    using (var fbxMatrix = new FbxMatrix()) {
                        // test with multiple bind pose arg
                        int index = fbxPose.Add(fbxNode, fbxMatrix, false, false); // true is default
                        Assert.Greater(index, -1);
                        Assert.AreEqual(fbxPose.GetNode(index), fbxNode);
                        Assert.AreEqual(fbxPose.GetMatrix(index), fbxMatrix);
                    }
            }
        }
Пример #22
0
    public static void ExportMesh(Mesh mesh, string directory, string fileName)
    {
        var filePath = Path.Combine(directory, fileName);
        // Make a temporary copy of the mesh to modify it
        Mesh tempMesh = Object.Instantiate(mesh);

        tempMesh.name = mesh.name;

        // If meters, divide by 100 since default is cm. Assume centered at origin.
        if (fbxUnit == FbxSystemUnit.m)
        {
            Vector3[] vertices = tempMesh.vertices;
            for (int i = 0; i < vertices.Length; ++i)
            {
                vertices[i] /= 100.0f;
            }
            tempMesh.vertices = vertices;
        }
        // You could handle other SystemUnits here

        // FBX Manager
        FbxManager manager = FbxManager.Create();

        manager.SetIOSettings(FbxIOSettings.Create(manager, Globals.IOSROOT));

        // FBX Exporter
        FbxExporter fbxExporter = FbxExporter.Create(manager, "Exporter");

        // Binary
        int fileFormat = -1;

        // Ascii
        if (saveFbxAsAscii)
        {
            fileFormat = manager.GetIOPluginRegistry().FindWriterIDByDescription("FBX ascii (*.fbx)");
        }

        fbxExporter.Initialize(filePath, fileFormat, manager.GetIOSettings());
        fbxExporter.SetFileExportVersion("FBX201400");

        // FBX Scene
        FbxScene        fbxScene  = FbxScene.Create(manager, "Scene");
        FbxDocumentInfo sceneInfo = FbxDocumentInfo.Create(manager, "SceneInfo");

        // Set up scene info
        sceneInfo.mTitle    = fbxFileTitle;
        sceneInfo.mSubject  = fbxFileSubject;
        sceneInfo.mComment  = fbxFileComment;
        sceneInfo.mAuthor   = fbxFileAuthor;
        sceneInfo.mRevision = fbxFileRevision;
        sceneInfo.mKeywords = fbxFileKeywords;
        sceneInfo.Original_ApplicationName.Set(fbxFileApplication);
        sceneInfo.LastSaved_ApplicationName.Set(fbxFileApplication);
        fbxScene.SetSceneInfo(sceneInfo);

        // Set up Global settings
        FbxGlobalSettings globalSettings = fbxScene.GetGlobalSettings();

        globalSettings.SetSystemUnit(fbxUnit);
        globalSettings.SetAxisSystem(fbxAxisSystem);

        FbxNode modelNode = FbxNode.Create(fbxScene, tempMesh.name);

        // Add mesh to a node in the scene
        // TODO Wat???
//        using (ModelExporter modelExporter = new ModelExporter())
//        {
//            if (!modelExporter.ExportMesh(tempMesh, modelNode))
//                Debug.LogError("Problem Exporting Mesh");
//        }
        // add the model to the scene
        fbxScene.GetRootNode().AddChild(modelNode);

        // Finally actually save the scene
        bool sceneSuccess = fbxExporter.Export(fbxScene);

        AssetDatabase.Refresh();

        // clean up temporary model
        if (Application.isPlaying)
        {
            Object.Destroy(tempMesh);
        }
        else
        {
            Object.DestroyImmediate(tempMesh);
        }
    }
Пример #23
0
            /// <summary>
            /// Export bones of skinned mesh, if this is a skinned mesh with
            /// bones and bind poses.
            /// </summary>
            private bool ExportSkeleton(GameObject unityGo, FbxScene fbxScene)
            {
                var unitySkinnedMeshRenderer = unityGo.GetComponentInChildren <SkinnedMeshRenderer> ();

                if (!unitySkinnedMeshRenderer)
                {
                    return(false);
                }
                var bones = unitySkinnedMeshRenderer.bones;

                if (bones == null || bones.Length == 0)
                {
                    return(false);
                }
                var mesh = unitySkinnedMeshRenderer.sharedMesh;

                if (!mesh)
                {
                    return(false);
                }
                var bindPoses = mesh.bindposes;

                if (bindPoses == null || bindPoses.Length != bones.Length)
                {
                    return(false);
                }

                // Three steps:
                // 0. Set up the map from bone to index.
                // 1. Create the bones, in arbitrary order.
                // 2. Connect up the hierarchy.
                // 3. Set the transforms.
                // Step 0 supports step 1 (finding which is the root bone) and step 3
                // (setting up transforms; the complication is the use of pivots).

                // Step 0: map transform to index so we can look up index by bone.
                Dictionary <Transform, int> index = new Dictionary <Transform, int>();

                for (int boneIndex = 0, n = bones.Length; boneIndex < n; boneIndex++)
                {
                    Transform unityBoneTransform = bones [boneIndex];
                    index[unityBoneTransform] = boneIndex;
                }

                // Step 1: create the bones.
                for (int boneIndex = 0, n = bones.Length; boneIndex < n; boneIndex++)
                {
                    Transform unityBoneTransform = bones [boneIndex];

                    // Create the bone node if we haven't already. Parent it to
                    // its corresponding parent, or to the scene if there is none.
                    FbxNode fbxBoneNode;
                    if (!MapUnityObjectToFbxNode.TryGetValue(unityBoneTransform.gameObject, out fbxBoneNode))
                    {
                        var     unityParent = unityBoneTransform.parent;
                        FbxNode fbxParent;
                        if (MapUnityObjectToFbxNode.TryGetValue(unityParent.gameObject, out fbxParent))
                        {
                            fbxBoneNode = FbxNode.Create(fbxParent, unityBoneTransform.name);
                        }
                        else
                        {
                            fbxBoneNode = FbxNode.Create(fbxScene, unityBoneTransform.name);
                        }
                        MapUnityObjectToFbxNode.Add(unityBoneTransform.gameObject, fbxBoneNode);
                    }

                    // Set it up as a skeleton node if we haven't already.
                    if (fbxBoneNode.GetSkeleton() == null)
                    {
                        FbxSkeleton fbxSkeleton     = FbxSkeleton.Create(fbxScene, unityBoneTransform.name + "_Skel");
                        var         fbxSkeletonType = index.ContainsKey(unityBoneTransform.parent)
                            ? FbxSkeleton.EType.eLimbNode : FbxSkeleton.EType.eRoot;
                        fbxSkeleton.SetSkeletonType(fbxSkeletonType);
                        fbxSkeleton.Size.Set(1.0f);
                        fbxBoneNode.SetNodeAttribute(fbxSkeleton);
                        if (Verbose)
                        {
                            Debug.Log("Converted " + unityBoneTransform.name + " to a " + fbxSkeletonType + " bone");
                        }
                    }
                }

                // Step 2: connect up the hierarchy.
                foreach (var unityBone in bones)
                {
                    var fbxBone   = MapUnityObjectToFbxNode[unityBone.gameObject];
                    var fbxParent = MapUnityObjectToFbxNode[unityBone.parent.gameObject];
                    fbxParent.AddChild(fbxBone);
                }

                // Step 3: set up the transforms.
                for (int boneIndex = 0, n = bones.Length; boneIndex < n; boneIndex++)
                {
                    var unityBone = bones[boneIndex];
                    var fbxBone   = MapUnityObjectToFbxNode[unityBone.gameObject];

                    Matrix4x4 pose;
                    if (fbxBone.GetSkeleton().GetSkeletonType() == FbxSkeleton.EType.eRoot)
                    {
                        // bind pose is local -> root. We want root -> local, so invert.
                        pose = bindPoses[boneIndex].inverse; // assuming parent is identity matrix
                    }
                    else
                    {
                        // Bind pose is local -> parent -> ... -> root.
                        // We want parent -> local.
                        // Invert our bind pose to get root -> local.
                        // The apply parent -> root to leave just parent -> local.
                        pose = bindPoses[index[unityBone.parent]] * bindPoses[boneIndex].inverse;
                    }

                    // FBX is transposed relative to Unity: transpose as we convert.
                    FbxMatrix matrix = new FbxMatrix();
                    matrix.SetColumn(0, new FbxVector4(pose.GetRow(0).x, pose.GetRow(0).y, pose.GetRow(0).z, pose.GetRow(0).w));
                    matrix.SetColumn(1, new FbxVector4(pose.GetRow(1).x, pose.GetRow(1).y, pose.GetRow(1).z, pose.GetRow(1).w));
                    matrix.SetColumn(2, new FbxVector4(pose.GetRow(2).x, pose.GetRow(2).y, pose.GetRow(2).z, pose.GetRow(2).w));
                    matrix.SetColumn(3, new FbxVector4(pose.GetRow(3).x, pose.GetRow(3).y, pose.GetRow(3).z, pose.GetRow(3).w));

                    // FBX wants translation, rotation (in euler angles) and scale.
                    // We assume there's no real shear, just rounding error.
                    FbxVector4 translation, rotation, shear, scale;
                    double     sign;
                    matrix.GetElements(out translation, out rotation, out shear, out scale, out sign);

                    // Bones should have zero rotation, and use a pivot instead.
                    fbxBone.LclTranslation.Set(new FbxDouble3(translation.X, translation.Y, translation.Z));
                    fbxBone.LclRotation.Set(new FbxDouble3(0, 0, 0));
                    fbxBone.LclScaling.Set(new FbxDouble3(scale.X, scale.Y, scale.Z));

                    fbxBone.SetRotationActive(true);
                    fbxBone.SetPivotState(FbxNode.EPivotSet.eSourcePivot, FbxNode.EPivotState.ePivotReference);
                    fbxBone.SetPreRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(rotation.X, rotation.Y, rotation.Z));
                }

                return(true);
            }
        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);

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

            // Test euler to quaternion conversion
            {
                // EulerToQuaternionZXY
                var v         = new Vector3(50, 45, 190);
                var quat      = ModelExporter.EulerToQuaternionZXY(v);
                var unityQuat = Quaternion.Euler(v);
                Assert.That((float)quat.X, Is.EqualTo(unityQuat.x));
                Assert.That((float)quat.Y, Is.EqualTo(unityQuat.y));
                Assert.That((float)quat.Z, Is.EqualTo(unityQuat.z));
                Assert.That((float)quat.W, Is.EqualTo(unityQuat.w));

                // EulerToQuaternionXYZ
                var fbxV    = new FbxVector4(v.x, v.y, v.z);
                var xyzQuat = ModelExporter.EulerToQuaternionXYZ(fbxV);

                // get the vector from the quaternion
                FbxAMatrix m = new FbxAMatrix();
                m.SetR(fbxV);
                var actualQuat = m.GetQ();

                // since this quaternion is XYZ instead of ZXY, it should not match the quaternion
                // created with EulerToQuaternionZXY
                Assert.That(xyzQuat, Is.Not.EqualTo(quat));
                Assert.That(xyzQuat, Is.EqualTo(actualQuat));
            }
        }
Пример #25
0
        public static bool ExportToFBX(Component_Mesh sourceMesh, string realFileName, out string error)
        {
            //!!!!как для Vegetation. оверрайдить в Component_Mesh?

            //get mesh data
            var operations = new List <Component_RenderingPipeline.RenderSceneData.MeshDataRenderOperation>();

            foreach (var geometry in sourceMesh.GetComponents <Component_MeshGeometry>())
            {
                if (geometry.Enabled)
                {
                    geometry.CompileDataOfThisObject(out var operation);
                    if (operation != null)
                    {
                        operations.Add(operation);
                    }
                }
            }
            //foreach( var geometry in mesh.Result.MeshData.RenderOperations )
            //{
            //}

            FbxManager    manager  = null;
            FbxIOSettings setting  = null;
            FbxExporter   exporter = null;
            FbxScene      scene    = null;

            try
            {
                //init FBX manager
                manager = FbxManager.Create();
                setting = FbxIOSettings.Create(manager, "IOSRoot");
                manager.SetIOSettings(setting);

                scene = FbxScene.Create(manager, "scene");
                scene.GetGlobalSettings().SetAxisSystem(new FbxAxisSystem(FbxAxisSystem.EPreDefinedAxisSystem.eMax));
                scene.GetGlobalSettings().SetSystemUnit(new FbxSystemUnit(100));

                //init FBX scene
                for (int nOper = 0; nOper < operations.Count; nOper++)
                {
                    var oper = operations[nOper];

                    //get data

                    Vector3F[]   positions = null;
                    Vector3F[]   normals   = null;
                    var          texCoords = new List <Vector2F[]>();
                    ColorValue[] colors    = null;
                    Vector3F[]   tangents  = null;
                    Vector3F[]   binormals = null;

                    //Position
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Position, out VertexElement element) && element.Type == VertexElementType.Float3)
                        {
                            var buffer = oper.VertexBuffers[element.Source];
                            positions = buffer.ExtractChannel <Vector3F>(element.Offset);
                        }
                    }

                    //Normal
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Normal, out VertexElement element) && element.Type == VertexElementType.Float3)
                        {
                            var buffer = oper.VertexBuffers[element.Source];
                            normals = buffer.ExtractChannel <Vector3F>(element.Offset);
                        }
                    }

                    //TexCoord
                    for (var channel = VertexElementSemantic.TextureCoordinate0; channel <= VertexElementSemantic.TextureCoordinate3; channel++)
                    {
                        if (oper.VertexStructure.GetElementBySemantic(channel, out VertexElement element) && element.Type == VertexElementType.Float2)
                        {
                            var buffer = oper.VertexBuffers[element.Source];
                            texCoords.Add(buffer.ExtractChannel <Vector2F>(element.Offset));
                        }
                    }

                    //Color
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Color0, out VertexElement element))
                        {
                            if (element.Type == VertexElementType.Float4)
                            {
                                var buffer = oper.VertexBuffers[element.Source];
                                var values = buffer.ExtractChannel <Vector4F>(element.Offset);
                                colors = new ColorValue[positions.Length];
                                int destIndex = 0;
                                foreach (var p in values)
                                {
                                    colors[destIndex++] = p.ToColorValue();
                                }
                            }
                            else if (element.Type == VertexElementType.ColorABGR)
                            {
                                //!!!!check

                                var buffer = oper.VertexBuffers[element.Source];
                                var values = buffer.ExtractChannel <uint>(element.Offset);
                                colors = new ColorValue[positions.Length];
                                int destIndex = 0;
                                foreach (var p in values)
                                {
                                    colors[destIndex++] = new ColorValue(ColorByte.FromABGR(p));
                                }
                            }
                            else if (element.Type == VertexElementType.ColorARGB)
                            {
                                //!!!!check

                                var buffer = oper.VertexBuffers[element.Source];
                                var values = buffer.ExtractChannel <uint>(element.Offset);
                                colors = new ColorValue[positions.Length];
                                int destIndex = 0;
                                foreach (var p in values)
                                {
                                    colors[destIndex++] = new ColorValue(ColorByte.FromARGB(p));
                                }
                            }
                        }
                    }

                    //Tangent, Binormal
                    if (normals != null)
                    {
                        if (oper.VertexStructure.GetElementBySemantic(VertexElementSemantic.Tangent, out VertexElement element) && element.Type == VertexElementType.Float4)
                        {
                            var buffer    = oper.VertexBuffers[element.Source];
                            var tangents4 = buffer.ExtractChannel <Vector4F>(element.Offset);

                            tangents  = new Vector3F[tangents4.Length];
                            binormals = new Vector3F[tangents4.Length];

                            int destIndex = 0;
                            foreach (var p in tangents4)
                            {
                                tangents[destIndex]  = p.ToVector3F();
                                binormals[destIndex] = Vector3F.Cross(p.ToVector3F(), normals[destIndex]) * p.W;
                                destIndex++;
                            }
                        }
                    }

                    //indices
                    int[] indices = null;
                    if (oper.IndexBuffer != null)
                    {
                        indices = oper.IndexBuffer.Indices;
                    }


                    //create geometry

                    var geometryName = "Geometry " + nOper.ToString();
                    var mesh         = FbxMesh.Create(scene, geometryName);

                    mesh.InitControlPoints(positions.Length);

                    FbxLayerElementNormal elementNormals = null;
                    if (normals != null)
                    {
                        elementNormals = mesh.CreateElementNormal();
                        elementNormals.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementNormals.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    FbxLayerElementVertexColor elementColors = null;
                    if (colors != null)
                    {
                        elementColors = mesh.CreateElementVertexColor();
                        elementColors.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementColors.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    FbxLayerElementTangent elementTangents = null;
                    if (tangents != null)
                    {
                        elementTangents = mesh.CreateElementTangent();
                        elementTangents.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementTangents.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    FbxLayerElementBinormal elementBinormals = null;
                    if (binormals != null)
                    {
                        elementBinormals = mesh.CreateElementBinormal();
                        elementBinormals.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        elementBinormals.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);
                    }

                    var uvElements = new List <FbxLayerElementUV>();
                    for (int uvIndex = 0; uvIndex < texCoords.Count; uvIndex++)
                    {
                        var pUVElement = mesh.CreateElementUV("texcoord" + uvIndex.ToString());
                        pUVElement.SetMappingMode(FbxLayerElement.EMappingMode.eByControlPoint);
                        pUVElement.SetReferenceMode(FbxLayerElement.EReferenceMode.eDirect);

                        uvElements.Add(pUVElement);
                    }

                    for (int n = 0; n < positions.Length; n++)
                    {
                        mesh.SetControlPointAt(ToFbxVector4(positions[n]), n);

                        if (normals != null)
                        {
                            elementNormals.GetDirectArray().Add(ToFbxVector4(normals[n]));
                        }

                        for (int uvIndex = 0; uvIndex < texCoords.Count; uvIndex++)
                        {
                            var texCoord = texCoords[uvIndex][n];
                            texCoord.Y = 1.0f - texCoord.Y;
                            uvElements[uvIndex].GetDirectArray().Add(ToFbxVector2(texCoord));
                        }

                        if (colors != null)
                        {
                            elementColors.GetDirectArray().Add(ToFbxColor(colors[n]));
                        }

                        if (tangents != null)
                        {
                            elementTangents.GetDirectArray().Add(ToFbxVector4(tangents[n]));
                        }

                        if (binormals != null)
                        {
                            elementBinormals.GetDirectArray().Add(ToFbxVector4(binormals[n]));
                        }
                    }

                    if (normals != null)
                    {
                        mesh.GetLayer(0).SetNormals(elementNormals);
                    }
                    if (colors != null)
                    {
                        mesh.GetLayer(0).SetVertexColors(elementColors);
                    }
                    if (tangents != null)
                    {
                        mesh.GetLayer(0).SetTangents(elementTangents);
                    }
                    if (binormals != null)
                    {
                        mesh.GetLayer(0).SetBinormals(elementBinormals);
                    }


                    int polygonCount = indices.Length / 3;
                    for (int i = 0; i < polygonCount; i++)
                    {
                        mesh.BeginPolygon(-1, -1, -1, false);
                        for (int j = 0; j < 3; j++)
                        {
                            int currentIndex = i * 3 + j;
                            int vertexIndex  = indices[currentIndex];
                            mesh.AddPolygon(vertexIndex);
                        }
                        mesh.EndPolygon();
                    }

                    var node = FbxNode.Create(scene, geometryName);
                    node.SetNodeAttribute(mesh);

                    scene.GetRootNode().AddChild(mesh.GetNode());
                }

                //save

                exporter = FbxExporter.Create(manager, "");
                if (!exporter.Initialize(realFileName, -1, manager.GetIOSettings()))
                {
                    error = "Can't initialize FBX exporter.";
                    return(false);
                }

                if (!exporter.Export(scene))
                {
                    error = "Export to FBX failed.";
                    return(false);
                }
            }
            finally
            {
                try { scene?.Destroy(); } catch { }
                try { exporter?.Destroy(); } catch { }
                try { setting?.Destroy(); } catch { }
                try { manager?.Destroy(); } catch { }
            }

            foreach (var op in operations)
            {
                op.DisposeBuffers();
            }

            error = "";
            return(true);
        }
Пример #26
0
        public void TestEquality()
        {
            using (var manager = FbxManager.Create()) {
                // FbxProperty
                var node      = FbxNode.Create(manager, "node");
                var prop1     = FbxProperty.Create(node, Globals.FbxBoolDT, "bool1");
                var prop2     = FbxProperty.Create(node, Globals.FbxBoolDT, "bool2");
                var prop1copy = node.FindProperty("bool1");
                EqualityTester <FbxProperty> .TestEquality(prop1, prop2, prop1copy);

                // FbxPropertyT<bool>
                var vis1     = node.VisibilityInheritance;
                var vis2     = FbxNode.Create(manager, "node2").VisibilityInheritance;
                var vis1copy = vis1; // TODO: node.FindProperty("Visibility Inheritance"); -- but that has a different proxy type
                EqualityTester <FbxPropertyBool> .TestEquality(vis1, vis2, vis1copy);

                // FbxPropertyT<EInheritType>
                var inhType1     = node.InheritType;
                var inhType2     = FbxNode.Create(manager, "node3").InheritType;
                var inhType1Copy = inhType1; // TODO: node.FindProperty("InheritType");
                EqualityTester <FbxPropertyEInheritType> .TestEquality(inhType1, inhType2, inhType1Copy);

                // FbxPropertyT<double>
                var lambert      = FbxSurfaceLambert.Create(manager, "lambert");
                var emissiveCopy = lambert.EmissiveFactor; // TODO: lambert.FindProperty("EmissiveFactor");
                EqualityTester <FbxPropertyDouble> .TestEquality(lambert.EmissiveFactor, lambert.AmbientFactor, emissiveCopy);

                // FbxPropertyT<FbxDouble3>
                var lclTranslationCopy = node.LclTranslation; // TODO: node.FindProperty("Lcl Translation");
                EqualityTester <FbxPropertyDouble3> .TestEquality(node.LclTranslation, node.LclRotation, lclTranslationCopy);

                // FbxPropertyT<float>
                var light = FbxLight.Create(manager, "light");
                EqualityTester <FbxPropertyFloat> .TestEquality(light.LeftBarnDoor, light.RightBarnDoor, light.LeftBarnDoor);

                // FbxPropertyT<int>
                var constraint      = FbxConstraintAim.Create(manager, "constraint");
                var constraint2     = FbxConstraintAim.Create(manager, "constraint2");
                var worldUpTypeCopy = constraint.WorldUpType; // TODO: constraint.FindProperty("WorldUpType");
                EqualityTester <FbxPropertyInt> .TestEquality(constraint.WorldUpType, constraint2.WorldUpType, worldUpTypeCopy);

                // FbxPropertyT<> for FbxTexture enums
                var tex1      = FbxTexture.Create(manager, "tex1");
                var tex2      = FbxTexture.Create(manager, "tex2");
                var blendCopy = tex1.CurrentTextureBlendMode; // TODO: tex1.FindProperty(...)
                EqualityTester <FbxPropertyEBlendMode> .TestEquality(tex1.CurrentTextureBlendMode, tex2.CurrentTextureBlendMode, blendCopy);

                var wrapCopy = tex1.WrapModeU; // TODO: tex1.FindProperty(...)
                EqualityTester <FbxPropertyEWrapMode> .TestEquality(tex1.WrapModeU, tex2.WrapModeU, wrapCopy);

                // FbxPropertyT<FbxNull.ELook>
                var null1 = FbxNull.Create(manager, "null1");
                var null2 = FbxNull.Create(manager, "null2");
                EqualityTester <FbxPropertyNullELook> .TestEquality(null1.Look, null2.Look, null1.Look);

                // FbxPropertyT<FbxMarker.ELook>
                var marker1 = FbxMarker.Create(manager, "marker1");
                var marker2 = FbxMarker.Create(manager, "marker2");
                EqualityTester <FbxPropertyMarkerELook> .TestEquality(marker1.Look, marker2.Look, marker1.Look);

                // FbxPropertyT<string>
                var impl          = FbxImplementation.Create(manager, "impl");
                var renderAPIcopy = impl.RenderAPI; // TODO: impl.FindProperty("RenderAPI");
                EqualityTester <FbxPropertyString> .TestEquality(impl.RenderAPI, impl.RenderAPIVersion, renderAPIcopy);

                // FbxPropertyT<> for FbxCamera enum EProjectionType
                var cam1           = FbxCamera.Create(manager, "cam1");
                var cam2           = FbxCamera.Create(manager, "cam2");
                var projectionCopy = cam1.ProjectionType;
                EqualityTester <FbxPropertyEProjectionType> .TestEquality(cam1.ProjectionType, cam2.ProjectionType, projectionCopy);

                // FbxPropertyT<> for FbxLight enum EType
                var light1   = FbxLight.Create(manager, "light1");
                var light2   = FbxLight.Create(manager, "light2");
                var typeCopy = light1.LightType;
                EqualityTester <FbxPropertyELightType> .TestEquality(light1.LightType, light2.LightType, typeCopy);

                var lightShapeCopy = light1.AreaLightShape;
                EqualityTester <FbxPropertyEAreaLightShape> .TestEquality(light1.AreaLightShape, light2.AreaLightShape, lightShapeCopy);

                var decayCopy = light1.DecayType;
                EqualityTester <FbxPropertyEDecayType> .TestEquality(light1.DecayType, light2.DecayType, decayCopy);

                var floatCopy = light1.LeftBarnDoor;
                EqualityTester <FbxPropertyFloat> .TestEquality(light1.LeftBarnDoor, light2.LeftBarnDoor, floatCopy);
            }
        }
Пример #27
0
            /// <summary>
            /// Export bones of skinned mesh
            /// </summary>
            protected bool ExportSkeleton(MeshInfo meshInfo, FbxScene fbxScene, FbxNode fbxParentNode,
                                          ref Dictionary <Transform, FbxNode> boneNodes)
            {
                SkinnedMeshRenderer unitySkinnedMeshRenderer
                    = meshInfo.renderer as SkinnedMeshRenderer;

                if (unitySkinnedMeshRenderer.bones.Length <= 0)
                {
                    return(false);
                }

                Dictionary <Transform, Matrix4x4> boneBindPose = new Dictionary <Transform, Matrix4x4>();

                for (int boneIndex = 0; boneIndex < unitySkinnedMeshRenderer.bones.Length; boneIndex++)
                {
                    Transform unityBoneTransform = unitySkinnedMeshRenderer.bones [boneIndex];

                    FbxNode fbxBoneNode = FbxNode.Create(fbxScene, unityBoneTransform.name);

                    // Create the node's attributes
                    FbxSkeleton fbxSkeleton = FbxSkeleton.Create(fbxScene, unityBoneTransform.name + "_Skel");

                    var fbxSkeletonType = FbxSkeleton.EType.eLimbNode;
                    if (unityBoneTransform == unityBoneTransform.root || fbxParentNode.GetName().Equals(unityBoneTransform.parent.name))
                    {
                        fbxSkeletonType = FbxSkeleton.EType.eRoot;
                    }
                    fbxSkeleton.SetSkeletonType(fbxSkeletonType);
                    fbxSkeleton.Size.Set(1.0f);

                    // Set the node's attribute
                    fbxBoneNode.SetNodeAttribute(fbxSkeleton);

                    boneBindPose.Add(unityBoneTransform, meshInfo.BindPoses [boneIndex]);

                    // save relatation between unity transform and fbx bone node for skinning
                    boneNodes [unityBoneTransform] = fbxBoneNode;
                }

                // set the hierarchy for the FbxNodes
                foreach (KeyValuePair <Transform, FbxNode> t in boneNodes)
                {
                    Matrix4x4 pose;

                    // if this is a root node then don't need to do anything
                    if (t.Key == t.Key.root || !boneNodes.ContainsKey(t.Key.parent))
                    {
                        fbxParentNode.AddChild(t.Value);

                        pose = boneBindPose[t.Key].inverse; // assuming parent is identity matrix
                    }
                    else
                    {
                        boneNodes [t.Key.parent].AddChild(t.Value);

                        // inverse of my bind pose times parent bind pose
                        pose = boneBindPose[t.Key.parent] * boneBindPose[t.Key].inverse;
                    }

                    // use FbxMatrix to get translation and rotation relative to parent
                    FbxMatrix matrix = new FbxMatrix();
                    matrix.SetColumn(0, new FbxVector4(pose.GetRow(0).x, pose.GetRow(0).y, pose.GetRow(0).z, pose.GetRow(0).w));
                    matrix.SetColumn(1, new FbxVector4(pose.GetRow(1).x, pose.GetRow(1).y, pose.GetRow(1).z, pose.GetRow(1).w));
                    matrix.SetColumn(2, new FbxVector4(pose.GetRow(2).x, pose.GetRow(2).y, pose.GetRow(2).z, pose.GetRow(2).w));
                    matrix.SetColumn(3, new FbxVector4(pose.GetRow(3).x, pose.GetRow(3).y, pose.GetRow(3).z, pose.GetRow(3).w));

                    FbxVector4 translation, rotation, shear, scale;
                    double     sign;
                    matrix.GetElements(out translation, out rotation, out shear, out scale, out sign);

                    // Negating the x value of the translation, and the y and z values of the prerotation
                    // to convert from Unity to Maya coordinates (left to righthanded)
                    t.Value.LclTranslation.Set(new FbxDouble3(-translation.X, translation.Y, translation.Z));
                    t.Value.LclRotation.Set(new FbxDouble3(0, 0, 0));
                    t.Value.LclScaling.Set(new FbxDouble3(scale.X, scale.Y, scale.Z));

                    t.Value.SetRotationActive(true);
                    t.Value.SetPivotState(FbxNode.EPivotSet.eSourcePivot, FbxNode.EPivotState.ePivotReference);
                    t.Value.SetPreRotation(FbxNode.EPivotSet.eSourcePivot, new FbxVector4(rotation.X, -rotation.Y, -rotation.Z));
                }

                return(true);
            }