Exemple #1
0
        private void ImportAnimation(Assimp.Node node, GameObject go, Quaternion cumulRotation)
        {
            Assimp.Animation animation = scene.Animations[0];
            if ((GlobalState.Animation.fps / (float)animation.TicksPerSecond) * animation.DurationInTicks > GlobalState.Animation.EndFrame)
            {
                GlobalState.Animation.EndFrame = Mathf.CeilToInt(GlobalState.Animation.fps / (float)animation.TicksPerSecond * (float)animation.DurationInTicks) + 1;
            }
            Assimp.NodeAnimationChannel nodeChannel = animation.NodeAnimationChannels.Find(x => x.NodeName == node.Name);
            if (nodeChannel == null)
            {
                nodeChannel = animation.NodeAnimationChannels.Find(x => x.NodeName.Split('_')[0] == node.Name);
            }
            if (null != nodeChannel)
            {
                if (nodeChannel.PositionKeyCount < 2 && nodeChannel.RotationKeyCount < 2)
                {
                    return;
                }
                AnimationSet animationSet = new AnimationSet(go);
                animationSet.ComputeCache();
                if (nodeChannel.PositionKeyCount > 1 || nodeChannel.RotationKeyCount == nodeChannel.PositionKeyCount)
                {
                    foreach (Assimp.VectorKey vectorKey in nodeChannel.PositionKeys)
                    {
                        int frame = Mathf.CeilToInt((float)vectorKey.Time * GlobalState.Animation.fps / (float)animation.TicksPerSecond) + 1;
                        animationSet.curves[AnimatableProperty.PositionX].AddKey(new AnimationKey(frame, vectorKey.Value.X, Interpolation.Bezier));
                        animationSet.curves[AnimatableProperty.PositionY].AddKey(new AnimationKey(frame, vectorKey.Value.Y, Interpolation.Bezier));
                        animationSet.curves[AnimatableProperty.PositionZ].AddKey(new AnimationKey(frame, vectorKey.Value.Z, Interpolation.Bezier));
                    }
                }
                foreach (Assimp.VectorKey vectorKey in nodeChannel.ScalingKeys)
                {
                    int frame = Mathf.CeilToInt((float)vectorKey.Time * GlobalState.Animation.fps / (float)animation.TicksPerSecond) + 1;
                    animationSet.curves[AnimatableProperty.ScaleX].AddKey(new AnimationKey(frame, vectorKey.Value.X, Interpolation.Bezier));
                    animationSet.curves[AnimatableProperty.ScaleY].AddKey(new AnimationKey(frame, vectorKey.Value.Y, Interpolation.Bezier));
                    animationSet.curves[AnimatableProperty.ScaleZ].AddKey(new AnimationKey(frame, vectorKey.Value.Z, Interpolation.Bezier));
                }
                Vector3 previousRotation = Vector3.zero;
                foreach (Assimp.QuaternionKey quaternionKey in nodeChannel.RotationKeys)
                {
                    int        frame       = Mathf.RoundToInt((float)quaternionKey.Time * GlobalState.Animation.fps / (float)animation.TicksPerSecond) + 1;
                    Quaternion uQuaternion = new Quaternion(quaternionKey.Value.X, quaternionKey.Value.Y, quaternionKey.Value.Z, quaternionKey.Value.W);
                    uQuaternion = cumulRotation * uQuaternion * Quaternion.Inverse(cumulRotation);

                    Vector3 eulerValue = uQuaternion.eulerAngles;
                    eulerValue.x = previousRotation.x + Mathf.DeltaAngle(previousRotation.x, eulerValue.x);
                    eulerValue.y = previousRotation.y + Mathf.DeltaAngle(previousRotation.y, eulerValue.y);
                    eulerValue.z = previousRotation.z + Mathf.DeltaAngle(previousRotation.z, eulerValue.z);
                    animationSet.curves[AnimatableProperty.RotationX].AddKey(new AnimationKey(frame, eulerValue.x, Interpolation.Bezier));
                    animationSet.curves[AnimatableProperty.RotationY].AddKey(new AnimationKey(frame, eulerValue.y, Interpolation.Bezier));
                    animationSet.curves[AnimatableProperty.RotationZ].AddKey(new AnimationKey(frame, eulerValue.z, Interpolation.Bezier));
                    previousRotation = eulerValue;
                }
                GlobalState.Animation.SetObjectAnimations(go, animationSet);
            }
        }
