예제 #1
0
            /// <summary>
            /// Export an AnimationCurve.
            /// NOTE: This is not used for rotations, because we need to convert from
            /// quaternion to euler and various other stuff.
            /// </summary>
            protected void ExportAnimCurve(UnityEngine.Object unityObj,
                                           AnimationCurve unityAnimCurve,
                                           string unityPropertyName,
                                           FbxScene fbxScene,
                                           FbxAnimLayer fbxAnimLayer)
            {
                FbxPropertyChannelPair fbxPropertyChannelPair;

                if (!FbxPropertyChannelPair.TryGetValue(unityPropertyName, out fbxPropertyChannelPair))
                {
                    Debug.LogWarning(string.Format("no mapping from Unity '{0}' to fbx property", unityPropertyName));
                    return;
                }

                GameObject unityGo = GetGameObject(unityObj);

                if (unityGo == null)
                {
                    Debug.LogError(string.Format("cannot find gameobject for {0}", unityObj.ToString()));
                    return;
                }

                FbxNode fbxNode;

                if (!MapUnityObjectToFbxNode.TryGetValue(unityGo, out fbxNode))
                {
                    Debug.LogError(string.Format("no fbx node for {0}", unityGo.ToString()));
                    return;
                }

                // map unity property name to fbx property
                var fbxProperty = fbxNode.FindProperty(fbxPropertyChannelPair.Property, false);

                if (!fbxProperty.IsValid())
                {
                    Debug.LogError(string.Format("no fbx property {0} found on {1} ", fbxPropertyChannelPair.Property, fbxNode.GetName()));
                    return;
                }

                if (Verbose)
                {
                    Debug.Log("Exporting animation for " + unityObj.ToString() + " (" + unityPropertyName + ")");
                }

                // Create the AnimCurve on the channel
                FbxAnimCurve fbxAnimCurve = fbxProperty.GetCurve(fbxAnimLayer, fbxPropertyChannelPair.Channel, true);

                // copy Unity AnimCurve to FBX AnimCurve.
                fbxAnimCurve.KeyModifyBegin();

                for (int keyIndex = 0, n = unityAnimCurve.length; keyIndex < n; ++keyIndex)
                {
                    var key     = unityAnimCurve [keyIndex];
                    var fbxTime = FbxTime.FromSecondDouble(key.time);
                    fbxAnimCurve.KeyAdd(fbxTime);
                    fbxAnimCurve.KeySet(keyIndex, fbxTime, key.value);
                }

                fbxAnimCurve.KeyModifyEnd();
            }
예제 #2
0
        public FbxAnimCurve GetCurve(FbxAnimLayer pAnimLayer, string pName, string pChannel, bool pCreate)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxProperty_GetCurve__SWIG_4(swigCPtr, FbxAnimLayer.getCPtr(pAnimLayer), pName, pChannel, pCreate);
            FbxAnimCurve          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimCurve(cPtr, false);

            return(ret);
        }
