Пример #1
0
        public RenderObjectODF(odfParser parser, HashSet<int> meshIDs)
        {
            HighlightSubmesh = new SortedSet<int>();
            highlightMaterial = new Material();
            highlightMaterial.Ambient = new Color4(1, 1, 1, 1);
            highlightMaterial.Diffuse = new Color4(1, 0, 1, 0);

            this.device = Gui.Renderer.Device;

            Textures = new Texture[parser.TextureSection != null ? parser.TextureSection.Count : 0];
            TextureDic = new Dictionary<int, int>(parser.TextureSection != null ? parser.TextureSection.Count : 0);
            Materials = new Material[parser.MaterialSection.Count];
            BoneMatrixDic = new Dictionary<string, Matrix>();

            rootFrame = CreateHierarchy(parser, meshIDs, device, out meshFrames);

            AnimationController = new AnimationController(numFrames, 30, 30, 1);
            Frame.RegisterNamedMatrices(rootFrame, AnimationController);

            for (int i = 0; i < meshFrames.Count; i++)
            {
                if (i == 0)
                {
                    Bounds = meshFrames[i].Bounds;
                }
                else
                {
                    Bounds = BoundingBox.Merge(Bounds, meshFrames[i].Bounds);
                }
            }
        }
Пример #2
0
        public static void ReplaceMorph(string destMorphName, odfParser parser, WorkspaceMorph wsMorphList, string newMorphName, bool replaceNormals, float minSquaredDistance)
        {
            odfMorphSection morphSection = parser.MorphSection;
            if (morphSection == null)
            {
                Report.ReportLog("The .odf file doesn't have a morph section. Skipping these morphs");
                return;
            }

            odfMorphObject morphObj = odf.FindMorphObject(destMorphName, morphSection);
            if (morphObj == null)
            {
                Report.ReportLog("Couldn't find morph object " + destMorphName + ". Skipping these morphs");
                return;
            }

            Report.ReportLog("Replacing morphs ...");
            try
            {
                ushort[] meshIndices = morphObj.MeshIndices;
                foreach (ImportedMorphKeyframe wsMorph in wsMorphList.KeyframeList)
                {
                    if (!wsMorphList.isMorphKeyframeEnabled(wsMorph))
                        continue;
                    odfMorphProfile profile = odf.FindMorphProfile(wsMorph.Name, morphObj);
                    if (profile == null)
                    {
                        Report.ReportLog("Warning: Couldn't find morph profile " + wsMorph.Name + ". Skipping this morph");
                        continue;
                    }

                    List<ImportedVertex> vertList = wsMorph.VertexList;
                    for (int i = 0; i < meshIndices.Length; i++)
                    {
                        Vector3 orgPos = new Vector3(profile.VertexList[i].Position.X, profile.VertexList[i].Position.Y, profile.VertexList[i].Position.Z),
                            newPos = new Vector3(vertList[meshIndices[i]].Position.X, vertList[meshIndices[i]].Position.Y, vertList[meshIndices[i]].Position.Z);
                        if ((orgPos - newPos).LengthSquared() >= minSquaredDistance)
                            profile.VertexList[i].Position = vertList[meshIndices[i]].Position;
                        if (replaceNormals)
                        {
                            profile.VertexList[i].Normal = vertList[meshIndices[i]].Normal;
                        }
                    }

                    string morphNewName = wsMorphList.getMorphKeyframeNewName(wsMorph);
                    if (morphNewName != String.Empty)
                    {
                        profile.Name = new ObjectName(morphNewName, null);
                    }
                }
                if (newMorphName != String.Empty)
                {
                    morphObj.Name = new ObjectName(newMorphName, null);
                }
            }
            catch (Exception ex)
            {
                Utility.ReportException(ex);
            }
        }
Пример #3
0
        public static odfANIMSection FindClip(string name, odfParser parser)
        {
            if (name == "ANIM" || name == String.Empty || parser.BANMList == null)
            {
                return parser.AnimSection;
            }
            foreach (odfBANMSection anim in parser.BANMList)
            {
                if (anim.Name == name)
                {
                    return anim;
                }
            }

            return null;
        }
