예제 #1
0
        public static void Write(Stream stream, Pmo pmo)
        {
            stream.Position = 0;

            BinaryMapping.WriteObject <Pmo.Header>(stream, pmo.header);

            for (int i = 0; i < pmo.header.TextureCount; i++)
            {
                BinaryMapping.WriteObject <Pmo.TextureInfo>(stream, pmo.textureInfo[i]);
            }

            WriteMeshData(stream, pmo);

            // Write textures.
            for (int t = 0; t < pmo.texturesData.Count; t++)
            {
                stream.Write(pmo.texturesData[t]);
            }

            if (pmo.header.SkeletonOffset != 0)
            {
                BinaryMapping.WriteObject <SkeletonHeader>(stream, pmo.skeletonHeader);

                for (int joint = 0; joint < pmo.jointList.Length; joint++)
                {
                    BinaryMapping.WriteObject <JointData>(stream, pmo.jointList[joint]);
                }
            }
        }
예제 #2
0
        public static void Write(Stream stream, Pmo pmo)
        {
            stream.Position = 0;

            WriteHeaderData(stream, pmo);
            WriteMeshData(stream, pmo);
            WriteTextureData(stream, pmo);
            WriteTextureOffsets(stream, pmo);

            if (pmo.boneList != null && pmo.boneList.Length > 0)
            {
                stream.Seek(0, SeekOrigin.End);
                pmo.header.SkeletonOffset = (uint)stream.Position;
                stream.Seek(0xC, SeekOrigin.Begin);
                stream.Write(pmo.header.SkeletonOffset);
                stream.Seek(0, SeekOrigin.End);
                stream.Seek(pmo.header.SkeletonOffset, SeekOrigin.Begin);
                Mapping.WriteObject <SkeletonHeader>(stream, pmo.skeletonHeader);

                for (int joint = 0; joint < pmo.boneList.Length; joint++)
                {
                    Mapping.WriteObject <BoneData>(stream, pmo.boneList[joint]);
                }
            }
        }
예제 #3
0
 public static void ReadTextureSection(Stream stream, Pmo pmo)
 {
     pmo.textureInfo = new TextureInfo[pmo.header.TextureCount];
     for (ushort i = 0; i < pmo.header.TextureCount; i++)
     {
         pmo.textureInfo[i] = Mapping.ReadObject <TextureInfo>(stream);
     }
 }
예제 #4
0
 public static void WriteTextureOffsets(Stream stream, Pmo pmo)
 {
     // Go back to write tm2 offsets.
     for (int p = 0; p < pmo.texturesData.Count; p++)
     {
         stream.Seek(0xA0 + (p * 0x20), SeekOrigin.Begin);
         stream.Write(pmo.TextureOffsets[p]);
     }
 }
예제 #5
0
        public static void WriteHeaderData(Stream stream, Pmo pmo)
        {
            Mapping.WriteObject <Pmo.Header>(stream, pmo.header);

            for (int i = 0; i < pmo.header.TextureCount; i++)
            {
                Mapping.WriteObject <Pmo.TextureInfo>(stream, pmo.textureInfo[i]);
            }
        }
