Пример #1
0
        public void RemoveMaterial(int id)
        {
            List <xxMaterial> materialList = Parser.MaterialList;

            int[] matIdxMap = new int[materialList.Count];
            for (int i = 0; i < id; i++)
            {
                matIdxMap[i] = i;
            }
            matIdxMap[id] = -1;
            for (int i = id + 1; i < materialList.Count; i++)
            {
                matIdxMap[i] = i - 1;
            }

            for (int i = 0; i < Meshes.Count; i++)
            {
                List <xxSubmesh> submeshList = Meshes[i].Mesh.SubmeshList;
                for (int j = 0; j < submeshList.Count; j++)
                {
                    xxSubmesh submesh = submeshList[j];
                    int       matIdx  = submesh.MaterialIndex;
                    if ((matIdx >= 0) && (matIdx < materialList.Count))
                    {
                        submesh.MaterialIndex = matIdxMap[submesh.MaterialIndex];
                    }
                }
            }

            Parser.MaterialList.RemoveAt(id);
        }
Пример #2
0
        public void SetSubmeshMaterial(int meshId, int submeshId, int material)
        {
            xxSubmesh submesh = Meshes[meshId].Mesh.SubmeshList[submeshId];

            submesh.MaterialIndex = material;
            Changed = true;
        }
Пример #3
0
        public static List <xxVertex> CreateVertexListDup(List <xxSubmesh> submeshList)
        {
            List <xxVertex>      vertListDup     = new List <xxVertex>(UInt16.MaxValue);
            List <VertexCompare> vertCompareList = new List <VertexCompare>(UInt16.MaxValue);

            for (int i = 0; i < submeshList.Count; i++)
            {
                xxSubmesh       meshObj  = submeshList[i];
                List <xxVertex> vertList = meshObj.VertexList;
                for (int j = 0; j < vertList.Count; j++)
                {
                    xxVertex      vert        = vertList[j];
                    VertexCompare vertCompare = new VertexCompare(vertCompareList.Count, vert.Position, vert.Normal, vert.BoneIndices, vert.Weights3);
                    int           idx         = vertCompareList.BinarySearch(vertCompare);
                    if (idx < 0)
                    {
                        vertCompareList.Insert(~idx, vertCompare);
                        vert.Index = vertCompareList.Count;
                        vertListDup.Add(vert.Clone());
                    }
                    else
                    {
                        vert.Index = vertCompareList[idx].index;
                    }
                }
            }
            vertListDup.TrimExcess();
            return(vertListDup);
        }
Пример #4
0
        public void SetSubmeshUnknowns(int meshId, int submeshId,
                                       byte[] unknown1, byte[] unknown2, byte[] unknown3, byte[] unknown4, byte[] unknown5, byte[] unknown6)
        {
            xxSubmesh submesh = Meshes[meshId].Mesh.SubmeshList[submeshId];

            submesh.Unknown1 = (byte[])unknown1.Clone();
            if (Parser.Format >= 7)
            {
                submesh.Unknown2 = (byte[])unknown2.Clone();
            }
            if (Parser.Format >= 2)
            {
                submesh.Unknown3 = (byte[])unknown3.Clone();
            }
            if (Parser.Format >= 3)
            {
                submesh.Unknown4 = (byte[])unknown4.Clone();
            }
            if (Parser.Format >= 5)
            {
                submesh.Unknown5 = (byte[])unknown5.Clone();
            }
            if (Parser.Format == 6)
            {
                submesh.Unknown6 = (byte[])unknown6.Clone();
            }
        }
