public odfMesh Clone() { odfMesh mesh = new odfMesh(Name, Id, Count); foreach (odfSubmesh submesh in this) { odfSubmesh newSubmesh = submesh.Clone(); mesh.AddChild(newSubmesh); } return(mesh); }
public static void ReplaceMesh(odfFrame frame, odfParser parser, WorkspaceMesh mesh, List <ImportedMaterial> materials, List <ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod) { Matrix transform = Matrix.Identity; odfFrame transformFrame = frame; while (transformFrame != null) { transform *= transformFrame.Matrix; transformFrame = transformFrame.Parent as odfFrame; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; odfMesh newMesh = CreateMesh(mesh, parser.MeshSection._FormatType, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); odfMesh frameMesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection); if (frameMesh != null) { if (parser.UsedIDs == null) // prevent misleading error message { parser.CollectObjectIDs(); } newMesh.Id = frameMesh.Id; newMesh.Name = frameMesh.Name; parser.MeshSection.InsertChild(parser.MeshSection.IndexOf(frameMesh), newMesh); } else { newMesh.Id = parser.GetNewID(typeof(odfMesh)); frame.MeshId = newMesh.Id; parser.MeshSection.AddChild(newMesh); } Dictionary <ObjectID, ObjectID> submeshIDtranslation = new Dictionary <ObjectID, ObjectID>(newMesh.Count); odfSubmesh[] replaceSubmeshes = frameMesh != null ? new odfSubmesh[frameMesh.Count] : null; List <odfSubmesh> addSubmeshes = new List <odfSubmesh>(newMesh.Count); for (int i = 0; i < newMesh.Count; i++) { ObjectID[] texIDs = new ObjectID[4] { ObjectID.INVALID, ObjectID.INVALID, ObjectID.INVALID, ObjectID.INVALID }; odfMaterial mat = odf.FindMaterialInfo(materialNames[i], parser.MaterialSection); if (materials != null && mat == null) { ImportedMaterial impMat = ImportedHelpers.FindMaterial(materialNames[i], materials); if (impMat != null) { mat = CreateMaterial(impMat, parser.GetNewID(typeof(odfMaterial))); parser.MaterialSection.AddChild(mat); for (int j = 0; j < impMat.Textures.Length; j++) { string texName = impMat.Textures[j]; odfTexture tex = odf.FindTextureInfo(texName, parser.TextureSection); if (tex == null) { ImportedTexture impTex = ImportedHelpers.FindTexture(texName, textures); if (impTex != null) { tex = CreateTexture(impTex, parser.GetNewID(typeof(odfTexture)), parser.TextureSection._FormatType, Path.GetDirectoryName(parser.ODFPath)); parser.TextureSection.AddChild(tex); texIDs[j] = tex.Id; } } else { texIDs[j] = tex.Id; } } } } odfSubmesh newSubmesh = newMesh[i]; newSubmesh.Id = parser.GetNewID(typeof(odfSubmesh)); newSubmesh.MaterialId = mat != null ? mat.Id : ObjectID.INVALID; newSubmesh.TextureIds = texIDs; List <odfVertex> newVertexList = newSubmesh.VertexList; if (worldCoords[i]) { for (int j = 0; j < newVertexList.Count; j++) { newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform); } } odfSubmesh baseSubmesh = null; odfBoneList newBones = null; int newBonesIdx = -1; int idx = indices[i]; if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count)) { baseSubmesh = frameMesh[idx]; submeshIDtranslation.Add(newSubmesh.Id, baseSubmesh.Id); for (int j = 0; j < baseSubmesh.TextureIds.Length; j++) { ObjectID texID = baseSubmesh.TextureIds[j]; newSubmesh.TextureIds[j] = texID; } newSubmesh.Name = new ObjectName(baseSubmesh.Name.Name, baseSubmesh.Name.Info); CopyUnknowns(baseSubmesh, newSubmesh, parser.MeshSection._FormatType); if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { odfBoneList baseBones = odf.FindBoneList(baseSubmesh.Id, parser.EnvelopeSection); if (baseBones != null) { newBones = baseBones.Clone(); newBones.Id = ObjectID.INVALID; // parser.GetNewID(typeof(odfBoneList)); newBones.SubmeshId = newSubmesh.Id; newBonesIdx = parser.EnvelopeSection.IndexOf(baseBones); } } else if (bonesMethod == CopyMeshMethod.Replace) { newBones = CreateBoneList(ObjectID.INVALID /*parser.GetNewID(typeof(odfBoneList))*/, frame.Id, newSubmesh, mesh.BoneList, transform, parser.FrameSection.RootFrame); newBonesIdx = parser.EnvelopeSection.Count; } } else { CreateUnknowns(newSubmesh, parser.MeshSection._FormatType); newBones = CreateBoneList(ObjectID.INVALID /*parser.GetNewID(typeof(odfBoneList))*/, frame.Id, newSubmesh, mesh.BoneList, transform, parser.FrameSection.RootFrame); newBonesIdx = parser.EnvelopeSection.Count; } if (newBones != null) { parser.EnvelopeSection.InsertChild(newBonesIdx, newBones); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { odf.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { odf.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { odf.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } else if (bonesMethod == CopyMeshMethod.CopyNear) { odf.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = newSubmesh; } else { addSubmeshes.Add(newSubmesh); } } if ((frameMesh != null) && merge) { newMesh.Clear(); newMesh.Capacity = replaceSubmeshes.Length + addSubmeshes.Count; for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { odfSubmesh newSubmesh = frameMesh[i - submeshesRemoved++]; frameMesh.RemoveChild(newSubmesh); // save the bone list from being deleted in RemoveMesh newMesh.AddChild(newSubmesh); } else { newMesh.AddChild(replaceSubmeshes[i]); } } newMesh.AddRange(addSubmeshes); } if (frameMesh != null) { RemoveMesh(parser, frameMesh, frame, false); parser.UsedIDs.Add((int)newMesh.Id, typeof(odfMesh)); frame.MeshId = newMesh.Id; List <ObjectID> removeKeyList = new List <ObjectID>(); foreach (odfSubmesh submesh in newMesh) { ObjectID newSubmeshID = submesh.Id; ObjectID baseSubmeshID; if (submeshIDtranslation.TryGetValue(newSubmeshID, out baseSubmeshID)) { if (odf.FindBoneList(baseSubmeshID, parser.EnvelopeSection) == null) { odfBoneList boneList = odf.FindBoneList(newSubmeshID, parser.EnvelopeSection); if (boneList != null) { boneList.SubmeshId = baseSubmeshID; } submesh.Id = baseSubmeshID; parser.UsedIDs.Remove((int)newSubmeshID); } foreach (KeyValuePair <ObjectID, ObjectID> pair in submeshIDtranslation) { if (pair.Value == baseSubmeshID) { removeKeyList.Add(pair.Key); } } foreach (ObjectID removeId in removeKeyList) { submeshIDtranslation.Remove(removeId); } removeKeyList.Clear(); } } } }
public static odfMesh CreateMesh(WorkspaceMesh mesh, int subMeshFormat, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption) { int numUncheckedSubmeshes = 0; foreach (ImportedSubmesh submesh in mesh.SubmeshList) { if (!mesh.isSubmeshEnabled(submesh)) { numUncheckedSubmeshes++; } } int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes; materialNames = new string[numSubmeshes]; indices = new int[numSubmeshes]; worldCoords = new bool[numSubmeshes]; replaceSubmeshesOption = new bool[numSubmeshes]; odfMesh newMesh = new odfMesh(new ObjectName(String.Empty, null), null, numSubmeshes); for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++) { while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx])) { submeshIdx++; } ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx]; odfSubmesh newSubmesh = new odfSubmesh(new ObjectName(String.Empty, null), null, subMeshFormat); newMesh.AddChild(newSubmesh); newSubmesh.MaterialId = ObjectID.INVALID; materialNames[i] = submesh.Material; indices[i] = submesh.Index; worldCoords[i] = submesh.WorldCoords; replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]); List <ImportedVertex> vertexList = submesh.VertexList; List <odfVertex> newVertexList = new List <odfVertex>(vertexList.Count); for (int j = 0; j < vertexList.Count; j++) { ImportedVertex vert = vertexList[j]; odfVertex newVertex = new odfVertex(); newVertex.Normal = vert.Normal; newVertex.UV = new Vector2(vert.UV[0], vert.UV[1]); newVertex.Weights = (float[])vert.Weights.Clone(); newVertex.BoneIndices = (byte[])vert.BoneIndices.Clone(); newVertex.Position = vert.Position; newVertexList.Add(newVertex); } newSubmesh.VertexList = newVertexList; List <ImportedFace> faceList = submesh.FaceList; List <odfFace> newFaceList = new List <odfFace>(faceList.Count); for (int j = 0; j < faceList.Count; j++) { int[] vertexIndices = faceList[j].VertexIndices; odfFace newFace = new odfFace(); newFace.VertexIndices = new ushort[3] { (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2] }; newFaceList.Add(newFace); } newSubmesh.FaceList = newFaceList; } return(newMesh); }
private bool loadMESH(BinaryReader reader, odfFileSection fileSec) { odfMeshSection meshSection = new odfMeshSection(0); meshSection._FormatType = 10; if (!reader.BaseStream.CanSeek) { byte[] buffer = reader.ReadBytes(fileSec.Size); reader = new BinaryReader(new MemoryStream(buffer)); } for (int endPosition = (int)reader.BaseStream.Position + fileSec.Size; reader.BaseStream.Position < endPosition;) { ObjectName name = new ObjectName(reader.ReadBytes(64)); ObjectID id = new ObjectID(reader.ReadBytes(4)); int numSubmeshes = reader.ReadInt32(); odfMesh mesh = new odfMesh(name, id, numSubmeshes); for (int submeshIdx = 0; submeshIdx < numSubmeshes; submeshIdx++) { name = new ObjectName(reader.ReadBytes(64)); id = new ObjectID(reader.ReadBytes(4)); int unknown1 = reader.ReadInt32(); byte[] alwaysZero1 = reader.ReadBytes(4); ObjectID materialId = new ObjectID(reader.ReadBytes(4)); ObjectID[] texID = new ObjectID[4]; for (int texIdx = 0; texIdx < 4; texIdx++) { texID[texIdx] = new ObjectID(reader.ReadBytes(4)); } UInt32 unknown31 = reader.ReadUInt32(); byte[] alwaysZero2 = reader.ReadBytes(16); int unknown3 = reader.ReadInt32(); byte[] numVertsOrUnknown = reader.ReadBytes(4); byte[] numVertIndicesOrUnknown = reader.ReadBytes(4); int unknown4 = reader.ReadInt32(); int unknown5 = reader.ReadInt32(); byte[] unknownOrNumVerts = reader.ReadBytes(4); byte[] unknownOrNumVertIndices = reader.ReadBytes(4); if (meshSection.Count == 0) { int numVerts = BitConverter.ToInt32(numVertsOrUnknown, 0); int numVertexIdxs = BitConverter.ToInt32(numVertIndicesOrUnknown, 0); if (numVerts * numVertexIdxs == 0) { meshSection._FormatType = 9; } } odfSubmesh submesh = new odfSubmesh(name, id, meshSection._FormatType); submesh.Unknown1 = unknown1; submesh.AlwaysZero1 = alwaysZero1; submesh.MaterialId = materialId; submesh.TextureIds = texID; submesh.Unknown31 = unknown31; submesh.AlwaysZero2 = alwaysZero2; submesh.Unknown4 = unknown3; submesh.Unknown5 = unknown4; submesh.Unknown6 = unknown5; int numVertices, numVertexIndices; if (meshSection._FormatType < 10) { submesh.Unknown7 = BitConverter.ToInt32(numVertsOrUnknown, 0); submesh.Unknown8 = numVertIndicesOrUnknown; numVertices = BitConverter.ToInt32(unknownOrNumVerts, 0); numVertexIndices = BitConverter.ToInt32(unknownOrNumVertIndices, 0); submesh.AlwaysZero3 = reader.ReadBytes(448); } else { numVertices = BitConverter.ToInt32(numVertsOrUnknown, 0); numVertexIndices = BitConverter.ToInt32(numVertIndicesOrUnknown, 0); submesh.Unknown7 = BitConverter.ToInt32(unknownOrNumVerts, 0); submesh.Unknown8 = unknownOrNumVertIndices; } submesh.VertexList = ParseVertexList(reader, numVertices); submesh.FaceList = ParseFaceList(reader, numVertexIndices / 3); submesh.AlwaysZero4 = reader.ReadBytes(24); mesh.AddChild(submesh); } meshSection.AddChild(mesh); } fileSec.Section = meshSection; MeshSection = meshSection; return(true); }