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