Esempio n. 1
0
        public void RootNode_AddChildNode_AddsNodeToScene()
        {
            // given:
            var scene = new FbxScene("TheScene");
            var root  = scene.GetRootNode();
            var node  = new FbxNode("ChildNode");

            // 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(scene, root.GetScene());

            Assert.AreEqual(0, node.GetSrcObjectCount());
            Assert.AreEqual(0, node.GetDstObjectCount());
            Assert.AreEqual(null, node.GetScene());

            // when:
            root.AddChild(node);

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

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

            Assert.AreEqual(0, node.GetSrcObjectCount());
            Assert.AreEqual(2, node.GetDstObjectCount());
            Assert.AreEqual(root, node.GetDstObject(0));
            Assert.AreEqual(scene, node.GetDstObject(1));
            Assert.AreEqual(scene, node.GetScene());
        }
Esempio n. 2
0
        public void Node_AddMaterial_SetsMaterialScene()
        {
            // given:
            var scene = new FbxScene("");
            var root  = scene.GetRootNode();
            var node  = new FbxNode("");
            var mat   = new FbxSurfacePhong("");

            root.AddChild(node);

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

            Assert.AreEqual(0, node.GetSrcObjectCount());
            Assert.AreEqual(2, node.GetDstObjectCount());
            Assert.AreEqual(root, node.GetDstObject(0));
            Assert.AreEqual(scene, node.GetDstObject(1));
            Assert.AreEqual(scene, node.GetScene());
            Assert.AreEqual(0, node.GetMaterialCount());

            Assert.AreEqual(0, mat.GetSrcObjectCount());
            Assert.AreEqual(0, mat.GetDstObjectCount());
            Assert.AreEqual(null, mat.GetScene());

            // when:
            node.AddMaterial(mat);

            // then:
            Assert.AreEqual(5, scene.GetSrcObjectCount());
            Assert.AreEqual(mat, scene.GetSrcObject(4));
            Assert.AreEqual(2, scene.GetNodeCount());
            Assert.AreEqual(scene.GetRootNode(), scene.GetNode(0));
            Assert.AreEqual(node, scene.GetNode(1));

            Assert.AreEqual(1, node.GetSrcObjectCount());
            Assert.AreEqual(mat, node.GetSrcObject(0));
            Assert.AreEqual(1, node.GetMaterialCount());
            Assert.AreEqual(mat, node.GetMaterial(0));

            Assert.AreEqual(0, mat.GetSrcObjectCount());
            Assert.AreEqual(2, mat.GetDstObjectCount());
            Assert.AreEqual(node, mat.GetDstObject(0));
            Assert.AreEqual(scene, mat.GetDstObject(1));
            Assert.AreEqual(scene, mat.GetScene());
        }
