Beispiel #1
0
        public odfMesh Clone()
        {
            odfMesh mesh = new odfMesh(Name, Id, Count);

            foreach (odfSubmesh submesh in this)
            {
                odfSubmesh newSubmesh = submesh.Clone();
                mesh.AddChild(newSubmesh);
            }
            return(mesh);
        }
Beispiel #2
0
        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();
                    }
                }
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }