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

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

            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);
        }
예제 #2
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);
                var fbxProperty = ExportCustomData(unityGo.transform, fbxNode);

                if (Verbose)
                {
                    Debug.Log(string.Format("exporting {0} ({1} components)", fbxNode.GetName(), (int)fbxProperty.GetFloat()));
                }

                fbxParentNode.AddChild(fbxNode);

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

                return;
            }
예제 #3
0
            /// <summary>
            /// Unconditionally export components on this game object
            /// </summary>
            protected void ExportComponents(GameObject unityGo, FbxScene fbxScene, FbxNode fbxNodeParent)
            {
                // create an FbxNode and add it as a child of parent
                FbxNode fbxNode = FbxNode.Create(fbxScene, unityGo.name);

                NumNodes++;

                ExportTransform(unityGo.transform, fbxNode);
                ExportMesh(GetMeshInfo(unityGo), fbxNode, fbxScene);

                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;
            }
예제 #4
0
        protected FbxNode CreateSkeleton(FbxScene scene)
        {
            FbxSkeleton skelRoot = FbxSkeleton.Create(scene, "SkelRoot");

            skelRoot.SetSkeletonType(FbxSkeleton.EType.eRoot);
            FbxNode skelRootNode = FbxNode.Create(scene, "SkelRootNode");

            skelRootNode.SetNodeAttribute(skelRoot);
            skelRootNode.LclTranslation.Set(new FbxDouble3(0.0, -40.0, 0.0));

            // create skeleton limb nodes
            FbxSkeleton skelLimb1 = FbxSkeleton.Create(scene, "SkelLimb1");

            skelLimb1.SetSkeletonType(FbxSkeleton.EType.eLimbNode);
            skelLimb1.Size.Set(1.5);
            FbxNode skelLimbNode1 = FbxNode.Create(scene, "SkelLimbNode1");

            skelLimbNode1.SetNodeAttribute(skelLimb1);
            skelLimbNode1.LclTranslation.Set(new FbxDouble3(0.0, 40.0, 0.0));

            FbxSkeleton skelLimb2 = FbxSkeleton.Create(scene, "SkelLimb2");

            skelLimb2.SetSkeletonType(FbxSkeleton.EType.eLimbNode);
            skelLimb2.Size.Set(1.5);
            FbxNode skelLimbNode2 = FbxNode.Create(scene, "SkelLimbNode2");

            skelLimbNode2.SetNodeAttribute(skelLimb2);
            skelLimbNode2.LclTranslation.Set(new FbxDouble3(0.0, 40.0, 0.0));

            // build skeleton hierarchy
            skelRootNode.AddChild(skelLimbNode1);
            skelLimbNode1.AddChild(skelLimbNode2);

            return(skelRootNode);
        }
예제 #5
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);

                var fbxNodeAttr = ExportNull(fbxScene);

                // set the fbxNode's node attribute
                fbxNode.SetNodeAttribute(fbxNodeAttr);
                fbxNode.SetShadingMode(FbxNode.EShadingMode.eWireFrame);

                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;
            }