예제 #6
0
파일: Pmp.cs 프로젝트: tommadness/OpenKh
        public static void Write(Stream stream, Pmp pmp)
        {
            stream.Position = 0;
            BinaryMapping.WriteObject <Header>(stream, pmp.header);

            for (int i = 0; i < pmp.objectInfo.Count; i++)
            {
                BinaryMapping.WriteObject <ObjectInfo>(stream, pmp.objectInfo[i]);
            }

            List <Pmo> nPmoList = pmp.PmoList;

            nPmoList.Sort((l, r) => l.PMO_StartPosition.CompareTo(r.PMO_StartPosition));

            for (int p = 0; p < nPmoList.Count; p++)
            {
                uint off = (uint)stream.Position;
                stream.Seek(0x44 + (p * 0x30), SeekOrigin.Begin);
                stream.Write(off);
                stream.Seek(0, SeekOrigin.End);

                BinaryMapping.WriteObject <Pmo.Header>(stream, nPmoList[p].header);

                for (int g = 0; g < nPmoList[p].textureInfo.Length; g++)
                {
                    BinaryMapping.WriteObject <Pmo.TextureInfo>(stream, nPmoList[p].textureInfo[g]);
                }

                Pmo.WriteMeshData(stream, nPmoList[p]);
            }

            uint pos = (uint)stream.Position;

            stream.Seek(0x1C, SeekOrigin.Begin);
            stream.Write(pos);
            stream.Seek(0, SeekOrigin.End);

            for (int tl = 0; tl < pmp.TextureList.Count; tl++)
            {
                BinaryMapping.WriteObject <PMPTextureInfo>(stream, pmp.TextureList[tl]);
            }

            for (int td = 0; td < pmp.TextureList.Count; td++)
            {
                uint       sPos = (uint)stream.Position;
                List <Tm2> l    = new List <Tm2>();
                l.Add(pmp.TextureDataList[td]);
                Tm2.Write(stream, l);

                stream.Seek(pos + (td * 0x20), SeekOrigin.Begin);
                stream.Write(sPos);
                stream.Seek(0, SeekOrigin.End);
            }
        }
예제 #7
0
 public static void WriteTextureData(Stream stream, Pmo pmo)
 {
     // Write textures.
     for (int t = 0; t < pmo.texturesData.Count; t++)
     {
         pmo.TextureOffsets.Add((uint)stream.Position);
         List <Tm2> tm2list = new List <Tm2>();
         tm2list.Add(pmo.texturesData[t]);
         Tm2.Write(stream, tm2list);
     }
 }
예제 #8
0
        public static Pmo Read(Stream stream)
        {
            Pmo pmo = new Pmo();

            pmo.PMO_StartPosition = (uint)stream.Position;

            ReadHeader(stream, pmo);
            ReadTextureSection(stream, pmo);

            // Read all data
            if (pmo.header.MeshOffset0 != 0)
            {
                ReadMeshData(stream, pmo, 0);
            }
            if (pmo.header.MeshOffset1 != 0)
            {
                ReadMeshData(stream, pmo, 1);
            }

            // Read textures.
            for (int i = 0; i < pmo.textureInfo.Length; i++)
            {
                if (pmo.textureInfo[i].TextureOffset != 0)
                {
                    stream.Seek(pmo.textureInfo[i].TextureOffset + 0x10, SeekOrigin.Begin);
                    uint tm2size = stream.ReadUInt32() + 0x10;
                    stream.Seek(pmo.textureInfo[i].TextureOffset, SeekOrigin.Begin);
                    Tm2 tm2 = Tm2.Read(stream, true).First();

                    pmo.texturesData.Add(tm2);
                }
            }

            // Read Skeleton.
            if (pmo.header.SkeletonOffset != 0)
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.SkeletonOffset, SeekOrigin.Begin);
                pmo.skeletonHeader = Mapping.ReadObject <SkeletonHeader>(stream);
                pmo.boneList       = new BoneData[pmo.skeletonHeader.BoneCount];
                for (int j = 0; j < pmo.skeletonHeader.BoneCount; j++)
                {
                    pmo.boneList[j] = Mapping.ReadObject <BoneData>(stream);
                }
            }

            return(pmo);
        }