Esempio n. 3
0
        //Calculates global transform of the node.
        //This function was taken from FBX SDK/Smaples/Transformations. Originaly it did not take into account AxisSystem, so the corrections to use AxisSystem was added.
        //Has the fbx sdk equivalent pNode.EvaluateGlobalTransform();
        //
        //Note: FBX Documentation for ConvertScene states - "The adjustment will affect the translation animation curves and the objects pivots values
        //(the rotation transformation is applied as a pre-rotation transform therefore the rotation animation curves do not need to be transformed)"
        //But ConvertScene, does not realy change node.PreRotation, these changes are in the matrix : node.GetScene().GetGlobalSettings().GetAxisSystem().GetMatrix
        //

        /*
         * Terminology:
         * Suffix "M" means this is a matrix, suffix "V" means it is a vector.
         * T is translation.
         * R is rotation.
         * S is scaling.
         * SH is shear.
         * GlobalRM(x) means the Global Rotation Matrix of node "x".
         * GlobalRM(P(x)) means the Global Rotation Matrix of the parent node of node "x".
         * All other transforms are described in the similar way.
         *
         * The algorithm description:
         * To calculate global transform of a node x according to different InheritType,
         * we need to calculate GlobalTM(x) and [GlobalRM(x) * (GlobalSHM(x) * GlobalSM(x))] separately.
         * GlobalM(x) = GlobalTM(x) * [GlobalRM(x) * (GlobalSHM(x) * GlobalSM(x))];
         *
         * InhereitType = RrSs:
         * GlobalRM(x) * (GlobalSHM(x) * GlobalSM(x)) = GlobalRM(P(x)) * LocalRM(x) * [GlobalSHM(P(x)) * GlobalSM(P(x))] * LocalSM(x);
         *
         * InhereitType = RSrs:
         * GlobalRM(x) * (GlobalSHM(x) * GlobalSM(x)) = GlobalRM(P(x)) * [GlobalSHM(P(x)) * GlobalSM(P(x))] * LocalRM(x) * LocalSM(x);
         *
         * InhereitType = Rrs:
         * GlobalRM(x) * (GlobalSHM(x) * GlobalSM(x)) = GlobalRM(P(x)) * LocalRM(x) * LocalSM(x);
         *
         * LocalM(x)= TM(x) * RoffsetM(x)  * RpivotM(x) * RpreM(x) * RM(x) * RpostM(x) * RpivotM(x)^-1 * SoffsetM(x) *SpivotM(x) * SM(x) * SpivotM(x)^-1
         * LocalTWithAllPivotAndOffsetInformationV(x) = Local(x).GetT();
         * GlobalTV(x) = GlobalM(P(x)) * LocalTWithAllPivotAndOffsetInformationV(x);
         *
         * Notice: FBX SDK does not support shear yet, so all local transform won't have shear.
         * However, global transform might bring in shear by combine the global transform of node in higher hierarchy.
         * For example, if you scale the parent by a non-uniform scale and then rotate the child node, then a shear will
         * be generated on the child node's global transform.
         * In this case, we always compensates shear and store it in the scale matrix too according to following formula:
         * Shear*Scaling = RotationMatrix.Inverse * TranslationMatrix.Inverse * WholeTranformMatrix
         */
        // ReSharper disable InconsistentNaming
        static FbxAMatrix CalculateGlobalTransform(FbxNode node)
        {
            if (node == null)
            {
                var ret = new FbxAMatrix();
                ret.SetIdentity();
                return(ret);
            }
            var lTranlationM     = new FbxAMatrix();
            var lScalingM        = new FbxAMatrix();
            var lScalingPivotM   = new FbxAMatrix();
            var lScalingOffsetM  = new FbxAMatrix();
            var lRotationOffsetM = new FbxAMatrix();
            var lRotationPivotM  = new FbxAMatrix();
            var lPreRotationM    = new FbxAMatrix();
            var lRotationM       = new FbxAMatrix();
            var lPostRotationM   = new FbxAMatrix();

            FbxAMatrix lParentGX = new FbxAMatrix();
            FbxAMatrix lGlobalT  = new FbxAMatrix();
            FbxAMatrix lGlobalRS = new FbxAMatrix();

            // Construct translation matrix
            FbxVector4 lTranslation = new FbxVector4(node.LclTranslation.Get());               //The fourth component of this object is assigned 1.

            lTranlationM.SetT(lTranslation);

            // Construct rotation matrices
            FbxVector4 lRotation     = new FbxVector4(node.LclRotation.Get());
            FbxVector4 lPreRotation  = new FbxVector4(node.PreRotation.Get());
            FbxVector4 lPostRotation = new FbxVector4(node.PostRotation.Get());

            lRotationM.SetR(lRotation);
            lPreRotationM.SetR(lPreRotation);
            lPostRotationM.SetR(lPostRotation);

            // Construct scaling matrix
            FbxVector4 lScaling = new FbxVector4(node.LclScaling.Get());

            lScalingM.SetS(lScaling);

            // Construct offset and pivot matrices
            FbxVector4 lScalingOffset  = new FbxVector4(node.ScalingOffset.Get());
            FbxVector4 lScalingPivot   = new FbxVector4(node.ScalingPivot.Get());
            FbxVector4 lRotationOffset = new FbxVector4(node.RotationOffset.Get());
            FbxVector4 lRotationPivot  = new FbxVector4(node.RotationPivot.Get());

            lScalingOffsetM.SetT(lScalingOffset);
            lScalingPivotM.SetT(lScalingPivot);
            lRotationOffsetM.SetT(lRotationOffset);
            lRotationPivotM.SetT(lRotationPivot);

            // Calculate the global transform matrix of the parent node
            FbxNode lParentNode = node.GetParent();

            if (lParentNode != null)
            {
                //Children of the root node must take into account the axis matrix.
                //Warning: this function CalculateGlobalTransform was taken from FBX SDK/Smaples/Transformations. Originaly it did not take into account AxisSystem
                if (lParentNode.GetParent() == null)
                {
                    FbxAMatrix axisMarix = new FbxAMatrix();
                    node.GetScene().GetGlobalSettings().GetAxisSystem().GetMatrix(axisMarix);
                    lPreRotationM = axisMarix.mul(lPreRotationM);
                }

                lParentGX = CalculateGlobalTransform(lParentNode);
            }
            else
            {
                lParentGX.SetIdentity();
            }

            //Construct Global Rotation
            FbxAMatrix lParentGRM = new FbxAMatrix();
            FbxVector4 lParentGR  = lParentGX.GetR();

            lParentGRM.SetR(lParentGR);
            var lLRM = lPreRotationM.mul(lRotationM).mul(lPostRotationM);

            //Construct Global Shear*Scaling
            //FBX SDK does not support shear, to patch this, we use:
            //Shear*Scaling = RotationMatrix.Inverse * TranslationMatrix.Inverse * WholeTranformMatrix
            FbxAMatrix lParentTM = new FbxAMatrix();
            FbxVector4 lParentGT = lParentGX.GetT();

            lParentTM.SetT(lParentGT);
            var lParentGRSM = lParentTM.Inverse().mul(lParentGX);
            var lParentGSM  = lParentGRM.Inverse().mul(lParentGRSM);
            var lLSM        = lScalingM;


            //Do not consider translation now
            FbxTransform.EInheritType lInheritType = node.InheritType.Get();
            if (lInheritType == FbxTransform.EInheritType.eInheritRrSs)
            {
                lGlobalRS = lParentGRM.mul(lLRM).mul(lParentGSM).mul(lLSM);
            }
            else if (lInheritType == FbxTransform.EInheritType.eInheritRSrs)
            {
                lGlobalRS = lParentGRM.mul(lParentGSM).mul(lLRM).mul(lLSM);
            }
            else if (lInheritType == FbxTransform.EInheritType.eInheritRrs)
            {
                if (lParentNode != null)
                {
                    FbxAMatrix lParentLSM = new FbxAMatrix();
                    FbxVector4 lParentLS  = new FbxVector4(lParentNode.LclScaling.Get());
                    lParentLSM.SetS(lParentLS);
                    FbxAMatrix lParentGSM_noLocal = lParentGSM.mul(lParentLSM.Inverse());
                    lGlobalRS = lParentGRM.mul(lLRM).mul(lParentGSM_noLocal).mul(lLSM);
                }
                else
                {
                    lGlobalRS = lParentGRM.mul(lLRM).mul(lLSM);
                }
            }
            else
            {
                FbxImportLog.LogError(node, "error, unknown inherit type!");
            }

            // Construct translation matrix
            // Calculate the local transform matrix
            var lTransform = lTranlationM.mul(lRotationOffsetM).mul(lRotationPivotM).mul(lPreRotationM).mul(lRotationM).mul(lPostRotationM)
                             .mul(lRotationPivotM.Inverse()).mul(lScalingOffsetM).mul(lScalingPivotM).mul(lScalingM).mul(lScalingPivotM.Inverse());
            FbxVector4 lLocalTWithAllPivotAndOffsetInfo = lTransform.GetT();
            // Calculate global translation vector according to:
            // GlobalTranslation = ParentGlobalTransform * LocalTranslationWithPivotAndOffsetInfo
            FbxVector4 lGlobalTranslation = lParentGX.MultT(lLocalTWithAllPivotAndOffsetInfo);

            lGlobalT.SetT(lGlobalTranslation);

            //Construct the whole global transform
            lTransform = lGlobalT.mul(lGlobalRS);

            return(lTransform);
        }