Exemple #2
0
        private Track GenerateTrack(Assimp.NodeAnimationChannel channel, Bone bone)
        {
            Track track = new Track();

            track.Translation = GenerateTranslationTrack(channel.PositionKeys, bone);
            track.Rotation    = GenerateRotationTrack(channel.RotationKeys, bone);
            track.Scale       = GenerateScaleTrack(channel.ScalingKeys, bone);

            return(track);
        }
Exemple #3
0
        public static int FindPosition(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            for (int i = 0; i < nodeAnim.PositionKeyCount - 1; i++)
            {
                if (animationTime < (float)nodeAnim.PositionKeys[i + 1].Time)
                {
                    return(i);
                }
            }

            return(0);
        }
Exemple #4
0
        public Assimp.Animation assimpExport(ref Assimp.Scene scn)
        {
            Assimp.Animation asAnim = new Assimp.Animation();
            asAnim.Name = Anim;


            //Make sure keyframe data is loaded from the files
            if (!loaded)
            {
                fetchAnimMetaData();
                loaded = true;
            }



            asAnim.TicksPerSecond  = 60;
            asAnim.DurationInTicks = animMeta.FrameCount;
            float time_interval = 1.0f / (float)asAnim.TicksPerSecond;


            //Add Node-Bone Channels
            for (int i = 0; i < animMeta.NodeCount; i++)
            {
                string name = animMeta.NodeData[i].Node;
                Assimp.NodeAnimationChannel mChannel = new Assimp.NodeAnimationChannel();
                mChannel.NodeName = name;

                //mChannel.PostState = Assimp.AnimationBehaviour.Linear;
                //mChannel.PreState = Assimp.AnimationBehaviour.Linear;


                //Export Keyframe Data
                for (int j = 0; j < animMeta.FrameCount; j++)
                {
                    //Position
                    Assimp.VectorKey vk = new Assimp.VectorKey(j * time_interval, MathUtils.convertVector(animMeta.anim_positions[name][j]));
                    mChannel.PositionKeys.Add(vk);
                    //Rotation
                    Assimp.QuaternionKey qk = new Assimp.QuaternionKey(j * time_interval, MathUtils.convertQuaternion(animMeta.anim_rotations[name][j]));
                    mChannel.RotationKeys.Add(qk);
                    //Scale
                    Assimp.VectorKey sk = new Assimp.VectorKey(j * time_interval, MathUtils.convertVector(animMeta.anim_scales[name][j]));
                    mChannel.ScalingKeys.Add(sk);
                }

                asAnim.NodeAnimationChannels.Add(mChannel);
            }

            return(asAnim);
        }
        private static uint FindPosition(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            for (uint i = 0; i < nodeAnim.PositionKeyCount - 1; i++)
            {
                if (animationTime < (float)nodeAnim.PositionKeys[i + 1].Time)
                {
                    return(i);
                }
            }

            //assert(0);

            return(0);
        }
        private static Assimp.NodeAnimationChannel FineNodeAnim(Assimp.Animation animation, string nodeName)
        {
            Assimp.NodeAnimationChannel channel = null;
            for (int i = 0; i < animation.NodeAnimationChannelCount; i++)
            {
                var nodeAnim = animation.NodeAnimationChannels[i];
                if (nodeAnim.NodeName == nodeName)
                {
                    channel = nodeAnim;
                    break;
                }
            }

            return(channel);
        }
        private static uint FindScaling(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            //assert(pNodeAnim->mNumScalingKeys > 0);

            for (uint i = 0; i < nodeAnim.ScalingKeyCount - 1; i++)
            {
                if (animationTime < (float)nodeAnim.ScalingKeys[i + 1].Time)
                {
                    return(i);
                }
            }

            //assert(0);

            return(0);
        }
Exemple #8
0
        public static int FindRotation(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            //assert(pNodeAnim->mNumRotationKeys > 0);

            for (int i = 0; i < nodeAnim.RotationKeyCount - 1; i++)
            {
                if (animationTime < (float)nodeAnim.RotationKeys[i + 1].Time)
                {
                    return(i);
                }
            }

            //assert(0);

            return(0);
        }
