コード例 #1
0
        private static RawMeshContainer ContainRawMesh(MemoryStream gfs, UInt32 vertCount, UInt32 indCount, UInt32 vertOffset, UInt32 tx0Offset, UInt32 normalOffset, UInt32 colorOffset, UInt32 tx1Offset, UInt32 indOffset, UInt32 vpStride, Vector4 qScale, Vector4 qTrans)
        {
            BinaryReader gbr = new BinaryReader(gfs);

            Vec3[] vertices  = new Vec3[vertCount];
            uint[] indices   = new uint[indCount];
            Vec2[] tx0coords = new Vec2[vertCount];
            Vec3[] normals   = new Vec3[vertCount];
            Vec4[] tangents  = new Vec4[vertCount];
            Vec4[] colors    = new Vec4[vertCount];
            Vec2[] tx1coords = new Vec2[vertCount];

            // geting vertices
            for (int i = 0; i < vertCount; i++)
            {
                gfs.Position = vertOffset + i * vpStride;

                float x = (gbr.ReadInt16() / 32767f) * qScale.X.Value + qTrans.X.Value;
                float y = (gbr.ReadInt16() / 32767f) * qScale.Y.Value + qTrans.Y.Value;
                float z = (gbr.ReadInt16() / 32767f) * qScale.Z.Value + qTrans.Z.Value;
                vertices[i] = new Vec3(x, y, z);
            }
            // got vertices

            Converters converter = new Converters(); // contains methods for halffloats

            float[] values = new float[vertCount * 2];

            if (tx0Offset != 0)
            {
                // getting texturecoord0 as half floats
                gfs.Position = tx0Offset;
                for (int i = 0; i < vertCount * 2; i++)
                {
                    UInt16 read = gbr.ReadUInt16();
                    values[i] = converter.hfconvert(read);
                }
                for (int i = 0; i < vertCount; i++)
                {
                    tx0coords[i] = new Vec2(values[2 * i], values[2 * i + 1]);
                }
                // got texturecoord0 as half floats
            }

            UInt32 NorRead32;

            // getting 10bit normals
            for (int i = 0; i < vertCount; i++)
            {
                gfs.Position = normalOffset + 8 * i;
                NorRead32    = gbr.ReadUInt32();
                Vec4 tempv = converter.U32toVec4(NorRead32);
                normals[i] = new Vec3(tempv.X, tempv.Y, tempv.Z);
            }
            // got 10bit normals

            // getting 10bit tangents
            for (int i = 0; i < vertCount; i++)
            {
                gfs.Position = normalOffset + 4 + 8 * i;
                NorRead32    = gbr.ReadUInt32();
                Vec4 tempv = converter.U32toVec4(NorRead32);
                tangents[i] = new Vec4(tempv.X, tempv.Y, tempv.Z, 1f);
            }


            if (tx1Offset != 0)
            {
                // getting texturecoord1 as half floats
                gfs.Position = tx1Offset;
                for (int i = 0; i < vertCount * 2; i++)
                {
                    UInt16 read = gbr.ReadUInt16();
                    values[i] = converter.hfconvert(read);
                }
                for (int i = 0; i < vertCount; i++)
                {
                    tx1coords[i] = new Vec2(values[2 * i], values[2 * i + 1]);
                }
                // got texturecoord1 as half floats
            }

            if (colorOffset != 0)
            {
                // getting vert colors, not sure of the format TBH RN,just a hush, may not work, lulz
                for (int i = 0; i < vertCount; i++)
                {
                    gfs.Position = colorOffset + i * 8;
                    Vec4 tempv = new Vec4(gbr.ReadUInt16() / 65535f, gbr.ReadUInt16() / 65535f, gbr.ReadUInt16() / 65535f, gbr.ReadUInt16() / 65535f);
                    colors[i] = new Vec4(tempv.Y, tempv.Z, tempv.W, tempv.X);
                }
                // got vert colors
            }

            // getting uint16 faces/indices
            gfs.Position = indOffset;
            for (int i = 0; i < indCount; i++)
            {
                indices[i] = gbr.ReadUInt16();
            }
            // got uint16 faces/indices


            RawMeshContainer mesh = new RawMeshContainer()
            {
                vertices  = vertices,
                indices   = indices,
                tx0coords = tx0coords,
                normals   = normals,
                tangents  = tangents,
                colors    = colors,
                tx1coords = tx1coords
            };

            return(mesh);
        }
