private void ApplyVertexAnimation( bool hardwareAnimation, bool stencilShadows )
{
bool swAnim = !hardwareAnimation || stencilShadows || ( this.softwareAnimationRequests > 0 );
// make sure we have enough hardware animation elements to play with
if ( hardwareAnimation )
{
if ( this.hardwareVertexAnimVertexData != null &&
this.mesh.SharedVertexDataAnimationType != VertexAnimationType.None )
{
this.InitHardwareAnimationElements( this.hardwareVertexAnimVertexData,
( this.mesh.SharedVertexDataAnimationType
== VertexAnimationType.Pose )
?
this.hardwarePoseCount
: (ushort)1 );
}
foreach ( SubEntity subEntity in this.subEntityList )
{
SubMesh subMesh = subEntity.SubMesh;
VertexAnimationType type = subMesh.VertexAnimationType;
if ( type != VertexAnimationType.None && !subMesh.useSharedVertices )
{
this.InitHardwareAnimationElements( subEntity.HardwareVertexAnimVertexData,
( type == VertexAnimationType.Pose )
? subEntity.HardwarePoseCount
: (ushort)1 );
}
}
}
else
{
// May be blending multiple poses in software
// Suppress hardware upload of buffers
if ( this.softwareVertexAnimVertexData != null &&
this.mesh.SharedVertexDataAnimationType == VertexAnimationType.Pose )
{
VertexElement elem =
this.softwareVertexAnimVertexData.vertexDeclaration.FindElementBySemantic(
VertexElementSemantic.Position );
HardwareVertexBuffer buf =
this.softwareVertexAnimVertexData.vertexBufferBinding.GetBuffer( elem.Source );
buf.SuppressHardwareUpdate( true );
}
foreach ( SubEntity subEntity in this.subEntityList )
{
SubMesh subMesh = subEntity.SubMesh;
if ( !subMesh.useSharedVertices && subMesh.VertexAnimationType == VertexAnimationType.Pose )
{
VertexData data = subEntity.SoftwareVertexAnimVertexData;
VertexElement elem =
data.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.Position );
HardwareVertexBuffer buf = data.vertexBufferBinding.GetBuffer( elem.Source );
buf.SuppressHardwareUpdate( true );
}
}
}
// Now apply the animation(s)
// Note - you should only apply one morph animation to each set of vertex data
// at once; if you do more, only the last one will actually apply
this.MarkBuffersUnusedForAnimation();
foreach ( AnimationState state in this.animationState.EnabledAnimationStates )
{
Animation anim = this.mesh.GetAnimation( state.Name );
if ( anim != null )
{
anim.Apply( this,
state.Time,
state.Weight,
swAnim,
hardwareAnimation );
}
}
// Deal with cases where no animation applied
this.RestoreBuffersForUnusedAnimation( hardwareAnimation );
// Unsuppress hardware upload if we suppressed it
if ( !hardwareAnimation )
{
if ( this.softwareVertexAnimVertexData != null &&
this.mesh.SharedVertexDataAnimationType == VertexAnimationType.Pose )
{
VertexElement elem =
this.softwareVertexAnimVertexData.vertexDeclaration.FindElementBySemantic(
VertexElementSemantic.Position );
HardwareVertexBuffer buf =
this.softwareVertexAnimVertexData.vertexBufferBinding.GetBuffer( elem.Source );
buf.SuppressHardwareUpdate( false );
}
foreach ( SubEntity subEntity in this.subEntityList )
{
SubMesh subMesh = subEntity.SubMesh;
if ( !subMesh.useSharedVertices &&
subMesh.VertexAnimationType == VertexAnimationType.Pose )
{
VertexData data = subEntity.SoftwareVertexAnimVertexData;
VertexElement elem =
data.vertexDeclaration.FindElementBySemantic( VertexElementSemantic.Position );
HardwareVertexBuffer buf = data.vertexBufferBinding.GetBuffer( elem.Source );
buf.SuppressHardwareUpdate( false );
}
}
}
}