Пример #4
0
 public odfEditor(odfParser parser)
 {
     Parser = parser;
     Frames = new List<odfFrame>();
     InitFrames(parser.FrameSection.RootFrame);
     if (parser.MaterialSection != null)
         Materials = parser.MaterialSection.ChildList;
     if (parser.TextureSection != null)
         Textures = parser.TextureSection.ChildList;
     if (parser.AnimSection != null)
     {
         Animations = new List<odfANIMSection>(1);
         Animations.Add(parser.AnimSection);
         if (parser.BANMList != null)
             Animations.AddRange(parser.BANMList);
     }
 }
Пример #5
0
        public static void CopyOrCreateUnknowns(odfFrame dest, odfParser parser)
        {
            odfFrame src = FindFrame(dest.Name, parser.FrameSection.RootFrame);
            if (src == null)
            {
                dest.Id = parser.GetNewID(typeof(odfFrame));
                CreateUnknowns(dest);
            }
            else
            {
                dest.Id = new ObjectID(src.Id);
                CopyUnknowns(src, dest);
            }

            for (int i = 0; i < dest.Count; i++)
            {
                CopyOrCreateUnknowns(dest[i], parser);
            }
        }
Пример #6
0
 public void AddFrame(odfFrame srcFrame, odfParser srcParser, int destParentIdx)
 {
     List<ObjectID> meshIDs = new List<ObjectID>();
     odfFrame newFrame = srcFrame.Clone(true, meshIDs, true);
     AddFrame(newFrame, destParentIdx);
     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.");
 }
Пример #7
0
 private AnimationFrame CreateHierarchy(odfParser parser, HashSet<int> meshIDs, Device device, out List<AnimationFrame> meshFrames)
 {
     meshFrames = new List<AnimationFrame>(meshIDs.Count);
     HashSet<int> extractFrames = odf.SearchHierarchy(parser, meshIDs);
     #if !DONT_MIRROR
     Vector3 translate, scale;
     Quaternion rotate;
     parser.FrameSection.RootFrame.Matrix.Decompose(out scale, out rotate, out translate);
     parser.FrameSection.RootFrame.Matrix = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate);
     #endif
     AnimationFrame rootFrame = CreateFrame(parser.FrameSection.RootFrame, parser, extractFrames, meshIDs, device, Matrix.Identity, meshFrames);
     SetupBoneMatrices(rootFrame, rootFrame);
     #if !DONT_MIRROR
     parser.FrameSection.RootFrame.Matrix = Matrix.Scaling(scale) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate);
     #endif
     return rootFrame;
 }