예제 #3
0
        protected override FbxAnimStack GenerateFbx()
        {
            HavokAnimationData anim = Souls.dsAnimation;

            IDictionary <int, FrameData> frameDatas = ExtractAnimationData(anim);

            var animStack = FbxAnimStack.Create(Scene, anim.Name + "_AnimStack");

            animStack.SetLocalTimeSpan(new FbxTimeSpan(FbxTime.FromFrame(0), FbxTime.FromFrame(anim.FrameCount)));

            FbxAnimLayer animLayer = FbxAnimLayer.Create(animStack, "Layer0");

            animStack.AddMember(animLayer);

            IDictionary <int, AnimExportHelper> boneHelpers = new Dictionary <int, AnimExportHelper>();

            foreach (DsBoneData boneData in Souls.skeleton.boneDatas)
            {
                boneData.exportData.FbxNode.LclTranslation.GetCurveNode(animLayer, true);
                boneData.exportData.FbxNode.LclRotation.GetCurveNode(animLayer, true);
                boneData.exportData.FbxNode.LclScaling.GetCurveNode(animLayer, true);

                boneHelpers.Add(boneData.exportData.SoulsData.HkxBoneIndex, new AnimExportHelper(
                                    animLayer,
                                    boneData.exportData.FbxNode.LclTranslation,
                                    boneData.exportData.FbxNode.LclRotation,
                                    boneData.exportData.FbxNode.LclScaling
                                    )
                                );
            }

            foreach (var frameData in frameDatas)
            {
                FbxTime time = FbxTime.FromFrame(frameData.Key);

                foreach (var boneData in frameData.Value.boneDatas)
                {
                    int hkxBoneIndex = boneData.hkxBoneIndex;

                    var newBlendableTransform = boneData.transform;

                    AnimExportHelper animExportHelper = boneHelpers[hkxBoneIndex];

                    var euler = new Quaternion(newBlendableTransform.Rotation.X, newBlendableTransform.Rotation.Y, newBlendableTransform.Rotation.Z, newBlendableTransform.Rotation.W).QuaternionToEuler();

                    animExportHelper.translation.AddPoint(time, newBlendableTransform.Translation);
                    animExportHelper.rotation.AddPoint(time, euler);
                    animExportHelper.scale.AddPoint(time, newBlendableTransform.Scale);
                }
            }

            foreach (AnimExportHelper helper in boneHelpers.Values)
            {
                helper.translation.Finish();
                helper.rotation.Finish();
                helper.scale.Finish();
            }

            return(null);
        }
예제 #4
0
        public static FbxAnimLayer Cast(FbxObject arg0)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxAnimLayer_Cast(FbxObject.getCPtr(arg0));
            FbxAnimLayer          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimLayer(cPtr, false);

            return(ret);
        }
예제 #5
0
        public new static FbxAnimLayer Create(FbxObject pContainer, string pName)
        {
            global::System.IntPtr cPtr = fbx_wrapperPINVOKE.FbxAnimLayer_Create__SWIG_1(FbxObject.getCPtr(pContainer), pName);
            FbxAnimLayer          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimLayer(cPtr, false);

            return(ret);
        }
예제 #6
0
        public new static FbxAnimLayer Create(FbxManager pManager, string pName)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxAnimLayer_Create__SWIG_0(FbxManager.getCPtr(pManager), pName);
            FbxAnimLayer          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimLayer(cPtr, false);

            return(ret);
        }