Exemple #9
0
        public static Assimp.Vector3D CalcInterpolatedScaling(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            if (nodeAnim.ScalingKeyCount == 1)
            {
                return(nodeAnim.ScalingKeys[0].Value);
            }

            Assimp.Vector3D result;
            int             index     = FindScaling(animationTime, nodeAnim);
            int             nextIndex = (index + 1);
            float           deltaTime = (float)(nodeAnim.ScalingKeys[nextIndex].Time - nodeAnim.ScalingKeys[index].Time);
            float           factor    = (animationTime - (float)nodeAnim.ScalingKeys[index].Time) / deltaTime;

            Assimp.Vector3D start = nodeAnim.ScalingKeys[index].Value;
            Assimp.Vector3D end   = nodeAnim.ScalingKeys[nextIndex].Value;
            Assimp.Vector3D delta = end - start;
            result = start + factor * delta;
            return(result);
        }
        private static Assimp.Vector3D CalcInterpolatedScaling(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            Assimp.Vector3D Out;
            if (nodeAnim.ScalingKeyCount == 1)
            {
                Out = nodeAnim.ScalingKeys[0].Value;
                return(Out);
            }

            uint ScalingIndex     = FindScaling(animationTime, nodeAnim);
            uint NextScalingIndex = (ScalingIndex + 1);
            //assert(NextScalingIndex < nodeAnim->mNumScalingKeys);
            float DeltaTime = (float)(nodeAnim.ScalingKeys[NextScalingIndex].Time - nodeAnim.ScalingKeys[ScalingIndex].Time);
            float Factor    = (animationTime - (float)nodeAnim.ScalingKeys[ScalingIndex].Time) / DeltaTime;

            //assert(Factor >= 0.0f && Factor <= 1.0f);
            Assimp.Vector3D Start = nodeAnim.ScalingKeys[ScalingIndex].Value;
            Assimp.Vector3D End   = nodeAnim.ScalingKeys[NextScalingIndex].Value;
            Assimp.Vector3D Delta = End - Start;
            Out = Start + Factor * Delta;
            return(Out);
        }
Exemple #11
0
        private static Assimp.Vector3D CalcInterpolatedPosition(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            Assimp.Vector3D result;
            if (nodeAnim.PositionKeyCount == 1)
            {
                result = nodeAnim.PositionKeys[0].Value;
                return(result);
            }

            uint index     = FindPosition(animationTime, nodeAnim);
            uint nextIndex = (index + 1);
            //assert(NextPositionIndex < nodeAnim->mNumPositionKeys);
            float deltaTime = (float)(nodeAnim.PositionKeys[nextIndex].Time - nodeAnim.PositionKeys[index].Time);
            float factor    = (animationTime - (float)nodeAnim.PositionKeys[index].Time) / deltaTime;

            //assert(Factor >= 0.0f && Factor <= 1.0f);
            Assimp.Vector3D start = nodeAnim.PositionKeys[index].Value;
            Assimp.Vector3D end   = nodeAnim.PositionKeys[nextIndex].Value;
            Assimp.Vector3D delta = end - start;
            result = start + factor * delta;
            return(result);
        }
        private static void ReadNodeHeirarchy(float animationTime, Assimp.Node node, Assimp.Animation animation, mat4 parentTransform, AllBoneInfos allBones)
        {
            string nodeName      = node.Name;
            mat4   nodeTransform = node.Transform.ToMat4();

            Assimp.NodeAnimationChannel nodeAnim = FineNodeAnim(animation, nodeName);
            if (nodeAnim != null)
            {
                mat4 mat = mat4.identity();
                // Interpolate scaling and generate scaling transformation matrix
                Assimp.Vector3D Scaling  = CalcInterpolatedScaling(animationTime, nodeAnim);
                mat4            ScalingM = glm.scale(mat, new vec3(Scaling.X, Scaling.Y, Scaling.Z));

                // Interpolate rotation and generate rotation transformation matrix
                Assimp.Quaternion RotationQ = CalcInterpolatedRotation(animationTime, nodeAnim);
                mat4 RotationM = new Assimp.Matrix4x4(RotationQ.GetMatrix()).ToMat4();

                // Interpolate translation and generate translation transformation matrix
                Assimp.Vector3D Translation  = CalcInterpolatedPosition(animationTime, nodeAnim);
                mat4            TranslationM = glm.translate(mat4.identity(), new vec3(Translation.X, Translation.Y, Translation.Z));

                // Combine the above transformations
                nodeTransform = TranslationM * RotationM * ScalingM;
            }

            mat4 transform = parentTransform * nodeTransform;

            if (allBones.nameIndexDict.ContainsKey(nodeName))
            {
                uint BoneIndex = allBones.nameIndexDict[nodeName];
                allBones.boneInfos[BoneIndex].finalTransformation = transform;
            }

            for (int i = 0; i < node.ChildCount; i++)
            {
                ReadNodeHeirarchy(animationTime, node.Children[i], animation, transform, allBones);
            }
        }