Пример #8
0
        private AnimationFrame CreateFrame(odfFrame frame, odfParser parser, HashSet<int> extractFrames, HashSet<int> meshIDs, Device device, Matrix combinedParent, List<AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();
            animationFrame.Name = frame.Name;
            animationFrame.TransformationMatrix = frame.Matrix;
            animationFrame.OriginalTransform = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform = combinedParent * animationFrame.TransformationMatrix;

            if ((int)frame.MeshId != 0 && meshIDs.Contains((int)frame.MeshId))
            {
                odfMesh mesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection);
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.Count];

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < mesh.Count; i++)
                {
                    odfSubmesh submesh = mesh[i];
                    List<odfFace> faceList = submesh.FaceList;
                    List<odfVertex> vertexList = submesh.VertexList;

                    odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                    bool skinned = boneList != null;
                    int numBones = skinned ? boneList.Count : 0;
                    string[] boneNames = new string[numBones];
                    Matrix[] boneOffsets = new Matrix[numBones];
                    for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                    {
                        odfBone bone = boneList[boneIdx];
                        boneNames[boneIdx] = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                        Matrix mirrored;
                        if (!BoneMatrixDic.TryGetValue(boneNames[boneIdx], out mirrored))
                        {
            #if !DONT_MIRROR
                            Vector3 translate, scale;
                            Quaternion rotate;
                            bone.Matrix.Decompose(out scale, out rotate, out translate);
                            mirrored = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate);
            #else
                            mirrored = bone.Matrix;
            #endif
                            BoneMatrixDic.Add(boneNames[boneIdx], mirrored);
                        }
                        boneOffsets[boneIdx] = mirrored;
                    }

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            ushort[] indices = faceList[j].VertexIndices;
                            indexStream.Write(indices[0]);
                            indexStream.Write(indices[1]);
                            indexStream.Write(indices[2]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        odfVertex vertex = vertexList[j];
            #if !DONT_MIRROR
                        Vector3 position = new Vector3(vertex.Position.X, vertex.Position.Y, -vertex.Position.Z);
                        Vector3 normal = new Vector3(vertex.Normal.X, vertex.Normal.Y, -vertex.Normal.Z);
            #else
                        Vector3 position = vertex.Position;
                        Vector3 normal = vertex.Normal;
            #endif
                        float[] boneWeights = vertexWeights[j];

                        normalLines[j * 2] = new PositionBlendWeightsIndexedColored(position, boneWeights, vertex.BoneIndices, Color.Yellow.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + (normal / 11), boneWeights, vertex.BoneIndices, Color.Blue.ToArgb());

                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name = animationFrame.Name;
                    meshContainer.MeshData = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i] = meshContainer;

                    odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient = mat.Ambient;
                        material3D.Diffuse = mat.Diffuse;
                        material3D.Emissive = mat.Emissive;
                        material3D.Specular = mat.Specular;
                        material3D.Power = mat.SpecularPower;
                        int matIdx = parser.MaterialSection.IndexOf(mat);
                        Materials[matIdx] = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = -1;
                        if ((int)submesh.TextureIds[0] != 0 && !TextureDic.TryGetValue((int)submesh.TextureIds[0], out texIdx))
                        {
                            odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[0], parser.TextureSection);
                            if (tex != null)
                            {
                                try
                                {
                                    odfTextureFile texFile = new odfTextureFile(null, Path.GetDirectoryName(parser.ODFPath) + Path.DirectorySeparatorChar + tex.TextureFile);
                                    int fileSize = 0;
                                    ImportedTexture impTex = new ImportedTexture(texFile.DecryptFile(ref fileSize).BaseStream, tex.TextureFile);
                                    Texture memTex = impTex.ToTexture(device);
                                    texIdx = TextureDic.Count;
                                    TextureDic.Add((int)submesh.TextureIds[0], texIdx);
                                    Textures[texIdx] = memTex;
                                }
                                catch (SlimDXException ex)
                                {
                                    Utility.ReportException(ex);
                                    Report.ReportLog("Please check " + tex.TextureFile + ". It may have an unsupported format.");
                                }
                                catch (Exception ex)
                                {
                                    Utility.ReportException(ex);
                                }
                            }
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                animationFrame.Bounds = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                odfFrame child = frame[i];
                if (extractFrames.Contains((int)child.Id))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshIDs, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return animationFrame;
        }
Пример #9
0
        public void HighlightBone(odfParser parser, int meshIdx, int submeshIdx, int boneIdx)
        {
            const int boneObjSize = 16;

            odfSubmesh submesh = parser.MeshSection[meshIdx][submeshIdx];
            odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
            string boneFrameName = null;
            if (boneIdx >= 0)
            {
                odfBone bone = boneList[boneIdx];
                boneFrameName = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
            }

            AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[0].MeshContainer;
            for (int i = 0; mesh != null; i++)
            {
                if (i == submeshIdx && (mesh.MeshData != null) && (mesh.MeshData.Mesh != null))
                {
                    List<odfVertex> vertexList = submesh.VertexList;
                    float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList);
                    FillVertexBuffer(mesh.MeshData.Mesh, vertexList, vertexWeights, boneIdx);
            //					break;
                }
                if (boneIdx >= 0)
                {
                    for (int idx = 0; idx < mesh.BoneLines.Length / boneObjSize; idx++)
                    {
                        if (mesh.BoneNames[idx] == boneFrameName)
                        {
                            for (int j = 0; j < boneObjSize; j++)
                            {
                                mesh.BoneLines[idx * boneObjSize + j].Color = Color.Crimson.ToArgb();
                            }
                            break;
                        }
                    }
                }
                else
                {
                    for (int idx = 0; idx < mesh.BoneLines.Length / boneObjSize; idx++)
                    {
                        for (int j = 0; j < boneObjSize; j++)
                        {
                            mesh.BoneLines[idx * boneObjSize + j].Color = Color.CornflowerBlue.ToArgb();
                        }
                    }
                }
                mesh = (AnimationMeshContainer)mesh.NextMeshContainer;
            }
        }
Пример #10
0
        public static void ReplaceTexture(odfParser parser, ImportedTexture impTex)
        {
            odfTexture newTex = CreateTexture(impTex, null, parser.TextureSection._FormatType, Path.GetDirectoryName(parser.ODFPath));

            if (odf.FindTextureInfo(impTex.Name, parser.TextureSection) == null)
            {
                newTex.Id = parser.GetNewID(typeof(odfTexture));
                parser.TextureSection.AddChild(newTex);
            }
        }