예제 #9
0
파일: Pmp.cs 프로젝트: osdanova/OpenKh
        public static Pmp Read(Stream stream)
        {
            Pmp pmp = new Pmp();

            pmp.header = BinaryMapping.ReadObject <Header>(stream);

            // Read Object List.
            for (int i = 0; i < pmp.header.ObjectCount; i++)
            {
                pmp.objectInfo.Add(Mapping.ReadObject <ObjectInfo>(stream));
                pmp.hasDifferentMatrix.Add(BitsUtil.Int.GetBit(pmp.objectInfo[i].ObjectFlags, 0));
            }

            // Read PMO list.
            for (int p = 0; p < pmp.header.ObjectCount; p++)
            {
                ObjectInfo currentPmoInfo = pmp.objectInfo[p];
                if (currentPmoInfo.PMO_Offset != 0)
                {
                    stream.Seek(currentPmoInfo.PMO_Offset, SeekOrigin.Begin);
                    pmp.PmoList.Add(Pmo.Read(stream));
                }
                else
                {
                    pmp.PmoList.Add(null);
                }
            }

            stream.Seek(pmp.header.TextureListOffset, SeekOrigin.Begin);

            for (int t = 0; t < pmp.header.TextureCount; t++)
            {
                pmp.TextureList.Add(BinaryMapping.ReadObject <PMPTextureInfo>(stream));
            }

            // Read textures.
            for (int k = 0; k < pmp.TextureList.Count; k++)
            {
                stream.Seek(pmp.TextureList[k].Offset + 0x10, SeekOrigin.Begin);
                uint tm2size = stream.ReadUInt32() + 0x10;
                stream.Seek(pmp.TextureList[k].Offset, SeekOrigin.Begin);

                pmp.TextureDataList.Add(Tm2.Read(stream, true).First());
            }

            return(pmp);
        }
예제 #10
0
        public static Pmo Read(Stream stream)
        {
            Pmo pmo = new Pmo();

            pmo.PMO_StartPosition = (uint)stream.Position;

            ReadHeader(stream, pmo);
            ReadTextureSection(stream, pmo);

            // Read all data
            if (pmo.header.MeshOffset0 != 0)
            {
                ReadMeshData(stream, pmo, 0);
            }
            if (pmo.header.MeshOffset1 != 0)
            {
                ReadMeshData(stream, pmo, 1);
            }

            // Read textures.
            for (int i = 0; i < pmo.textureInfo.Length; i++)
            {
                stream.Seek(pmo.textureInfo[i].TextureOffset + 0x10, SeekOrigin.Begin);
                uint tm2size = stream.ReadUInt32() + 0x10;
                stream.Seek(pmo.textureInfo[i].TextureOffset, SeekOrigin.Begin);

                byte[] TextureBuffer = new byte[tm2size];
                TextureBuffer = stream.ReadBytes((int)tm2size);

                pmo.texturesData.Add(TextureBuffer);
            }

            // Read Skeleton.
            if (pmo.header.SkeletonOffset != 0)
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.SkeletonOffset, SeekOrigin.Begin);
                pmo.skeletonHeader = BinaryMapping.ReadObject <SkeletonHeader>(stream);
                pmo.jointList      = new JointData[pmo.skeletonHeader.JointCount];
                for (int j = 0; j < pmo.skeletonHeader.JointCount; j++)
                {
                    pmo.jointList[j] = BinaryMapping.ReadObject <JointData>(stream);
                }
            }

            return(pmo);
        }
예제 #11
0
파일: Pmo.cs 프로젝트: shinerkz/OpenKh
        public static void Write(Stream stream, Pmo pmo)
        {
            stream.Position = 0;

            WriteHeaderData(stream, pmo);
            WriteMeshData(stream, pmo);
            WriteTextureData(stream, pmo);
            WriteTextureOffsets(stream, pmo);

            if (pmo.header.SkeletonOffset != 0)
            {
                stream.Seek(pmo.header.SkeletonOffset, SeekOrigin.Begin);
                BinaryMapping.WriteObject <SkeletonHeader>(stream, pmo.skeletonHeader);

                for (int joint = 0; joint < pmo.boneList.Length; joint++)
                {
                    BinaryMapping.WriteObject <BoneData>(stream, pmo.boneList[joint]);
                }
            }
        }
