// Internal creation internal BonePose(ModelBone bone, ModelBoneCollection bones, BonePose[] anims) { // Set the values according to the bone index = bone.Index; name = bone.Name; defaultMatrix = bone.Transform; if (bone.Parent != null) { parent = anims[bone.Parent.Index]; } anims[index] = this; // Recurse on children List <BonePose> childList = new List <BonePose>(); foreach (ModelBone child in bone.Children) { BonePose newChild = new BonePose( bones[child.Index], bones, anims); childList.Add(newChild); } children = new BonePoseCollection(childList); }
/// <summary> /// Creates a new instance of ModelAnimator. /// </summary> /// <param name="game">The game to which this component will belong.</param> /// <param name="model">The model to be animated.</param> public ModelAnimator(Game game, Model model) : base(game) { this.model = model; animations = AnimationInfoCollection.FromModel(model); bonePoses = BonePoseCollection.FromModelBoneCollection( model.Bones); numMeshes = model.Meshes.Count; // Find total number of effects used by the model numEffects = 0; foreach (ModelMesh mesh in model.Meshes) { foreach (Effect effect in mesh.Effects) { numEffects++; } } // Initialize the arrays that store effect parameters modelEffects = new Effect[numEffects]; worldParams = new EffectParameter[numEffects]; matrixPaletteParams = new EffectParameter[numEffects]; InitializeEffectParams(); pose = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(pose); // Get all the skinning info for the model Dictionary <string, object> modelTagInfo = (Dictionary <string, object>)model.Tag; if (modelTagInfo == null) { throw new Exception("Model Processor must subclass AnimatedModelProcessor."); } skinInfo = (SkinInfoCollection[])modelTagInfo["SkinInfo"]; if (skinInfo == null) { throw new Exception("Model processor must pass skinning info through the tag."); } palette = new Matrix[model.Meshes.Count][]; for (int i = 0; i < skinInfo.Length; i++) { if (Util.IsSkinned(model.Meshes[i])) { palette[i] = new Matrix[skinInfo[i].Count]; } else { palette[i] = null; } } // Update after AnimationController by default base.UpdateOrder = 1; game.Components.Add(this); // Test to see if model has too many bones for (int i = 0; i < model.Meshes.Count; i++) { if (palette[i] != null && matrixPaletteParams[i] != null) { Matrix[] meshPalette = palette[i]; try { matrixPaletteParams[i].SetValue(meshPalette); } catch { throw new Exception("Model has too many skinned bones for the matrix palette."); } } } }