Пример #11
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();
                    }
                }
            }
        }
Пример #12
0
 private ExporterMorph(DirectoryInfo dir, odfParser parser, odfMorphObject morphObj, bool skipUnusedProfiles)
 {
     this.parser = parser;
     this.morphObj = morphObj;
     this.skipUnusedProfiles = skipUnusedProfiles;
 }
Пример #13
0
 public static void ExportMorphMqo([DefaultVar]string dirPath, odfParser odfParser, string morphObjName, bool skipUnusedProfiles)
 {
     if (dirPath == null)
         dirPath = Path.GetDirectoryName(odfParser.ODFPath) + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(odfParser.ODFPath);
     odfMorphObject morphObj = odf.FindMorphObject(morphObjName, odfParser.MorphSection);
     Mqo.ExporterMorph.Export(dirPath, odfParser, morphObj, skipUnusedProfiles);
 }
Пример #14
0
        public void MergeMaterial(odfMaterial srcMat, odfParser srcParser)
        {
            odfMaterial newMat = srcMat.Clone();

            bool found = false;
            for (int i = 0; i < Parser.MaterialSection.Count; i++)
            {
                odfMaterial oldMat = Parser.MaterialSection[i];
                if (oldMat.Name == newMat.Name)
                {
                    newMat.Id = oldMat.Id;
                    Parser.MaterialSection.RemoveChild(i);
                    Parser.MaterialSection.InsertChild(i, newMat);

                    found = true;
                    break;
                }
            }

            if (!found)
            {
                Parser.MaterialSection.AddChild(newMat);
                if (Parser.IsUsedID(newMat.Id))
                {
                    newMat.Id = Parser.GetNewID(typeof(odfMaterial));
                    Report.ReportLog("Warning! Material " + newMat.Name + " got a new ID : " + newMat.Id);
                } else
                    Parser.UsedIDs.Add((int)newMat.Id, typeof(odfMaterial));
            }

            if (Parser.MataSection != null && srcParser.MataSection != null)
            {
                odfMaterialList newMatList = odf.FindMaterialList(newMat.Id, srcParser.MataSection);
                if (newMatList != null)
                {
                    odfMaterialList matList = odf.FindMaterialList(newMat.Id, Parser.MataSection);
                    if (matList != null)
                    {
                        int originalIdx = Parser.MataSection.IndexOf(matList);
                        Parser.MataSection.RemoveChild(originalIdx);
                        Parser.MataSection.InsertChild(originalIdx, newMatList);
                    }
                    else
                        Parser.MataSection.AddChild(newMatList);
                }
            }
        }
Пример #15
0
 public ODFConverter(odfParser parser, List<odfMesh> meshes)
 {
     FrameList = new List<ImportedFrame>();
     ConvertFrames(parser.FrameSection.RootFrame);
     ConvertMeshes(meshes, parser);
     AnimationList = new List<ImportedAnimation>();
 }
Пример #16
0
        public static odfFrame CreateFrame(ImportedFrame frame, odfParser parser)
        {
            odfFrame newFrame = new odfFrame(new ObjectName(frame.Name, null), null, frame.Count);
            newFrame.MeshId = ObjectID.INVALID;
            newFrame.Matrix = frame.Matrix;

            for (int i = 0; i < frame.Count; i++)
            {
                newFrame.AddChild(CreateFrame(frame[i], parser));
            }

            return newFrame;
        }