예제 #7
0
        public static void GenericTests<T>(T fbxCollection, FbxManager manager) where T : FbxCollection
        {
            // TODO: FbxScene has a member count of 3 instead of one (even after clearing), is this normal?
            int initialMemberCount = fbxCollection.GetMemberCount ();

            // test AddMember
            FbxObject obj = FbxObject.Create (manager, "");
            bool result = fbxCollection.AddMember (obj);
            Assert.IsTrue (result);
            Assert.AreEqual(initialMemberCount+1, fbxCollection.GetMemberCount());

            // test Clear
            fbxCollection.Clear ();
            Assert.AreEqual (initialMemberCount, fbxCollection.GetMemberCount());

            // test GetAnimLayerMember()
            fbxCollection.AddMember(FbxAnimLayer.Create(manager, "animLayer"));
            var animLayer = fbxCollection.GetAnimLayerMember ();
            Assert.IsInstanceOf<FbxAnimLayer> (animLayer);

            var animLayer2 = fbxCollection.GetAnimLayerMember (0);

            Assert.AreEqual (animLayer, animLayer2);

            // check invalid
            Assert.IsNull(fbxCollection.GetAnimLayerMember (1));
            Assert.IsNull(fbxCollection.GetAnimLayerMember (-1));
        }
        protected override void CheckScene(FbxScene scene)
        {
            FbxScene origScene = CreateScene(FbxManager);

            FbxNode origAnimNode   = origScene.GetRootNode().GetChild(0);
            FbxNode importAnimNode = scene.GetRootNode().GetChild(0);

            Assert.AreEqual(origScene.GetRootNode().GetChildCount(), scene.GetRootNode().GetChildCount());
            Assert.IsNotNull(origAnimNode);
            Assert.IsNotNull(importAnimNode);
            Assert.AreEqual(origAnimNode.GetName(), importAnimNode.GetName());

            FbxAnimStack origStack   = origScene.GetCurrentAnimationStack();
            FbxAnimStack importStack = scene.GetCurrentAnimationStack();

            CheckAnimStack(origStack, importStack);

            FbxAnimLayer origLayer   = origStack.GetAnimLayerMember();
            FbxAnimLayer importLayer = importStack.GetAnimLayerMember();

            Assert.IsNotNull(origLayer);
            Assert.IsNotNull(importLayer);

            Assert.AreEqual(FbxTime.EMode.eFrames30, scene.GetGlobalSettings().GetTimeMode());

            CheckAnimCurve(origAnimNode, importAnimNode, origLayer, importLayer, PropertyComponentList);
        }
        public void Animate(Transform unityTransform, FbxNode fbxNode, FbxAnimLayer fbxAnimLayer, bool Verbose)
        {
            if (!unityTransform || fbxNode == null)
            {
                return;
            }

            /* Find or create the three curves. */
            var fbxAnimCurveX = fbxNode.LclRotation.GetCurve(fbxAnimLayer, Globals.FBXSDK_CURVENODE_COMPONENT_X, true);
            var fbxAnimCurveY = fbxNode.LclRotation.GetCurve(fbxAnimLayer, Globals.FBXSDK_CURVENODE_COMPONENT_Y, true);
            var fbxAnimCurveZ = fbxNode.LclRotation.GetCurve(fbxAnimLayer, Globals.FBXSDK_CURVENODE_COMPONENT_Z, true);

            /* set the keys */
            using (new FbxAnimCurveModifyHelper(new List <FbxAnimCurve> {
                fbxAnimCurveX, fbxAnimCurveY, fbxAnimCurveZ
            }))
            {
                foreach (var key in ComputeKeys(unityTransform.localRotation, fbxNode))
                {
                    int i = fbxAnimCurveX.KeyAdd(key.time);
                    fbxAnimCurveX.KeySet(i, key.time, (float)key.euler.X);

                    i = fbxAnimCurveY.KeyAdd(key.time);
                    fbxAnimCurveY.KeySet(i, key.time, (float)key.euler.Y);

                    i = fbxAnimCurveZ.KeyAdd(key.time);
                    fbxAnimCurveZ.KeySet(i, key.time, (float)key.euler.Z);
                }
            }

            if (Verbose)
            {
                Debug.Log("Exported rotation animation for " + fbxNode.GetName());
            }
        }
예제 #10
0
        public FbxAnimCurve GetCurve(FbxAnimLayer pAnimLayer)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxProperty_GetCurve__SWIG_1(swigCPtr, FbxAnimLayer.getCPtr(pAnimLayer));
            FbxAnimCurve          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimCurve(cPtr, false);

            return(ret);
        }
        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 animNode = FbxNode.Create(scene, "animNode");

            // 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(
                animNode, fbxAnimLayer, PropertyComponentList, (index) => { return(index * 2.0); }, (index) => { return(index * 3.0f - 1); }
                );

            // TODO: avoid needing to 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);
            scene.GetRootNode().AddChild(animNode);
            return(scene);
        }
예제 #12
0
        public void FbxAnimLayer_Create_HasNamespacePrefix()
        {
            // given:
            var obj = new FbxAnimLayer("asdf");

            // then:
            Assert.AreEqual("AnimLayer::", obj.GetNameSpacePrefix());
        }
예제 #13
0
 public bool Equals(FbxAnimLayer other)
 {
     if (object.ReferenceEquals(other, null))
     {
         return(false);
     }
     return(this.swigCPtr.Handle.Equals(other.swigCPtr.Handle));
 }