Exemple #13
0
        public BCK(Assimp.Animation src_anim, List <Rigging.Bone> bone_list)
        {
            Name         = src_anim.Name;
            LoopMode     = LoopMode.Loop;
            RotationFrac = 0;
            Duration     = (short)(src_anim.DurationInTicks * 30.0f);

            Tracks = new Track[bone_list.Count];

            for (int i = 0; i < bone_list.Count; i++)
            {
                Assimp.NodeAnimationChannel node = src_anim.NodeAnimationChannels.Find(x => x.NodeName == bone_list[i].Name);

                if (node == null)
                {
                    Tracks[i] = Track.Identity(bone_list[i].TransformationMatrix, Duration);
                }
                else
                {
                    Tracks[i] = GenerateTrack(node, bone_list[i]);
                }
            }
        }
        public static Assimp.Scene ToAssimpScene(RwAnimationNode animation, RwFrameListNode frameList)
        {
            var aiScene = new Assimp.Scene();

            // RootNode
            var rootFrame  = frameList[0];
            var aiRootNode = new Assimp.Node("RootNode", null);

            aiRootNode.Transform = new Assimp.Matrix4x4(rootFrame.Transform.M11, rootFrame.Transform.M21, rootFrame.Transform.M31, rootFrame.Transform.M41,
                                                        rootFrame.Transform.M12, rootFrame.Transform.M22, rootFrame.Transform.M32, rootFrame.Transform.M42,
                                                        rootFrame.Transform.M13, rootFrame.Transform.M23, rootFrame.Transform.M33, rootFrame.Transform.M43,
                                                        rootFrame.Transform.M14, rootFrame.Transform.M24, rootFrame.Transform.M34, rootFrame.Transform.M44);

            aiScene.RootNode = aiRootNode;

            for (int i = 1; i < frameList.Count; i++)
            {
                var frame     = frameList[i];
                var frameName = "_" + frame.HAnimFrameExtensionNode.NameId;

                Assimp.Node aiParentNode = null;
                if (frame.Parent != null)
                {
                    string parentName = "RootNode";
                    if (frame.Parent.HasHAnimExtension)
                    {
                        parentName = "_" + frame.Parent.HAnimFrameExtensionNode.NameId;
                    }

                    aiParentNode = aiRootNode.FindNode(parentName);
                }

                var aiNode = new Assimp.Node(frameName, aiParentNode);
                aiNode.Transform = new Assimp.Matrix4x4(frame.Transform.M11, frame.Transform.M21, frame.Transform.M31, frame.Transform.M41,
                                                        frame.Transform.M12, frame.Transform.M22, frame.Transform.M32, frame.Transform.M42,
                                                        frame.Transform.M13, frame.Transform.M23, frame.Transform.M33, frame.Transform.M43,
                                                        frame.Transform.M14, frame.Transform.M24, frame.Transform.M34, frame.Transform.M44);
                aiParentNode.Children.Add(aiNode);
            }

            var aiAnimation = new Assimp.Animation();

            aiAnimation.TicksPerSecond  = FPS;
            aiAnimation.DurationInTicks = animation.Duration * FPS;
            aiAnimation.Name            = "Take 01";
            aiScene.Animations.Add(aiAnimation);

            var keyFrameToNodeAnimationChannel = new Dictionary <RwKeyFrame, Assimp.NodeAnimationChannel>();

            for (var i = 0; i < frameList.AnimationRootNode.HAnimFrameExtensionNode.Hierarchy.Nodes.Count; i++)
            {
                var hierarchyNode = frameList.AnimationRootNode.HAnimFrameExtensionNode.Hierarchy.Nodes[i];
                var keyFrame      = animation.KeyFrames[i];

                // Create channel
                var aiNodeAnimationChannel = new Assimp.NodeAnimationChannel();
                aiNodeAnimationChannel.NodeName  = "_" + hierarchyNode.NodeId;
                aiNodeAnimationChannel.PostState = Assimp.AnimationBehaviour.Default;
                aiNodeAnimationChannel.PreState  = Assimp.AnimationBehaviour.Default;
                aiNodeAnimationChannel.PositionKeys.Add(new Assimp.VectorKey(0, new Assimp.Vector3D(keyFrame.Translation.X, keyFrame.Translation.Y, keyFrame.Translation.Z)));
                aiNodeAnimationChannel.RotationKeys.Add(new Assimp.QuaternionKey(0, new Assimp.Quaternion(keyFrame.Rotation.X, keyFrame.Rotation.Y, keyFrame.Rotation.Z, keyFrame.Rotation.W)));
                aiNodeAnimationChannel.ScalingKeys.Add(new Assimp.VectorKey(0, new Assimp.Vector3D(1, 1, 1)));
                aiNodeAnimationChannel.ScalingKeys.Add(new Assimp.VectorKey(Math.Round(animation.Duration * FPS), new Assimp.Vector3D(1, 1, 1)));

                keyFrameToNodeAnimationChannel[keyFrame] = aiNodeAnimationChannel;
                aiAnimation.NodeAnimationChannels.Add(aiNodeAnimationChannel);
            }

            for (int i = frameList.AnimationRootNode.HAnimFrameExtensionNode.Hierarchy.Nodes.Count; i < animation.KeyFrames.Count; i++)
            {
                var keyFrame = animation.KeyFrames[i];

                // Add keys
                var aiNodeAnimationChannel = keyFrameToNodeAnimationChannel[keyFrame.Previous];
                aiNodeAnimationChannel.PositionKeys.Add(new Assimp.VectorKey(keyFrame.Time * FPS, new Assimp.Vector3D(keyFrame.Translation.X, keyFrame.Translation.Y, keyFrame.Translation.Z)));
                aiNodeAnimationChannel.RotationKeys.Add(new Assimp.QuaternionKey(keyFrame.Time * FPS, new Assimp.Quaternion(keyFrame.Rotation.X, keyFrame.Rotation.Y, keyFrame.Rotation.Z, keyFrame.Rotation.W)));

                keyFrameToNodeAnimationChannel[keyFrame] = aiNodeAnimationChannel;
            }

            return(aiScene);
        }
