public static void ExtractModelMeshData(ModelMesh mm, ref Matrix xform, List <Vector3> vertices, List <TriangleVertexIndices> indices, string name, bool includeNoncoll) { foreach (ModelMeshPart mmp in mm.MeshParts) { if (!includeNoncoll) { EffectAnnotation annot = mmp.Effect.CurrentTechnique.Annotations["collide"]; if (annot != null && annot.GetValueBoolean() == false) { Console.WriteLine("Ignoring model mesh part {0}:{1} because it's set to not collide.", name, mm.Name); continue; } } ExtractModelMeshPartData(mm, mmp, ref xform, vertices, indices, name); } }
public ModelDraw(Model m, string name) { name_ = name; model_ = m; world_ = Matrix.Identity; // I'll need the world-space pose of each bone matrices_ = new Matrix[m.Bones.Count]; // inverse bind pose for skinning pose only object ibp; Dictionary <string, object> tagDict = m.Tag as Dictionary <string, object>; if (tagDict == null) { throw new System.ArgumentException("Model {0} wasn't processed with the AnimationProcessor.", name); } if (tagDict.TryGetValue("InverseBindPose", out ibp)) { inverseBindPose_ = ibp as SkinnedBone[]; CalculateIndices(); } // information about bounds, in case the bind pose contains scaling object bi; if (((Dictionary <string, object>)m.Tag).TryGetValue("BoundsInfo", out bi)) { boundsInfo_ = bi as BoundsInfo; } if (boundsInfo_ == null) { boundsInfo_ = new BoundsInfo(1, 0); } // pick apart the model, so I know how to draw the different pieces List <Chunk> chl = new List <Chunk>(); foreach (ModelMesh mm in m.Meshes) { int mmpIx = 0; foreach (ModelMeshPart mmp in mm.MeshParts) { ++mmpIx; // chunk is used to draw an individual subset Chunk ch = new Chunk(); // set up all the well-known parameters through the EffectConfig helper. ch.Fx = new EffectConfig(mmp.Effect, mm.Name + "_" + mmpIx.ToString()); // if this effect is skinned, set up additional data if (ch.Fx.HasPose) { // If I haven't built the pose, then build it now if (pose_ == null) { if (inverseBindPose_ == null) { throw new System.ArgumentNullException(String.Format( "The model {0} should have an inverse bone transform because it has a pose, but it doesn't.", name)); } // Send bones as sets of three 4-vectors (column major) to the shader pose_ = new Vector4[inverseBindPose_.Length * 3]; for (int i = 0; i != inverseBindPose_.Length; ++i) { // start out with the identity pose (which is terrible) pose_[i * 3 + 0] = new Vector4(1, 0, 0, 0); pose_[i * 3 + 1] = new Vector4(0, 1, 0, 0); pose_[i * 3 + 2] = new Vector4(0, 0, 1, 0); } } ch.Fx.PoseData = pose_; } ch.Mesh = mm; ch.Part = mmp; // check out whether the technique contains transparency EffectAnnotation ea = mmp.Effect.CurrentTechnique.Annotations["transparent"]; if (ea != null && ea.GetValueBoolean() == true) { ch.Deferred = true; } chl.Add(ch); } } // use a native array instead of a List<> for permanent storage chunks_ = chl.ToArray(); // calculate bounds information (won't take animation into account) CalcBoundingSphere(); // animate this instance based on the bind pose Animation an = GetAnimation("$bind$", false); if (an != null) { instance_ = new AnimationInstance(an); instance_.Advance(0); } }