예제 #12
0
        public static void Write(Stream stream, Pmp pmp)
        {
            stream.Position = 0;
            BinaryMapping.WriteObject <Header>(stream, pmp.header);

            for (int i = 0; i < pmp.objectInfo.Count; i++)
            {
                BinaryMapping.WriteObject <ObjectInfo>(stream, pmp.objectInfo[i]);
            }

            List <Pmo> nPmoList = pmp.PmoList;

            nPmoList.Sort((l, r) => l.PMO_StartPosition.CompareTo(r.PMO_StartPosition));

            for (int p = 0; p < nPmoList.Count; p++)
            {
                BinaryMapping.WriteObject <Pmo.Header>(stream, nPmoList[p].header);

                for (int g = 0; g < nPmoList[p].textureInfo.Length; g++)
                {
                    BinaryMapping.WriteObject <Pmo.TextureInfo>(stream, nPmoList[p].textureInfo[g]);
                }

                Pmo.WriteMeshData(stream, nPmoList[p]);
            }

            for (int tl = 0; tl < pmp.TextureList.Count; tl++)
            {
                BinaryMapping.WriteObject <PMPTextureInfo>(stream, pmp.TextureList[tl]);
            }

            for (int td = 0; td < pmp.TextureList.Count; td++)
            {
                List <Tm2> l = new List <Tm2>();
                l.Add(pmp.TextureDataList[td]);
                Tm2.Write(stream, l);
            }
        }
예제 #13
0
        public static void WriteMeshData(Stream stream, Pmo pmo)
        {
            bool hasSwappedToSecondModel = false;

            // Write Mesh Data.
            for (int j = 0; j < pmo.Meshes.Count; j++)
            {
                if (!hasSwappedToSecondModel && pmo.Meshes[j].MeshNumber == 1 && pmo.header.MeshOffset0 != 0)
                {
                    hasSwappedToSecondModel = true;

                    for (uint b = 0; b < 0xC; b++)
                    {
                        stream.Write((byte)0x00);
                    }

                    for (uint b = 0; stream.Position % 0x10 != 0; b++)
                    {
                        stream.Write((byte)0x00);
                    }
                }

                MeshChunks chunk = pmo.Meshes[j];

                Mapping.WriteObject <Pmo.MeshSection>(stream, chunk.SectionInfo);
                if (chunk.SectionInfo_opt1 != null)
                {
                    Mapping.WriteObject <Pmo.MeshSectionOptional1>(stream, chunk.SectionInfo_opt1);
                }
                if (chunk.SectionInfo_opt2 != null)
                {
                    Mapping.WriteObject <Pmo.MeshSectionOptional2>(stream, chunk.SectionInfo_opt2);
                }

                if (chunk.TriangleStripValues.Length > 0)
                {
                    for (int z = 0; z < chunk.TriangleStripValues.Length; z++)
                    {
                        stream.Write((ushort)chunk.TriangleStripValues[z]);
                    }
                }

                for (int k = 0; k < pmo.Meshes[j].SectionInfo.VertexCount; k++)
                {
                    long vertexStartPos       = stream.Position;
                    int  vertexIncreaseAmount = 0;

                    VertexFlags flags = Pmo.GetFlags(chunk.SectionInfo);

                    // Write Joints.
                    if (flags.WeightFormat != CoordinateFormat.NO_VERTEX)
                    {
                        for (int w = 0; w < flags.SkinningWeightsCount + 1; w++)
                        {
                            int currentIndex = w + (k * (flags.SkinningWeightsCount + 1));

                            switch (flags.WeightFormat)
                            {
                            case CoordinateFormat.NORMALIZED_8_BITS:
                                stream.Write((byte)(chunk.jointWeights[k].weights[currentIndex] * 127.0f));
                                break;

                            case CoordinateFormat.NORMALIZED_16_BITS:
                                stream.Write((byte)(chunk.jointWeights[k].weights[currentIndex] * 32767.0f));
                                break;

                            case CoordinateFormat.FLOAT_32_BITS:
                                StreamExtensions.Write(stream, chunk.jointWeights[k].weights[currentIndex]);
                                break;
                            }
                        }
                    }

                    // Write Texture Coords.
                    switch (flags.TextureCoordinateFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        stream.Write((byte)(chunk.textureCoordinates[k].X * 128.0f));
                        stream.Write((byte)(chunk.textureCoordinates[k].Y * 128.0f));
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        stream.Write((ushort)(chunk.textureCoordinates[k].X * 32768.0f));
                        stream.Write((ushort)(chunk.textureCoordinates[k].Y * 32768.0f));
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, chunk.textureCoordinates[k].X);
                        StreamExtensions.Write(stream, chunk.textureCoordinates[k].Y);
                        break;
                    }

                    // Write colors.
                    switch (flags.ColorFormat)
                    {
                    case Pmo.ColorFormat.NO_COLOR:
                        break;

                    case Pmo.ColorFormat.BGR_5650_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_5551_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_4444_16BITS:
                        break;

                    case Pmo.ColorFormat.ABGR_8888_32BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        stream.Write((byte)(chunk.colors[k].X));
                        stream.Write((byte)(chunk.colors[k].Y));
                        stream.Write((byte)(chunk.colors[k].Z));
                        stream.Write((byte)(chunk.colors[k].W));
                        break;
                    }

                    // Write vertices.
                    switch (flags.PositionFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].X * 128.0f));
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Y * 128.0f));
                        StreamExtensions.Write(stream, (sbyte)(chunk.vertices[k].Z * 128.0f));
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].X * 32768.0f));
                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].Y * 32768.0f));
                        StreamExtensions.Write(stream, (short)(chunk.vertices[k].Z * 32768.0f));
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        for (int a = 0; a < vertexIncreaseAmount; a++)
                        {
                            stream.Write((byte)0xAB);
                        }

                        StreamExtensions.Write(stream, chunk.vertices[k].X);
                        StreamExtensions.Write(stream, chunk.vertices[k].Y);
                        StreamExtensions.Write(stream, chunk.vertices[k].Z);
                        break;
                    }

                    int padding = ((int)vertexStartPos + chunk.SectionInfo.VertexSize) - (int)stream.Position;
                    for (int p = 0; p < padding; p++)
                    {
                        stream.Write((byte)0xAB);
                    }
                }

                // Remainder.
                uint remainder = (uint)stream.Position % 4;
                for (int p = 0; p < remainder; p++)
                {
                    stream.Write((byte)0x00);
                }

                if (j == (pmo.Meshes.Count - 1))
                {
                    for (uint b = 0; b < 0xC; b++)
                    {
                        try
                        {
                            stream.Write((byte)0x00);
                        }
                        catch (Exception ex)
                        {
                            ex.ToString();
                        }
                    }


                    int pd = (int)stream.Position % 0x10;

                    for (int n = 0; pd != 0; n++)
                    {
                        try
                        {
                            stream.Write((byte)0x00);
                        }
                        catch (Exception ex)
                        {
                            ex.ToString();
                        }

                        pd = (int)stream.Position % 0x10;
                    }
                }
            }
        }