Exemple #15
0
        private static Assimp.Quaternion CalcInterpolatedRotation(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            Assimp.Quaternion result;
            // we need at least two values to interpolate...
            if (nodeAnim.RotationKeyCount == 1)
            {
                result = nodeAnim.RotationKeys[0].Value;
                return(result);
            }

            uint index     = FindRotation(animationTime, nodeAnim);
            uint nextIndex = (index + 1);
            //assert(NextRotationIndex < nodeAnim.RotationKeyCount);
            float deltaTime = (float)(nodeAnim.RotationKeys[nextIndex].Time - nodeAnim.RotationKeys[index].Time);
            float factor    = (animationTime - (float)nodeAnim.RotationKeys[index].Time) / deltaTime;

            //assert(Factor >= 0.0f && Factor <= 1.0f);
            Assimp.Quaternion start = nodeAnim.RotationKeys[index].Value;
            Assimp.Quaternion end   = nodeAnim.RotationKeys[nextIndex].Value;
            result = Interpolate(start, end, factor);
            result.Normalize();
            return(result);
        }
Exemple #16
0
        public override void Export(Model model, Motion motion, string filepath, Config config)
        {
            var aiScene = AssimpModelExporter.Instance.ConvertToScene(model, new AssimpModelExporter.Config());

            var aiAnimation = new Assimp.Animation
            {
                DurationInTicks = motion.Duration,
                TicksPerSecond  = 30
            };

            var aiChannelLookup = new Dictionary <int, Assimp.NodeAnimationChannel>();

            for (var i = 0; i < model.Nodes.Count; i++)
            {
                var node = model.Nodes[i];
                aiAnimation.NodeAnimationChannels.Add(aiChannelLookup[i] = new Assimp.NodeAnimationChannel()
                {
                    NodeName = node.Name.Replace(" ", "_"),
                });
            }

            var aiChannelLookupRev = new Dictionary <Assimp.NodeAnimationChannel, int>();

            foreach (var lookup in aiChannelLookup)
            {
                aiChannelLookupRev[lookup.Value] = lookup.Key;
            }

            foreach (var controller in motion.Controllers)
            {
                if (!aiChannelLookup.TryGetValue(controller.NodeIndex, out var aiChannel))
                {
                    throw new InvalidOperationException();
                }

                switch (controller.Type)
                {
                case ControllerType.Position:
                    foreach (var key in controller.Keys)
                    {
                        switch (key)
                        {
                        case Vector3Key positionKey:
                            aiChannel.PositionKeys.RemoveAll(x => x.Time == positionKey.Time);
                            aiChannel.PositionKeys.Add(new Assimp.VectorKey(positionKey.Time, positionKey.Value.ToAssimp()));
                            break;
                        }
                    }
                    break;

                case ControllerType.Type1:
                    break;

                case ControllerType.Scale:
                    foreach (var key in controller.Keys)
                    {
                        switch (key)
                        {
                        case Vector3Key scaleKey:
                            aiChannel.ScalingKeys.RemoveAll(x => x.Time == scaleKey.Time);
                            aiChannel.ScalingKeys.Add(new Assimp.VectorKey(scaleKey.Time, scaleKey.Value.ToAssimp()));
                            break;
                        }
                    }
                    break;

                case ControllerType.Rotation:
                    foreach (var key in controller.Keys)
                    {
                        switch (key)
                        {
                        case QuaternionKey rotationKey:
                            aiChannel.RotationKeys.RemoveAll(x => x.Time == rotationKey.Time);
                            aiChannel.RotationKeys.Add(new Assimp.QuaternionKey(rotationKey.Time, Quaternion.Inverse(rotationKey.Value).ToAssimp()));
                            break;
                        }
                    }
                    break;

                case ControllerType.Morph:
                    break;

                case ControllerType.Type5:
                    break;

                case ControllerType.Type8:
                    break;
                }
            }

            foreach (var aiChannel in aiAnimation.NodeAnimationChannels)
            {
                if (aiChannel.PositionKeys.Count == 0 || aiChannel.PositionKeys[0].Time != 0)
                {
                    aiChannel.PositionKeys.Insert(0, new Assimp.VectorKey(0, model.Nodes[aiChannelLookupRev[aiChannel]].Position.ToAssimp()));
                }

                if (aiChannel.RotationKeys.Count == 0 || aiChannel.RotationKeys[0].Time != 0)
                {
                    var rotation = model.Nodes[aiChannelLookupRev[aiChannel]].Rotation;
                    aiChannel.RotationKeys.Insert(0, new Assimp.QuaternionKey(0, Quaternion.Inverse(Quaternion.CreateFromRotationMatrix((Matrix4x4.CreateRotationX(rotation.X) *
                                                                                                                                         Matrix4x4.CreateRotationY(rotation.Y) *
                                                                                                                                         Matrix4x4.CreateRotationZ(rotation.Z)))).ToAssimp()));
                }

                if (aiChannel.ScalingKeys.Count == 0 || aiChannel.ScalingKeys[0].Time != 0)
                {
                    aiChannel.ScalingKeys.Insert(0, new Assimp.VectorKey(0, model.Nodes[aiChannelLookupRev[aiChannel]].Scale.ToAssimp()));
                }


                var keyCount =
                    Math.Max(1, Math.Max(aiChannel.PositionKeyCount, Math.Max(aiChannel.RotationKeyCount, aiChannel.ScalingKeyCount)));

                if (aiChannel.PositionKeyCount < keyCount)
                {
                    var lastKey = aiChannel.PositionKeyCount == 0
                        ? new Assimp.VectorKey(-1, model.Nodes[aiChannelLookupRev[aiChannel]].Position.ToAssimp())
                        : aiChannel.PositionKeys[aiChannel.PositionKeyCount - 1];

                    while (aiChannel.PositionKeyCount < keyCount)
                    {
                        lastKey.Time++;
                        if (lastKey.Time > aiAnimation.DurationInTicks)
                        {
                            break;
                        }
                        aiChannel.PositionKeys.Add(lastKey);
                    }
                }

                if (aiChannel.RotationKeyCount < keyCount)
                {
                    var rotation = model.Nodes[aiChannelLookupRev[aiChannel]].Rotation;

                    var lastKey = aiChannel.RotationKeyCount == 0
                        ? new Assimp.QuaternionKey(-1, Quaternion.Inverse(Quaternion.CreateFromRotationMatrix((Matrix4x4.CreateRotationX(rotation.X) *
                                                                                                               Matrix4x4.CreateRotationY(rotation.Y) *
                                                                                                               Matrix4x4.CreateRotationZ(rotation.Z)))).ToAssimp())
                        : aiChannel.RotationKeys[aiChannel.RotationKeyCount - 1];

                    while (aiChannel.RotationKeyCount < keyCount)
                    {
                        lastKey.Time++;
                        if (lastKey.Time > aiAnimation.DurationInTicks)
                        {
                            break;
                        }
                        aiChannel.RotationKeys.Add(lastKey);
                    }
                }

                if (aiChannel.ScalingKeyCount < keyCount)
                {
                    var lastKey = aiChannel.ScalingKeyCount == 0
                        ? new Assimp.VectorKey(-1, model.Nodes[aiChannelLookupRev[aiChannel]].Scale.ToAssimp())
                        : aiChannel.ScalingKeys[aiChannel.ScalingKeyCount - 1];

                    while (aiChannel.ScalingKeyCount < keyCount)
                    {
                        lastKey.Time++;
                        if (lastKey.Time > aiAnimation.DurationInTicks)
                        {
                            break;
                        }
                        aiChannel.ScalingKeys.Add(lastKey);
                    }
                }
            }

            aiScene.Animations.Add(aiAnimation);

            //aiScene.ExportColladaFile( filepath );
            using (var aiContext = new Assimp.AssimpContext())
                aiContext.ExportFile(aiScene, filepath, "collada", Assimp.PostProcessSteps.FlipUVs);
        }
