Engines/FlatRedBallXNA/FlatRedBall.Content/ModelAnimation/AnimatedModelProcessor.cs
/// <summary>
/// Go through the vertex channels in the geometry and replace the 
/// BoneWeightCollection objects with weight and index channels.
/// </summary>
/// <param name="geometry">The geometry to process.</param>
/// <param name="vertexChannelIndex">The index of the vertex channel to process.</param>
/// <param name="context">The processor context.</param>
Go through the vertex channels in the geometry and replace the
BoneWeightCollection objects with weight and index channels.
Go through the vertex channels in the geometry and replace the BoneWeightCollection objects with weight and index channels .
protected override void ProcessVertexChannel(GeometryContent geometry, int vertexChannelIndex, ContentProcessorContext context)
        {
            bool boneCollectionsWithZeroWeights = false;
            if (geometry.Vertices.Channels[vertexChannelIndex].Name == VertexChannelNames.Weights())
            {
                int meshIndex = (int)geometry.Parent.OpaqueData["MeshIndex"];
                BoneIndexer indexer = indexers[meshIndex];
                VertexChannel<BoneWeightCollection> vc = 
                    (VertexChannel<BoneWeightCollection>)
                    geometry.Vertices.Channels[vertexChannelIndex];
                int maxBonesPerVertex = 0;
                for (int i = 0; i < vc.Count; i++)
                {
                    int count = vc[i].Count;
                    if (count > maxBonesPerVertex)
                        maxBonesPerVertex = count;
                }
                Color[] weightsToAdd = new Color[vc.Count];
                Byte4[] indicesToAdd = new Byte4[vc.Count];
                for (int i = 0; i < vc.Count; i++)
                {
                    BoneWeightCollection bwc = vc[i];
                    if (bwc.Count == 0)
                    {
                        boneCollectionsWithZeroWeights = true;
                        continue;
                    }
                    bwc.NormalizeWeights(4);
                    int count = bwc.Count;
                    if (count>maxBonesPerVertex)
                        maxBonesPerVertex = count;
                    Vector4 bi = new Vector4();
                    bi.X = count > 0 ? indexer.GetBoneIndex(bwc[0].BoneName) : (byte)0;
                    bi.Y = count > 1 ? indexer.GetBoneIndex(bwc[1].BoneName) : (byte)0;
                    bi.Z = count > 2 ? indexer.GetBoneIndex(bwc[2].BoneName) : (byte)0;
                    bi.W = count > 3 ? indexer.GetBoneIndex(bwc[3].BoneName) : (byte)0;
                    indicesToAdd[i] = new Byte4(bi);
                    Vector4 bw = new Vector4();
                    bw.X = count > 0 ? bwc[0].Weight : 0;
                    bw.Y = count > 1 ? bwc[1].Weight : 0;
                    bw.Z = count > 2 ? bwc[2].Weight : 0;
                    bw.W = count > 3 ? bwc[3].Weight : 0;
                    weightsToAdd[i] = new Color(bw);
                }
                geometry.Vertices.Channels.Remove(vc);
                geometry.Vertices.Channels.Add<Byte4>(VertexElementUsage.BlendIndices.ToString(), indicesToAdd);
                geometry.Vertices.Channels.Add<Color>(VertexElementUsage.BlendWeight.ToString(), weightsToAdd);
            }
            else
            {
                base.ProcessVertexChannel(geometry, vertexChannelIndex, context);
            }
            if (boneCollectionsWithZeroWeights)
                context.Logger.LogWarning("", geometry.Identity,
                    "BonesWeightCollections with zero weights found in geometry.");
        }
protected override void ProcessVertexChannel ( GeometryContent geometry , int vertexChannelIndex , ContentProcessorContext context ) { bool boneCollectionsWithZeroWeights = false ; if ( geometry . Vertices . Channels [ vertexChannelIndex ] . Name == VertexChannelNames . Weights ( ) ) { int meshIndex = ( int ) geometry . Parent . OpaqueData [ " " ] ; BoneIndexer indexer = indexers [ meshIndex ] ; VertexChannel < BoneWeightCollection > vc = ( VertexChannel < BoneWeightCollection > ) geometry . Vertices . Channels [ vertexChannelIndex ] ; int maxBonesPerVertex = 0 ; for ( int i = 0 ; i < vc . Count ; i ++ ) { int count = vc [ i ] . Count ; if ( count > maxBonesPerVertex ) maxBonesPerVertex = count ; } Color [ ] weightsToAdd = new Color [ vc . Count ] ; Byte4 [ ] indicesToAdd = new Byte4 [ vc . Count ] ; for ( int i = 0 ; i < vc . Count ; i ++ ) { BoneWeightCollection bwc = vc [ i ] ; if ( bwc . Count == 0 ) { boneCollectionsWithZeroWeights = true ; continue ; } bwc . NormalizeWeights ( 4 ) ; int count = bwc . Count ; if ( count > maxBonesPerVertex ) maxBonesPerVertex = count ; Vector4 bi = new Vector4 ( ) ; bi . X = count > 0 ? indexer . GetBoneIndex ( bwc [ 0 ] . BoneName ) : ( byte ) 0 ; bi . Y = count > 1 ? indexer . GetBoneIndex ( bwc [ 1 ] . BoneName ) : ( byte ) 0 ; bi . Z = count > 2 ? indexer . GetBoneIndex ( bwc [ 2 ] . BoneName ) : ( byte ) 0 ; bi . W = count > 3 ? indexer . GetBoneIndex ( bwc [ 3 ] . BoneName ) : ( byte ) 0 ; indicesToAdd [ i ] = new Byte4 ( bi ) ; Vector4 bw = new Vector4 ( ) ; bw . X = count > 0 ? bwc [ 0 ] . Weight : 0 ; bw . Y = count > 1 ? bwc [ 1 ] . Weight : 0 ; bw . Z = count > 2 ? bwc [ 2 ] . Weight : 0 ; bw . W = count > 3 ? bwc [ 3 ] . Weight : 0 ; weightsToAdd [ i ] = new Color ( bw ) ; } geometry . Vertices . Channels . Remove ( vc ) ; geometry . Vertices . Channels . Add < Byte4 > ( VertexElementUsage . BlendIndices . ToString ( ) , indicesToAdd ) ; geometry . Vertices . Channels . Add < Color > ( VertexElementUsage . BlendWeight . ToString ( ) , weightsToAdd ) ; } else { base . ProcessVertexChannel ( geometry , vertexChannelIndex , context ) ; } if ( boneCollectionsWithZeroWeights ) context . Logger . LogWarning ( " " , geometry . Identity , " " ) ; }
Go through the vertex channels in the geometry and replace the
BoneWeightCollection objects with weight and index channels.
Go through the vertex channels in the geometry and replace the BoneWeightCollection objects with weight and index channels .
// Skin channels are passed in from importers as BoneWeightCollection objects // Add weights as colors (Converts well to 4 floats) // and indices as packed 4byte vectors. // Go through the BoneWeightCollections and create a new // weightsToAdd and indicesToAdd array for each BoneWeightCollection. // Add the appropriate bone indices based on the bone names in the // BoneWeightCollection // Remove the old BoneWeightCollection channel // Add the new channels // No skinning info, so we let the base class process the channel
geometry
GeometryContent
The geometry to process.
The geometry to process .
vertexChannelIndex
int
The index of the vertex channel to process.
The index of the vertex channel to process .
context
ContentProcessorContext
The processor context.
The processor context .