public void Apply( Entity entity, float time, float weight, bool software, bool hardware ) { foreach ( KeyValuePair<ushort, VertexAnimationTrack> pair in vertexTrackList ) { int handle = pair.Key; VertexAnimationTrack track = pair.Value; VertexData swVertexData; VertexData hwVertexData; VertexData origVertexData; bool firstAnim = false; if ( handle == 0 ) { // shared vertex data firstAnim = !entity.BuffersMarkedForAnimation; swVertexData = entity.SoftwareVertexAnimVertexData; hwVertexData = entity.HardwareVertexAnimVertexData; origVertexData = entity.Mesh.SharedVertexData; entity.MarkBuffersUsedForAnimation(); } else { // sub entity vertex data (-1) SubEntity s = entity.GetSubEntity( handle - 1 ); firstAnim = !s.BuffersMarkedForAnimation; swVertexData = s.SoftwareVertexAnimVertexData; hwVertexData = s.HardwareVertexAnimVertexData; origVertexData = s.SubMesh.vertexData; s.MarkBuffersUsedForAnimation(); } // Apply to both hardware and software, if requested if ( software ) { Debug.Assert( !EqualityComparer<VertexData>.ReferenceEquals( origVertexData, swVertexData ) ); if ( firstAnim && track.AnimationType == VertexAnimationType.Pose ) { // First time through for a piece of pose animated vertex data // We need to copy the original position values to the temp accumulator VertexElement origelem = origVertexData.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.Position ); VertexElement destelem = swVertexData.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.Position ); HardwareVertexBuffer origBuffer = origVertexData.vertexBufferBinding.GetBuffer( origelem.Source ); HardwareVertexBuffer destBuffer = swVertexData.vertexBufferBinding.GetBuffer( destelem.Source ); // Debug.Assert(!EqualityComparer<HardwareVertexBuffer>.ReferenceEquals(origBuffer, destBuffer)); if ( !EqualityComparer<HardwareVertexBuffer>.ReferenceEquals( origBuffer, destBuffer ) ) destBuffer.CopyData( origBuffer, 0, 0, destBuffer.Size, true ); } track.TargetMode = VertexAnimationTargetMode.Software; track.ApplyToVertexData( swVertexData, time, weight, entity.Mesh.PoseList ); } if ( hardware ) { track.TargetMode = VertexAnimationTargetMode.Hardware; track.ApplyToVertexData( hwVertexData, time, weight, entity.Mesh.PoseList ); } } }