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); }
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); }