/// <summary> /// Replaces a bone in this skeleton's list of bones with a specific bone. /// </summary> /// <param name="Index">The index of the bone to replace/update.</param> /// <param name="Bne">The bone with which to replace the bone at the specified index.</param> public void UpdateBone(int Index, Bone Bne) { m_Bones[Index] = Bne; }
/// <summary> /// Transforms the vertices in a mesh to their location in 3D-space based on /// the location of a bone. /// </summary> /// <param name="Bne">The bone to start with (should be a skeleton's ROOT bone).</param> /// <param name="Effect">The BasicEffect instance used for rendering.</param> public void TransformVertices2(Bone Bne, ref Matrix World) { int BoneIndex = 0; Matrix WorldMat = World * Bne.AbsoluteTransform; for (BoneIndex = 0; BoneIndex < m_BndCount; BoneIndex++) { if (Bne.BoneName == m_BoneNames[m_BoneBindings[BoneIndex].BoneIndex]) break; } if (BoneIndex < m_BndCount) { for (int i = 0; i < m_BoneBindings[BoneIndex].VertexCount; i++) { int VertexIndex = m_BoneBindings[BoneIndex].FirstVertex + i; Vector3 RelativeVertex = new Vector3(m_VertexData[VertexIndex, 0], m_VertexData[VertexIndex, 1], m_VertexData[VertexIndex, 2]); Vector3 RelativeNormal = new Vector3(m_VertexData[VertexIndex, 3], m_VertexData[VertexIndex, 4], m_VertexData[VertexIndex, 5]); WorldMat *= Matrix.CreateTranslation(RelativeVertex); Vector3.Transform(RelativeVertex, WorldMat); m_TransformedVertices[VertexIndex].Coord.X = WorldMat.M41; m_TransformedVertices[VertexIndex].Coord.Y = WorldMat.M42; m_TransformedVertices[VertexIndex].Coord.Z = WorldMat.M43; WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeVertex.X, -RelativeVertex.Y, -RelativeVertex.Z)); WorldMat *= Matrix.CreateTranslation(RelativeNormal); Vector3.TransformNormal(RelativeNormal, WorldMat); m_TransformedVertices[VertexIndex].Normal.X = WorldMat.M41; m_TransformedVertices[VertexIndex].Normal.Y = WorldMat.M42; m_TransformedVertices[VertexIndex].Normal.Z = WorldMat.M43; WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeNormal.X, -RelativeNormal.Y, -RelativeNormal.Z)); } for (int i = 0; i < m_BoneBindings[BoneIndex].BlendedVertexCount; i++) { int VertexIndex = m_RealVertexCount + m_BoneBindings[BoneIndex].FirstBlendedVert + i; Vector3 RelativeVertex = new Vector3(m_VertexData[VertexIndex, 0], m_VertexData[VertexIndex, 1], m_VertexData[VertexIndex, 2]); Vector3 RelativeNormal = new Vector3(m_VertexData[VertexIndex, 3], m_VertexData[VertexIndex, 4], m_VertexData[VertexIndex, 5]); WorldMat *= Matrix.CreateTranslation(RelativeVertex); Vector3.Transform(RelativeVertex, WorldMat); m_TransformedVertices[VertexIndex].Coord.X = WorldMat.M41; m_TransformedVertices[VertexIndex].Coord.Y = WorldMat.M42; m_TransformedVertices[VertexIndex].Coord.Z = WorldMat.M43; WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeVertex.X, -RelativeVertex.Y, -RelativeVertex.Z)); WorldMat *= Matrix.CreateTranslation(RelativeNormal); Vector3.TransformNormal(RelativeNormal, WorldMat); m_TransformedVertices[VertexIndex].Normal.X = WorldMat.M41; m_TransformedVertices[VertexIndex].Normal.Y = WorldMat.M42; m_TransformedVertices[VertexIndex].Normal.Z = WorldMat.M43; WorldMat *= Matrix.CreateTranslation(new Vector3(-RelativeNormal.X, -RelativeNormal.Y, -RelativeNormal.Z)); } } if (Bne.NumChildren == 1) TransformVertices2(Bne.Children[0], ref World); else if (Bne.NumChildren > 1) { for (int i = 0; i < Bne.NumChildren; i++) TransformVertices2(Bne.Children[i], ref World); } }
public Skeleton(GraphicsDevice Device, byte[] Filedata) { MemoryStream MemStream = new MemoryStream(Filedata); BinaryReader Reader = new BinaryReader(MemStream); m_Version = Endian.SwapUInt32(Reader.ReadUInt32()); m_Name = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte())); m_BoneCount = Endian.SwapUInt16(Reader.ReadUInt16()); m_Bones = new Bone[m_BoneCount]; for (int i = 0; i < m_BoneCount; i++) { Endian.SwapUInt32(Reader.ReadUInt32()); //1 in hexadecimal... typical useless Maxis value... Bone Bne = new Bone(); Bne.ID = i; Bne.BoneName = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte())); Bne.ParentName = Encoding.ASCII.GetString(Reader.ReadBytes(Reader.ReadByte())); Bne.HasPropertyList = Reader.ReadByte(); if (Bne.HasPropertyList == 1) Bne.PList = ReadPropList(Reader); //Little Endian Bne.Translations = new float[3]; Bne.Translations[0] = Reader.ReadSingle(); Bne.Translations[1] = Reader.ReadSingle(); Bne.Translations[2] = Reader.ReadSingle(); Bne.Quaternions = new float[4]; Bne.Quaternions[0] = Reader.ReadSingle(); Bne.Quaternions[1] = Reader.ReadSingle(); Bne.Quaternions[2] = Reader.ReadSingle(); Bne.Quaternions[3] = Reader.ReadSingle(); Bne.CanTranslate = Endian.SwapInt32(Reader.ReadInt32()); Bne.CanRotate = Endian.SwapInt32(Reader.ReadInt32()); Bne.CanUseBlending = Endian.SwapInt32(Reader.ReadInt32()); //Little endian. Bne.CanWiggle = Reader.ReadSingle(); Bne.WiggleAmount = Reader.ReadSingle(); Bne.BoneEffect = new BasicEffect(Device, null); Bne.Children = new Bone[m_BoneCount - i - 1]; m_Bones[i] = Bne; } for(int i = 0; i < m_Bones.Length; i++) { for(int j = 0; j < m_Bones.Length; j++) { if (m_Bones[i].ParentName == m_Bones[j].BoneName) m_Bones[i].Parent = m_Bones[j]; } } foreach (Bone Bne in m_Bones) { Bne.ComputeAbsoluteTransform(); } Reader.Close(); }