예제 #14
0
        public static void ReadMeshData(Stream stream, Pmo pmo, int MeshNumber = 0)
        {
            // Go to mesh position.
            if (MeshNumber == 0)
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.MeshOffset0, SeekOrigin.Begin);
            }
            else
            {
                stream.Seek(pmo.PMO_StartPosition + pmo.header.MeshOffset1, SeekOrigin.Begin);
            }

            UInt16 VertCnt = 0xFFFF;

            while (VertCnt > 0)
            {
                MeshChunks meshChunk = new MeshChunks();
                meshChunk.MeshNumber = MeshNumber;

                meshChunk.SectionInfo = Mapping.ReadObject <MeshSection>(stream);

                // Exit if Vertex Count is zero.
                if (meshChunk.SectionInfo.VertexCount <= 0)
                {
                    break;
                }

                meshChunk.TextureID = meshChunk.SectionInfo.TextureID;
                VertexFlags flags = GetFlags(meshChunk.SectionInfo);

                bool isColorFlagRisen = flags.UniformDiffuseFlag;

                if (pmo.header.SkeletonOffset != 0)
                {
                    meshChunk.SectionInfo_opt1 = Mapping.ReadObject <MeshSectionOptional1>(stream);
                }
                if (isColorFlagRisen)
                {
                    meshChunk.SectionInfo_opt2 = Mapping.ReadObject <MeshSectionOptional2>(stream);
                }
                if (meshChunk.SectionInfo.TriangleStripCount > 0)
                {
                    meshChunk.TriangleStripValues = new UInt16[meshChunk.SectionInfo.TriangleStripCount];
                    for (int i = 0; i < meshChunk.SectionInfo.TriangleStripCount; i++)
                    {
                        meshChunk.TriangleStripValues[i] = stream.ReadUInt16();
                    }
                }

                // Get Formats.
                CoordinateFormat TexCoordFormat       = flags.TextureCoordinateFormat;
                CoordinateFormat VertexPositionFormat = flags.PositionFormat;
                CoordinateFormat WeightFormat         = flags.WeightFormat;
                ColorFormat      ColorFormat          = flags.ColorFormat;
                UInt32           SkinningWeightsCount = flags.SkinningWeightsCount;
                BinaryReader     r = new BinaryReader(stream);
                long             positionAfterHeader = stream.Position;

                if (meshChunk.SectionInfo.TriangleStripCount > 0)
                {
                    int vertInd = 0;
                    for (int p = 0; p < meshChunk.SectionInfo.TriangleStripCount; p++)
                    {
                        for (int s = 0; s < (meshChunk.TriangleStripValues[p] - 2); s++)
                        {
                            if (s % 2 == 0)
                            {
                                meshChunk.Indices.Add(vertInd + s + 0);
                                meshChunk.Indices.Add(vertInd + s + 1);
                                meshChunk.Indices.Add(vertInd + s + 2);
                            }
                            else
                            {
                                meshChunk.Indices.Add(vertInd + s + 0);
                                meshChunk.Indices.Add(vertInd + s + 2);
                                meshChunk.Indices.Add(vertInd + s + 1);
                            }
                        }

                        vertInd += meshChunk.TriangleStripValues[p];
                    }
                }
                else
                {
                    if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE_STRIP)
                    {
                        for (int s = 0; s < (meshChunk.SectionInfo.VertexCount - 2); s++)
                        {
                            if (s % 2 == 0)
                            {
                                meshChunk.Indices.Add(s + 0);
                                meshChunk.Indices.Add(s + 1);
                                meshChunk.Indices.Add(s + 2);
                            }
                            else
                            {
                                meshChunk.Indices.Add(s + 1);
                                meshChunk.Indices.Add(s + 0);
                                meshChunk.Indices.Add(s + 2);
                            }
                        }
                    }
                }

                for (int v = 0; v < meshChunk.SectionInfo.VertexCount; v++)
                {
                    long vertexStartPos       = stream.Position;
                    int  vertexIncreaseAmount = 0;

                    // Vertex Weights.
                    if (pmo.header.SkeletonOffset != 0 && WeightFormat != CoordinateFormat.NO_VERTEX)
                    {
                        WeightData WeightList = new WeightData();
                        WeightList.weights      = new List <float>();
                        WeightList.coordFormart = WeightFormat;

                        for (int i = 0; i < (SkinningWeightsCount + 1); i++)
                        {
                            switch (WeightFormat)
                            {
                            case CoordinateFormat.NORMALIZED_8_BITS:
                                WeightList.weights.Add(stream.ReadByte() / 128.0f);
                                break;

                            case CoordinateFormat.NORMALIZED_16_BITS:
                                WeightList.weights.Add(stream.ReadUInt16() / 32768.0f);
                                break;

                            case CoordinateFormat.FLOAT_32_BITS:
                                WeightList.weights.Add(stream.ReadFloat());
                                break;

                            case CoordinateFormat.NO_VERTEX:
                                break;
                            }
                        }

                        meshChunk.jointWeights.Add(WeightList);
                    }

                    Vector2 currentTexCoord = new Vector2(0, 0);

                    switch (TexCoordFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        currentTexCoord.X = stream.ReadByte() / 128.0f;
                        currentTexCoord.Y = stream.ReadByte() / 128.0f;
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentTexCoord.X = stream.ReadUInt16() / 32768.0f;
                        currentTexCoord.Y = stream.ReadUInt16() / 32768.0f;
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentTexCoord.X = stream.ReadFloat();
                        currentTexCoord.Y = stream.ReadFloat();
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;

                    case CoordinateFormat.NO_VERTEX:
                        meshChunk.textureCoordinates.Add(currentTexCoord);
                        break;
                    }

                    Vector4 col;

                    if (isColorFlagRisen)
                    {
                        uint c = meshChunk.SectionInfo_opt2.DiffuseColor;
                        col.X = c % 0x100;
                        col.Y = (c >> 8) % 0x100;
                        col.Z = (c >> 16) % 0x100;
                        col.W = (c >> 24) % 0x100;

                        meshChunk.colors.Add(col);
                    }
                    else
                    {
                        switch (ColorFormat)
                        {
                        case Pmo.ColorFormat.NO_COLOR:
                            meshChunk.colors.Add(new Vector4(0xFF, 0xFF, 0xFF, 0xFF));
                            break;

                        case Pmo.ColorFormat.BGR_5650_16BITS:
                            stream.ReadUInt16();
                            break;

                        case Pmo.ColorFormat.ABGR_5551_16BITS:
                            stream.ReadUInt16();
                            break;

                        case Pmo.ColorFormat.ABGR_4444_16BITS:
                            stream.ReadUInt16();
                            break;

                        case Pmo.ColorFormat.ABGR_8888_32BITS:
                            vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                            stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                            col.X = stream.ReadByte();
                            col.Y = stream.ReadByte();
                            col.Z = stream.ReadByte();
                            col.W = stream.ReadByte();
                            meshChunk.colors.Add(col);
                            break;
                        }
                    }

                    Vector3 currentVertex;

                    // Handle triangles and triangle strips.
                    switch (VertexPositionFormat)
                    {
                    case CoordinateFormat.NORMALIZED_8_BITS:
                        currentVertex.X = r.ReadSByte() / 128.0f;
                        currentVertex.Y = r.ReadSByte() / 128.0f;
                        currentVertex.Z = r.ReadSByte() / 128.0f;
                        meshChunk.vertices.Add(currentVertex);
                        break;

                    case CoordinateFormat.NORMALIZED_16_BITS:
                        vertexIncreaseAmount = ((0x2 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x1)) & 0x1);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentVertex.X = (float)stream.ReadInt16() / 32768.0f;
                        currentVertex.Y = (float)stream.ReadInt16() / 32768.0f;
                        currentVertex.Z = (float)stream.ReadInt16() / 32768.0f;
                        meshChunk.vertices.Add(currentVertex);
                        break;

                    case CoordinateFormat.FLOAT_32_BITS:
                        vertexIncreaseAmount = ((0x4 - (Convert.ToInt32(stream.Position - vertexStartPos) & 0x3)) & 0x3);
                        stream.Seek(vertexIncreaseAmount, SeekOrigin.Current);

                        currentVertex.X = stream.ReadFloat();
                        currentVertex.Y = stream.ReadFloat();
                        currentVertex.Z = stream.ReadFloat();
                        meshChunk.vertices.Add(currentVertex);
                        break;
                    }

                    stream.Seek(vertexStartPos + meshChunk.SectionInfo.VertexSize, SeekOrigin.Begin);

                    if (flags.Primitive == PrimitiveType.PRIMITIVE_TRIANGLE)
                    {
                        meshChunk.Indices.Add(v);
                    }
                }

                VertCnt = meshChunk.SectionInfo.VertexCount;
                pmo.Meshes.Add(meshChunk);

                // Find position of next data chunk.
                stream.Seek(positionAfterHeader + (meshChunk.SectionInfo.VertexCount * meshChunk.SectionInfo.VertexSize), SeekOrigin.Begin);
                stream.Seek(stream.Position % 4, SeekOrigin.Current);
            }
        }
예제 #15
0
 public static void ReadHeader(Stream stream, Pmo pmo)
 {
     pmo.header = Mapping.ReadObject <Header>(stream);
 }
예제 #16
0
파일: Pmo.cs 프로젝트: PlancakeJB/OpenKh
 public static void ReadHeader(Stream stream, Pmo pmo)
 {
     pmo.header = BinaryMapping.ReadObject <Header>(stream.SetPosition(0));
 }