Пример #5
0
        public static void CreateUnknowns(xxSubmesh submesh, int xxFormat, byte numVector2PerVertex)
        {
            List <xxVertex> vertList = submesh.VertexList;

            submesh.Unknown1 = (xxFormat >= 7) ? new byte[64] : new byte[] { 0x0C, 0x64, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

            if (numVector2PerVertex > 0)
            {
                submesh.Vector2Lists = new List <List <Vector2> >(vertList.Count);
                for (int j = 0; j < vertList.Count; j++)
                {
                    List <Vector2> vectorList = new List <Vector2>(numVector2PerVertex);
                    submesh.Vector2Lists.Add(vectorList);
                    for (byte k = 0; k < numVector2PerVertex; k++)
                    {
                        vectorList.Add(new Vector2());
                    }
                }
            }

            if (xxFormat >= 2)
            {
                submesh.Unknown3 = new byte[100];
            }

            if (xxFormat >= 7)
            {
                submesh.Unknown2 = new byte[20];
                submesh.Unknown4 = new byte[284];

                if (xxFormat >= 8)
                {
                    submesh.Unknown5 = new byte[21];
                }
            }
            else
            {
                if (xxFormat >= 3)
                {
                    submesh.Unknown4 = new byte[64];
                }
                if (xxFormat >= 5)
                {
                    submesh.Unknown5 = new byte[20];
                }
                if (xxFormat >= 6)
                {
                    submesh.Unknown6 = new byte[28];
                }
            }

            if (xxFormat >= 4)
            {
                for (int j = 0; j < vertList.Count; j++)
                {
                    vertList[j].Unknown1 = new byte[20];
                }
            }
        }
Пример #6
0
            private void Export(DirectoryInfo dir, xxFrame meshFrame)
            {
                try
                {
                    xaMorphSection  morphSection = xaParser.MorphSection;
                    xaMorphIndexSet indexSet     = xa.FindMorphIndexSet(clip.Name, morphSection);
                    ushort[]        meshIndices  = indexSet.MeshIndices;
                    ushort[]        morphIndices = indexSet.MorphIndices;

                    xxMesh meshList   = meshFrame.Mesh;
                    int    meshObjIdx = xa.MorphMeshObjIdx(meshIndices, meshList);
                    if (meshObjIdx < 0)
                    {
                        throw new Exception("no valid mesh object was found for the morph");
                    }

                    xxSubmesh meshObjBase = meshList.SubmeshList[meshObjIdx];
                    colorVertex = new bool[meshObjBase.VertexList.Count];
                    for (int i = 0; i < meshIndices.Length; i++)
                    {
                        colorVertex[meshIndices[i]] = true;
                    }

                    string dest = Utility.GetDestFile(dir, meshFrame.Name + "-" + clip.Name + "-", ".morph.mqo");

                    List <xaMorphKeyframeRef> refList = clip.KeyframeRefList;
                    morphNames = new List <string>(refList.Count);
                    vertLists  = new List <List <ImportedVertex> >(refList.Count);
                    for (int i = 0; i < refList.Count; i++)
                    {
                        if (!morphNames.Contains(refList[i].Name))
                        {
                            List <ImportedVertex> vertList = xx.ImportedVertexList(meshObjBase.VertexList, xx.IsSkinned(meshList));
                            vertLists.Add(vertList);

                            xaMorphKeyframe keyframe = xa.FindMorphKeyFrame(refList[i].Name, morphSection);
                            for (int j = 0; j < meshIndices.Length; j++)
                            {
                                ImportedVertex vert = vertList[meshIndices[j]];
                                vert.Position = keyframe.PositionList[morphIndices[j]];
                            }
                            morphNames.Add(keyframe.Name);
                        }
                    }

                    faceList = xx.ImportedFaceList(meshObjBase.FaceList);
                    Export(dest, meshObjBase.MaterialIndex);
                    foreach (xxTexture tex in usedTextures)
                    {
                        xx.ExportTexture(tex, dir.FullName + @"\" + Path.GetFileName(tex.Name));
                    }
                    Report.ReportLog("Finished exporting morph to " + dest);
                }
                catch (Exception ex)
                {
                    Report.ReportLog("Error exporting morph: " + ex.Message);
                }
            }
Пример #7
0
        public void MoveSubmesh(int meshId, int submeshId, int newPosition)
        {
            xxMesh    mesh = Meshes[meshId].Mesh;
            xxSubmesh src  = mesh.SubmeshList[submeshId];

            mesh.SubmeshList.Remove(src);
            mesh.SubmeshList.Insert(newPosition, src);
            Changed = true;
        }
Пример #8
0
        private void InitTables()
        {
            xxTable.Rows.Add(new object[] { 0, "Header", Utility.BytesToString(parser.Header) });
            xxTable.Rows.Add(new object[] { 1, "MaterialSection", Utility.BytesToString(parser.MaterialSectionUnknown) });
            if (parser.Format >= 2)
            {
                xxTable.Rows.Add(new object[] { 2, "Footer", Utility.BytesToString(parser.Footer) });                 // 3
            }

            for (int i = 0; i < editor.Frames.Count; i++)
            {
                xxFrame frame = editor.Frames[i];
                frameTable.Rows.Add(new object[] { i, frame.Name, Utility.BytesToString(frame.Unknown1), Utility.BytesToString(frame.Unknown2) });
            }

            for (int i = 0; i < editor.Meshes.Count; i++)
            {
                xxFrame frame = editor.Meshes[i];
                meshTable.Rows.Add(new object[] { i, frame.Name, frame.Mesh.NumVector2PerVertex.ToString("X2"), Utility.BytesToString(frame.Mesh.VertexListDuplicateUnknown) });

                for (int j = 0; j < frame.Mesh.SubmeshList.Count; j++)
                {
                    xxSubmesh submesh = frame.Mesh.SubmeshList[j];
                    submeshTable.Rows.Add(new object[] { new int[] { i, j }, frame.Name + "[" + j + "]",
                                                         Utility.BytesToString(submesh.Unknown1),
                                                         Utility.BytesToString(submesh.Unknown2),
                                                         Utility.BytesToString(submesh.Unknown3),
                                                         Utility.BytesToString(submesh.Unknown4),
                                                         Utility.BytesToString(submesh.Unknown5),
                                                         Utility.BytesToString(submesh.Unknown6) });
                }
            }

            for (int i = 0; i < parser.MaterialList.Count; i++)
            {
                xxMaterial mat = parser.MaterialList[i];
                materialTable.Rows.Add(new object[] { i, mat.Name,
                                                      Utility.BytesToString(mat.Unknown1),
                                                      Utility.BytesToString(mat.Textures[0].Unknown1),
                                                      Utility.BytesToString(mat.Textures[1].Unknown1),
                                                      Utility.BytesToString(mat.Textures[2].Unknown1),
                                                      Utility.BytesToString(mat.Textures[3].Unknown1) });
            }

            for (int i = 0; i < parser.TextureList.Count; i++)
            {
                xxTexture tex = parser.TextureList[i];
                textureTable.Rows.Add(new object[] { i, tex.Name,
                                                     Utility.BytesToString(tex.Unknown1) });
            }
        }
Пример #9
0
        public xxSubmesh Clone()
        {
            xxSubmesh submesh = new xxSubmesh();

            submesh.Unknown1      = (byte[])Unknown1.Clone();
            submesh.MaterialIndex = MaterialIndex;
            submesh.FaceList      = new List <xxFace>(FaceList.Count);
            for (int i = 0; i < FaceList.Count; i++)
            {
                submesh.FaceList.Add(FaceList[i].Clone());
            }
            submesh.VertexList = new List <xxVertex>(VertexList.Count);
            for (int i = 0; i < VertexList.Count; i++)
            {
                submesh.VertexList.Add(VertexList[i].Clone());
            }

            submesh.Unknown2 = Unknown2.CloneIfNotNull();

            if (Vector2Lists != null)
            {
                submesh.Vector2Lists = new List <List <Vector2> >(Vector2Lists.Count);
                for (int i = 0; i < Vector2Lists.Count; i++)
                {
                    List <Vector2> vectorList = new List <Vector2>(Vector2Lists[i].Count);
                    submesh.Vector2Lists.Add(vectorList);
                    for (int j = 0; j < Vector2Lists[i].Count; j++)
                    {
                        vectorList.Add(Vector2Lists[i][j]);
                    }
                }
            }

            submesh.Unknown3 = Unknown3.CloneIfNotNull();
            submesh.Unknown4 = Unknown4.CloneIfNotNull();
            submesh.Unknown5 = Unknown5.CloneIfNotNull();
            submesh.Unknown6 = Unknown6.CloneIfNotNull();

            return(submesh);
        }
Пример #10
0
        private static void CalculateNormals(xaParser parser, xxFrame meshFrame, xaMorphKeyframe keyframe, xaMorphIndexSet set, float threshold)
        {
            xxMesh mesh = meshFrame.Mesh;

            ushort[] meshIndices     = set.MeshIndices;
            ushort[] morphIndices    = set.MorphIndices;
            int      morphSubmeshIdx = MorphMeshObjIdx(meshIndices, mesh);

            if (morphSubmeshIdx < 0)
            {
                throw new Exception("no valid mesh object was found for the morph " + set.Name);
            }
            xxSubmesh       submesh         = mesh.SubmeshList[morphSubmeshIdx];
            List <xxVertex> morphedVertices = new List <xxVertex>(submesh.VertexList.Count);

            for (ushort i = 0; i < submesh.VertexList.Count; i++)
            {
                xxVertex vert = new xxVertexUShort();
                vert.Index    = i;
                vert.Position = submesh.VertexList[i].Position;
                vert.Normal   = submesh.VertexList[i].Normal;
                morphedVertices.Add(vert);
            }
            for (int i = 0; i < meshIndices.Length; i++)
            {
                morphedVertices[meshIndices[i]].Position = keyframe.PositionList[morphIndices[i]];
            }

            var pairList = new List <Tuple <List <xxFace>, List <xxVertex> > >(1);

            pairList.Add(new Tuple <List <xxFace>, List <xxVertex> >(submesh.FaceList, morphedVertices));
            xx.CalculateNormals(pairList, threshold);

            for (int i = 0; i < meshIndices.Length; i++)
            {
                keyframe.NormalList[morphIndices[i]] = morphedVertices[meshIndices[i]].Normal;
            }
        }
Пример #11
0
        private AnimationFrame CreateFrame(xxFrame frame, xxParser parser, HashSet <string> extractFrames, HashSet <string> meshNames, 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;

            xxMesh mesh = frame.Mesh;

            if (meshNames.Contains(frame.Name) && (mesh != null))
            {
                List <xxBone> boneList = mesh.BoneList;

                string[] boneNames   = new string[boneList.Count];
                Matrix[] boneOffsets = new Matrix[boneList.Count];
                for (int i = 0; i < boneList.Count; i++)
                {
                    xxBone bone = boneList[i];
                    boneNames[i]   = bone.Name;
                    boneOffsets[i] = bone.Matrix;
                }

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

                    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[2]);
                            indexStream.Write(indices[1]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    FillVertexBuffer(animationMesh, vertexList, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        xxVertex vertex = vertexList[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(vertex.Position, vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.Position + (vertex.Normal / 16), vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb());

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

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

                    int matIdx = submesh.MaterialIndex;
                    if ((matIdx >= 0) && (matIdx < parser.MaterialList.Count))
                    {
                        int texIdx;
                        if (!MatTexIndices.TryGetValue(matIdx, out texIdx))
                        {
                            texIdx = -1;

                            xxMaterial mat         = parser.MaterialList[matIdx];
                            Material   materialD3D = new Material();
                            materialD3D.Ambient  = mat.Ambient;
                            materialD3D.Diffuse  = mat.Diffuse;
                            materialD3D.Emissive = mat.Emissive;
                            materialD3D.Specular = mat.Specular;
                            materialD3D.Power    = mat.Power;
                            Materials[matIdx]    = materialD3D;

                            xxMaterialTexture matTex     = mat.Textures[0];
                            string            matTexName = matTex.Name;
                            if (matTexName != String.Empty)
                            {
                                for (int j = 0; j < parser.TextureList.Count; j++)
                                {
                                    xxTexture tex = parser.TextureList[j];
                                    if (tex.Name == matTexName)
                                    {
                                        texIdx = j;
                                        if (Textures[j] == null)
                                        {
                                            ImportedTexture importedTex = xx.ImportedTexture(tex);
                                            Textures[j] = Texture.FromMemory(device, importedTex.Data);
                                        }
                                        break;
                                    }
                                }
                            }

                            MatTexIndices.Add(matIdx, texIdx);
                        }

                        meshContainer.MaterialIndex = matIdx;
                        meshContainer.TextureIndex  = texIdx;
                    }
                }

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

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

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

            numFrames++;
            return(animationFrame);
        }
Пример #12
0
            private static List <xxTexture> Export(string dest, xxParser parser, List <xxFrame> meshParents, bool worldCoords)
            {
                List <xxTexture> usedTextures = new List <xxTexture>(parser.TextureList.Count);
                DirectoryInfo    dir          = new DirectoryInfo(Path.GetDirectoryName(dest));

                if (!dir.Exists)
                {
                    dir.Create();
                }

                List <int> materialList = new List <int>(parser.MaterialList.Count);

                using (StreamWriter writer = new StreamWriter(dest, false))
                {
                    for (int i = 0; i < meshParents.Count; i++)
                    {
                        xxMesh meshListSome = meshParents[i].Mesh;
                        for (int j = 0; j < meshListSome.SubmeshList.Count; j++)
                        {
                            xxSubmesh meshObj       = meshListSome.SubmeshList[j];
                            int       meshObjMatIdx = meshObj.MaterialIndex;
                            if ((meshObjMatIdx >= 0) && (meshObjMatIdx < parser.MaterialList.Count))
                            {
                                if (!materialList.Contains(meshObjMatIdx))
                                {
                                    materialList.Add(meshObjMatIdx);
                                }
                            }
                            else
                            {
                                Report.ReportLog("Warning: Mesh " + meshParents[i].Name + " Object " + j + " has an invalid material");
                            }
                        }
                    }

                    writer.WriteLine("Metasequoia Document");
                    writer.WriteLine("Format Text Ver 1.0");
                    writer.WriteLine();
                    writer.WriteLine("Material " + materialList.Count + " {");
                    foreach (int matIdx in materialList)
                    {
                        xxMaterial mat        = parser.MaterialList[matIdx];
                        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)";
                        string     matTexName = mat.Textures[0].Name;
                        if (matTexName != String.Empty)
                        {
                            s += " tex(\"" + Path.GetFileName(matTexName) + "\")";
                        }
                        writer.WriteLine(s);
                    }
                    writer.WriteLine("}");

                    Random rand = new Random();
                    for (int i = 0; i < meshParents.Count; i++)
                    {
                        Matrix transform = Matrix.Identity;
                        if (worldCoords)
                        {
                            xxFrame parent = meshParents[i];
                            while (parent != null)
                            {
                                transform = parent.Matrix * transform;
                                parent    = (xxFrame)parent.Parent;
                            }
                        }

                        string meshName     = meshParents[i].Name;
                        xxMesh meshListSome = meshParents[i].Mesh;
                        for (int j = 0; j < meshListSome.SubmeshList.Count; j++)
                        {
                            xxSubmesh meshObj       = meshListSome.SubmeshList[j];
                            int       meshObjMatIdx = meshObj.MaterialIndex;
                            int       mqoMatIdx     = -1;
                            if ((meshObjMatIdx >= 0) && (meshObjMatIdx < parser.MaterialList.Count))
                            {
                                mqoMatIdx = materialList.IndexOf(meshObjMatIdx);
                            }
                            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]";
                            }
                            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 = xx.ImportedVertexList(meshObj.VertexList, xx.IsSkinned(meshListSome));
                            List <ImportedFace>   faceList = xx.ImportedFaceList(meshObj.FaceList);
                            if (worldCoords)
                            {
                                for (int k = 0; k < vertList.Count; k++)
                                {
                                    vertList[k].Position = Vector3.TransformCoordinate(vertList[k].Position, transform);
                                }
                            }

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

                foreach (int matIdx in materialList)
                {
                    xxMaterial        mat        = parser.MaterialList[matIdx];
                    xxMaterialTexture matTex     = mat.Textures[0];
                    string            matTexName = matTex.Name;
                    if (matTexName != String.Empty)
                    {
                        for (int i = 0; i < parser.TextureList.Count; i++)
                        {
                            xxTexture tex     = parser.TextureList[i];
                            string    texName = tex.Name;
                            if ((texName == matTexName) && !usedTextures.Contains(tex))
                            {
                                usedTextures.Add(tex);
                                break;
                            }
                        }
                    }
                }
                return(usedTextures);
            }
Пример #13
0
        protected xxFrame ParseFrame()
        {
            xxFrame frame = new xxFrame();

            frame.Name = reader.ReadName();

            int numChildFrames = reader.ReadInt32();

            frame.InitChildren(numChildFrames);

            frame.Matrix   = reader.ReadMatrix();
            frame.Unknown1 = (Format >= 7) ? reader.ReadBytes(32) : reader.ReadBytes(16);

            int numSubmeshes = reader.ReadInt32();

            frame.Bounds   = new BoundingBox(reader.ReadVector3(), reader.ReadVector3());
            frame.Unknown2 = (Format >= 7) ? reader.ReadBytes(64) : reader.ReadBytes(16);

            if (Format >= 6)
            {
                frame.Name2 = reader.ReadName();
            }

            if (numSubmeshes > 0)
            {
                xxMesh mesh = new xxMesh();
                frame.Mesh = mesh;
                mesh.NumVector2PerVertex = reader.ReadByte();

                mesh.SubmeshList = new List <xxSubmesh>(numSubmeshes);
                for (int i = 0; i < numSubmeshes; i++)
                {
                    xxSubmesh submesh = new xxSubmesh();
                    mesh.SubmeshList.Add(submesh);

                    submesh.Unknown1      = (Format >= 7) ? reader.ReadBytes(64) : reader.ReadBytes(16);
                    submesh.MaterialIndex = reader.ReadInt32();

                    submesh.FaceList   = ParseFaceList();
                    submesh.VertexList = ParseVertexList();

                    if (Format >= 7)
                    {
                        submesh.Unknown2 = reader.ReadBytes(20);
                    }

                    if (mesh.NumVector2PerVertex > 0)
                    {
                        submesh.Vector2Lists = new List <List <Vector2> >(submesh.VertexList.Count);
                        for (int j = 0; j < submesh.VertexList.Count; j++)
                        {
                            List <Vector2> vectorList = new List <Vector2>(mesh.NumVector2PerVertex);
                            submesh.Vector2Lists.Add(vectorList);
                            for (byte k = 0; k < mesh.NumVector2PerVertex; k++)
                            {
                                vectorList.Add(reader.ReadVector2());
                            }
                        }
                    }

                    if (Format >= 2)
                    {
                        submesh.Unknown3 = reader.ReadBytes(100);                         // 96 + 4
                    }

                    if (Format >= 7)
                    {
                        submesh.Unknown4 = reader.ReadBytes(284);                         // 256 + 28

                        if (Format >= 8)
                        {
                            byte   format    = reader.ReadByte();
                            string nullFrame = reader.ReadName();
                            byte[] u5end     = reader.ReadBytes(12 + 4);

                            byte[] encryptedName = Utility.EncryptName(nullFrame);
                            submesh.Unknown5    = new byte[1 + 4 + encryptedName.Length + 12 + 4];
                            submesh.Unknown5[0] = format;
                            BitConverter.GetBytes(encryptedName.Length).CopyTo(submesh.Unknown5, 1);
                            encryptedName.CopyTo(submesh.Unknown5, 1 + 4);
                            u5end.CopyTo(submesh.Unknown5, 1 + 4 + encryptedName.Length);
                        }
                    }
                    else
                    {
                        if (Format >= 3)
                        {
                            submesh.Unknown4 = reader.ReadBytes(64);
                        }
                        if (Format >= 5)
                        {
                            submesh.Unknown5 = reader.ReadBytes(20);
                        }
                        if (Format >= 6)
                        {
                            submesh.Unknown6 = reader.ReadBytes(28);
                        }
                    }
                }

                ushort numVerticesDup = reader.ReadUInt16();
                mesh.VertexListDuplicate        = new List <xxVertex>(numVerticesDup);
                mesh.VertexListDuplicateUnknown = reader.ReadBytes(8);                  // 4 + 4
                for (int i = 0; i < numVerticesDup; i++)
                {
                    mesh.VertexListDuplicate.Add(ParseVertex());
                }

                mesh.BoneList = ParseBoneList();
            }

            for (int i = 0; i < numChildFrames; i++)
            {
                frame.AddChild(ParseFrame());
            }

            return(frame);
        }
Пример #14
0
        public static void ConvertFormat(xxFrame frame, int srcFormat, int destFormat)
        {
            if ((srcFormat < 7) && (destFormat >= 7))
            {
                byte[] unknown1 = frame.Unknown1;
                frame.Unknown1 = new byte[32];
                Array.Copy(unknown1, frame.Unknown1, unknown1.Length);

                byte[] unknown2 = frame.Unknown2;
                frame.Unknown2 = new byte[64];
                Array.Copy(unknown2, frame.Unknown2, unknown2.Length);
            }
            else if ((srcFormat >= 7) && (destFormat < 7))
            {
                byte[] unknown1 = frame.Unknown1;
                frame.Unknown1 = new byte[16];
                Array.Copy(unknown1, frame.Unknown1, frame.Unknown1.Length);

                byte[] unknown2 = frame.Unknown2;
                frame.Unknown2 = new byte[16];
                Array.Copy(unknown2, frame.Unknown2, frame.Unknown2.Length);
            }

            if ((srcFormat < 6) && (destFormat >= 6))
            {
                frame.Name2 = String.Empty;
            }
            else if ((srcFormat >= 6) && (destFormat < 6))
            {
                frame.Name2 = null;
            }

            if (frame.Mesh != null)
            {
                for (int i = 0; i < frame.Mesh.SubmeshList.Count; i++)
                {
                    xxSubmesh submesh = frame.Mesh.SubmeshList[i];

                    if ((srcFormat < 7) && (destFormat >= 7))
                    {
                        byte[] unknown1 = submesh.Unknown1;
                        submesh.Unknown1 = new byte[64];
                        Array.Copy(unknown1, submesh.Unknown1, unknown1.Length);

                        submesh.Unknown2 = new byte[20];
                    }
                    else if ((srcFormat >= 7) && (destFormat < 7))
                    {
                        byte[] unknown1 = submesh.Unknown1;
                        submesh.Unknown1 = new byte[16];
                        Array.Copy(unknown1, submesh.Unknown1, submesh.Unknown1.Length);

                        submesh.Unknown2 = null;
                    }

                    if ((srcFormat < 2) && (destFormat >= 2))
                    {
                        submesh.Unknown3 = new byte[100];
                    }
                    else if ((srcFormat >= 2) && (destFormat < 2))
                    {
                        submesh.Unknown3 = null;
                    }

                    if ((srcFormat < 3) && ((destFormat >= 3) && (destFormat < 7)))
                    {
                        submesh.Unknown4 = new byte[64];
                    }
                    else if ((srcFormat < 3) && (destFormat >= 7))
                    {
                        submesh.Unknown4 = new byte[284];
                    }
                    else if (((srcFormat >= 3) && (srcFormat < 7)) && (destFormat < 3))
                    {
                        submesh.Unknown4 = null;
                    }
                    else if (((srcFormat >= 3) && (srcFormat < 7)) && (destFormat >= 7))
                    {
                        byte[] unknown4 = submesh.Unknown4;
                        submesh.Unknown4 = new byte[284];
                        Array.Copy(unknown4, submesh.Unknown4, unknown4.Length);
                    }
                    else if ((srcFormat >= 7) && (destFormat < 3))
                    {
                        submesh.Unknown4 = null;
                    }
                    else if ((srcFormat >= 7) && ((destFormat >= 3) && (destFormat < 7)))
                    {
                        byte[] unknown4 = submesh.Unknown4;
                        submesh.Unknown4 = new byte[64];
                        Array.Copy(unknown4, submesh.Unknown4, submesh.Unknown4.Length);
                    }

                    if ((srcFormat < 5) && ((destFormat >= 5) && (destFormat < 8)))
                    {
                        submesh.Unknown5 = new byte[20];
                    }
                    else if ((srcFormat < 5) && (destFormat >= 8))
                    {
                        submesh.Unknown5 = new byte[21];
                    }
                    else if (((srcFormat >= 5) && (srcFormat < 8)) && (destFormat < 5))
                    {
                        submesh.Unknown5 = null;
                    }
                    else if (((srcFormat >= 5) && (srcFormat < 8)) && (destFormat >= 8))
                    {
                        byte[] unknown5 = submesh.Unknown5;
                        submesh.Unknown5 = new byte[21];
                        Array.Copy(unknown5, submesh.Unknown5, unknown5.Length);
                    }
                    else if ((srcFormat >= 8) && (destFormat < 5))
                    {
                        submesh.Unknown5 = null;
                    }
                    else if ((srcFormat >= 8) && ((destFormat >= 5) && (destFormat < 8)))
                    {
                        byte[] unknown5 = submesh.Unknown5;
                        submesh.Unknown5 = new byte[20];
                        Array.Copy(unknown5, submesh.Unknown5, submesh.Unknown5.Length);
                    }

                    if ((srcFormat == 6) && (destFormat != 6))
                    {
                        submesh.Unknown6 = null;
                    }
                    else if ((srcFormat != 6) && (destFormat == 6))
                    {
                        submesh.Unknown6 = new byte[28];
                    }

                    ConvertFormat(submesh.VertexList, srcFormat, destFormat);
                }

                ConvertFormat(frame.Mesh.VertexListDuplicate, srcFormat, destFormat);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                ConvertFormat(frame[i], srcFormat, destFormat);
            }
        }
Пример #15
0
        public static void ReplaceMesh(xxFrame frame, xxParser parser, WorkspaceMesh mesh, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool targetFullMesh)
        {
            Matrix  transform      = Matrix.Identity;
            xxFrame transformFrame = frame;

            while (transformFrame != null)
            {
                transform      = transformFrame.Matrix * transform;
                transformFrame = (xxFrame)transformFrame.Parent;
            }
            transform.Invert();

            string[] materialNames;
            int[]    indices;
            bool[]   worldCoords;
            bool[]   replaceSubmeshesOption;
            xxMesh   xxMesh = CreateMesh(mesh, parser.Format, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption);

            List <xxVertex> allVertices = null;

            if (frame.Mesh == null)
            {
                CreateUnknowns(xxMesh);
            }
            else
            {
                CopyUnknowns(frame.Mesh, xxMesh);

                if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear))
                {
                    xxMesh.BoneList = new List <xxBone>(frame.Mesh.BoneList.Count);
                    for (int i = 0; i < frame.Mesh.BoneList.Count; i++)
                    {
                        xxMesh.BoneList.Add(frame.Mesh.BoneList[i].Clone());
                    }
                }

                if (targetFullMesh && (normalsMethod == CopyMeshMethod.CopyNear || bonesMethod == CopyMeshMethod.CopyNear))
                {
                    allVertices = new List <xxVertex>();
                    HashSet <Vector3> posSet = new HashSet <Vector3>(new VertexPositionComparer());
                    foreach (xxSubmesh submesh in frame.Mesh.SubmeshList)
                    {
                        allVertices.Capacity = allVertices.Count + submesh.VertexList.Count;
                        foreach (xxVertex vertex in submesh.VertexList)
                        {
                            if (!posSet.Contains(vertex.Position))
                            {
                                posSet.Add(vertex.Position);
                                allVertices.Add(vertex);
                            }
                        }
                    }
                }
            }

            xxSubmesh[]      replaceSubmeshes = (frame.Mesh == null) ? null : new xxSubmesh[frame.Mesh.SubmeshList.Count];
            List <xxSubmesh> addSubmeshes     = new List <xxSubmesh>(xxMesh.SubmeshList.Count);

            for (int i = 0; i < xxMesh.SubmeshList.Count; i++)
            {
                for (int j = 0; j < parser.MaterialList.Count; j++)
                {
                    if (parser.MaterialList[j].Name == materialNames[i])
                    {
                        xxMesh.SubmeshList[i].MaterialIndex = j;
                        break;
                    }
                }

                xxSubmesh       xxSubmesh    = xxMesh.SubmeshList[i];
                List <xxVertex> xxVertexList = xxSubmesh.VertexList;
                if (worldCoords[i])
                {
                    for (int j = 0; j < xxVertexList.Count; j++)
                    {
                        xxVertexList[j].Position = Vector3.TransformCoordinate(xxVertexList[j].Position, transform);
                    }
                }

                xxSubmesh baseSubmesh = null;
                int       idx         = indices[i];
                if ((frame.Mesh != null) && (idx >= 0) && (idx < frame.Mesh.SubmeshList.Count))
                {
                    baseSubmesh = frame.Mesh.SubmeshList[idx];
                    CopyUnknowns(baseSubmesh, xxSubmesh, parser.Format, xxMesh.NumVector2PerVertex);
                }
                else
                {
                    CreateUnknowns(xxSubmesh, parser.Format, xxMesh.NumVector2PerVertex);
                }

                if (baseSubmesh != null)
                {
                    if (normalsMethod == CopyMeshMethod.CopyOrder)
                    {
                        xx.CopyNormalsOrder(baseSubmesh.VertexList, xxSubmesh.VertexList);
                    }
                    else if (normalsMethod == CopyMeshMethod.CopyNear)
                    {
                        xx.CopyNormalsNear(targetFullMesh ? allVertices : baseSubmesh.VertexList, xxSubmesh.VertexList);
                    }

                    if (bonesMethod == CopyMeshMethod.CopyOrder)
                    {
                        xx.CopyBonesOrder(baseSubmesh.VertexList, xxSubmesh.VertexList);
                    }
                    else if (bonesMethod == CopyMeshMethod.CopyNear)
                    {
                        xx.CopyBonesNear(targetFullMesh ? allVertices : baseSubmesh.VertexList, xxSubmesh.VertexList);
                    }
                }

                if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i])
                {
                    replaceSubmeshes[idx] = xxSubmesh;
                }
                else
                {
                    addSubmeshes.Add(xxSubmesh);
                }
            }

            if ((frame.Mesh != null) && merge)
            {
                xxMesh.SubmeshList = new List <xxSubmesh>(replaceSubmeshes.Length + addSubmeshes.Count);
                List <xxSubmesh> copiedSubmeshes = new List <xxSubmesh>(replaceSubmeshes.Length);
                for (int i = 0; i < replaceSubmeshes.Length; i++)
                {
                    if (replaceSubmeshes[i] == null)
                    {
                        xxSubmesh xxSubmesh = frame.Mesh.SubmeshList[i].Clone();
                        copiedSubmeshes.Add(xxSubmesh);
                        xxMesh.SubmeshList.Add(xxSubmesh);
                    }
                    else
                    {
                        xxMesh.SubmeshList.Add(replaceSubmeshes[i]);
                    }
                }
                xxMesh.SubmeshList.AddRange(addSubmeshes);

                if ((frame.Mesh.BoneList.Count == 0) && (xxMesh.BoneList.Count > 0))
                {
                    for (int i = 0; i < copiedSubmeshes.Count; i++)
                    {
                        List <xxVertex> vertexList = copiedSubmeshes[i].VertexList;
                        for (int j = 0; j < vertexList.Count; j++)
                        {
                            vertexList[j].BoneIndices = new byte[4] {
                                0xFF, 0xFF, 0xFF, 0xFF
                            };
                        }
                    }
                }
                else if ((frame.Mesh.BoneList.Count > 0) && (xxMesh.BoneList.Count == 0))
                {
                    for (int i = 0; i < replaceSubmeshes.Length; i++)
                    {
                        if (replaceSubmeshes[i] != null)
                        {
                            List <xxVertex> vertexList = replaceSubmeshes[i].VertexList;
                            for (int j = 0; j < vertexList.Count; j++)
                            {
                                vertexList[j].BoneIndices = new byte[4] {
                                    0xFF, 0xFF, 0xFF, 0xFF
                                };
                            }
                        }
                    }
                    for (int i = 0; i < addSubmeshes.Count; i++)
                    {
                        List <xxVertex> vertexList = addSubmeshes[i].VertexList;
                        for (int j = 0; j < vertexList.Count; j++)
                        {
                            vertexList[j].BoneIndices = new byte[4] {
                                0xFF, 0xFF, 0xFF, 0xFF
                            };
                        }
                    }
                }
                else if ((frame.Mesh.BoneList.Count > 0) && (xxMesh.BoneList.Count > 0))
                {
                    byte[] boneIdxMap;
                    xxMesh.BoneList = MergeBoneList(frame.Mesh.BoneList, xxMesh.BoneList, out boneIdxMap);
                    for (int i = 0; i < replaceSubmeshes.Length; i++)
                    {
                        if (replaceSubmeshes[i] != null)
                        {
                            List <xxVertex> vertexList = replaceSubmeshes[i].VertexList;
                            for (int j = 0; j < vertexList.Count; j++)
                            {
                                byte[] boneIndices = vertexList[j].BoneIndices;
                                vertexList[j].BoneIndices = new byte[4];
                                for (int k = 0; k < 4; k++)
                                {
                                    vertexList[j].BoneIndices[k] = boneIndices[k] < 0xFF ? boneIdxMap[boneIndices[k]] : (byte)0xFF;
                                }
                            }
                        }
                    }
                    for (int i = 0; i < addSubmeshes.Count; i++)
                    {
                        List <xxVertex> vertexList = addSubmeshes[i].VertexList;
                        for (int j = 0; j < vertexList.Count; j++)
                        {
                            byte[] boneIndices = vertexList[j].BoneIndices;
                            vertexList[j].BoneIndices = new byte[4];
                            for (int k = 0; k < 4; k++)
                            {
                                vertexList[j].BoneIndices[k] = boneIndices[k] < 0xFF ? boneIdxMap[boneIndices[k]] : (byte)0xFF;
                            }
                        }
                    }
                }
            }

            if ((xxMesh.NumVector2PerVertex > 0) || ((frame.Mesh != null) && merge))
            {
                xxMesh.VertexListDuplicate = CreateVertexListDup(xxMesh.SubmeshList);
            }

            frame.Mesh = xxMesh;
            SetBoundingBox(frame);
        }
