/// <summary> /// Creates a new VertexAnimationTrack automatically associated with a Vertex. /// </summary> /// <param name="index">Handle to give the track, used for accessing the track later.</param> /// <param name="target">Vertex object which will be affected by this track.</param> /// <returns></returns> public VertexAnimationTrack CreateVertexTrack(ushort handle, VertexData targetVertexData, VertexAnimationType type) { // create a new track and set it's target VertexAnimationTrack track = CreateVertexTrack(handle, type); track.TargetVertexData = targetVertexData; return(track); }
/// <summary> /// Creates an VertexAnimationTrack. /// </summary> /// <param name="handle">Handle to give the track, used for accessing the track later.</param> /// <returns></returns> public VertexAnimationTrack CreateVertexTrack(ushort handle, VertexAnimationType animType) { VertexAnimationTrack track = new VertexAnimationTrack(this, handle, animType); // add the track to the list vertexTrackList[handle] = track; return(track); }
protected void WriteAnimationTrack( BinaryWriter writer, VertexAnimationTrack track ) { var start_offset = writer.Seek( 0, SeekOrigin.Current ); WriteChunk( writer, MeshChunkID.AnimationTrack, 0 ); WriteUShort( writer, (ushort)track.AnimationType ); WriteUShort( writer, track.Handle ); foreach ( var keyFrame in track.KeyFrames ) { if ( keyFrame is VertexMorphKeyFrame ) { var vmkf = keyFrame as VertexMorphKeyFrame; WriteMorphKeyframe( writer, vmkf ); } else if ( keyFrame is VertexPoseKeyFrame ) { var vpkf = keyFrame as VertexPoseKeyFrame; WritePoseKeyframe( writer, vpkf ); } } var end_offset = writer.Seek( 0, SeekOrigin.Current ); writer.Seek( (int)start_offset, SeekOrigin.Begin ); WriteChunk( writer, MeshChunkID.AnimationTrack, (int)( end_offset - start_offset ) ); writer.Seek( (int)end_offset, SeekOrigin.Begin ); }
protected void ReadPoseKeyframe( BinaryReader reader, VertexAnimationTrack track ) { var time = ReadFloat( reader ); var vkf = track.CreateVertexPoseKeyFrame( time ); if ( !IsEOF( reader ) ) { var chunkID = ReadChunk( reader ); while ( !IsEOF( reader ) && chunkID == MeshChunkID.AnimationPoseRef ) { switch ( chunkID ) { case MeshChunkID.AnimationPoseRef: { var poseIndex = ReadUShort( reader ); var influence = ReadFloat( reader ); vkf.AddPoseReference( poseIndex, influence ); break; } } if ( !IsEOF( reader ) ) { chunkID = ReadChunk( reader ); } } if ( !IsEOF( reader ) ) { // backpedal to the start of chunk Seek( reader, -ChunkOverheadSize ); } } }
protected void ReadMorphKeyframe( BinaryReader reader, VertexAnimationTrack track ) { var time = ReadFloat( reader ); var mkf = track.CreateVertexMorphKeyFrame( time ); var vertexCount = track.TargetVertexData.vertexCount; // create/populate vertex buffer var decl = HardwareBufferManager.Instance.CreateVertexDeclaration(); decl.AddElement( 0, 0, VertexElementType.Float3, VertexElementSemantic.Position ); var buffer = HardwareBufferManager.Instance.CreateVertexBuffer( decl, vertexCount, BufferUsage.Static, true ); // lock the buffer for editing var vertices = buffer.Lock( BufferLocking.Discard ); // stuff the floats into the normal buffer ReadFloats( reader, vertexCount*3, vertices ); // unlock the buffer to commit buffer.Unlock(); mkf.VertexBuffer = buffer; }
/// <summary> /// Creates an VertexAnimationTrack. /// </summary> /// <param name="handle">Handle to give the track, used for accessing the track later.</param> /// <param name="animType"></param> /// <returns></returns> public VertexAnimationTrack CreateVertexTrack( ushort handle, VertexAnimationType animType ) { VertexAnimationTrack track = new VertexAnimationTrack( this, handle, animType ); // add the track to the list vertexTrackList[ handle ] = track; return track; }
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); } } }
protected void ReadMorphKeyframe(BinaryMemoryReader reader, VertexAnimationTrack track) { float time = ReadFloat(reader); VertexMorphKeyFrame mkf = track.CreateVertexMorphKeyFrame(time); int vertexCount = track.TargetVertexData.vertexCount; // create/populate vertex buffer HardwareVertexBuffer buffer = HardwareBufferManager.Instance.CreateVertexBuffer( VertexElement.GetTypeSize(VertexElementType.Float3), vertexCount, BufferUsage.Static, true); // lock the buffer for editing IntPtr vertices = buffer.Lock(BufferLocking.Discard); // stuff the floats into the normal buffer ReadFloats(reader, vertexCount * 3, vertices); // unlock the buffer to commit buffer.Unlock(); mkf.VertexBuffer = buffer; }