private void CopyBodyVertices(Bone Bne) { BoneBinding boneBinding = BodyMesh.BoneBindings.FirstOrDefault(x => BodyMesh.Bones[(int)x.BoneIndex] == Bne.Name); if (boneBinding != null) { for (int i = 0; i < (boneBinding.RealVertexCount - 2); i += 3) { int vertexIndex = (int)boneBinding.FirstRealVertexIndex + i; BodyMesh.TransformedVertices[vertexIndex].BoneBinding = boneBinding.BoneIndex; BodyMesh.TransformedVertices[vertexIndex].Position = BodyMesh.RealVertices[vertexIndex].Position; BodyMesh.TransformedVertices[vertexIndex + 1].BoneBinding = boneBinding.BoneIndex; BodyMesh.TransformedVertices[vertexIndex + 1].Position = BodyMesh.RealVertices[vertexIndex + 1].Position; BodyMesh.TransformedVertices[vertexIndex + 2].BoneBinding = boneBinding.BoneIndex; BodyMesh.TransformedVertices[vertexIndex + 2].Position = BodyMesh.RealVertices[vertexIndex + 2].Position; BodyMesh.TransformedVertices[vertexIndex].TextureCoordinate = BodyMesh.RealVertices[vertexIndex].TextureCoordinate; BodyMesh.TransformedVertices[vertexIndex + 1].TextureCoordinate = BodyMesh.RealVertices[vertexIndex + 1].TextureCoordinate; BodyMesh.TransformedVertices[vertexIndex + 2].TextureCoordinate = BodyMesh.RealVertices[vertexIndex + 2].TextureCoordinate; BodyMesh.TransformedVertices[vertexIndex].Normal = BodyMesh.RealVertices[vertexIndex].Normal; BodyMesh.TransformedVertices[vertexIndex + 1].Normal = BodyMesh.RealVertices[vertexIndex + 1].Normal; BodyMesh.TransformedVertices[vertexIndex + 2].Normal = BodyMesh.RealVertices[vertexIndex + 2].Normal; } } foreach (Bone Child in Bne.Children) { CopyBodyVertices(Child); } }
public void Merge(BoneBinding other) { if (Position == null) { Position = other.Position; } else if (other.Position != null) { Position.Merge(other.Position); } if (Rotation == null) { Rotation = other.Rotation; } else if (other.Rotation != null) { Rotation.Merge(other.Rotation); } }
/// <summary> /// Transforms all vertices in a given mesh to their correct positions. /// </summary> /// <param name="Msh">The mesh to transform.</param> /// <param name="bone">The bone to transform to.</param> private void TransformVertices(Mesh Msh, Bone bone, MeshType MshType) { switch (MshType) { case MeshType.Head: for (int i = 0; i < Msh.TotalVertexCount; i++) { //Transform the head vertices' position by the absolute transform //for the headbone (which is always bone 17) to render the head in place. Msh.TransformedVertices[i].Position = Vector3.Transform(Msh.RealVertices[i].Position, Skel.Bones[Skel.FindBone("HEAD")].AbsoluteMatrix); Msh.TransformedVertices[i].TextureCoordinate = Msh.RealVertices[i].TextureCoordinate; //Transform the head normals' position by the absolute transform //for the headbone (which is always bone 17) to render the head in place. Msh.TransformedVertices[i].Normal = Vector3.Transform(Msh.RealVertices[i].Normal, Skel.Bones[Skel.FindBone("HEAD")].AbsoluteMatrix); } return; case MeshType.Body: BoneBinding boneBinding = Msh.BoneBindings.FirstOrDefault(x => Msh.Bones[(int)x.BoneIndex] == bone.Name); if (boneBinding != null) { for (int i = 0; i < boneBinding.RealVertexCount; i++) { int vertexIndex = (int)boneBinding.FirstRealVertexIndex + i; VertexPositionNormalTexture relativeVertex = Msh.RealVertices[vertexIndex]; Matrix translatedMatrix = Matrix.CreateTranslation(new Vector3(relativeVertex.Position.X, relativeVertex.Position.Y, relativeVertex.Position.Z)) * bone.AbsoluteMatrix; Msh.TransformedVertices[vertexIndex].Position = Vector3.Transform(Vector3.Zero, translatedMatrix); Msh.TransformedVertices[vertexIndex].TextureCoordinate = relativeVertex.TextureCoordinate; //Normals... translatedMatrix = Matrix.CreateTranslation(new Vector3(relativeVertex.Normal.X, relativeVertex.Normal.Y, relativeVertex.Normal.Z)) * bone.AbsoluteMatrix; Msh.TransformedVertices[vertexIndex].Normal = Vector3.Transform(Vector3.Zero, translatedMatrix); } } foreach (var child in bone.Children) { TransformVertices(Msh, child, MshType); } break; case MeshType.LHand: for (int i = 0; i < Msh.TotalVertexCount; i++) { //Transform the left hand vertices' position by the absolute transform //for the left handbone (which is always bone 10) to render the left hand in place. Msh.TransformedVertices[i].Position = Vector3.Transform(Msh.RealVertices[i].Position, Skel.Bones[Skel.FindBone("L_HAND")].AbsoluteMatrix); //Transform the left hand normals' position by the absolute transform //for the left handbone (which is always bone 10) to render the left hand in place. Msh.TransformedVertices[i].Normal = Vector3.Transform(Msh.RealVertices[i].Normal, Skel.Bones[Skel.FindBone("L_HAND")].AbsoluteMatrix); } return; case MeshType.RHand: for (int i = 0; i < Msh.TotalVertexCount; i++) { //Transform the right hand vertices' position by the absolute transform //for the right handbone (which is always bone 15) to render the right hand in place. Msh.TransformedVertices[i].Position = Vector3.Transform(Msh.RealVertices[i].Position, Skel.Bones[Skel.FindBone("R_HAND")].AbsoluteMatrix); //Transform the right hand normals' position by the absolute transform //for the right handbone (which is always bone 15) to render the right hand in place. Msh.TransformedVertices[i].Normal = Vector3.Transform(Msh.RealVertices[i].Normal, Skel.Bones[Skel.FindBone("R_HAND")].AbsoluteMatrix); } return; } }
private void ConformMeshBoneBindings(Mesh mesh, Mesh conformToMesh) { foreach (var conformBone in conformToMesh.BoneBindings) { BoneBinding inputBone = null; foreach (var bone in mesh.BoneBindings) { if (bone.BoneName == conformBone.BoneName) { inputBone = bone; break; } } if (inputBone == null) { // Create a new "dummy" binding if it does not exist in the new mesh inputBone = new BoneBinding(); inputBone.BoneName = conformBone.BoneName; mesh.BoneBindings.Add(inputBone); } // The bones match, copy relevant parameters from the conforming binding to the input. inputBone.OBBMin = conformBone.OBBMin; inputBone.OBBMax = conformBone.OBBMax; } }
private void GenerateDummySkeleton(Root root) { foreach (var model in root.Models) { if (model.Skeleton == null) { Utils.Info(String.Format("Generating dummy skeleton for model '{0}'", model.Name)); var skeleton = new Skeleton(); skeleton.Name = model.Name; skeleton.LODType = 0; skeleton.IsDummy = true; root.Skeletons.Add(skeleton); var bone = new Bone(); bone.Name = model.Name; bone.ParentIndex = -1; skeleton.Bones = new List<Bone> { bone }; bone.Transform = new Transform(); // TODO: Transform / IWT is not always identity on dummy bones! skeleton.UpdateInverseWorldTransforms(); model.Skeleton = skeleton; foreach (var mesh in model.MeshBindings) { if (mesh.Mesh.BoneBindings != null && mesh.Mesh.BoneBindings.Count > 0) { throw new ParsingException("Failed to generate dummy skeleton: Mesh already has bone bindings."); } var binding = new BoneBinding(); binding.BoneName = bone.Name; // TODO: Calculate bounding box! binding.OBBMin = new float[] { -10, -10, -10 }; binding.OBBMax = new float[] { 10, 10, 10 }; mesh.Mesh.BoneBindings = new List<BoneBinding> { binding }; } } } }