Пример #1
0
        private ProcessedAnimationChannel ConvertChannel(NodeAnimationChannel nac)
        {
            string nodeName = nac.NodeName;

            AssetPrimitives.VectorKey[] positions = new AssetPrimitives.VectorKey[nac.PositionKeyCount];
            for (int i = 0; i < nac.PositionKeyCount; i++)
            {
                Assimp.VectorKey assimpKey = nac.PositionKeys[i];
                positions[i] = new AssetPrimitives.VectorKey(assimpKey.Time, assimpKey.Value.ToSystemVector3());
            }

            AssetPrimitives.VectorKey[] scales = new AssetPrimitives.VectorKey[nac.ScalingKeyCount];
            for (int i = 0; i < nac.ScalingKeyCount; i++)
            {
                Assimp.VectorKey assimpKey = nac.ScalingKeys[i];
                scales[i] = new AssetPrimitives.VectorKey(assimpKey.Time, assimpKey.Value.ToSystemVector3());
            }

            AssetPrimitives.QuaternionKey[] rotations = new AssetPrimitives.QuaternionKey[nac.RotationKeyCount];
            for (int i = 0; i < nac.RotationKeyCount; i++)
            {
                Assimp.QuaternionKey assimpKey = nac.RotationKeys[i];
                rotations[i] = new AssetPrimitives.QuaternionKey(assimpKey.Time, assimpKey.Value.ToSystemQuaternion());
            }

            return(new ProcessedAnimationChannel(nodeName, positions, scales, rotations));
        }
        /// <summary>
        /// protected Constructor
        /// </summary>
        /// <param name="nodeAnimationChannel">Assimp NodeAnimationChannel</param>
        protected AssimpNodeAnimationNode(NodeAnimationChannel nodeAnimationChannel)
        {
            if (nodeAnimationChannel == null)
            {
                throw new ArgumentNullException(nameof(nodeAnimationChannel));
            }

            NodeAnimationChannel = nodeAnimationChannel;

            if (nodeAnimationChannel.HasPositionKeys)
            {
                foreach (var positionKey in nodeAnimationChannel.PositionKeys)
                {
                    this.PositionTrack.Keys.Add(new Position3DKeyFrame(positionKey.Time, positionKey.Value.ToWpfPoint3D()));
                }
            }

            if (nodeAnimationChannel.HasScalingKeys)
            {
                foreach (var scalingKeys in nodeAnimationChannel.ScalingKeys)
                {
                    this.ScaleTrack.Keys.Add(new Vector3DKeyFrame(scalingKeys.Time, scalingKeys.Value.ToWpfVector3D()));
                }
            }

            if (nodeAnimationChannel.HasRotationKeys)
            {
                foreach (var quaternionKey in nodeAnimationChannel.RotationKeys)
                {
                    this.RotationTrack.Keys.Add(new QuaternionRotationKeyFrame(quaternionKey.Time, new System.Windows.Media.Media3D.Quaternion(quaternionKey.Value.X, quaternionKey.Value.Y, quaternionKey.Value.Z, quaternionKey.Value.W)));
                }
            }
        }
        private aiMatrix4x4 InterpolateRotation(double time, NodeAnimationChannel channel)
        {
            aiQuaternion rotation;

            if (channel.RotationKeyCount == 1)
            {
                rotation = channel.RotationKeys[0].Value;
            }
            else
            {
                uint frameIndex = 0;
                for (uint i = 0; i < channel.RotationKeyCount - 1; i++)
                {
                    if (time < (float)channel.RotationKeys[(int)(i + 1)].Time)
                    {
                        frameIndex = i;
                        break;
                    }
                }

                QuaternionKey currentFrame = channel.RotationKeys[(int)frameIndex];
                QuaternionKey nextFrame    = channel.RotationKeys[(int)((frameIndex + 1) % channel.RotationKeyCount)];

                double delta = (time - (float)currentFrame.Time) / (float)(nextFrame.Time - currentFrame.Time);

                aiQuaternion start = currentFrame.Value;
                aiQuaternion end   = nextFrame.Value;
                rotation = aiQuaternion.Slerp(start, end, (float)delta);
                rotation.Normalize();
            }

            return(rotation.GetMatrix());
        }
Пример #4
0
        Matrix4x4 FindRotation(NodeAnimationChannel n)
        {
            Matrix4x4 result = Matrix4x4.Identity;

            for (int c = 0; c < n.RotationKeyCount; c++)
            {
                QuaternionKey q = n.RotationKeys[c];

                q.Value = new Assimp.Quaternion(q.Value.W, q.Value.X, q.Value.Y, q.Value.Z);

                VectorKey pk = n.PositionKeys[c];
                VectorKey ps = n.ScalingKeys[c];

                if (_animationController.FrameCounter <= q.Time)
                {
                    result =
                        (Matrix4x4)q.Value.GetMatrix()
                        * (Matrix4x4.FromTranslation(pk.Value))
                        * (Matrix4x4.FromScaling(ps.Value))
                    ;
                    break;
                }
            }
            return(result);
        }
        private aiMatrix4x4 InterpolateScale(double time, NodeAnimationChannel channel)
        {
            Vector3D scale;

            if (channel.ScalingKeyCount == 1)
            {
                scale = channel.ScalingKeys[0].Value;
            }
            else
            {
                uint frameIndex = 0;
                for (uint i = 0; i < channel.ScalingKeyCount - 1; i++)
                {
                    if (time < (float)channel.ScalingKeys[(int)(i + 1)].Time)
                    {
                        frameIndex = i;
                        break;
                    }
                }

                VectorKey currentFrame = channel.ScalingKeys[(int)frameIndex];
                VectorKey nextFrame    = channel.ScalingKeys[(int)((frameIndex + 1) % channel.ScalingKeyCount)];

                double delta = (time - (float)currentFrame.Time) / (float)(nextFrame.Time - currentFrame.Time);

                Vector3D start = currentFrame.Value;
                Vector3D end   = nextFrame.Value;

                scale = (start + (float)delta * (end - start));
            }

            return(aiMatrix4x4.FromScaling(scale));
        }
Пример #6
0
        public void CalcAnimation2(Node node, Animation ani, Matrix4x4 parent_transform)
        {
            NodeAnimationChannel n = FindChannel(ani, node.Name);

            Matrix4x4 node_transform = node.Transform;

            string node_name = node.Name;

            if (n != null)
            {
                node_transform = FindRotation(n);
            }
            Matrix4x4 global_transform = node_transform * parent_transform;

            if (m_bone_mapping.ContainsKey(node_name))
            {
                uint       bone_index = m_bone_mapping[node_name];
                BoneMatrix bi         = m_bone_matrices[(int)bone_index];
                //bi.final_world_transform = m_global_inverse_transform * global_transform * m_bone_matrices[(int)bone_index].offset_matrix;
                bi.final_world_transform         = m_bone_matrices[(int)bone_index].offset_matrix * global_transform * m_global_inverse_transform;
                m_bone_matrices[(int)bone_index] = bi;
                //counter++;
            }

            for (int i = 0; i < node.ChildCount; i++)
            {
                Node child = node.Children[i];
                CalcAnimation2(child, ani, global_transform);
            }
        }