예제 #6
0
        public void NodesInHierarchy_CalcGlobalTransform_ChildsIsTimesParent()
        {
            // given:
            var node1 = new FbxNode("node1");
            var node2 = new FbxNode("node2");

            node1.AddChild(node2);
            var r1 = new FbxVector4(45, 0, 0);
            var r2 = new FbxVector4(0, 60, 0);

            node1.LclRotation.Set(r1);
            node2.LclRotation.Set(r2);

            // when:
            var g1 = node1.EvaluateGlobalTransform();
            var g2 = node2.EvaluateGlobalTransform();
            var l1 = node1.EvaluateLocalTransform();
            var l2 = node2.EvaluateLocalTransform();

            Assert.AreEqual(l1.Get(0, 0), g1.Get(0, 0), 0.000001f);
            Assert.AreEqual(l1.Get(0, 1), g1.Get(0, 1), 0.000001f);
            Assert.AreEqual(l1.Get(0, 2), g1.Get(0, 2), 0.000001f);
            Assert.AreEqual(l1.Get(0, 3), g1.Get(0, 3), 0.000001f);
            Assert.AreEqual(l1.Get(1, 0), g1.Get(1, 0), 0.000001f);
            Assert.AreEqual(l1.Get(1, 1), g1.Get(1, 1), 0.000001f);
            Assert.AreEqual(l1.Get(1, 2), g1.Get(1, 2), 0.000001f);
            Assert.AreEqual(l1.Get(1, 3), g1.Get(1, 3), 0.000001f);
            Assert.AreEqual(l1.Get(2, 0), g1.Get(2, 0), 0.000001f);
            Assert.AreEqual(l1.Get(2, 1), g1.Get(2, 1), 0.000001f);
            Assert.AreEqual(l1.Get(2, 2), g1.Get(2, 2), 0.000001f);
            Assert.AreEqual(l1.Get(2, 3), g1.Get(2, 3), 0.000001f);
            Assert.AreEqual(l1.Get(3, 0), g1.Get(3, 0), 0.000001f);
            Assert.AreEqual(l1.Get(3, 1), g1.Get(3, 1), 0.000001f);
            Assert.AreEqual(l1.Get(3, 2), g1.Get(3, 2), 0.000001f);
            Assert.AreEqual(l1.Get(3, 3), g1.Get(3, 3), 0.000001f);

            var m = l1 * l2;

            Assert.AreEqual(m.Get(0, 0), g2.Get(0, 0), 0.000001f);
            Assert.AreEqual(m.Get(0, 1), g2.Get(0, 1), 0.000001f);
            Assert.AreEqual(m.Get(0, 2), g2.Get(0, 2), 0.000001f);
            Assert.AreEqual(m.Get(0, 3), g2.Get(0, 3), 0.000001f);
            Assert.AreEqual(m.Get(1, 0), g2.Get(1, 0), 0.000001f);
            Assert.AreEqual(m.Get(1, 1), g2.Get(1, 1), 0.000001f);
            Assert.AreEqual(m.Get(1, 2), g2.Get(1, 2), 0.000001f);
            Assert.AreEqual(m.Get(1, 3), g2.Get(1, 3), 0.000001f);
            Assert.AreEqual(m.Get(2, 0), g2.Get(2, 0), 0.000001f);
            Assert.AreEqual(m.Get(2, 1), g2.Get(2, 1), 0.000001f);
            Assert.AreEqual(m.Get(2, 2), g2.Get(2, 2), 0.000001f);
            Assert.AreEqual(m.Get(2, 3), g2.Get(2, 3), 0.000001f);
            Assert.AreEqual(m.Get(3, 0), g2.Get(3, 0), 0.000001f);
            Assert.AreEqual(m.Get(3, 1), g2.Get(3, 1), 0.000001f);
            Assert.AreEqual(m.Get(3, 2), g2.Get(3, 2), 0.000001f);
            Assert.AreEqual(m.Get(3, 3), g2.Get(3, 3), 0.000001f);
        }