Пример #16
0
        public static xxMesh CreateMesh(WorkspaceMesh mesh, int xxFormat, 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];

            xxMesh xxMesh = new xxMesh();

            xxMesh.BoneList = CreateBoneList(mesh.BoneList);

            xxMesh.SubmeshList = new List <xxSubmesh>(mesh.SubmeshList.Count);
            for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++)
            {
                while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx]))
                {
                    submeshIdx++;
                }

                xxSubmesh xxSubmesh = new xxSubmesh();
                xxMesh.SubmeshList.Add(xxSubmesh);

                xxSubmesh.MaterialIndex = -1;
                materialNames[i]        = mesh.SubmeshList[submeshIdx].Material;
                indices[i]                = mesh.SubmeshList[submeshIdx].Index;
                worldCoords[i]            = mesh.SubmeshList[submeshIdx].WorldCoords;
                replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]);

                List <ImportedVertex> vertexList   = mesh.SubmeshList[submeshIdx].VertexList;
                List <xxVertex>       xxVertexList = new List <xxVertex>(vertexList.Count);
                for (int j = 0; j < vertexList.Count; j++)
                {
                    ImportedVertex vert = vertexList[j];
                    xxVertex       xxVertex;
                    if (xxFormat >= 4)
                    {
                        xxVertex = new xxVertexUShort();
                        CreateUnknown(xxVertex);
                    }
                    else
                    {
                        xxVertex = new xxVertexInt();
                    }

                    xxVertex.Index    = j;
                    xxVertex.Normal   = vert.Normal;
                    xxVertex.UV       = (float[])vert.UV.Clone();
                    xxVertex.Weights3 = new float[3] {
                        vert.Weights[0], vert.Weights[1], vert.Weights[2]
                    };
                    xxVertex.BoneIndices = (byte[])vert.BoneIndices.Clone();
                    xxVertex.Position    = vert.Position;
                    xxVertexList.Add(xxVertex);
                }
                xxSubmesh.VertexList = xxVertexList;

                List <ImportedFace> faceList   = mesh.SubmeshList[submeshIdx].FaceList;
                List <xxFace>       xxFaceList = new List <xxFace>(faceList.Count);
                for (int j = 0; j < faceList.Count; j++)
                {
                    int[]  vertexIndices = faceList[j].VertexIndices;
                    xxFace xxFace        = new xxFace();
                    xxFace.VertexIndices = new ushort[3] {
                        (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2]
                    };
                    xxFaceList.Add(xxFace);
                }
                xxSubmesh.FaceList = xxFaceList;
            }

            xxMesh.VertexListDuplicate = CreateVertexListDup(xxMesh.SubmeshList);
            return(xxMesh);
        }