예제 #14
0
            /// <summary>
            /// Exports all animation
            /// </summary>
            private void ExportAnimationClip(AnimationClip unityAnimClip, GameObject unityRoot, FbxScene fbxScene)
            {
                if (unityAnimClip == null)
                {
                    return;
                }

                // setup anim stack
                FbxAnimStack fbxAnimStack = FbxAnimStack.Create(fbxScene, unityAnimClip.name);

                fbxAnimStack.Description.Set("Animation Take: " + unityAnimClip.name);

                // add one mandatory animation layer
                FbxAnimLayer fbxAnimLayer = FbxAnimLayer.Create(fbxScene, "Animation Base Layer");

                fbxAnimStack.AddMember(fbxAnimLayer);

                // Set up the FPS so our frame-relative math later works out
                // Custom frame rate isn't really supported in FBX SDK (there's
                // a bug), so try hard to find the nearest time mode.
                FbxTime.EMode timeMode  = FbxTime.EMode.eCustom;
                double        precision = 1e-6;

                while (timeMode == FbxTime.EMode.eCustom && precision < 1000)
                {
                    timeMode   = FbxTime.ConvertFrameRateToTimeMode(unityAnimClip.frameRate, precision);
                    precision *= 10;
                }
                if (timeMode == FbxTime.EMode.eCustom)
                {
                    timeMode = FbxTime.EMode.eFrames30;
                }
                FbxTime.SetGlobalTimeMode(timeMode);

                // set time correctly
                var fbxStartTime = FbxTime.FromSecondDouble(0);
                var fbxStopTime  = FbxTime.FromSecondDouble(unityAnimClip.length);

                fbxAnimStack.SetLocalTimeSpan(new FbxTimeSpan(fbxStartTime, fbxStopTime));

                foreach (EditorCurveBinding unityCurveBinding in AnimationUtility.GetCurveBindings(unityAnimClip))
                {
                    Object unityObj = AnimationUtility.GetAnimatedObject(unityRoot, unityCurveBinding);
                    if (!unityObj)
                    {
                        continue;
                    }

                    AnimationCurve unityAnimCurve = AnimationUtility.GetEditorCurve(unityAnimClip, unityCurveBinding);
                    if (unityAnimCurve == null)
                    {
                        continue;
                    }

                    ExportAnimCurve(unityObj, unityAnimCurve, unityCurveBinding.propertyName, fbxAnimLayer);
                }
            }
예제 #15
0
                public AnimExportHelperHelper(FbxAnimLayer animLayer, FbxPropertyDouble3 node)
                {
                    curveX = node.GetCurve(animLayer, Globals.FBXSDK_CURVENODE_COMPONENT_X, /*pCreate =*/ true);
                    curveY = node.GetCurve(animLayer, Globals.FBXSDK_CURVENODE_COMPONENT_Y, /*pCreate =*/ true);
                    curveZ = node.GetCurve(animLayer, Globals.FBXSDK_CURVENODE_COMPONENT_Z, /*pCreate =*/ true);

                    curveX.KeyModifyBegin();
                    curveY.KeyModifyBegin();
                    curveZ.KeyModifyBegin();
                }