Пример #7
0
        public void ExtractAnimations(string animationName = "*")
        {
            for (int i = 0; i < ModelAnimationGraph.Animations.Count; i++)
            {
                var tagAnimation = ModelAnimationGraph.Animations[i];
                var name         = CacheContext.StringTable.GetString(tagAnimation.Name);

                if (animationName == "*" || name == animationName)
                {
                    Animation animation = new Animation
                    {
                        Name = name
                    };

                    animation.TicksPerSecond  = 30;
                    animation.DurationInTicks = tagAnimation.FrameCount;

                    //
                    // Convert tag animation into assimp animation. A channel affects only a single node (bone)
                    //

                    //Animation data should go here

                    for (int j = 0; j < tagAnimation.NodeCount; j++)
                    {
                        NodeAnimationChannel channel = new NodeAnimationChannel();
                        channel.NodeName = Nodes[j].Name;

                        // parse animation data for a specific node
                    }
                    Scene.Animations.Add(animation);
                }
            }
        }
Пример #8
0
        public Animations.Animation CreateGenericAnimation(Assimp.Animation animation)
        {
            Animations.Animation STanim = new Animations.Animation();
            STanim.Text       = animation.Name;
            STanim.FrameCount = (int)animation.DurationInTicks;

            //Load node animations
            if (animation.HasNodeAnimations)
            {
                var _channels = new NodeAnimationChannel[animation.NodeAnimationChannelCount];
                for (int i = 0; i < _channels.Length; i++)
                {
                    _channels[i] = new NodeAnimationChannel();
                }
            }

            //Load mesh animations
            if (animation.HasMeshAnimations)
            {
                var _meshChannels = new MeshAnimationChannel[animation.MeshAnimationChannelCount];
                for (int i = 0; i < _meshChannels.Length; i++)
                {
                    _meshChannels[i] = new MeshAnimationChannel();
                }
            }

            return(STanim);
        }
Пример #9
0
        static NumMatrix4x4 GetTransformForFrame(NodeAnimationChannel Ch, int Frame)
        {
            VectorKey PosKey = Ch.PositionKeys[Ch.PositionKeys.Count - 1];

            if (Frame < Ch.PositionKeys.Count)
            {
                PosKey = Ch.PositionKeys[Frame];
            }

            QuaternionKey RotKey = Ch.RotationKeys[Ch.RotationKeys.Count - 1];

            if (Frame < Ch.RotationKeys.Count)
            {
                RotKey = Ch.RotationKeys[Frame];
            }

            VectorKey SclKey = Ch.ScalingKeys[Ch.ScalingKeys.Count - 1];

            if (Frame < Ch.ScalingKeys.Count)
            {
                SclKey = Ch.ScalingKeys[Frame];
            }


            NumMatrix4x4 Rot = NumMatrix4x4.CreateFromQuaternion(ConvertQuat(RotKey.Value));
            NumMatrix4x4 Pos = NumMatrix4x4.CreateTranslation(ConvertVec(PosKey.Value));
            NumMatrix4x4 Scl = NumMatrix4x4.CreateScale(ConvertVec(SclKey.Value));

            //return Pos * Rot * Scl;
            return(Scl * Rot * Pos);
        }
Пример #10
0
        private void FillAnimationNode(Scene scene, Node node, int animationIndex)
        {
            var animation = scene.Animations[animationIndex];
            NodeAnimationChannel channel = null;

            for (var i = 0; i < animation.NodeAnimationChannelCount; i++)
            {
                if (animation.NodeAnimationChannels[i].NodeName == node.Name)
                {
                    channel = animation.NodeAnimationChannels[i];
                }
            }
            if (channel != null && !СurrentAnimation.AnimationNodes.ContainsKey(node.Name))
            {
                var nodeAnim = new NodeAnimation
                {
                    PositionKeysCount = channel.PositionKeyCount,
                    ScalingKeysCount  = channel.ScalingKeyCount,
                    RotationKeysCount = channel.RotationKeyCount
                };
                nodeAnim.PositionKeys = new VectorInfo[nodeAnim.PositionKeysCount];
                for (var i = 0; i < nodeAnim.PositionKeysCount; i++)
                {
                    nodeAnim.PositionKeys[i] = new VectorInfo
                    {
                        Time  = (float)channel.PositionKeys[i].Time,
                        Value = FromVector(channel.PositionKeys[i].Value)
                    }
                }
                ;
                nodeAnim.RotationKeys = new QuaternionInfo[nodeAnim.RotationKeysCount];
                for (var i = 0; i < nodeAnim.RotationKeysCount; i++)
                {
                    nodeAnim.RotationKeys[i] = new QuaternionInfo
                    {
                        Time  = (float)channel.RotationKeys[i].Time,
                        Value = channel.RotationKeys[i].Value
                    }
                }
                ;
                nodeAnim.ScalingKeys = new VectorInfo[nodeAnim.ScalingKeysCount];
                for (var i = 0; i < nodeAnim.ScalingKeysCount; i++)
                {
                    nodeAnim.ScalingKeys[i] = new VectorInfo
                    {
                        Time  = (float)channel.ScalingKeys[i].Time,
                        Value = FromVector(channel.ScalingKeys[i].Value)
                    }
                }
                ;
                СurrentAnimation.AnimationNodes.Add(node.Name, nodeAnim);
            }
            for (var i = 0; i < node.ChildCount; i++)
            {
                FillAnimationNode(scene, node.Children[i], animationIndex);
            }
        }