コード例 #2
0
        public static List <RawMeshContainer> ContainRawMesh(MemoryStream gfs, MeshesInfo info, bool LODFilter)
        {
            BinaryReader gbr = new BinaryReader(gfs);

            List <RawMeshContainer> expMeshes = new List <RawMeshContainer>();

            for (int index = 0; index < info.meshC; index++)
            {
                if (info.LODLvl[index] != 1 && LODFilter)
                {
                    continue;
                }
                Vec3[] vertices  = new Vec3[info.vertCounts[index]];
                uint[] indices   = new uint[info.indCounts[index]];
                Vec2[] tx0coords = new Vec2[info.vertCounts[index]];
                Vec3[] normals   = new Vec3[0];
                Vec4[] tangents  = new Vec4[0];
                Vec4[] colors    = new Vec4[info.vertCounts[index]];
                Vec2[] tx1coords = new Vec2[info.vertCounts[index]];
                float[,] weights      = new float[info.vertCounts[index], info.weightcounts[index]];
                UInt16[,] boneindices = new UInt16[info.vertCounts[index], info.weightcounts[index]];
                Vec3[] extradata = new Vec3[info.vertCounts[index]];

                // geting vertices
                for (int i = 0; i < info.vertCounts[index]; i++)
                {
                    gfs.Position = info.vertOffsets[index] + i * info.vpStrides[index];

                    float x = (gbr.ReadInt16() / 32767f) * info.qScale.X + info.qTrans.X;
                    float y = (gbr.ReadInt16() / 32767f) * info.qScale.Y + info.qTrans.Y;
                    float z = (gbr.ReadInt16() / 32767f) * info.qScale.Z + info.qTrans.Z;
                    // changing orientation of geomerty, Y+ Z+ RHS-LHS BS
                    vertices[i] = new Vec3(x, z, -y);
                }
                // got vertices

                float[] values = new float[info.vertCounts[index] * 2];

                if (info.tx0Offsets[index] != 0)
                {
                    // getting texturecoord0 as half floats
                    gfs.Position = info.tx0Offsets[index];
                    for (int i = 0; i < info.vertCounts[index] * 2; i++)
                    {
                        UInt16 read = gbr.ReadUInt16();
                        values[i] = Converters.hfconvert(read);
                    }
                    for (int i = 0; i < info.vertCounts[index]; i++)
                    {
                        tx0coords[i] = new Vec2(values[2 * i], values[2 * i + 1]);
                    }
                    // got texturecoord0 as half floats
                }

                UInt32 NorRead32;
                bool   invalidNors = true;
                if (info.normalOffsets[index] != 0)
                {
                    normals = new Vec3[info.vertCounts[index]];
                    // getting 10bit normals
                    int str = 4;
                    if (info.tangentOffsets[index] != 0)
                    {
                        str += 4;
                    }
                    for (int i = 0; i < info.vertCounts[index]; i++)
                    {
                        gfs.Position = info.normalOffsets[index] + str * i;
                        NorRead32    = gbr.ReadUInt32();
                        Vec4 tempv = Converters.TenBitShifted(NorRead32);
                        // changing orientation of geomerty, Y+ Z+ RHS-LHS BS
                        normals[i] = new Vec3(tempv.X, tempv.Z, -tempv.Y);
                        normals[i] = Vec3.Normalize(normals[i]);
                        if (NorRead32 != 0x5FF7FDFF)
                        {
                            invalidNors = false;
                        }
                    }
                }
                // got 10bit normals
                if (info.tangentOffsets[index] != 0 && info.normalOffsets[index] != 0)
                {
                    tangents = new Vec4[info.vertCounts[index]];
                    info.tangentOffsets[index] += 4;
                    // getting 10bit tangents
                    for (int i = 0; i < info.vertCounts[index]; i++)
                    {
                        gfs.Position = info.tangentOffsets[index] + 8 * i;
                        NorRead32    = gbr.ReadUInt32();
                        Vec4 tempv = Converters.TenBitShifted(NorRead32);
                        // changing orientation of geomerty, Y+ Z+ RHS-LHS BS
                        Vec3 vec = Vec3.Normalize(new Vec3(tempv.X, tempv.Z, -tempv.Y));
                        tangents[i] = new Vec4(vec.X, vec.Y, vec.Z, 1f);
                    }
                }

                if (invalidNors)
                {
                    normals  = new Vec3[0];
                    tangents = new Vec4[0];
                }

                if (info.tx1Offsets[index] != 0)
                {
                    if (info.colorOffsets[index] != 0)
                    {
                        info.tx1Offsets[index] += 4;
                    }
                    gfs.Position = info.tx1Offsets[index];
                    // getting texturecoord1 as half floats
                    for (int i = 0; i < info.vertCounts[index] * 2; i++)
                    {
                        UInt16 read = gbr.ReadUInt16();
                        values[i] = Converters.hfconvert(read);
                        if (i % 2 != 0)
                        {
                            gfs.Position += 4;
                        }
                    }
                    for (int i = 0; i < info.vertCounts[index]; i++)
                    {
                        tx1coords[i] = new Vec2(values[2 * i], values[2 * i + 1]);
                    }
                    // got texturecoord1 as half floats
                }

                if (info.colorOffsets[index] != 0)
                {
                    int str = 4;
                    if (info.tx1Offsets[index] != 0)
                    {
                        str += 4;
                    }
                    for (int i = 0; i < info.vertCounts[index]; i++)
                    {
                        gfs.Position = info.colorOffsets[index] + i * str;
                        Vec4 tempv = new Vec4(gbr.ReadByte() / 255f, gbr.ReadByte() / 255f, gbr.ReadByte() / 255f, gbr.ReadByte() / 255f);
                        colors[i] = new Vec4(tempv.X, tempv.Y, tempv.Z, tempv.W);
                    }
                    // got vert colors
                }

                // getting bone indices
                for (int i = 0; i < info.vertCounts[index]; i++)
                {
                    gfs.Position = info.vertOffsets[index] + i * info.vpStrides[index] + 8;
                    for (int e = 0; e < info.weightcounts[index]; e++)
                    {
                        boneindices[i, e] = gbr.ReadByte();
                    }
                }
                // got bone indexes

                // getting weights
                for (int i = 0; i < info.vertCounts[index]; i++)
                {
                    float sum = 0;
                    gfs.Position = info.vertOffsets[index] + i * info.vpStrides[index] + 8 + info.weightcounts[index];
                    for (int e = 0; e < info.weightcounts[index]; e++)
                    {
                        weights[i, e] = gbr.ReadByte() / 255f;
                        sum          += weights[i, e];
                    }
                    if (sum == 0 && info.weightcounts[index] > 0)
                    {
                        boneindices[i, 0] = 0;
                        weights[i, 0]     = 1f;
                        sum = 1;
                    }
                    for (int e = 0; e < info.weightcounts[index]; e++)
                    {
                        weights[i, e] *= 1f / sum;
                    }
                }
                // got weights

                if (info.extraExists[index])
                {
                    for (int i = 0; i < info.vertCounts[index]; i++)
                    {
                        gfs.Position = info.vertOffsets[index] + i * info.vpStrides[index] + 8 + 2 * info.weightcounts[index];
                        float x = Converters.hfconvert(gbr.ReadUInt16());
                        float y = Converters.hfconvert(gbr.ReadUInt16());
                        float z = Converters.hfconvert(gbr.ReadUInt16());
                        extradata[i] = new Vec3(x, z, -y);
                    }
                }
                // getting uint16 faces/indices
                gfs.Position = info.indicesOffsets[index];
                for (int i = 0; i < info.indCounts[index]; i++)
                {
                    indices[i] = gbr.ReadUInt16();
                }
                // got uint16 faces/indices

                RawMeshContainer mesh = new RawMeshContainer()
                {
                    vertices    = vertices,
                    indices     = indices,
                    tx0coords   = tx0coords,
                    normals     = normals,
                    tangents    = tangents,
                    colors      = colors,
                    tx1coords   = tx1coords,
                    boneindices = boneindices,
                    weights     = weights,
                    weightcount = info.weightcounts[index],
                    extradata   = extradata,
                    extraExist  = info.extraExists[index]
                };
                mesh.name = "submesh_" + Convert.ToString(index).PadLeft(2, '0') + "_LOD_" + info.LODLvl[index];

                mesh.appNames      = new string[info.appearances.Count];
                mesh.materialNames = new string[info.appearances.Count];
                for (int e = 0; e < info.appearances.Count; e++)
                {
                    mesh.appNames[e]      = info.appearances[e].Name;
                    mesh.materialNames[e] = info.appearances[e].MaterialNames[index];
                }
                expMeshes.Add(mesh);
            }
            return(expMeshes);
        }