GetBoneIndex() public method

Creates an index for a bone if one doesn't exist, and returns the palette index for the given bone.
public GetBoneIndex ( string boneName ) : byte
boneName string The name of the bone.
return byte
Exemplo n.º 1
0
 private void CreatePaletteIndices(MeshContent mesh)
 {
     foreach (GeometryContent meshPart in mesh.Geometry)
     {
         int         meshIndex = (int)mesh.OpaqueData["MeshIndex"];
         BoneIndexer indexer   = indexers[meshIndex];
         foreach (VertexChannel channel in meshPart.Vertices.Channels)
         {
             if (channel.Name == VertexChannelNames.Weights())
             {
                 VertexChannel <BoneWeightCollection> vc =
                     (VertexChannel <BoneWeightCollection>)channel;
                 foreach (BoneWeightCollection boneWeights in vc)
                 {
                     foreach (BoneWeight weight in boneWeights)
                     {
                         indexer.GetBoneIndex(weight.BoneName);
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 2
0
        /// <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>
        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];
                // Skin channels are passed in from importers as BoneWeightCollection objects
                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;
                    }
                }

                // Add weights as colors (Converts well to 4 floats)
                // and indices as packed 4byte vectors.
                Color[] weightsToAdd = new Color[vc.Count];
                Byte4[] indicesToAdd = new Byte4[vc.Count];

                // Go through the BoneWeightCollections and create a new
                // weightsToAdd and indicesToAdd array for each BoneWeightCollection.
                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;
                    }

                    // Add the appropriate bone indices based on the bone names in the
                    // BoneWeightCollection
                    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);
                }

                // Remove the old BoneWeightCollection channel
                geometry.Vertices.Channels.Remove(vc);
                // Add the new channels
                geometry.Vertices.Channels.Add <Byte4>(VertexElementUsage.BlendIndices.ToString(), indicesToAdd);
                geometry.Vertices.Channels.Add <Color>(VertexElementUsage.BlendWeight.ToString(), weightsToAdd);
            }
            else
            {
                // No skinning info, so we let the base class process the channel
                base.ProcessVertexChannel(geometry, vertexChannelIndex, context);
            }
            if (boneCollectionsWithZeroWeights)
            {
                context.Logger.LogWarning("", geometry.Identity,
                                          "BonesWeightCollections with zero weights found in geometry.");
            }
        }
Exemplo n.º 3
0
        private SkinInfoContentCollection[] ProcessSkinInfo(ModelContent model)
        {
            SkinInfoContentCollection[] info     = new SkinInfoContentCollection[model.Meshes.Count];
            Dictionary <string, int>    boneDict = new Dictionary <string, int>();

            //if (model.Bones.Count > maximumNumberOfPCBones)
            //{
            //    throw new Exception("There are too many bones! You have " + model.Bones.Count + " and you can only have " + maximumNumberOfPCBones);
            //}

            foreach (ModelBoneContent b in model.Bones)
            {
                if (b.Name != null && !boneDict.ContainsKey(b.Name))
                {
                    boneDict.Add(b.Name, b.Index);
                }
            }

            for (int i = 0; i < info.Length; i++)
            {
                info[i] = new SkinInfoContentCollection();
                BoneIndexer indexer = indexers[i];
                ReadOnlyCollection <string> skinnedBoneNames = indexer.SkinnedBoneNames;

                Matrix[] absoluteTransforms = new Matrix[model.Bones.Count];
                CalculateAbsoluteTransforms(model.Bones[0], absoluteTransforms);

                Matrix absoluteMeshTransform;
                if (absoluteMeshTransforms == null)
                {
                    absoluteMeshTransform = absoluteTransforms[model.Meshes[i].ParentBone.Index];
                }
                else
                {
                    absoluteMeshTransform = absoluteMeshTransforms[i];
                }

                for (int j = 0; j < skinnedBoneNames.Count; j++)
                {
                    string          name    = skinnedBoneNames[j];
                    SkinInfoContent content = new SkinInfoContent();

                    try
                    {
                        content.BoneIndex = boneDict[name];
                    }
                    catch (KeyNotFoundException knfe)
                    {
                        string error = "Could not find a bone by the name of " + name + ".  This is skinned bone index " + j + ".";

                        error += "\nThere are " + skinnedBoneNames.Count + " skinned bones:";

                        for (int boneIndex = 0; boneIndex < skinnedBoneNames.Count; boneIndex++)
                        {
                            error += "\n " + skinnedBoneNames[boneIndex];
                        }

                        error += "\nThere are " + model.Bones.Count + " bones:";

                        foreach (ModelBoneContent b in model.Bones)
                        {
                            error += "\n " + b.Name;
                        }

                        throw new KeyNotFoundException(error);
                    }

                    content.PaletteIndex             = indexer.GetBoneIndex(name);
                    content.InverseBindPoseTransform = absoluteMeshTransform *
                                                       Matrix.Invert(absoluteTransforms[boneDict[name]]);
                    content.BoneName = name;
                    info[i].Add(content);
                }
            }
            return(info);
        }