Esempio n. 4
0
        public void Scene_AddObjectWithSrcObjects_AddsAllSrcObjects()
        {
            // given:
            var scene = new FbxScene("s");
            var node  = new FbxNode("n");
            var m1    = new FbxMesh("m1");
            var m2    = new FbxMesh("m2");
            var v     = new FbxVideo("v");
            var c     = new FbxCluster("c");
            var n2    = new FbxNode("n2");
            var c2    = new FbxCluster("c2");

            node.ConnectSrcObject(m1);
            node.ConnectSrcObject(m2);
            node.ConnectSrcObject(v);
            node.ConnectSrcObject(c);
            c.ConnectSrcObject(n2);;
            n2.ConnectSrcObject(c2);

            // require:
            Assert.AreEqual(3, scene.GetSrcObjectCount());

            Assert.AreEqual(4, node.GetSrcObjectCount());
            Assert.AreSame(m1, node.GetSrcObject(0));
            Assert.AreSame(m2, node.GetSrcObject(1));
            Assert.AreSame(v, node.GetSrcObject(2));
            Assert.AreSame(c, node.GetSrcObject(3));
            Assert.AreEqual(0, node.GetDstObjectCount());
            Assert.Null(node.GetScene());

            Assert.AreEqual(0, m1.GetSrcObjectCount());
            Assert.AreEqual(1, m1.GetDstObjectCount());
            Assert.AreSame(node, m1.GetDstObject(0));
            Assert.Null(m1.GetScene());

            Assert.AreEqual(0, m2.GetSrcObjectCount());
            Assert.AreEqual(1, m2.GetDstObjectCount());
            Assert.AreSame(node, m2.GetDstObject(0));
            Assert.Null(m2.GetScene());

            Assert.AreEqual(0, v.GetSrcObjectCount());
            Assert.AreEqual(1, v.GetDstObjectCount());
            Assert.AreSame(node, v.GetDstObject(0));
            Assert.Null(v.GetScene());

            Assert.AreEqual(1, c.GetSrcObjectCount());
            Assert.AreSame(n2, c.GetSrcObject());;
            Assert.AreEqual(1, c.GetDstObjectCount());
            Assert.AreSame(node, c.GetDstObject(0));
            Assert.Null(c.GetScene());

            Assert.AreEqual(1, n2.GetSrcObjectCount());
            Assert.AreSame(c2, n2.GetSrcObject());;
            Assert.AreEqual(1, n2.GetDstObjectCount());
            Assert.AreSame(c, n2.GetDstObject(0));
            Assert.Null(n2.GetScene());

            Assert.AreEqual(0, c2.GetSrcObjectCount());
            Assert.AreEqual(1, c2.GetDstObjectCount());
            Assert.AreSame(n2, c2.GetDstObject(0));
            Assert.Null(c2.GetScene());

            // when:
            scene.ConnectSrcObject(node);

            // then:
            Assert.AreEqual(10, scene.GetSrcObjectCount());
            Assert.AreSame(node, scene.GetSrcObject(3));
            Assert.AreSame(m1, scene.GetSrcObject(4));
            Assert.AreSame(m2, scene.GetSrcObject(5));
            Assert.AreSame(v, scene.GetSrcObject(6));
            Assert.AreSame(c, scene.GetSrcObject(7));
            Assert.AreSame(n2, scene.GetSrcObject(8));
            Assert.AreSame(c2, scene.GetSrcObject(9));

            Assert.AreEqual(4, node.GetSrcObjectCount());
            Assert.AreSame(m1, node.GetSrcObject(0));
            Assert.AreSame(m2, node.GetSrcObject(1));
            Assert.AreSame(v, node.GetSrcObject(2));
            Assert.AreSame(c, node.GetSrcObject(3));
            Assert.AreEqual(1, node.GetDstObjectCount());
            Assert.AreSame(scene, node.GetDstObject(0));
            Assert.AreSame(scene, node.GetScene());

            Assert.AreEqual(0, m1.GetSrcObjectCount());
            Assert.AreEqual(2, m1.GetDstObjectCount());
            Assert.AreSame(node, m1.GetDstObject(0));
            Assert.AreSame(scene, m1.GetDstObject(1));
            Assert.AreSame(scene, m1.GetScene());

            Assert.AreEqual(0, m2.GetSrcObjectCount());
            Assert.AreEqual(2, m2.GetDstObjectCount());
            Assert.AreSame(node, m2.GetDstObject(0));
            Assert.AreSame(scene, m2.GetDstObject(1));
            Assert.AreSame(scene, m2.GetScene());

            Assert.AreEqual(0, v.GetSrcObjectCount());
            Assert.AreEqual(2, v.GetDstObjectCount());
            Assert.AreSame(node, v.GetDstObject(0));
            Assert.AreSame(scene, v.GetDstObject(1));
            Assert.AreSame(scene, v.GetScene());

            Assert.AreEqual(1, c.GetSrcObjectCount());
            Assert.AreSame(n2, c.GetSrcObject(0));
            Assert.AreEqual(2, c.GetDstObjectCount());
            Assert.AreSame(node, c.GetDstObject(0));
            Assert.AreSame(scene, c.GetDstObject(1));
            Assert.AreSame(scene, c.GetScene());

            Assert.AreEqual(1, n2.GetSrcObjectCount());
            Assert.AreSame(c2, n2.GetSrcObject());;
            Assert.AreEqual(2, n2.GetDstObjectCount());
            Assert.AreSame(c, n2.GetDstObject(0));
            Assert.AreSame(scene, n2.GetDstObject(1));
            Assert.AreSame(scene, n2.GetScene());

            Assert.AreEqual(0, c2.GetSrcObjectCount());
            Assert.AreEqual(2, c2.GetDstObjectCount());
            Assert.AreSame(n2, c2.GetDstObject(0));
            Assert.AreSame(scene, c2.GetDstObject(1));
            Assert.AreSame(scene, c2.GetScene());
        }