예제 #16
0
        public FbxAnimCurve GetCurve(FbxAnimLayer pAnimLayer, string pName, string pChannel, bool pCreate)
        {
            global::System.IntPtr cPtr = NativeMethods.FbxProperty_GetCurve__SWIG_4(swigCPtr, FbxAnimLayer.getCPtr(pAnimLayer), pName, pChannel, pCreate);
            FbxAnimCurve          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimCurve(cPtr, false);

            if (NativeMethods.SWIGPendingException.Pending)
            {
                throw NativeMethods.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #17
0
        public FbxAnimCurveNode GetPropertyCurveNode(FbxProperty pProperty, FbxAnimLayer pAnimLayer)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxAnimEvaluator_GetPropertyCurveNode(swigCPtr, FbxProperty.getCPtr(pProperty), FbxAnimLayer.getCPtr(pAnimLayer));
            FbxAnimCurveNode      ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimCurveNode(cPtr, false);

            if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending)
            {
                throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #18
0
        public FbxAnimCurveNode GetCurveNode(FbxAnimLayer pAnimLayer)
        {
            global::System.IntPtr cPtr = NativeMethods.FbxProperty_GetCurveNode__SWIG_5(swigCPtr, FbxAnimLayer.getCPtr(pAnimLayer));
            FbxAnimCurveNode      ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimCurveNode(cPtr, false);

            if (NativeMethods.SWIGPendingException.Pending)
            {
                throw NativeMethods.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #19
0
        public new static FbxAnimLayer Create(FbxObject pContainer, string pName)
        {
            global::System.IntPtr cPtr = NativeMethods.FbxAnimLayer_Create__SWIG_1(FbxObject.getCPtr(pContainer), pName);
            FbxAnimLayer          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimLayer(cPtr, false);

            if (NativeMethods.SWIGPendingException.Pending)
            {
                throw NativeMethods.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
        public FbxAnimLayer GetAnimLayerMember()
        {
            global::System.IntPtr cPtr = NativeMethods.FbxCollection_GetAnimLayerMember__SWIG_1(swigCPtr);
            FbxAnimLayer          ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxAnimLayer(cPtr, false);

            if (NativeMethods.SWIGPendingException.Pending)
            {
                throw NativeMethods.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #21
0
        protected override FbxScene CreateScene(FbxManager manager)
        {
            FbxScene scene     = base.CreateScene(manager);
            FbxNode  lightNode = scene.GetRootNode().GetChild(0);

            FbxLight light = FbxLight.Create(scene, "light");

            light.LightType.Set(FbxLight.EType.eSpot);

            light.InnerAngle.Set(20);
            light.OuterAngle.Set(95);

            // Export bounceIntensity as custom property
            ExportFloatProperty(lightNode, 3, "bounceIntensity");

            light.Color.Set(new FbxDouble3(0.3, 0.1, 0.75));

            // Export colorTemperature as custom property
            ExportFloatProperty(lightNode, 6, "colorTemperature");

            light.FileName.Set("/path/to/texture.png");
            light.DrawGroundProjection.Set(true);
            light.DrawVolumetricLight.Set(true);
            light.DrawFrontFacingVolumetricLight.Set(false);

            ExportFloatProperty(lightNode, 4.2f, "cookieSize");

            light.Intensity.Set(120);
            light.FarAttenuationStart.Set(0.01f /* none zero start */);
            light.FarAttenuationEnd.Set(9.8f);
            light.CastShadows.Set(true);

            FbxAnimStack animStack = scene.GetCurrentAnimationStack();
            FbxAnimLayer animLayer = animStack.GetAnimLayerMember();

            // TODO: (UNI-19438) figure out why trying to add anim curves to FbxNodeAttribute.sColor,
            //          Intensity and InnerAngle fails
            // add animation
            CreateAnimCurves(lightNode, animLayer, new List <PropertyComponentPair> ()
            {
                new PropertyComponentPair("colorTemperature", new string[] { null }),
                new PropertyComponentPair("cookieSize", new string[] { null })
            }, (index) => { return((index + 1) / 2.0); }, (index) => { return(index % 2); });

            // set ambient lighting
            scene.GetGlobalSettings().SetAmbientColor(new FbxColor(0.1, 0.2, 0.3));

            lightNode.SetNodeAttribute(light);
            scene.GetRootNode().AddChild(lightNode);
            return(scene);
        }
예제 #22
0
        public AnimationTrackInfo(FbxAnimStack pAnimStack, FbxNode pRootNode)
        {
            Name = pAnimStack.GetName();
            //Duration = GetAnimationMaxTime(pRootNode, pAnimStack);

            int animLayersNum = FbxExtensions.GetAnimLayerCount(pAnimStack);

            mLayers = new List <FbxAnimLayer>();
            for (int j = 0; j < animLayersNum; j++)
            {
                FbxAnimLayer pAnimLayer = FbxExtensions.GetAnimLayer(pAnimStack, j);
                mLayers.Add(pAnimLayer);
            }
        }
예제 #23
0
        protected override void CheckScene(FbxScene scene)
        {
            base.CheckScene(scene);
            FbxScene origScene = CreateScene(FbxManager);

            FbxNode origLightNode   = origScene.GetRootNode().GetChild(0);
            FbxNode importLightNode = scene.GetRootNode().GetChild(0);

            Assert.IsNotNull(origLightNode);
            Assert.IsNotNull(importLightNode);

            FbxLight origLight   = origLightNode.GetLight();
            FbxLight importLight = importLightNode.GetLight();

            Assert.IsNotNull(origLight);
            Assert.IsNotNull(importLight);

            Assert.AreEqual(origLight.GetName(), importLight.GetName());

            // Check properties
            CheckProperties(
                origLightNode, importLightNode,
                origLight, importLight,
                new string[] { "bounceIntensity", "colorTemperature", "cookieSize" }
                );

            // Check anim
            FbxAnimStack origAnimStack = origScene.GetCurrentAnimationStack();
            FbxAnimLayer origAnimLayer = origAnimStack.GetAnimLayerMember();

            Assert.IsNotNull(origAnimStack);
            Assert.IsNotNull(origAnimLayer);

            FbxAnimStack importAnimStack = scene.GetCurrentAnimationStack();
            FbxAnimLayer importAnimLayer = importAnimStack.GetAnimLayerMember();

            Assert.IsNotNull(importAnimStack);
            Assert.IsNotNull(importAnimLayer);

            // TODO: (UNI-19438) figure out why trying to add anim curves to FbxNodeAttribute.sColor,
            //                  Intensity and InnerAngle fails
            CheckAnimCurve(origLightNode, importLightNode, origAnimLayer, importAnimLayer, new List <PropertyComponentPair>()
            {
                new PropertyComponentPair("colorTemperature", new string[] { null }),
                new PropertyComponentPair("cookieSize", new string[] { null })
            }, origLight, importLight);
        }
예제 #24
0
        protected override void CheckScene(FbxScene scene)
        {
            FbxScene origScene = CreateScene(FbxManager);

            Assert.That(origScene.GetRootNode().GetChildCount(), Is.EqualTo(scene.GetRootNode().GetChildCount()));

            // check nodes match
            FbxNode origSourceNode      = origScene.GetRootNode().GetChild(0);
            FbxNode origConstrainedNode = origScene.GetRootNode().GetChild(1);

            FbxNode importSourceNode      = scene.GetRootNode().GetChild(0);
            FbxNode importConstrainedNode = scene.GetRootNode().GetChild(1);

            Assert.That(origSourceNode, Is.Not.Null);
            Assert.That(importSourceNode, Is.Not.Null);
            Assert.That(origConstrainedNode, Is.Not.Null);
            Assert.That(importConstrainedNode, Is.Not.Null);
            Assert.That(importSourceNode.GetName(), Is.EqualTo(origSourceNode.GetName()));
            Assert.That(importConstrainedNode.GetName(), Is.EqualTo(origConstrainedNode.GetName()));

            // check constraints match
            // TODO: find a way to cast to FbxConstraint
            Assert.That(scene.GetSrcObjectCount(), Is.EqualTo(origScene.GetSrcObjectCount()));
            FbxObject origPosConstraint   = origScene.FindSrcObject(ConstraintName);
            FbxObject importPosConstraint = scene.FindSrcObject(ConstraintName);

            Assert.That(origPosConstraint, Is.Not.Null);
            Assert.That(importPosConstraint, Is.Not.Null);
            Assert.That(importPosConstraint.GetName(), Is.EqualTo(origPosConstraint.GetName()));

            // check animation matches
            FbxAnimStack origStack   = origScene.GetCurrentAnimationStack();
            FbxAnimStack importStack = scene.GetCurrentAnimationStack();

            CheckAnimStack(origStack, importStack);

            FbxAnimLayer origLayer   = origStack.GetAnimLayerMember();
            FbxAnimLayer importLayer = importStack.GetAnimLayerMember();

            Assert.That(origLayer, Is.Not.Null);
            Assert.That(importLayer, Is.Not.Null);

            Assert.That(scene.GetGlobalSettings().GetTimeMode(), Is.EqualTo(FbxTime.EMode.eFrames30));

            CheckAnimCurve(origPosConstraint, importPosConstraint, origLayer, importLayer, PropertyComponentList);
        }
예제 #25
0
        protected override void CheckScene(FbxScene scene)
        {
            base.CheckScene(scene);

            FbxScene origScene = CreateScene(FbxManager);

            FbxNode origCameraNode   = origScene.GetRootNode().GetChild(0);
            FbxNode importCameraNode = scene.GetRootNode().GetChild(0);

            Assert.IsNotNull(origCameraNode);
            Assert.IsNotNull(importCameraNode);

            Assert.AreEqual(origScene.GetGlobalSettings().GetDefaultCamera(), scene.GetGlobalSettings().GetDefaultCamera());

            FbxCamera origCamera   = origCameraNode.GetCamera();
            FbxCamera importCamera = importCameraNode.GetCamera();

            Assert.IsNotNull(origCamera);
            Assert.IsNotNull(importCamera);

            CheckCameraSettings(origCamera, importCamera, origCameraNode, importCameraNode);

            // check anim
            FbxAnimStack origAnimStack = origScene.GetCurrentAnimationStack();
            FbxAnimLayer origAnimLayer = origAnimStack.GetAnimLayerMember();

            Assert.IsNotNull(origAnimStack);
            Assert.IsNotNull(origAnimLayer);

            FbxAnimStack importAnimStack = scene.GetCurrentAnimationStack();
            FbxAnimLayer importAnimLayer = importAnimStack.GetAnimLayerMember();

            Assert.IsNotNull(importAnimStack);
            Assert.IsNotNull(importAnimLayer);

            CheckAnimCurve(origCameraNode, importCameraNode, origAnimLayer, importAnimLayer, new List <PropertyComponentPair>()
            {
                new PropertyComponentPair("backgroundColor", new string[] {
                    Globals.FBXSDK_CURVENODE_COLOR_RED,
                    Globals.FBXSDK_CURVENODE_COLOR_GREEN,
                    Globals.FBXSDK_CURVENODE_COLOR_BLUE, "W"
                }),
                new PropertyComponentPair("FocalLength", new string[] { null }),
                new PropertyComponentPair("clearFlags", new string[] { null })
            }, origCamera, importCamera);
        }
예제 #26
0
        //ToDo : ??? Только для одного Layer грузить? Хотя у Layers должны быть одинаковые отсчеты времени, если они должны смешиваться?
        static void LoadKeyFrames(AnimationTrackInfo animationTrack,
                                  FbxPropertyTFbxDouble3 transformProperty,
                                  HashSet <double> keyFrames, string xChannelName,
                                  string yChannelName, string zChannelName)
        {
            for (int i = 0; i < animationTrack.GetLayerCount(); i++)
            {
                FbxAnimLayer pAnimLayer = animationTrack.GetLayer(i);
                FbxAnimCurve pAnimCurve = null;

                pAnimCurve = transformProperty.GetCurve(pAnimLayer, xChannelName);
                if (pAnimCurve != null)
                {
                    for (int j = 0; j < pAnimCurve.KeyGetCount(); j++)
                    {
                        FbxAnimCurveKey key = pAnimCurve.KeyGet(j);
                        //ToDo :? Учитывать key.GetInterpolation();
                        double time = key.GetTime().GetSecondDouble();
                        keyFrames.Add(time);
                    }
                }

                pAnimCurve = transformProperty.GetCurve(pAnimLayer, yChannelName);
                if (pAnimCurve != null)
                {
                    for (int j = 0; j < pAnimCurve.KeyGetCount(); j++)
                    {
                        FbxAnimCurveKey key  = pAnimCurve.KeyGet(j);
                        double          time = key.GetTime().GetSecondDouble();
                        keyFrames.Add(time);
                    }
                }

                pAnimCurve = transformProperty.GetCurve(pAnimLayer, zChannelName);
                if (pAnimCurve != null)
                {
                    for (int j = 0; j < pAnimCurve.KeyGetCount(); j++)
                    {
                        FbxAnimCurveKey key  = pAnimCurve.KeyGet(j);
                        double          time = key.GetTime().GetSecondDouble();
                        keyFrames.Add(time);
                    }
                }
            }
        }
예제 #27
0
        AnimationLayer LoadLayer(FbxNode node, FbxAnimLayer animLayer, double[] keyTimes)
        {
            //ToDo : animLayer.BlendMode
            var ret = new AnimationLayer();

            ret.Name      = animLayer.GetName();
            ret.Transform = new KeyFrame[keyTimes.Length];
            for (int i = 0; i < keyTimes.Length; i++)
            {
                var t = new FbxTime();
                t.SetSecondDouble(keyTimes[i]);
                var transform = node.EvaluateLocalTransform(t);
                ret.Transform[i] = new KeyFrame {
                    TimeInSeconds = keyTimes[i], Value = transform.ToMatrix4()
                };
            }
            return(ret);
        }
예제 #28
0
    void CorrectAnimTrackInterpolation(ref List <FbxNode> BoneNodes, FbxAnimLayer InAnimLayer)
    {
        // Add the animation data to the bone nodes
        for (int BoneIndex = 0; BoneIndex < BoneNodes.Count; ++BoneIndex)
        {
            FbxNode CurrentBoneNode = BoneNodes[BoneIndex];

            // Fetch the AnimCurves
            FbxAnimCurve[] Curves = new FbxAnimCurve[3];
            Curves[0] = CurrentBoneNode.LclRotation.GetCurve(InAnimLayer, "X", true);
            Curves[1] = CurrentBoneNode.LclRotation.GetCurve(InAnimLayer, "Y", true);
            Curves[2] = CurrentBoneNode.LclRotation.GetCurve(InAnimLayer, "Z", true);

            for (int CurveIndex = 0; CurveIndex < 3; ++CurveIndex)
            {
                FbxAnimCurve CurrentCurve = Curves[CurveIndex];
                CurrentCurve.KeyModifyBegin();

                float CurrentAngleOffset = 0.0f;
                for (int KeyIndex = 1; KeyIndex < CurrentCurve.KeyGetCount(); ++KeyIndex)
                {
                    float PreviousOutVal = CurrentCurve.KeyGetValue(KeyIndex - 1);
                    float CurrentOutVal  = CurrentCurve.KeyGetValue(KeyIndex);

                    float DeltaAngle = (CurrentOutVal + CurrentAngleOffset) - PreviousOutVal;

                    if (DeltaAngle >= 180)
                    {
                        CurrentAngleOffset -= 360;
                    }
                    else if (DeltaAngle <= -180)
                    {
                        CurrentAngleOffset += 360;
                    }

                    CurrentOutVal += CurrentAngleOffset;

                    CurrentCurve.KeySetValue(KeyIndex, CurrentOutVal);
                }

                CurrentCurve.KeyModifyEnd();
            }
        }
    }
        protected void CheckAnimCurve(
            FbxObject origAnimObject, FbxObject importAnimObject,
            FbxAnimLayer origLayer, FbxAnimLayer importLayer,
            List <PropertyComponentPair> propCompPairs,
            FbxNodeAttribute origNodeAttr = null, FbxNodeAttribute importNodeAttr = null)
        {
            foreach (var pair in propCompPairs)
            {
                FbxProperty origProperty = origAnimObject.FindProperty(pair.propertyName, false);
                if (origNodeAttr != null && (origProperty == null || !origProperty.IsValid()))
                {
                    origProperty = origNodeAttr.FindProperty(pair.propertyName, false);
                }
                FbxProperty importProperty = importAnimObject.FindProperty(pair.propertyName, false);
                if (importNodeAttr != null && (importProperty == null || !importProperty.IsValid()))
                {
                    importProperty = importNodeAttr.FindProperty(pair.propertyName, false);
                }

                Assert.IsNotNull(origProperty);
                Assert.IsNotNull(importProperty);
                Assert.IsTrue(origProperty.IsValid());
                Assert.IsTrue(importProperty.IsValid());

                foreach (var component in pair.componentList)
                {
                    FbxAnimCurve origAnimCurve   = origProperty.GetCurve(origLayer, component, false);
                    FbxAnimCurve importAnimCurve = importProperty.GetCurve(importLayer, component, false);

                    Assert.IsNotNull(origAnimCurve);
                    Assert.IsNotNull(importAnimCurve);

                    Assert.AreEqual(origAnimCurve.KeyGetCount(), importAnimCurve.KeyGetCount());

                    for (int i = 0; i < origAnimCurve.KeyGetCount(); i++)
                    {
                        Assert.AreEqual(origAnimCurve.KeyGetTime(i), importAnimCurve.KeyGetTime(i));
                        Assert.AreEqual(origAnimCurve.KeyGetValue(i), importAnimCurve.KeyGetValue(i));
                    }
                }
            }
        }
예제 #30
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);
        }