Пример #11
0
        public NodeAnimationChannel ExtractChannel(AnimationData data)
        {
            NodeAnimationChannel channel = new NodeAnimationChannel();

            channel.NodeName = "";



            return(null);
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="nodeAnimationChannel">Assimp NodeAnimationChannel</param>
        /// <param name="animatedModel3D">WPF Model3D</param>
        public AssimpNodeAnimationNode(NodeAnimationChannel nodeAnimationChannel, Model3D animatedModel3D)
            : this(nodeAnimationChannel)
        {
            if (animatedModel3D == null)
            {
                throw new ArgumentNullException(nameof(animatedModel3D));
            }

            _animatedModel3D      = animatedModel3D;
            _animatedSkeletonNode = null;
        }
Пример #13
0
        static FoamAnimationFrame ReadFrame(List <NodeAnimationChannel> Channels, string[] BoneNames, int Frame)
        {
            NumMatrix4x4[] BoneTransforms = new NumMatrix4x4[BoneNames.Length];

            for (int i = 0; i < BoneNames.Length; i++)
            {
                NodeAnimationChannel Ch = FindBoneChannel(Channels, BoneNames[i]);
                BoneTransforms[i] = GetTransformForFrame(Ch, Frame);
            }

            return(new FoamAnimationFrame(BoneTransforms));
        }
Пример #14
0
 NodeAnimationChannel FindChannel(Animation ani, string NodeName)
 {
     for (int i = 0; i < ani.NodeAnimationChannelCount; i++)
     {
         NodeAnimationChannel n = ani.NodeAnimationChannels[i];
         if (n.NodeName == NodeName)
         {
             return(n);
         }
     }
     return(null);
 }
Пример #15
0
        IEnumerable <Frame> GetFrames(NodeAnimationChannel nch)
        {
            var m = new[] { nch.PositionKeyCount, nch.RotationKeyCount, nch.ScalingKeyCount }.Max();

            for (int i = 0; i < m; i++)
            {
                var pos   = new Vector3D();
                var scale = new Vector3D(1);
                var rot   = new Assimp.Quaternion(1, 0, 0, 0);
                if (nch.HasPositionKeys)
                {
                    if (i < nch.PositionKeyCount)
                    {
                        pos = nch.PositionKeys[i].Value;
                    }
                    else
                    {
                        pos = nch.PositionKeys.Last().Value;
                    }
                }
                if (nch.HasRotationKeys)
                {
                    if (i < nch.RotationKeyCount)
                    {
                        rot = nch.RotationKeys[i].Value;
                    }
                    else
                    {
                        rot = nch.RotationKeys.Last().Value;
                    }
                }
                if (nch.HasScalingKeys)
                {
                    if (i < nch.ScalingKeyCount)
                    {
                        scale = nch.ScalingKeys[i].Value;
                    }
                    else
                    {
                        scale = nch.ScalingKeys.Last().Value;
                    }
                }

                yield return(new Frame()
                {
                    pos = pos,
                    rot = rot,
                    scal = scale
                });
            }
            yield break;
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="nodeAnimationChannel">Assimp NodeAnimationChannel</param>
        /// <param name="animatedSkeletonNode">SkeletonNode</param>
        public AssimpNodeAnimationNode(NodeAnimationChannel nodeAnimationChannel, SkeletonNode animatedSkeletonNode)
            : this(nodeAnimationChannel)
        {
            if (animatedSkeletonNode == null)
            {
                throw new ArgumentNullException(nameof(animatedSkeletonNode));
            }

            //if (nodeAnimationChannel.NodeName != animatedSkeletonNode.AssimpNode.Name)
            //    throw new Exception("nodeAnimationChannel and animatedSkeletonNode that were used to create an instance of AssimpNodeAnimationNode are not connected to each other (do not have the same name)");

            _animatedModel3D      = null;
            _animatedSkeletonNode = animatedSkeletonNode;
        }
        private int FindPosition(float animationTime, NodeAnimationChannel pNodeAnim)
        {
            // TODO add asserts

            for (int i = 0; i < pNodeAnim.PositionKeyCount - 1; i++)
            {
                if (animationTime < pNodeAnim.PositionKeys[i + 1].Time)
                {
                    return(i);
                }
            }

            return(0);
        }
        private bool GetChannel(Node node, out NodeAnimationChannel channel)
        {
            foreach (NodeAnimationChannel c in _animation.NodeAnimationChannels)
            {
                if (c.NodeName == node.Name)
                {
                    channel = c;
                    return(true);
                }
            }

            channel = null;
            return(false);
        }
            private ErrorCode AddAnimationsToScene(Scene scene)
            {
                if (animations == null || animations.Count == 0)
                {
                    return(ErrorCode.Succeed);
                }

                for (int i = 0; i < animations.Count; ++i)
                {
                    var ani = new Animation
                    {
                        Name            = string.IsNullOrEmpty(animations[i].Name) ? $"Animation_{i}" : animations[i].Name,
                        TicksPerSecond  = DefaultTicksPerSecond,
                        DurationInTicks = (animations[i].EndTime - animations[i].StartTime) * DefaultTicksPerSecond
                    };
                    foreach (var f in animations[i].NodeAnimationCollection)
                    {
                        if (f.Node == null || string.IsNullOrEmpty(f.Node.Name))
                        {
                            logger.LogWarning("Node Animation NodeName is empty. AnimationName:{}", ani.Name);
                            continue;
                        }
                        var ch = new NodeAnimationChannel
                        {
                            NodeName = f.Node.Name
                        };
                        foreach (var kf in f.KeyFrames)
                        {
                            var t = kf.Time * DefaultTicksPerSecond;
                            ch.PositionKeys.Add(new VectorKey(t, kf.Translation.ToAssimpVector3D()));
                            ch.ScalingKeys.Add(new VectorKey(t, kf.Scale.ToAssimpVector3D()));
                            ch.RotationKeys.Add(new QuaternionKey(t, kf.Rotation.ToAssimpQuaternion()));
                        }

                        ani.NodeAnimationChannels.Add(ch);
                    }

                    scene.Animations.Add(ani);
                }
                return(ErrorCode.Succeed);
            }
        private Vector3 CalcInterpolatedPosition(float animationTime, NodeAnimationChannel pNodeAnim)
        {
            // TODO add asserts

            if (pNodeAnim.PositionKeyCount == 1)
            {
                return(pNodeAnim.PositionKeys[0].Value.ToOtk());
            }

            var positionIndex     = FindPosition(animationTime, pNodeAnim);
            var nextPositionIndex = (positionIndex + 1);

            var deltaTime = pNodeAnim.PositionKeys[nextPositionIndex].Time - pNodeAnim.PositionKeys[positionIndex].Time;
            var factor    = (animationTime - pNodeAnim.PositionKeys[positionIndex].Time) / deltaTime;

            var start = pNodeAnim.PositionKeys[positionIndex].Value;
            var end   = pNodeAnim.PositionKeys[nextPositionIndex].Value;
            var delta = end - start;

            return((start + ((float)factor * delta)).ToOtk());
        }
Пример #21
0
        private static AnimationChannel BuildAnimtionChannel(Node animatedNode, NodeAnimationChannel nac)
        {
            AnimationChannel newChan = new AnimationChannel();

            Matrix animatedNodeTransform = Matrix.Transpose(ToXna(animatedNode.Transform));

            Vector3 xnaScale;

            Microsoft.Xna.Framework.Quaternion xnaRotation;
            Vector3 xnaPositon;

            animatedNodeTransform.Decompose(out xnaScale, out xnaRotation, out xnaPositon);

            Vector3D scale = new Vector3D(xnaScale.X, xnaScale.Y, xnaScale.Z);

            Assimp.Quaternion rotation;
            rotation.W = xnaRotation.W;
            rotation.X = xnaRotation.X;
            rotation.Y = xnaRotation.Y;
            rotation.Z = xnaRotation.Z;
            Vector3D position = new Vector3D(xnaPositon.X, xnaPositon.Y, xnaPositon.Z);

            int sKeyIndex = 0;
            int qKeyIndex = 0;
            int tKeyIndex = 0;

            double firstSKeyTime = nac.ScalingKeyCount > sKeyIndex ? nac.ScalingKeys[sKeyIndex].Time : Double.MaxValue;
            double firstQKeyTime = nac.RotationKeyCount > qKeyIndex ? nac.RotationKeys[qKeyIndex].Time : Double.MaxValue;
            double firstTKeyTime = nac.PositionKeyCount > tKeyIndex ? nac.PositionKeys[tKeyIndex].Time : Double.MaxValue;

            double currTime = Math.Min(Math.Min(firstSKeyTime, firstQKeyTime), firstTKeyTime);

            if (firstSKeyTime <= currTime)
            {
                scale = nac.ScalingKeys[sKeyIndex].Value;
            }

            if (firstQKeyTime <= currTime)
            {
                rotation = nac.RotationKeys[qKeyIndex].Value;
            }

            if (firstTKeyTime <= currTime)
            {
                position = nac.PositionKeys[tKeyIndex].Value;
            }

            while (currTime < double.MaxValue)
            {
                while (nac.ScalingKeyCount > sKeyIndex + 1 &&
                       nac.ScalingKeys[sKeyIndex + 1].Time <= currTime)
                {
                    sKeyIndex++;
                    scale = nac.ScalingKeys[sKeyIndex].Value;
                }

                while (nac.RotationKeyCount > qKeyIndex + 1 &&
                       nac.RotationKeys[qKeyIndex + 1].Time <= currTime)
                {
                    qKeyIndex++;
                    rotation = nac.RotationKeys[qKeyIndex].Value;
                }

                while (nac.PositionKeyCount > tKeyIndex + 1 &&
                       nac.PositionKeys[tKeyIndex + 1].Time <= currTime)
                {
                    tKeyIndex++;
                    position = nac.PositionKeys[tKeyIndex].Value;
                }

                xnaRotation.W = rotation.W;
                xnaRotation.X = rotation.X;
                xnaRotation.Y = rotation.Y;
                xnaRotation.Z = rotation.Z;

                Matrix transform =
                    Matrix.CreateScale(ToXna(scale)) *
                    Matrix.CreateFromQuaternion(xnaRotation) *
                    Matrix.CreateTranslation(ToXna(position));

                AnimationKeyframe newKeyframe = new AnimationKeyframe(TimeSpan.FromSeconds(currTime), transform);
                newChan.Add(newKeyframe);

                // Increment the time:

                double nextSKeyTime = nac.ScalingKeyCount > sKeyIndex + 1 ? nac.ScalingKeys[sKeyIndex + 1].Time : Double.MaxValue;
                double nextQKeyTime = nac.RotationKeyCount > qKeyIndex + 1 ? nac.RotationKeys[qKeyIndex + 1].Time : Double.MaxValue;
                double nextTKeyTime = nac.PositionKeyCount > tKeyIndex + 1 ? nac.PositionKeys[tKeyIndex + 1].Time : Double.MaxValue;

                currTime = Math.Min(Math.Min(nextSKeyTime, nextQKeyTime), nextTKeyTime);
            }

            return(newChan);
        }
Пример #22
0
        public unsafe override ProcessedModel ProcessT(Stream stream, string extension)
        {
            AssimpContext ac    = new AssimpContext();
            Scene         scene = ac.ImportFileFromStream(
                stream,
                PostProcessSteps.FlipWindingOrder | PostProcessSteps.GenerateNormals | PostProcessSteps.FlipUVs,
                extension);
            aiMatrix4x4 rootNodeInverseTransform = scene.RootNode.Transform;

            rootNodeInverseTransform.Inverse();

            List <ProcessedMeshPart>  parts      = new List <ProcessedMeshPart>();
            List <ProcessedAnimation> animations = new List <ProcessedAnimation>();

            HashSet <string> encounteredNames = new HashSet <string>();

            for (int meshIndex = 0; meshIndex < scene.MeshCount; meshIndex++)
            {
                Mesh   mesh     = scene.Meshes[meshIndex];
                string meshName = mesh.Name;
                if (string.IsNullOrEmpty(meshName))
                {
                    meshName = $"mesh_{meshIndex}";
                }
                int counter = 1;
                while (!encounteredNames.Add(meshName))
                {
                    meshName = mesh.Name + "_" + counter.ToString();
                    counter += 1;
                }
                int vertexCount = mesh.VertexCount;

                int positionOffset    = 0;
                int normalOffset      = 12;
                int texCoordsOffset   = -1;
                int boneWeightOffset  = -1;
                int boneIndicesOffset = -1;

                List <VertexElementDescription> elementDescs = new List <VertexElementDescription>();
                elementDescs.Add(new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3));
                elementDescs.Add(new VertexElementDescription("Normal", VertexElementSemantic.Normal, VertexElementFormat.Float3));
                normalOffset = 12;

                int vertexSize = 24;

                bool hasTexCoords = mesh.HasTextureCoords(0);
                elementDescs.Add(new VertexElementDescription("TexCoords", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2));
                texCoordsOffset = vertexSize;
                vertexSize     += 8;

                bool hasBones = mesh.HasBones;
                if (hasBones)
                {
                    elementDescs.Add(new VertexElementDescription("BoneWeights", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float4));
                    elementDescs.Add(new VertexElementDescription("BoneIndices", VertexElementSemantic.TextureCoordinate, VertexElementFormat.UInt4));

                    boneWeightOffset = vertexSize;
                    vertexSize      += 16;

                    boneIndicesOffset = vertexSize;
                    vertexSize       += 16;
                }

                byte[]            vertexData = new byte[vertexCount * vertexSize];
                VertexDataBuilder builder    = new VertexDataBuilder(vertexData, vertexSize);
                Vector3           min        = vertexCount > 0 ? mesh.Vertices[0].ToSystemVector3() : Vector3.Zero;
                Vector3           max        = vertexCount > 0 ? mesh.Vertices[0].ToSystemVector3() : Vector3.Zero;

                for (int i = 0; i < vertexCount; i++)
                {
                    Vector3 position = mesh.Vertices[i].ToSystemVector3();
                    min = Vector3.Min(min, position);
                    max = Vector3.Max(max, position);

                    builder.WriteVertexElement(
                        i,
                        positionOffset,
                        position);

                    Vector3 normal = mesh.Normals[i].ToSystemVector3();
                    builder.WriteVertexElement(i, normalOffset, normal);

                    if (mesh.HasTextureCoords(0))
                    {
                        builder.WriteVertexElement(
                            i,
                            texCoordsOffset,
                            new Vector2(mesh.TextureCoordinateChannels[0][i].X, mesh.TextureCoordinateChannels[0][i].Y));
                    }
                    else
                    {
                        builder.WriteVertexElement(
                            i,
                            texCoordsOffset,
                            new Vector2());
                    }
                }

                List <int> indices = new List <int>();
                foreach (Face face in mesh.Faces)
                {
                    if (face.IndexCount == 3)
                    {
                        indices.Add(face.Indices[0]);
                        indices.Add(face.Indices[1]);
                        indices.Add(face.Indices[2]);
                    }
                }

                Dictionary <string, uint>   boneIDsByName = new Dictionary <string, uint>();
                System.Numerics.Matrix4x4[] boneOffsets   = new System.Numerics.Matrix4x4[mesh.BoneCount];

                if (hasBones)
                {
                    Dictionary <int, int> assignedBoneWeights = new Dictionary <int, int>();
                    for (uint boneID = 0; boneID < mesh.BoneCount; boneID++)
                    {
                        Bone   bone     = mesh.Bones[(int)boneID];
                        string boneName = bone.Name;
                        int    suffix   = 1;
                        while (boneIDsByName.ContainsKey(boneName))
                        {
                            boneName = bone.Name + "_" + suffix.ToString();
                            suffix  += 1;
                        }

                        boneIDsByName.Add(boneName, boneID);
                        foreach (VertexWeight weight in bone.VertexWeights)
                        {
                            int relativeBoneIndex = GetAndIncrementRelativeBoneIndex(assignedBoneWeights, weight.VertexID);
                            builder.WriteVertexElement(weight.VertexID, boneIndicesOffset + (relativeBoneIndex * sizeof(uint)), boneID);
                            builder.WriteVertexElement(weight.VertexID, boneWeightOffset + (relativeBoneIndex * sizeof(float)), weight.Weight);
                        }

                        System.Numerics.Matrix4x4 offsetMat = bone.OffsetMatrix.ToSystemMatrixTransposed();
                        System.Numerics.Matrix4x4.Decompose(offsetMat, out var scale, out var rot, out var trans);
                        offsetMat = System.Numerics.Matrix4x4.CreateScale(scale)
                                    * System.Numerics.Matrix4x4.CreateFromQuaternion(rot)
                                    * System.Numerics.Matrix4x4.CreateTranslation(trans);

                        boneOffsets[boneID] = offsetMat;
                    }
                }
                builder.FreeGCHandle();

                uint indexCount = (uint)indices.Count;

                int[]  int32Indices = indices.ToArray();
                byte[] indexData    = new byte[indices.Count * sizeof(uint)];
                fixed(byte *indexDataPtr = indexData)
                {
                    fixed(int *int32Ptr = int32Indices)
                    {
                        Buffer.MemoryCopy(int32Ptr, indexDataPtr, indexData.Length, indexData.Length);
                    }
                }

                ProcessedMeshPart part = new ProcessedMeshPart(
                    vertexData,
                    elementDescs.ToArray(),
                    indexData,
                    IndexFormat.UInt32,
                    (uint)indices.Count,
                    boneIDsByName,
                    boneOffsets);
                parts.Add(part);
            }

            // Nodes
            Node rootNode = scene.RootNode;
            List <ProcessedNode> processedNodes = new List <ProcessedNode>();

            ConvertNode(rootNode, -1, processedNodes);

            ProcessedNodeSet nodes = new ProcessedNodeSet(processedNodes.ToArray(), 0, rootNodeInverseTransform.ToSystemMatrixTransposed());

            for (int animIndex = 0; animIndex < scene.AnimationCount; animIndex++)
            {
                Animation animation = scene.Animations[animIndex];
                Dictionary <string, ProcessedAnimationChannel> channels = new Dictionary <string, ProcessedAnimationChannel>();
                for (int channelIndex = 0; channelIndex < animation.NodeAnimationChannelCount; channelIndex++)
                {
                    NodeAnimationChannel nac = animation.NodeAnimationChannels[channelIndex];
                    channels[nac.NodeName] = ConvertChannel(nac);
                }

                string baseAnimName = animation.Name;
                if (string.IsNullOrEmpty(baseAnimName))
                {
                    baseAnimName = "anim_" + animIndex;
                }

                string animationName = baseAnimName;


                int counter = 1;
                while (!encounteredNames.Add(animationName))
                {
                    animationName = baseAnimName + "_" + counter.ToString();
                    counter      += 1;
                }
            }

            return(new ProcessedModel()
            {
                MeshParts = parts.ToArray(),
                Animations = animations.ToArray(),
                Nodes = nodes
            });
        }
Пример #23
0
        /// <summary>
        /// Create a new geometry given filename
        /// </summary>
        /// <param name="fileName"> filepath to the 3D model file </param>
        public Geometry(string fileName, bool enableRigging = false)
        {
            RiggingEnabled = enableRigging;
            sourceFileName = fileName;

            //Create new importer.
            importer = new AssimpContext();

            //import the file
            scene = importer.ImportFile(fileName,
                                        PostProcessSteps.CalculateTangentSpace | PostProcessSteps.Triangulate |
                                        PostProcessSteps.JoinIdenticalVertices | PostProcessSteps.SortByPrimitiveType |
                                        PostProcessSteps.GenerateUVCoords | PostProcessSteps.FlipUVs |
                                        PostProcessSteps.LimitBoneWeights | PostProcessSteps.ValidateDataStructure);

            //make sure scene not null
            if (scene == null)
            {
                throw new FileNotFoundException();
            }

            //loop through sizes and count them.
            allMeshes = new List <ClientMesh>(scene.MeshCount);

            //loop through and store sizes
            for (int idx = 0; idx < scene.MeshCount; idx++)
            {
                ClientMesh mesh = new ClientMesh();
                allMeshes.Add(mesh);

                mesh.CountVertices = scene.Meshes[idx].VertexCount;

                mesh.vertSize = scene.Meshes[idx].VertexCount * Vector3.SizeInBytes;
                mesh.normSize = scene.Meshes[idx].Normals.Count * Vector3.SizeInBytes;
                mesh.faceSize = scene.Meshes[idx].FaceCount * scene.Meshes[idx].Faces[0].IndexCount * sizeof(int);
                if (scene.Meshes[idx].HasTextureCoords(0))
                {
                    mesh.texSize = scene.Meshes[idx].TextureCoordinateChannels[0].Count * Vector3.SizeInBytes;
                }
            }

            diffuseTextureSRV = new Dictionary <string, ShaderResourceView>();

            // do all the processing that rigging is required to have
            if (enableRigging)
            {
                _allBones        = new List <ClientBone>();
                _allBoneMappings = new Dictionary <string, int>();
                _allBoneLookup   = new Dictionary <string, ClientBone>();

                // set the animation related lookup tables
                AnimationIndices = new Dictionary <string, int>();
                _animationNodes  = new List <Dictionary <string, ClientAnimationNode> >(scene.AnimationCount);
                for (int i = 0; i < scene.AnimationCount; i++)
                {
                    AnimationIndices[scene.Animations[i].Name] = i;
                    _animationNodes.Add(new Dictionary <string, ClientAnimationNode>());

                    for (int j = 0; j < scene.Animations[i].NodeAnimationChannelCount; j++)
                    {
                        NodeAnimationChannel ch     = scene.Animations[i].NodeAnimationChannels[j];
                        ClientAnimationNode  myNode = new ClientAnimationNode(ch.NodeName);

                        _animationNodes[i][ch.NodeName] = myNode;
                        myNode.Translations             = new List <Vector3>();
                        myNode.TranslationTime          = new List <double>();
                        myNode.Rotations    = new List <Quaternion>();
                        myNode.RotationTime = new List <double>();
                        myNode.Scalings     = new List <Vector3>();
                        myNode.ScalingTime  = new List <double>();

                        // copy over all the necessary information in the animation channels
                        for (int k = 0; k < ch.PositionKeyCount; k++)
                        {
                            myNode.Translations.Add(ch.PositionKeys[k].Value.ToVector3());
                            myNode.TranslationTime.Add(ch.PositionKeys[k].Time);
                        }

                        for (int k = 0; k < ch.RotationKeyCount; k++)
                        {
                            myNode.Rotations.Add(ch.RotationKeys[k].Value.ToQuaternion());
                            myNode.RotationTime.Add(ch.RotationKeys[k].Time);
                        }

                        for (int k = 0; k < ch.ScalingKeyCount; k++)
                        {
                            myNode.Scalings.Add(ch.ScalingKeys[k].Value.ToVector3());
                            myNode.ScalingTime.Add(ch.ScalingKeys[k].Time);
                        }
                    }
                }

                // create and store the big scene tree
                _rootBone = CreateBoneTree(scene.RootNode, null);

                // set each bone offset
                foreach (var sceneMesh in scene.Meshes)
                {
                    foreach (var rawBone in sceneMesh.Bones)
                    {
                        ClientBone found;
                        if (!_allBoneLookup.TryGetValue(rawBone.Name, out found))
                        {
                            Console.WriteLine("Cannot find bone: " + rawBone.Name);
                            continue;
                        }

                        found.BoneOffset = rawBone.OffsetMatrix.ToMatrix();
                        _allBones.Add(found);
                        _allBoneMappings[found.BoneName] = _allBones.IndexOf(found);
                    }
                }

                // for bones not inside the meshes...? jasdkl;fja;lskdjkfl
                foreach (var boneName in _allBoneLookup.Keys.Where(b =>
                                                                   _allBones.All(b1 => b1.BoneName != b) && b.StartsWith("Bone")))
                {
                    _allBoneLookup[boneName].BoneOffset = _allBoneLookup[boneName].Parent.BoneOffset.Clone();
                    _allBones.Add(_allBoneLookup[boneName]);
                    _allBoneMappings[boneName] = _allBones.IndexOf(_allBoneLookup[boneName]);
                }

                // load the bone weights
                for (int idx = 0; idx < scene.MeshCount; idx++)
                {
                    LoadBoneWeights(scene.Meshes[idx], allMeshes[idx]);
                }

                //_boneTransformStream = new DataStream(MAX_BONES_PER_GEO * sizeof(float) * 16, true, true);
                _boneTransformList = new List <Matrix>(MAX_BONES_PER_GEO);
                for (int i = 0; i < MAX_BONES_PER_GEO; i++)
                {
                    _boneTransformList.Add(Matrix.Identity);
                }
            }

            // main loading loop; copy cover the scene content into the datastreams and then to the buffers
            for (int idx = 0; idx < scene.MeshCount; idx++)
            {
                ClientMesh mesh = allMeshes[idx];

                //create new datastreams.
                mesh.Vertices = new DataStream(mesh.vertSize, true, true);
                mesh.Normals  = new DataStream(mesh.normSize, true, true);
                mesh.Faces    = new DataStream(mesh.faceSize, true, true);

                // create a new material
                mesh.Materials = new ClientMaterial();

                //min and max bounds
                var min = new Vector3(float.MaxValue);
                var max = new Vector3(float.MinValue);
                // copy the buffers
                scene.Meshes[idx].Vertices.ForEach(vertex =>
                {
                    mesh.Vertices.Write(vertex.ToVector3());

                    //keep track of min and max for obj boundaries.
                    min = Vector3.Minimize(min, vertex.ToVector3());
                    max = Vector3.Maximize(max, vertex.ToVector3());
                });
                BoundingBoxes.Add(new BoundingBox(min, max));


                scene.Meshes[idx].Normals.ForEach(normal =>
                {
                    mesh.Normals.Write(normal.ToVector3());
                });
                scene.Meshes[idx].Faces.ForEach(face =>
                {
                    mesh.Faces.WriteRange(face.Indices.ToArray());
                });

                // check if the mesh has texture coordinates
                if (scene.Meshes[idx].HasTextureCoords(0))
                {
                    mesh.TexCoords = new DataStream(mesh.texSize, true, true);
                    scene.Meshes[idx].TextureCoordinateChannels[0].ForEach(texture => {
                        mesh.TexCoords.Write(texture);
                    });

                    mesh.TexCoords.Position = 0;
                }

                // Parse material properties
                ApplyMaterial(scene.Materials[scene.Meshes[idx].MaterialIndex], mesh.Materials);

                // reset datastream positions
                mesh.Vertices.Position = 0;
                mesh.Normals.Position  = 0;
                mesh.Faces.Position    = 0;

                //create vertex vbo and faces ebo.
                mesh.VBOPositions = new Buffer(GraphicsRenderer.Device, mesh.Vertices, mesh.vertSize, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                mesh.VBONormals   = new Buffer(GraphicsRenderer.Device, mesh.Normals, mesh.normSize, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                if (scene.Meshes[idx].HasTextureCoords(0))
                {
                    mesh.VBOTexCoords = new Buffer(GraphicsRenderer.Device, mesh.TexCoords, mesh.texSize, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
                }

                // buffer creation flags
                var ibd = new BufferDescription(
                    mesh.faceSize,
                    ResourceUsage.Immutable,
                    BindFlags.IndexBuffer,
                    CpuAccessFlags.None,
                    ResourceOptionFlags.None,
                    0);

                mesh.EBO = new Buffer(GraphicsRenderer.Device, mesh.Faces, ibd);
            }

            _inverseGlobalTransform = Matrix.Invert(scene.RootNode.Transform.ToMatrix());
        }
        public static Scene ExportToScene(HavokAnimationData anim)
        {
            var scene = new Scene();

            scene.RootNode = new Node("scene_root");

            scene.RootNode.Metadata["FrameRate"]       = new Metadata.Entry(MetaDataType.Int32, 14);
            scene.RootNode.Metadata["TimeSpanStart"]   = new Metadata.Entry(MetaDataType.UInt64, (ulong)0);
            scene.RootNode.Metadata["TimeSpanStop"]    = new Metadata.Entry(MetaDataType.UInt64, (ulong)0);
            scene.RootNode.Metadata["CustomFrameRate"] = new Metadata.Entry(MetaDataType.Float, 1f / anim.FrameDuration);

            scene.RootNode.Metadata["FrontAxisSign"]           = new Metadata.Entry(MetaDataType.Int32, -1);
            scene.RootNode.Metadata["OriginalUnitScaleFactor"] = new Metadata.Entry(MetaDataType.Int32, 100);
            scene.RootNode.Metadata["UnitScaleFactor"]         = new Metadata.Entry(MetaDataType.Int32, 100);



            var a = new Assimp.Animation();

            a.DurationInTicks = anim.Duration * 30;
            a.TicksPerSecond  = 30;
            a.Name            = anim.Name;

            List <Node> animTrackNodes = new List <Node>();

            for (int i = 0; i < anim.TransformTrackIndexToHkxBoneMap.Length; i++)
            {
                int boneIndex = anim.TransformTrackIndexToHkxBoneMap[i];
                if (boneIndex < 0 || boneIndex > anim.hkaSkeleton.Bones.Capacity)
                {
                    continue;
                }
                string trackName = anim.hkaSkeleton.Bones[boneIndex].Name.GetString();
                var    animTrack = new NodeAnimationChannel();
                animTrack.NodeName = trackName;
                for (int f = 0; f < anim.FrameCount; f++)
                {
                    var t = anim.GetTransformOnFrame(i, f, enableLooping: false);
                    animTrack.PositionKeys.Add(new VectorKey(1.0 * f * anim.FrameDuration, new Vector3D(t.Translation.X * -100, t.Translation.Y * 100, t.Translation.Z * 100)));
                    animTrack.ScalingKeys.Add(new VectorKey(1.0 * f * anim.FrameDuration, new Vector3D(t.Scale.X, t.Scale.Y, t.Scale.Z)));
                    var q = t.Rotation;

                    //q.X *= -1;
                    //q.Y *= -1;
                    //q.Z *= -1;
                    //q.W *= -1;
                    q = SapMath.MirrorQuat(q);
                    //q.X *= -1;
                    //q.Y *= -1;
                    //q.Z *= -1;
                    //q.W *= -1;
                    animTrack.RotationKeys.Add(new QuaternionKey(1.0 * f * anim.FrameDuration, new Quaternion(q.W, q.X, q.Y, q.Z)));
                }



                a.NodeAnimationChannels.Add(animTrack);

                var fakeNode = new Node(trackName);
                animTrackNodes.Add(fakeNode);
            }

            List <Node> topLevelTrackNodes = new List <Node>();

            for (int i = 0; i < animTrackNodes.Count; i++)
            {
                var hkxBoneIndex    = anim.TransformTrackIndexToHkxBoneMap[i];
                var parentBoneIndex = anim.hkaSkeleton.ParentIndices[hkxBoneIndex].data;
                if (parentBoneIndex >= 0)
                {
                    var parentTrackIndex = anim.HkxBoneIndexToTransformTrackMap[parentBoneIndex];
                    if (parentTrackIndex >= 0)
                    {
                        animTrackNodes[parentTrackIndex].Children.Add(animTrackNodes[i]);
                    }
                }
                else
                {
                    topLevelTrackNodes.Add(animTrackNodes[i]);
                }
            }

            var actualRootNode = new Node("root");

            if (anim.RootMotion != null)
            {
                var animTrack = new NodeAnimationChannel();
                animTrack.NodeName = actualRootNode.Name;

                for (int f = 0; f < anim.FrameCount; f++)
                {
                    var rootMotionOnFrame = anim.RootMotion.GetSampleClamped(f * anim.FrameDuration);

                    animTrack.PositionKeys.Add(new VectorKey(1.0 * f * anim.FrameDuration, new Vector3D(rootMotionOnFrame.X * -100, rootMotionOnFrame.Y * 100, rootMotionOnFrame.Z * 100)));

                    var q = NQuaternion.CreateFromRotationMatrix(NMatrix.CreateRotationY(rootMotionOnFrame.W));
                    animTrack.RotationKeys.Add(new QuaternionKey(1.0 * f * anim.FrameDuration, new Quaternion(q.W, q.X, q.Y, q.Z)));
                }

                a.NodeAnimationChannels.Add(animTrack);
            }

            foreach (var t in topLevelTrackNodes)
            {
                actualRootNode.Children.Add(t);
            }

            scene.RootNode.Children.Add(actualRootNode);

            scene.Animations.Add(a);

            return(scene);
        }
        private OpenToolkit.Mathematics.Quaternion CalcInterpolatedRotation(float animationTime, NodeAnimationChannel pNodeAnim)
        {
            // TODO add asserts

            if (pNodeAnim.RotationKeyCount == 1)
            {
                return(pNodeAnim.RotationKeys[0].Value.ToOtk());
            }

            var rotationIndex     = FindRotation(animationTime, pNodeAnim);
            var nextRotationIndex = rotationIndex + 1;

            var deltaTime = pNodeAnim.RotationKeys[nextRotationIndex].Time - pNodeAnim.RotationKeys[rotationIndex].Time;
            var factor    = (animationTime - pNodeAnim.RotationKeys[rotationIndex].Time) / deltaTime;

            var startRotationQ = pNodeAnim.RotationKeys[rotationIndex].Value;
            var endRotationQ   = pNodeAnim.RotationKeys[nextRotationIndex].Value;

            var interpolated = Assimp.Quaternion.Slerp(startRotationQ, endRotationQ, (float)factor);

            interpolated.Normalize();

            return(interpolated.ToOtk());
        }
            /// <summary>
            /// Processes the node animation.
            /// </summary>
            /// <param name="channel">The channel.</param>
            /// <param name="ticksPerSecond">The ticks per second.</param>
            /// <param name="list">The list.</param>
            /// <returns></returns>
            protected virtual ErrorCode ProcessNodeAnimation(NodeAnimationChannel channel, double ticksPerSecond, out FastList <HxAnimations.Keyframe> list)
            {
                var posCount   = channel.HasPositionKeys ? channel.PositionKeyCount : 0;
                var rotCount   = channel.HasRotationKeys ? channel.RotationKeyCount : 0;
                var scaleCount = channel.HasScalingKeys ? channel.ScalingKeyCount : 0;
                int maxCount   = Math.Max(posCount, Math.Max(rotCount, scaleCount));
                var ret        = new FastList <HxAnimations.Keyframe>(maxCount);

                if (posCount != rotCount || rotCount != scaleCount)
                {
                    Log(HelixToolkit.Logger.LogLevel.Trace,
                        "Animation Channel is non-uniform lengths." +
                        $" Position={posCount}; Rotation={rotCount}; Scale={scaleCount};" +
                        " Trying to automatically create uniform animation keys");
                    // Adds dummy key if it is empty
                    if (posCount == 0)
                    {
                        channel.PositionKeys.Add(new VectorKey(0, new Vector3D()));
                    }
                    if (rotCount == 0)
                    {
                        channel.RotationKeys.Add(new QuaternionKey(0, new Quaternion()));
                    }
                    if (scaleCount == 0)
                    {
                        channel.ScalingKeys.Add(new VectorKey(0, new Vector3D(1, 1, 1)));
                    }
                    int    i = 0, j = 0, k = 0;
                    double nextT1 = channel.PositionKeys[i].Time,
                           nextT2 = channel.RotationKeys[j].Time,
                           nextT3 = channel.ScalingKeys[k].Time;
                    var minT      = Math.Min(nextT1, Math.Min(nextT2, nextT3));

                    for (int x = 0; x < maxCount && i < posCount && j < rotCount && k < scaleCount; ++x)
                    {
                        ret.Add(new HxAnimations.Keyframe()
                        {
                            Time        = (float)(minT / ticksPerSecond),
                            Translation = channel.PositionKeys[i].Value.ToSharpDXVector3(),
                            Rotation    = channel.RotationKeys[j].Value.ToSharpDXQuaternion(),
                            Scale       = channel.ScalingKeys[k].Value.ToSharpDXVector3(),
                        });
                        nextT1 = (i + 1) < posCount ? channel.PositionKeys[i + 1].Time : double.MaxValue; // Set to max so index will not increase
                        nextT2 = (j + 1) < rotCount ? channel.RotationKeys[j + 1].Time : double.MaxValue;
                        nextT3 = (k + 1) < scaleCount ? channel.ScalingKeys[k + 1].Time : double.MaxValue;

                        minT = Math.Min(nextT1, Math.Min(nextT2, nextT3));
                        if (minT == nextT1)
                        {
                            ++i;
                        }
                        if (minT == nextT2)
                        {
                            ++j;
                        }
                        if (minT == nextT3)
                        {
                            ++k;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < posCount; ++i)
                    {
                        ret.Add(new HxAnimations.Keyframe()
                        {
                            Time        = (float)(channel.PositionKeys[i].Time / ticksPerSecond),
                            Translation = channel.PositionKeys[i].Value.ToSharpDXVector3(),
                            Rotation    = channel.RotationKeys[i].Value.ToSharpDXQuaternion(),
                            Scale       = channel.ScalingKeys[i].Value.ToSharpDXVector3()
                        });
                    }
                }

                list = ret;
                return(ErrorCode.Succeed);
            }
Пример #27
0
        static void Main(string[] args)
        {
            string[] strs = Directory.GetFiles(Environment.CurrentDirectory, "*.dae", SearchOption.TopDirectoryOnly);
            foreach (string path in strs)
            {
                try
                {
                    using (AssimpContext ACont = new AssimpContext())
                    {
                        ACont.SetConfig(new NormalSmoothingAngleConfig(66f));
                        Scene scene = ACont.ImportFile(path, PostProcessSteps.Triangulate);
                        if (!scene.HasAnimations)
                        {
                            Console.WriteLine("Skipping " + path);
                            continue;
                        }
                        Animation anim = scene.Animations[0];
                        if (!anim.HasNodeAnimations)
                        {
                            Console.WriteLine("Invalid animation in " + path);
                            continue;
                        }
                        StringBuilder sb = new StringBuilder();
                        sb.Append("// mcmonkey's animation details file format v0.2\n");
                        sb.Append("general\n");
                        sb.Append("{\n");
                        sb.Append("\tlength: ").Append((anim.DurationInTicks / anim.TicksPerSecond).ToString()).Append(";\n");
                        sb.Append("}\n");
                        for (int i = 0; i < anim.NodeAnimationChannelCount; i++)
                        {
                            NodeAnimationChannel node = anim.NodeAnimationChannels[i];
                            sb.Append(node.NodeName).Append('\n');
                            sb.Append("{\n");
                            Node   found = LookForMatch(scene.RootNode, node.NodeName);
                            string pNode = "<none>";
                            if (found != null)
                            {
                                pNode = found.Parent.Name;
                            }
                            sb.Append("\tparent: " + pNode + ";\n");

                            /*Bone bfound = LookForBone(scene, node.NodeName);
                             * Matrix4x4 mat = Matrix4x4.Identity;
                             * if (bfound != null)
                             * {
                             *  mat = bfound.OffsetMatrix;
                             *  //bpos = bfound.OffsetMatrix.C1 + "=" + bfound.OffsetMatrix.C2 + "=" + bfound.OffsetMatrix.C3;
                             *  //bpos = bfound.OffsetMatrix.A4 + "=" + bfound.OffsetMatrix.B4 + "=" + bfound.OffsetMatrix.C4;
                             * }*/
                            /*sb.Append("\toffset: " + mat.A1 + "=" + mat.A2 + "=" + mat.A3 + "=" + mat.A4 + "=" +
                             *  mat.B1 + "=" + mat.B2 + "=" + mat.B3 + "=" + mat.B4 + "=" +
                             *  mat.C1 + "=" + mat.C2 + "=" + mat.C3 + "=" + mat.C4 + "=" +
                             *  mat.D1 + "=" + mat.D2 + "=" + mat.D3 + "=" + mat.D4 +";\n");*/
                            if (node.HasPositionKeys)
                            {
                                sb.Append("\tpositions: ");
                                for (int x = 0; x < node.PositionKeyCount; x++)
                                {
                                    VectorKey key = node.PositionKeys[x];
                                    sb.Append(key.Time.ToString() + "=" + key.Value.X.ToString() + "=" + key.Value.Y.ToString() + "=" + key.Value.Z.ToString() + " ");
                                }
                                sb.Append(";\n");
                            }
                            if (node.HasRotationKeys)
                            {
                                sb.Append("\trotations: ");
                                for (int x = 0; x < node.RotationKeyCount; x++)
                                {
                                    QuaternionKey key = node.RotationKeys[x];
                                    sb.Append(key.Time.ToString() + "=" + key.Value.X.ToString() + "=" + key.Value.Y.ToString() + "=" + key.Value.Z.ToString() + "=" + key.Value.W + " ");
                                }
                                sb.Append(";\n");
                            }
                            // TODO: Should scaling matter? Probably not.
                            sb.Append("}\n");
                        }
                        File.WriteAllText(path + ".anim", sb.ToString());
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Processing " + path + ": " + ex.ToString());
                }
            }
        }
Пример #28
0
        public static Animations.Animation CreateGenericAnimation(Assimp.Animation animation)
        {
            Animations.Animation STanim = new Animations.Animation();
            STanim.Text = animation.Name;
            float TicksPerSecond = animation.TicksPerSecond != 0 ? (float)animation.TicksPerSecond : 25.0f;
            float Duriation      = (float)animation.DurationInTicks;

            STanim.FrameCount = (int)(Duriation * 30);


            //Load node animations
            if (animation.HasNodeAnimations)
            {
                var _channels = new NodeAnimationChannel[animation.NodeAnimationChannelCount];
                for (int i = 0; i < _channels.Length; i++)
                {
                    _channels[i] = new NodeAnimationChannel();
                    var boneAnim = new Animations.Animation.KeyNode(_channels[i].NodeName);
                    boneAnim.RotType = Animations.Animation.RotationType.EULER;
                    STanim.Bones.Add(boneAnim);

                    STConsole.WriteLine($"Creating Bone Anims {boneAnim.Text} ");

                    for (int frame = 0; frame < STanim.FrameCount; i++)
                    {
                        if (_channels[i].HasPositionKeys)
                        {
                            for (int key = 0; key < _channels[i].PositionKeyCount; key++)
                            {
                                if (frame == _channels[i].PositionKeys[key].Time)
                                {
                                    boneAnim.XPOS.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].PositionKeys[key].Value.X,
                                        Frame = frame,
                                    });
                                    boneAnim.YPOS.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].PositionKeys[key].Value.Y,
                                        Frame = frame,
                                    });
                                    boneAnim.ZPOS.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].PositionKeys[key].Value.Z,
                                        Frame = frame,
                                    });
                                }
                            }
                        }
                        if (_channels[i].HasRotationKeys)
                        {
                            for (int key = 0; key < _channels[i].RotationKeyCount; key++)
                            {
                                if (frame == _channels[i].RotationKeys[key].Time)
                                {
                                    var quat  = _channels[i].RotationKeys[key].Value;
                                    var euler = STMath.ToEulerAngles(quat.X, quat.Y, quat.Z, quat.W);

                                    boneAnim.XROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = euler.X,
                                        Frame = frame,
                                    });
                                    boneAnim.YROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = euler.Y,
                                        Frame = frame,
                                    });
                                    boneAnim.ZROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = euler.Z,
                                        Frame = frame,
                                    });
                                    boneAnim.WROT.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = 1,
                                        Frame = frame,
                                    });
                                }
                            }
                        }
                        if (_channels[i].HasScalingKeys)
                        {
                            for (int key = 0; key < _channels[i].ScalingKeyCount; key++)
                            {
                                if (frame == _channels[i].ScalingKeys[key].Time)
                                {
                                    boneAnim.XSCA.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].ScalingKeys[key].Value.X,
                                        Frame = frame,
                                    });
                                    boneAnim.YSCA.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].ScalingKeys[key].Value.Y,
                                        Frame = frame,
                                    });
                                    boneAnim.ZSCA.Keys.Add(new Animations.Animation.KeyFrame()
                                    {
                                        Value = _channels[i].ScalingKeys[key].Value.Z,
                                        Frame = frame,
                                    });
                                }
                            }
                        }
                    }
                }
            }

            //Load mesh animations
            if (animation.HasMeshAnimations)
            {
                var _meshChannels = new MeshAnimationChannel[animation.MeshAnimationChannelCount];
                for (int i = 0; i < _meshChannels.Length; i++)
                {
                    _meshChannels[i] = new MeshAnimationChannel();
                }
            }

            return(STanim);
        }