Пример #17
0
        public static void CopyUnknowns(xxSubmesh src, xxSubmesh dest, int xxFormat, byte xxMeshNumUnknownA)
        {
            List <xxVertex> srcVertexList  = src.VertexList;
            List <xxVertex> destVertexList = dest.VertexList;

            dest.Unknown1 = (byte[])src.Unknown1.Clone();

            if (xxFormat >= 7)
            {
                dest.Unknown2 = (byte[])src.Unknown2.Clone();
            }

            if (xxMeshNumUnknownA > 0)
            {
                dest.Vector2Lists = new List <List <Vector2> >(destVertexList.Count);
                for (int j = 0; (j < destVertexList.Count) && (j < srcVertexList.Count); j++)
                {
                    List <Vector2> vectorList = new List <Vector2>(xxMeshNumUnknownA);
                    dest.Vector2Lists.Add(vectorList);
                    for (byte k = 0; k < xxMeshNumUnknownA; k++)
                    {
                        vectorList.Add(src.Vector2Lists[j][k]);
                    }
                }
                for (int j = srcVertexList.Count; j < destVertexList.Count; j++)
                {
                    List <Vector2> vectorList = new List <Vector2>(xxMeshNumUnknownA);
                    dest.Vector2Lists.Add(vectorList);
                    for (byte k = 0; k < xxMeshNumUnknownA; k++)
                    {
                        vectorList.Add(new Vector2());
                    }
                }
            }

            if (xxFormat >= 2)
            {
                dest.Unknown3 = (byte[])src.Unknown3.Clone();
            }

            if (xxFormat >= 7)
            {
                dest.Unknown4 = (byte[])src.Unknown4.Clone();

                if (xxFormat >= 7)
                {
                    dest.Unknown5 = (byte[])src.Unknown5.Clone();
                }
            }
            else
            {
                if (xxFormat >= 3)
                {
                    dest.Unknown4 = (byte[])src.Unknown4.Clone();
                }
                if (xxFormat >= 5)
                {
                    dest.Unknown5 = (byte[])src.Unknown5.Clone();
                }
                if (xxFormat >= 6)
                {
                    dest.Unknown6 = (byte[])src.Unknown6.Clone();
                }
            }

            if (xxFormat >= 4)
            {
                for (int j = 0; j < destVertexList.Count; j++)
                {
                    if (j < srcVertexList.Count)
                    {
                        destVertexList[j].Unknown1 = (byte[])srcVertexList[j].Unknown1.Clone();
                    }
                    else
                    {
                        destVertexList[j].Unknown1 = new byte[20];
                    }
                }
            }
        }