Example #1
0
        public void MergeFrame(odfFrame srcFrame, odfParser srcParser, int destParentIdx)
        {
            List <ObjectID>    newMeshIDs   = new List <ObjectID>();
            odfFrame           newFrame     = srcFrame.Clone(true, newMeshIDs, true);
            List <odfMesh>     newMeshes    = new List <odfMesh>(newMeshIDs.Count);
            List <odfBoneList> newBoneLists = new List <odfBoneList>(srcParser.EnvelopeSection != null ? srcParser.EnvelopeSection.Count : 0);
            string             boneWarning  = String.Empty;

            foreach (ObjectID meshID in newMeshIDs)
            {
                odfMesh srcMesh = odf.FindMeshListSome(meshID, srcParser.MeshSection);
                odfMesh mesh    = srcMesh.Clone();
                newMeshes.Add(mesh);
                if (srcParser.EnvelopeSection != null)
                {
                    foreach (odfSubmesh submesh in mesh)
                    {
                        odfBoneList boneList = odf.FindBoneList(submesh.Id, srcParser.EnvelopeSection);
                        if (boneList != null)
                        {
                            if (Parser.EnvelopeSection != null)
                            {
                                odfBoneList copy = boneList.Clone();
                                newBoneLists.Add(copy);
                            }
                            else
                            {
                                boneWarning += (boneWarning != String.Empty ? ", " : "") + mesh.ToString();
                                break;
                            }
                        }
                    }
                }
            }
            MergeFrame(newFrame, destParentIdx);
            foreach (odfMesh mesh in newMeshes)
            {
                Parser.MeshSection.AddChild(mesh);
            }
            if (Parser.EnvelopeSection != null)
            {
                foreach (odfBoneList boneList in newBoneLists)
                {
                    Parser.EnvelopeSection.AddChild(boneList);
                }
            }
            Parser.CollectObjectIDs();
            if (boneWarning != String.Empty)
            {
                Report.ReportLog("Warning! Bones of " + boneWarning + " dropped because the destination had no Envelope section.");
            }
        }
Example #2
0
        public void ReplaceFrame(odfFrame srcFrame, odfParser srcParser, int destParentIdx, bool deleteMorphs)
        {
            List <ObjectID> meshIDs  = new List <ObjectID>();
            odfFrame        newFrame = srcFrame.Clone(true, meshIDs, true);

            ReplaceFrame(newFrame, destParentIdx, deleteMorphs);
            string boneWarning = String.Empty;

            foreach (ObjectID meshID in meshIDs)
            {
                odfMesh srcMesh = odf.FindMeshListSome(meshID, srcParser.MeshSection);
                odfMesh mesh    = srcMesh.Clone();
                Parser.MeshSection.AddChild(mesh);
                if (srcParser.EnvelopeSection != null)
                {
                    foreach (odfSubmesh submesh in mesh)
                    {
                        odfBoneList boneList = odf.FindBoneList(submesh.Id, srcParser.EnvelopeSection);
                        if (boneList != null)
                        {
                            if (Parser.EnvelopeSection != null)
                            {
                                odfBoneList copy = boneList.Clone();
                                Parser.EnvelopeSection.AddChild(copy);
                            }
                            else
                            {
                                boneWarning += (boneWarning != String.Empty ? ", " : "") + mesh.ToString();
                                break;
                            }
                        }
                    }
                }
            }
            Parser.CollectObjectIDs();
            if (boneWarning != String.Empty)
            {
                Report.ReportLog("Warning! Bones of " + boneWarning + " dropped because the destination had no Envelope section.");
            }
        }
Example #3
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();
                    }
                }
            }
        }