Пример #17
0
            private void ConvertMeshes(List<odfMesh> meshes, odfParser parser)
            {
                MeshList = new List<ImportedMesh>(meshes.Count);
                MaterialList = new List<ImportedMaterial>(meshes.Count);
                TextureList = new List<ImportedTexture>(parser.TextureSection != null ? parser.TextureSection.Count : 0);
                foreach (odfMesh mesh in meshes)
                {
                    ImportedMesh iMesh = new ImportedMesh();
                    MeshList.Add(iMesh);
                    iMesh.Name = odf.FindMeshFrame(mesh.Id, parser.FrameSection.RootFrame).Name;
                    iMesh.BoneList = new List<ImportedBone>();
                    Dictionary<ObjectID, byte> boneDic = new Dictionary<ObjectID, byte>();
                    iMesh.SubmeshList = new List<ImportedSubmesh>(mesh.Count);
                    foreach (odfSubmesh submesh in mesh)
                    {
                        ImportedSubmesh iSubmesh = new ImportedSubmesh();
                        iMesh.SubmeshList.Add(iSubmesh);
                        odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                        if (mat != null)
                        {
                            iSubmesh.Material = mat.Name;
                            ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList);
                            if (iMat == null)
                            {
                                iMat = new ImportedMaterial();
                                MaterialList.Add(iMat);
                                iMat.Name = iSubmesh.Material;
                                iMat.Diffuse = mat.Diffuse;
                                iMat.Ambient = mat.Ambient;
                                iMat.Specular = mat.Specular;
                                iMat.Emissive = mat.Emissive;
                                iMat.Power = mat.SpecularPower;

                                iMat.Textures = new string[4];
                                for (int i = 0; i < 4; i++)
                                {
                                    if (submesh.TextureIds[i] != ObjectID.INVALID)
                                    {
                                        odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[i], parser.TextureSection);
                                        iMat.Textures[i] =  tex.Name;
                                        if (ImportedHelpers.FindTexture(iMat.Textures[i], TextureList) == null)
                                        {
                                            try
                                            {
                                                odfTextureFile texFile = new odfTextureFile(iMat.Textures[i], Path.GetDirectoryName(parser.ODFPath) + @"\" + iMat.Textures[i]);
                                                MemoryStream memStream;
                                                int filesize = 0;
                                                using (BinaryReader reader = texFile.DecryptFile(ref filesize))
                                                {
                                                    memStream = new MemoryStream(reader.ReadBytes(filesize));
                                                }
                                                ImportedTexture iTex = new ImportedTexture(memStream, iMat.Textures[i]);
                                                TextureList.Add(iTex);
                                            }
                                            catch
                                            {
                                                Report.ReportLog("cant read texture " + iMat.Textures[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        iMat.Textures[i] = String.Empty;
                                    }
                                }
                            }
                        }

                        List<Tuple<byte, float>>[] skin = new List<Tuple<byte, float>>[submesh.NumVertices];
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            skin[i] = new List<Tuple<byte, float>>(4);
                        }
                        odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                        if (boneList != null)
                        {
                            if (iMesh.BoneList.Capacity < boneList.Count)
                            {
                                iMesh.BoneList.Capacity += boneList.Count;
                            }
                            foreach (odfBone bone in boneList)
                            {
                                byte idx;
                                if (!boneDic.TryGetValue(bone.FrameId, out idx))
                                {
                                    ImportedBone iBone = new ImportedBone();
                                    iMesh.BoneList.Add(iBone);
                                    iBone.Name = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                                    iBone.Matrix = bone.Matrix;
                                    boneDic.Add(bone.FrameId, idx = (byte)boneDic.Count);
                                }
                                for (int i = 0; i < bone.NumberIndices; i++)
                                {
                                    skin[bone.VertexIndexArray[i]].Add(new Tuple<byte, float>(idx, bone.WeightArray[i]));
                                }
                            }
                        }

                        iSubmesh.VertexList = new List<ImportedVertex>(submesh.NumVertices);
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            odfVertex vert = submesh.VertexList[i];
                            ImportedVertex iVert = new ImportedVertex();
                            iSubmesh.VertexList.Add(iVert);
                            iVert.Position = vert.Position;
                            iVert.Normal = vert.Normal;
                            iVert.UV = new float[] { vert.UV[0], vert.UV[1] };
                            iVert.BoneIndices = new byte[4];
                            iVert.Weights = new float[4];
                            for (int j = 0; j < 4; j++)
                            {
                                if (j < skin[i].Count)
                                {
                                    Tuple<byte, float> vertIdxWeight = skin[i][j];
                                    iVert.BoneIndices[j] = vertIdxWeight.Item1;
                                    iVert.Weights[j] = vertIdxWeight.Item2;
                                }
                                else
                                {
                                    iVert.BoneIndices[j] = 0xFF;
                                }
                            }
                        }

                        iSubmesh.FaceList = new List<ImportedFace>(submesh.NumVertexIndices / 3);
                        foreach (odfFace face in submesh.FaceList)
                        {
                            ImportedFace iFace = new ImportedFace();
                            iSubmesh.FaceList.Add(iFace);
                            iFace.VertexIndices = new int[3];
                            for (int i = 0; i < 3; i++)
                            {
                                iFace.VertexIndices[i] = face.VertexIndices[i];
                            }
                        }
                    }
                }
            }
Пример #18
0
 public void ConvertAnimations(odfParser odaParser, bool odaSkeleton)
 {
     if (odaParser.AnimSection != null)
         ConvertAnimation(odaParser.AnimSection, odaParser, odaSkeleton);
     if (odaParser.BANMList != null)
     {
         foreach (odfANIMSection anim in odaParser.BANMList)
         {
             ConvertAnimation(anim, odaParser, odaSkeleton);
         }
     }
 }
Пример #19
0
            public void ConvertAnimation(odfANIMSection anim, odfParser odaParser, bool odaSkeleton)
            {
                if (odaSkeleton)
                {
                    FrameList.Clear();
                    ConvertFrames(odaParser.FrameSection.RootFrame);
                }

                ImportedKeyframedAnimation iAnim = new ImportedKeyframedAnimation();
                AnimationList.Add(iAnim);
                iAnim.TrackList = new List<ImportedAnimationKeyframedTrack>(anim.Count);
                string notFound = String.Empty;
                foreach (odfTrack track in anim)
                {
                    odfFrame boneFrame = odf.FindFrame(track.BoneFrameId, odaParser.FrameSection.RootFrame);
                    if (boneFrame == null)
                    {
                        notFound += (notFound.Length > 0 ? ", " : "") + track.BoneFrameId;
                        continue;
                    }

                    ImportedAnimationKeyframedTrack iTrack = new ImportedAnimationKeyframedTrack();
                    iAnim.TrackList.Add(iTrack);
                    iTrack.Name = boneFrame.Name;
                    iTrack.Keyframes = ConvertTrack(track.KeyframeList);
                }
                if (notFound.Length > 0)
                {
                    Report.ReportLog("Warning: Animations weren't converted for the following missing frame IDs: " + notFound);
                }
            }
Пример #20
0
 public void ExportMorphObject(string path, odfParser parser, string morphObj, bool skipUnusedProfiles)
 {
     Plugins.ExportMorphMqo(path, parser, morphObj, skipUnusedProfiles);
 }
Пример #21
0
        public static void RemoveSubmesh(odfParser parser, odfSubmesh submesh, bool deleteMorphs)
        {
            odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
            if (boneList != null)
            {
                parser.EnvelopeSection.RemoveChild(boneList);
                parser.UsedIDs.Remove((int)boneList.Id);
            }

            if (parser.MorphSection != null && deleteMorphs)
            {
                for (int i = 0; i < parser.MorphSection.Count; i++)
                {
                    odfMorphObject morphObj = parser.MorphSection[i];
                    if (morphObj.SubmeshId == submesh.Id)
                    {
                        parser.MorphSection.RemoveChild(i);
                        --i;
                    }
                }
            }

            ((odfMesh)submesh.Parent).RemoveChild(submesh);
        }
Пример #22
0
            public static void Export(string dirPath, odfParser parser, List<odfMesh> meshes, bool singleMqo, bool worldCoords)
            {
                DirectoryInfo dir = new DirectoryInfo(dirPath);
                List<odfTexture> usedTextures = new List<odfTexture>(parser.TextureSection.Count);
                if (singleMqo)
                {
                    try
                    {
                        string dest = Utility.GetDestFile(dir, "meshes", ".odf.mqo");
                        List<odfTexture> texList = Export(dest, parser, meshes, worldCoords);
                        foreach (odfTexture tex in texList)
                        {
                            if (!usedTextures.Contains(tex))
                            {
                                usedTextures.Add(tex);
                            }
                        }
                        Report.ReportLog("Finished exporting meshes to " + dest);
                    }
                    catch (Exception ex)
                    {
                        Report.ReportLog("Error exporting meshes: " + ex.Message);
                    }
                }
                else
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        try
                        {
                            string frameName = meshes[i].Name;
                            string dest = dir.FullName + @"\" + frameName + ".odf.mqo";
                            List<odfTexture> texList = Export(dest, parser, new List<odfMesh> { meshes[i] }, worldCoords);
                            foreach (odfTexture tex in texList)
                            {
                                if (!usedTextures.Contains(tex))
                                {
                                    usedTextures.Add(tex);
                                }
                            }
                            Report.ReportLog("Finished exporting mesh to " + dest);
                        }
                        catch (Exception ex)
                        {
                            Report.ReportLog("Error exporting mesh: " + ex.Message);
                        }
                    }
                }

                foreach (odfTexture tex in usedTextures)
                {
                    String texFilePath = Path.GetDirectoryName(parser.ODFPath) + @"\" + tex.TextureFile;
                    try
                    {
                        odfTextureFile odfTex = new odfTextureFile(tex.Name, texFilePath);
                        odf.ExportTexture(odfTex, dir.FullName + @"\" + tex.TextureFile);
                    }
                    catch (Exception ex)
                    {
                        Utility.ReportException(ex);
                    }
                }
            }