예제 #7
0
        public void NodesInHierarchy_CalcGlobalTransformWithTranslationAndWithRotation_ReturnsRotatedThenTranslated()
        {
            // given:
            var node1 = new FbxNode("node1");
            var node2 = new FbxNode("node2");

            node1.AddChild(node2);
            var t = new FbxVector4(2, 3, 4);
            var r = new FbxVector4(45, 0, 0);

            node1.LclTranslation.Set(t);
            node2.LclRotation.Set(r);

            // when:
            var actual = node1.EvaluateGlobalTransform();

            // then:
            Assert.AreEqual(1.000000f, actual.Get(0, 0), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(0, 1), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(0, 2), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(0, 3), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(1, 0), 0.000001f);
            Assert.AreEqual(1.000000f, actual.Get(1, 1), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(1, 2), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(1, 3), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(2, 0), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(2, 1), 0.000001f);
            Assert.AreEqual(1.000000f, actual.Get(2, 2), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(2, 3), 0.000001f);
            Assert.AreEqual(2.000000f, actual.Get(3, 0), 0.000001f);
            Assert.AreEqual(3.000000f, actual.Get(3, 1), 0.000001f);
            Assert.AreEqual(4.000000f, actual.Get(3, 2), 0.000001f);
            Assert.AreEqual(1.000000f, actual.Get(3, 3), 0.000001f);

            // when:
            actual = node2.EvaluateGlobalTransform();

            // then:
            Assert.AreEqual(1.000000f, actual.Get(0, 0), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(0, 1), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(0, 2), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(0, 3), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(1, 0), 0.000001f);
            Assert.AreEqual(0.707107f, actual.Get(1, 1), 0.000001f);
            Assert.AreEqual(0.707107f, actual.Get(1, 2), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(1, 3), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(2, 0), 0.000001f);
            Assert.AreEqual(-0.707107f, actual.Get(2, 1), 0.000001f);
            Assert.AreEqual(0.707107f, actual.Get(2, 2), 0.000001f);
            Assert.AreEqual(0.000000f, actual.Get(2, 3), 0.000001f);
            Assert.AreEqual(2.000000f, actual.Get(3, 0), 0.000001f);
            Assert.AreEqual(3.000000f, actual.Get(3, 1), 0.000001f);
            Assert.AreEqual(4.000000f, actual.Get(3, 2), 0.000001f);
            Assert.AreEqual(1.000000f, actual.Get(3, 3), 0.000001f);
        }
예제 #8
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);
        }
예제 #9
0
        // This writes out the local xform, and requires that parentNode use payload.instanceXform
        static void ExportMeshPayload_Local(
            FbxExportGlobals G, ModelMeshPayload payload, FbxNode parentNode)
        {
            // If these aren't unique, either FBX or Unity will uniquify them for us -- not sure which.
            // So roll payload.id into the name.
            FbxNode fbxNode = FbxNode.Create(G.m_manager, payload.nodeName);

            fbxNode.SetLocalTransform(payload.localXform);
            fbxNode.SetNodeAttribute(G.GetOrCreateFbxMesh(payload));
            fbxNode.AddMaterial(G.GetOrCreateFbxMaterial(
                                    payload.MeshNamespace, payload.exportableMaterial));

            parentNode.AddChild(fbxNode);
        }
예제 #10
0
            /// <summary>
            /// Unconditionally export this mesh object to the file.
            /// We have decided; this mesh is definitely getting exported.
            /// </summary>
            public FbxNode ExportMesh(MeshInfo meshInfo, FbxScene fbxScene, FbxNode fbxNode)
            {
                if (!meshInfo.IsValid)
                {
                    Debug.LogError("Invalid mesh info");
                    return(null);
                }

                // create a node for the mesh
                FbxNode meshNode = FbxNode.Create(fbxScene, "geo");

                // create the mesh structure.
                FbxMesh fbxMesh = FbxMesh.Create(fbxScene, "Mesh");

                // Create control points.
                int NumControlPoints = meshInfo.VertexCount;

                fbxMesh.InitControlPoints(NumControlPoints);

                // copy control point data from Unity to FBX
                for (int v = 0; v < NumControlPoints; v++)
                {
                    // convert from left to right-handed by negating x (Unity negates x again on import)
                    fbxMesh.SetControlPointAt(new FbxVector4(-meshInfo.Vertices [v].x, meshInfo.Vertices [v].y, meshInfo.Vertices [v].z), v);
                }

                /*
                 * Create polygons
                 * Triangles have to be added in reverse order,
                 * or else they will be inverted on import
                 * (due to the conversion from left to right handed coords)
                 */
                for (int f = 0; f < meshInfo.Triangles.Length / 3; f++)
                {
                    fbxMesh.BeginPolygon();
                    fbxMesh.AddPolygon(meshInfo.Triangles [3 * f + 2]);
                    fbxMesh.AddPolygon(meshInfo.Triangles [3 * f + 1]);
                    fbxMesh.AddPolygon(meshInfo.Triangles [3 * f]);
                    fbxMesh.EndPolygon();
                }

                // set the fbxNode containing the mesh
                meshNode.SetNodeAttribute(fbxMesh);
                meshNode.SetShadingMode(FbxNode.EShadingMode.eWireFrame);

                fbxNode.AddChild(meshNode);

                return(meshNode);
            }
