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);
        }
            /// <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);
                }
            }
Example #3
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);
        }
Example #4
0
    public void CreateDocument()
    {
        Scene = FbxScene.Create(SdkManager, "");

        FbxDocumentInfo SceneInfo = FbxDocumentInfo.Create(SdkManager, "SceneInfo");

        SceneInfo.mTitle   = new FbxString("Unreal FBX Exporter");
        SceneInfo.mSubject = new FbxString("Export FBX meshes from Unreal");
        SceneInfo.Original_ApplicationVendor.Set(new FbxString("Epic Games"));
        SceneInfo.Original_ApplicationName.Set(new FbxString("Unreal Engine"));
        SceneInfo.Original_ApplicationVersion.Set(new FbxString("4.18"));
        SceneInfo.LastSaved_ApplicationVendor.Set(new FbxString("Epic Games"));
        SceneInfo.LastSaved_ApplicationName.Set(new FbxString("Unreal Engine"));
        SceneInfo.LastSaved_ApplicationVersion.Set(new FbxString("4.18"));

        FbxAxisSystem.EFrontVector FrontVector = (FbxAxisSystem.EFrontVector)(0 - FbxAxisSystem.EFrontVector.eParityOdd);
        if (bForceFrontXAxis)
        {
            FrontVector = FbxAxisSystem.EFrontVector.eParityEven;
        }

        FbxAxisSystem UnrealZUp = new FbxAxisSystem(FbxAxisSystem.EUpVector.eZAxis, FrontVector, FbxAxisSystem.ECoordSystem.eRightHanded);

        //const FbxAxisSystem UnrealZUp(FbxAxisSystem.EUpVector, FrontVector, FbxAxisSystem::eRightHanded);
        Scene.GetGlobalSettings().SetAxisSystem(FbxAxisSystem.Max);
        Scene.GetGlobalSettings().SetOriginalUpAxis(FbxAxisSystem.Max);
        Scene.GetGlobalSettings().SetSystemUnit(FbxSystemUnit.cm);

        Scene.SetSceneInfo(SceneInfo);

        // setup anim stack
        AnimStack = FbxAnimStack.Create(Scene, "Unreal Take");
        //KFbxSet<KTime>(AnimStack.LocalStart, KTIME_ONE_SECOND);
        AnimStack.Description.Set((new FbxString("Animation Take for Unreal.")));

        // this take contains one base layer. In fact having at least one layer is mandatory.
        AnimLayer = FbxAnimLayer.Create(Scene, "Base Layer");
        AnimStack.AddMember(AnimLayer);
        //if(Mathf)
    }
            /// <summary>
            /// Export an AnimationClip as a single take
            /// </summary>
            protected void ExportAnimationClip(AnimationClip unityAnimClip, GameObject unityRoot, FbxScene fbxScene)
            {
                if (Verbose)
                {
                    Debug.Log(string.Format("exporting clip {1} for {0}", unityRoot.name, unityAnimClip.name));
                }

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

                /* The major difficulty: Unity uses quaternions for rotation
                 * (which is how it should be) but FBX uses euler angles. So we
                 * need to gather up the list of transform curves per object. */
                var quaternions = new Dictionary <UnityEngine.GameObject, QuaternionCurve> ();

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

                    int index = QuaternionCurve.GetQuaternionIndex(unityCurveBinding.propertyName);
                    if (index == -1)
                    {
                        if (Verbose)
                        {
                            Debug.Log(string.Format("export binding {1} for {0}", unityCurveBinding.propertyName, unityObj.ToString()));
                        }

                        /* Some normal property (e.g. translation), export right away */
                        ExportAnimCurve(unityObj, unityAnimCurve, unityCurveBinding.propertyName,
                                        fbxScene, fbxAnimLayer);
                    }
                    else
                    {
                        /* Rotation property; save it to convert quaternion -> euler later. */

                        var unityGo = GetGameObject(unityObj);
                        if (!unityGo)
                        {
                            continue;
                        }

                        QuaternionCurve quat;
                        if (!quaternions.TryGetValue(unityGo, out quat))
                        {
                            quat = new QuaternionCurve();
                            quaternions.Add(unityGo, quat);
                        }
                        quat.SetCurve(index, unityAnimCurve);
                    }
                }

                /* now export all the quaternion curves */
                foreach (var kvp in quaternions)
                {
                    var unityGo = kvp.Key;
                    var quat    = kvp.Value;

                    FbxNode fbxNode;
                    if (!MapUnityObjectToFbxNode.TryGetValue(unityGo, out fbxNode))
                    {
                        Debug.LogError(string.Format("no fbxnode found for '0'", unityGo.name));
                        continue;
                    }
                    quat.Animate(unityGo.transform, fbxNode, fbxAnimLayer, Verbose);
                }
            }