Пример #23
0
        public static void ReplaceMaterial(odfParser parser, ImportedMaterial material)
        {
            odfMaterial mat = CreateMaterial(material, null);

            bool found = false;
            for (int i = 0; i < parser.MaterialSection.Count; i++)
            {
                if (parser.MaterialSection[i].Name == material.Name)
                {
                    odfMaterial original = parser.MaterialSection[i];
                    mat.Id = original.Id;
                    CopyUnknown(original, mat);

                    parser.MaterialSection.RemoveChild(i);
                    parser.MaterialSection.InsertChild(i, mat);
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                mat.Id = parser.GetNewID(typeof(odfMaterial));
                CreateUnknown(mat);
                parser.MaterialSection.AddChild(mat);
            }
        }
Пример #24
0
 public static void Export(string dirPath, odfParser parser, odfMorphObject morphObj, bool skipUnusedProfiles)
 {
     DirectoryInfo dir = new DirectoryInfo(dirPath);
     ExporterMorph exporter = new ExporterMorph(dir, parser, morphObj, skipUnusedProfiles);
     exporter.Export(dir);
 }
Пример #25
0
        public void MergeTexture(odfTexture tex, odfParser srcParser)
        {
            ImportedTexture impTex = new ImportedTexture(Path.GetDirectoryName(srcParser.ODFPath) + @"\" + tex.TextureFile);

            odfTexture newTex = odf.CreateTexture(impTex, null, Parser.TextureSection._FormatType, Path.GetDirectoryName(Parser.ODFPath));
            newTex = tex.Clone(Parser.TextureSection._FormatType);

            bool found = false;
            for (int i = 0; i < Parser.TextureSection.Count; i++)
            {
                var oldTex = Parser.TextureSection[i];
                if (oldTex.Name == newTex.Name)
                {
                    newTex.Id = oldTex.Id;
                    Parser.TextureSection.RemoveChild(i);
                    Parser.TextureSection.InsertChild(i, newTex);
                    found = true;
                    break;
                }
            }

            if (!found)
            {
                Parser.TextureSection.AddChild(newTex);
                if (Parser.IsUsedID(newTex.Id))
                {
                    newTex.Id = Parser.GetNewID(typeof(odfTexture));
                    Report.ReportLog("Warning! Texture " + newTex.Name + " got a new ID : " + newTex.Id);
                }
                else
                    Parser.UsedIDs.Add((int)newTex.Id, typeof(odfTexture));
            }
        }
Пример #26
0
            private static List<odfTexture> Export(string dest, odfParser parser, List<odfMesh> meshes, bool worldCoords)
            {
                List<odfTexture> usedTextures = new List<odfTexture>(parser.TextureSection.Count);
                DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(dest));
                if (!dir.Exists)
                {
                    dir.Create();
                }

                List<odfMaterial> materialList = new List<odfMaterial>(parser.MaterialSection.Count);
                Dictionary<ObjectName, ObjectName> matTexDic = new Dictionary<ObjectName, ObjectName>();
                using (StreamWriter writer = new StreamWriter(dest, false))
                {
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        odfMesh meshListSome = meshes[i];
                        for (int j = 0; j < meshListSome.Count; j++)
                        {
                            odfSubmesh meshObj = meshListSome[j];
                            odfMaterial mat = odf.FindMaterialInfo(meshObj.MaterialId, parser.MaterialSection);
                            if (mat != null)
                            {
                                if (!materialList.Contains(mat))
                                {
                                    materialList.Add(mat);
                                }
                                odfTexture tex = odf.FindTextureInfo(meshObj.TextureIds[0], parser.TextureSection);
                                if (tex != null && !usedTextures.Contains(tex))
                                {
                                    usedTextures.Add(tex);
                                }
                                if (tex != null && !matTexDic.ContainsKey(mat.Name))
                                {
                                    matTexDic.Add(mat.Name, tex.Name);
                                }
                            }
                            else
                            {
                                Report.ReportLog("Warning: Mesh " + meshes[i].Name + " Object " + meshObj.Name + " has an invalid material");
                            }
                        }
                    }

                    writer.WriteLine("Metasequoia Document");
                    writer.WriteLine("Format Text Ver 1.0");
                    writer.WriteLine();
                    writer.WriteLine("Material " + materialList.Count + " {");
                    foreach (odfMaterial mat in materialList)
                    {
                        string s = "\t\"" + mat.Name + "\" col(0.800 0.800 0.800 1.000) dif(0.500) amb(0.100) emi(0.500) spc(0.100) power(30.00)";
                        ObjectName matTexName;
                        if (matTexDic.TryGetValue(mat.Name, out matTexName))
                        {
                            s += " tex(\"" + matTexName + "\")";
                        }
                        writer.WriteLine(s);
                    }
                    writer.WriteLine("}");

                    Random rand = new Random();
                    for (int i = 0; i < meshes.Count; i++)
                    {
                        Matrix transform = Matrix.Identity;
                        if (worldCoords)
                        {
                            odfFrame parent = odf.FindMeshFrame(meshes[i].Id, parser.FrameSection.RootFrame);
                            while (parent != null)
                            {
                                transform = parent.Matrix * transform;
                                parent = parent.Parent as odfFrame;
                            }
                        }

                        odfMesh meshListSome = meshes[i];
                        string meshName = meshes[i].Name;
                        if (meshName == String.Empty)
                            meshName = meshes[i].Id.ToString();
                        for (int j = 0; j < meshListSome.Count; j++)
                        {
                            odfSubmesh meshObj = meshListSome[j];
                            odfMaterial mat = odf.FindMaterialInfo(meshObj.MaterialId, parser.MaterialSection);
                            int mqoMatIdx = -1;
                            if (mat != null)
                            {
                                mqoMatIdx = materialList.IndexOf(mat);
                            }
                            float[] color = new float[3];
                            for (int k = 0; k < color.Length; k++)
                            {
                                color[k] = (float)((rand.NextDouble() / 2) + 0.5);
                            }

                            string mqoName = meshName + "[" + j + "]";
                            if (worldCoords)
                            {
                                mqoName += "[W]";
                            }
                            string meshObjName = meshObj.Name;
                            if (meshObjName != String.Empty)
                            {
                                mqoName += meshObjName;
                            }
                            writer.WriteLine("Object \"" + mqoName + "\" {");
                            writer.WriteLine("\tshading 1");
                            writer.WriteLine("\tcolor " + color[0].ToFloatString() + " " + color[1].ToFloatString() + " " + color[2].ToFloatString());
                            writer.WriteLine("\tcolor_type 1");

                            List<ImportedVertex> vertList = odf.ImportedVertexListUnskinned(meshObj.VertexList);
                            List<ImportedFace> faceList = odf.ImportedFaceList(meshObj.FaceList);
                            if (worldCoords)
                            {
                                for (int k = 0; k < vertList.Count; k++)
                                {
                                    Vector4 v4 = Vector3.Transform(vertList[k].Position, transform);
                                    vertList[k].Position = new Vector3(v4.X, v4.Y, v4.Z);
                                }
                            }

                            SB3Utility.Mqo.ExporterCommon.WriteMeshObject(writer, vertList, faceList, mqoMatIdx, null);
                            writer.WriteLine("}");
                        }
                    }
                    writer.WriteLine("Eof");
                }

                return usedTextures;
            }
Пример #27
0
 public static void RemoveMesh(odfParser parser, odfMesh mesh, odfFrame meshFrame, bool deleteMorphs)
 {
     while (mesh.Count > 0)
     {
         odfSubmesh submesh = mesh[0];
         RemoveSubmesh(parser, submesh, deleteMorphs);
     }
     meshFrame.MeshId = ObjectID.INVALID;
     parser.MeshSection.RemoveChild(mesh);
     parser.UsedIDs.Remove((int)mesh.Id);
 }