예제 #11
0
    public FbxNode ExportAnimSequence(AnimSequence AnimSeq, List <FMeshBoneInfo> boneInfos)
    {
        if (Scene == null)
        {
            return(null);
        }
        List <FbxNode> BoneNodes        = new List <FbxNode>();
        FbxNode        RootNode         = Scene.GetRootNode();
        FbxNode        SkeletonRootNode = CreateSkeleton(boneInfos, ref BoneNodes);

        RootNode.AddChild(SkeletonRootNode);

        ExportAnimSequenceToFbx(AnimSeq, ref BoneNodes, AnimLayer, 0.0f, 0.0f, 1.0f, 0.0f);
        CorrectAnimTrackInterpolation(ref BoneNodes, AnimLayer);
        return(SkeletonRootNode);
    }
예제 #12
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);
        }
예제 #13
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;
            }
예제 #14
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;
            }
예제 #15
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;
            }
예제 #16
0
        public void Node_AddChild_AddsChild()
        {
            // given:
            var node1 = new FbxNode("Node1");
            var node2 = new FbxNode("Node2");

            // require:
            Assert.AreEqual(0, node1.GetSrcObjectCount());
            Assert.AreEqual(0, node1.GetDstObjectCount());
            Assert.AreEqual(0, node1.GetSrcPropertyCount());
            Assert.AreEqual(0, node1.GetDstPropertyCount());
            Assert.AreEqual(0, node1.GetChildCount());
            Assert.AreEqual(null, node1.GetParent());

            Assert.AreEqual(0, node2.GetSrcObjectCount());
            Assert.AreEqual(0, node2.GetDstObjectCount());
            Assert.AreEqual(0, node2.GetSrcPropertyCount());
            Assert.AreEqual(0, node2.GetDstPropertyCount());
            Assert.AreEqual(0, node2.GetChildCount());
            Assert.AreEqual(null, node1.GetParent());

            // when:
            node1.AddChild(node2);

            // then:
            Assert.AreEqual(1, node1.GetSrcObjectCount());
            Assert.AreEqual(node2, node1.GetSrcObject(0));
            Assert.AreEqual(0, node1.GetDstObjectCount());
            Assert.AreEqual(0, node1.GetSrcPropertyCount());
            Assert.AreEqual(0, node1.GetDstPropertyCount());
            Assert.AreEqual(1, node1.GetChildCount());
            Assert.AreEqual(node2, node1.GetChild(0));
            Assert.AreEqual(null, node1.GetParent());

            Assert.AreEqual(0, node2.GetSrcObjectCount());
            Assert.AreEqual(1, node2.GetDstObjectCount());
            Assert.AreEqual(node1, node2.GetDstObject(0));
            Assert.AreEqual(0, node2.GetSrcPropertyCount());
            Assert.AreEqual(0, node2.GetDstPropertyCount());
            Assert.AreEqual(0, node2.GetChildCount());
            Assert.AreEqual(node1, node2.GetParent());
        }
예제 #17
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;
            }
예제 #18
0
        protected override FbxScene CreateScene(FbxManager manager)
        {
            // Add a skeleton to the cube that we created in StaticMeshExportTest
            FbxScene scene = base.CreateScene(manager);

            FbxNode meshNode         = scene.GetRootNode().GetChild(0);
            FbxNode skeletonRootNode = CreateSkeleton(scene);

            FbxNode rootNode = scene.GetRootNode();

            rootNode.AddChild(skeletonRootNode);

            LinkMeshToSkeleton(scene, meshNode, skeletonRootNode);

            FbxNode limb1 = skeletonRootNode.GetChild(0);
            FbxNode limb2 = limb1.GetChild(0);

            ExportBindPose(meshNode, scene, new List <FbxNode> ()
            {
                skeletonRootNode, limb1, limb2
            });

            return(scene);
        }
예제 #19
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);
            }
예제 #20
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");
                }
            }