Exemple #17
0
        public static Assimp.Quaternion CalcInterpolatedRotation(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            if (nodeAnim.RotationKeyCount == 1)
            {
                return(nodeAnim.RotationKeys[0].Value);
            }

            Assimp.Quaternion result;
            int   index     = FindRotation(animationTime, nodeAnim);
            int   nextIndex = (index + 1);
            float deltaTime = (float)(nodeAnim.RotationKeys[nextIndex].Time - nodeAnim.RotationKeys[index].Time);
            float factor    = (animationTime - (float)nodeAnim.RotationKeys[index].Time) / deltaTime;

            Assimp.Quaternion start = nodeAnim.RotationKeys[index].Value;
            Assimp.Quaternion end   = nodeAnim.RotationKeys[nextIndex].Value;
            result = Interpolate(start, end, factor);
            result.Normalize();
            return(result);
        }
        private static Assimp.Quaternion CalcInterpolatedRotation(float animationTime, Assimp.NodeAnimationChannel nodeAnim)
        {
            Assimp.Quaternion Out;
            // we need at least two values to interpolate...
            if (nodeAnim.RotationKeyCount == 1)
            {
                Out = nodeAnim.RotationKeys[0].Value;
                return(Out);
            }

            uint RotationIndex     = FindRotation(animationTime, nodeAnim);
            uint NextRotationIndex = (RotationIndex + 1);
            //assert(NextRotationIndex < nodeAnim.RotationKeyCount);
            float DeltaTime = (float)(nodeAnim.RotationKeys[NextRotationIndex].Time - nodeAnim.RotationKeys[RotationIndex].Time);
            float Factor    = (animationTime - (float)nodeAnim.RotationKeys[RotationIndex].Time) / DeltaTime;

            //assert(Factor >= 0.0f && Factor <= 1.0f);
            Assimp.Quaternion StartRotationQ = nodeAnim.RotationKeys[RotationIndex].Value;
            Assimp.Quaternion EndRotationQ   = nodeAnim.RotationKeys[NextRotationIndex].Value;
            Out = Interpolate(StartRotationQ, EndRotationQ, Factor);
            Out.Normalize();
            return(Out);
        }