public unsafe void Update(ModelViewHierarchyUpdater hierarchy, AnimationClipResult result)
        {
            // Check if we need to regenerate "update channels" (i.e. how to copy data from result to hierarchy)
            if (updateChannels == null || // First time?...
                currentSourceChannels != result.Channels || // ... or changed?
                currentSourceChannels.Count != currentSourceChannelCount)    // .. or modified? (could only append channel)
            {
                RegenerateUpdateChannels(hierarchy, result.Channels);
                currentSourceChannels     = result.Channels;
                currentSourceChannelCount = currentSourceChannels.Count;
            }

            // Copy results to node hierarchy
            fixed(byte *structures = result.Data)
            {
                foreach (var updateChannel in updateChannels)
                {
                    var structureData = (float *)(structures + updateChannel.Offset);
                    var factor        = *structureData++;
                    if (factor == 0.0f)
                    {
                        continue;
                    }

                    switch (updateChannel.Type)
                    {
                    case ChannelType.Translation:
                        Utilities.Read((IntPtr)structureData, ref hierarchy.NodeTransformations[updateChannel.Index].Transform.Translation);
                        break;

                    case ChannelType.Rotation:
                        Utilities.Read((IntPtr)structureData, ref hierarchy.NodeTransformations[updateChannel.Index].Transform.Rotation);
                        break;

                    case ChannelType.Scaling:
                        Utilities.Read((IntPtr)structureData, ref hierarchy.NodeTransformations[updateChannel.Index].Transform.Scaling);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
        }
        private void RegenerateUpdateChannels(ModelViewHierarchyUpdater hierarchy, List <AnimationBlender.Channel> channels)
        {
            var newUpdateChannels = new List <UpdateChannel>();

            // TODO: Temporary implementation due to lack of time before first release.
            foreach (var channel in channels)
            {
                string nodeName = channel.NodeName;
                if (nodeName == null)
                {
                    continue;
                }

                var updateChannel = new UpdateChannel();
                updateChannel.Index = -1;

                var hierarchyNodes = hierarchy.Nodes;
                for (int i = 0; i < hierarchyNodes.Length; ++i)
                {
                    var node = hierarchyNodes[i];
                    if (node.Name == nodeName)
                    {
                        updateChannel.Index = i;
                        break;
                    }
                }

                if (updateChannel.Index == -1)
                {
                    // TODO: Warning?
                    //throw new InvalidOperationException(string.Format("Could not find matching node in animation for {0}", nodeName));
                    continue;
                }

                updateChannel.Offset = channel.Offset;
                updateChannel.Type   = channel.Type;

                newUpdateChannels.Add(updateChannel);
            }

            updateChannels = newUpdateChannels.ToArray();
        }
示例#3
0
        public static void Update(ModelViewHierarchyUpdater hierarchy, RenderModel renderModel)
        {
            var boneMatrices = staticBoneMatrices;

            foreach (var meshes in renderModel.RenderMeshes)
            {
                if (meshes == null)
                {
                    continue;
                }

                foreach (var renderMesh in meshes)
                {
                    var mesh     = renderMesh.Mesh;
                    var skinning = mesh.Skinning;
                    if (skinning == null)
                    {
                        continue;
                    }

                    var bones = skinning.Bones;

                    // Make sure there is enough spaces in boneMatrices
                    if (boneMatrices == null || bones.Length > boneMatrices.Length)
                    {
                        staticBoneMatrices = boneMatrices = new Matrix[bones.Length];
                    }

                    for (int index = 0; index < bones.Length; index++)
                    {
                        var nodeIndex = bones[index].NodeIndex;

                        // Compute bone matrix
                        Matrix.Multiply(ref bones[index].LinkToMeshMatrix, ref hierarchy.NodeTransformations[nodeIndex].WorldMatrix, out boneMatrices[index]);
                    }

                    // Upload bones
                    renderMesh.Mesh.Parameters.Set(TransformationSkinningKeys.BlendMatrixArray, boneMatrices, 0, bones.Length);
                }
            }
        }