예제 #21
0
        public void RootNode_AddChild_AddsNodeSubtree()
        {
            // given:
            var scene = new FbxScene("TheScene");
            var root  = scene.GetRootNode();
            var node2 = new FbxNode("ChildNode");
            var node3 = new FbxNode("ChildNode");

            node2.AddChild(node3);

            // require:
            Assert.AreEqual(3, scene.GetSrcObjectCount());
            Assert.AreEqual(root, scene.GetSrcObject(0));
            Assert.AreEqual(scene.GetGlobalSettings(), scene.GetSrcObject(1));
            Assert.AreEqual(scene.GetAnimationEvaluator(), scene.GetSrcObject(2));
            Assert.AreEqual(0, scene.GetDstObjectCount());
            Assert.AreEqual(1, scene.GetNodeCount());
            Assert.AreEqual(root, scene.GetNode(0));

            Assert.AreEqual(0, root.GetSrcObjectCount());
            Assert.AreEqual(1, root.GetDstObjectCount());
            Assert.AreEqual(scene, root.GetDstObject(0));
            Assert.AreEqual(0, root.GetChildCount());
            Assert.AreEqual(scene, root.GetScene());

            Assert.AreEqual(1, node2.GetSrcObjectCount());
            Assert.AreEqual(node3, node2.GetSrcObject(0));
            Assert.AreEqual(0, node2.GetDstObjectCount());
            Assert.AreEqual(1, node2.GetChildCount());
            Assert.AreEqual(node3, node2.GetChild(0));
            Assert.AreEqual(null, node2.GetParent());
            Assert.AreEqual(null, node2.GetScene());

            Assert.AreEqual(0, node3.GetSrcObjectCount());
            Assert.AreEqual(1, node3.GetDstObjectCount());
            Assert.AreEqual(node2, node3.GetDstObject(0));
            Assert.AreEqual(0, node3.GetChildCount());
            Assert.AreEqual(node2, node3.GetParent());
            Assert.AreEqual(null, node3.GetScene());

            // when:
            root.AddChild(node2);

            // then:
            Assert.AreEqual(5, scene.GetSrcObjectCount());
            Assert.AreEqual(root, scene.GetSrcObject(0));
            Assert.AreEqual(scene.GetGlobalSettings(), scene.GetSrcObject(1));
            Assert.AreEqual(scene.GetAnimationEvaluator(), scene.GetSrcObject(2));
            Assert.AreEqual(node2, scene.GetSrcObject(3));
            Assert.AreEqual(node3, scene.GetSrcObject(4));
            Assert.AreEqual(0, scene.GetDstObjectCount());
            Assert.AreEqual(3, scene.GetNodeCount());
            Assert.AreEqual(root, scene.GetNode(0));
            Assert.AreEqual(node2, scene.GetNode(1));
            Assert.AreEqual(node3, scene.GetNode(2));

            Assert.AreEqual(1, root.GetSrcObjectCount());
            Assert.AreEqual(node2, root.GetSrcObject(0));
            Assert.AreEqual(1, root.GetDstObjectCount());
            Assert.AreEqual(scene, root.GetDstObject(0));
            Assert.AreEqual(1, root.GetChildCount());
            Assert.AreEqual(node2, root.GetChild(0));
            Assert.AreEqual(scene, root.GetScene());

            Assert.AreEqual(1, node2.GetSrcObjectCount());
            Assert.AreEqual(node3, node2.GetSrcObject(0));
            Assert.AreEqual(2, node2.GetDstObjectCount());
            Assert.AreEqual(root, node2.GetDstObject(0));
            Assert.AreEqual(scene, node2.GetDstObject(1));
            Assert.AreEqual(1, node2.GetChildCount());
            Assert.AreEqual(node3, node2.GetChild(0));
            Assert.AreEqual(root, node2.GetParent());
            Assert.AreEqual(scene, node2.GetScene());

            Assert.AreEqual(0, node3.GetSrcObjectCount());
            Assert.AreEqual(2, node3.GetDstObjectCount());
            Assert.AreEqual(node2, node3.GetDstObject(0));
            Assert.AreEqual(scene, node3.GetDstObject(1));
            Assert.AreEqual(0, node3.GetChildCount());
            Assert.AreEqual(node2, node3.GetParent());
            Assert.AreEqual(scene, node3.GetScene());
        }
        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);
        }
예제 #23
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);
            }
        }