public static GeoMesh ReadGeoMesh(string fileName) { using (Scripts.System.FastBinaryReader br = VirtualFilesystem.Instance.GetFileStream(fileName)) { GeoMesh mesh = new GeoMesh(); string magic = br.ReadCString(4); uint unk1 = br.ReadUInt32(); mesh.Name = br.ReadCString(16); uint vertexCount = br.ReadUInt32(); uint faceCount = br.ReadUInt32(); uint unk2 = br.ReadUInt32(); mesh.Vertices = new Vector3[vertexCount]; for (int i = 0; i < vertexCount; i++) { Vector3 vertex = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); mesh.Vertices[i] = vertex; } mesh.Normals = new Vector3[vertexCount]; for (int i = 0; i < vertexCount; i++) { Vector3 normal = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); mesh.Normals[i] = normal; } mesh.Faces = new GeoFace[faceCount]; for (int i = 0; i < faceCount; i++) { GeoFace face = new GeoFace(); face.Index = br.ReadUInt32(); uint numVerticesInFace = br.ReadUInt32(); face.Color = new Color32(br.ReadByte(), br.ReadByte(), br.ReadByte(), 255); face.SurfaceNormal = new Vector4(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); uint unk3 = br.ReadUInt32(); face.SurfaceFlags1 = br.ReadByte(); face.SurfaceFlags2 = br.ReadByte(); face.SurfaceFlags3 = br.ReadByte(); string textureName = br.ReadCString(13); if (textureName != "") { face.TextureName = textureName; } uint unk4 = br.ReadUInt32(); uint unk5 = br.ReadUInt32(); //Debug.Log("Surf " + face.TextureName + " flags: " + face.SurfaceFlags1 + ", " + face.SurfaceFlags2 + ", " + face.SurfaceFlags3 + ", " + unk3 + ", " + unk4 + ", " + unk5 + ", color=" + face.Color); face.VertexRefs = new GeoVertexRef[numVerticesInFace]; for (int v = 0; v < numVerticesInFace; v++) { face.VertexRefs[v] = new GeoVertexRef { VertexIndex = br.ReadUInt32(), NormalIndex = br.ReadUInt32(), Uv = new Vector2(br.ReadSingle(), br.ReadSingle()) }; } mesh.Faces[i] = face; } return(mesh); } }
/* * TMT's are referred in this order: * Front, Back, Right, Left, Top, Under * * Given a filename of: * 1CP1FTFT * * decodes as * 1CP = First cop car skin * 1 = LOD level * FTFT = Front Front * * Sequence of tmt files: * Front * Mid * Back * Top * * Full list: * * FTFT * FTBK * FTRT * FTLT * FTTP * FTUN * * MDFT * MDBK * MDRT * MDLT * MDTP * MDUN * * BKFT * BKBK * BKRT * BKLT * BKTP * BKUN * * TPFT * TPBK * TPRT * TPLT * TPTP * TPUN */ public static Vtf ParseVtf(string filename) { Vtf vtf = new Vtf(); using (Bwd2Reader br = new Bwd2Reader(filename)) { br.FindNext("VTFC"); vtf.VdfFilename = br.ReadCString(13); vtf.PaintSchemeName = br.ReadCString(16); vtf.TmtFilenames = new string[78]; for (int i = 0; i < vtf.TmtFilenames.Length; i++) { vtf.TmtFilenames[i] = br.ReadCString(13); } vtf.Maps = new string[13]; for (int i = 0; i < vtf.Maps.Length; i++) { vtf.Maps[i] = br.ReadCString(13).Replace(".map", ""); } } vtf.Tmts = new Dictionary <string, Tmt>(); for (int tmtIdx = 0; tmtIdx < vtf.TmtFilenames.Length; tmtIdx++) { string tmtFilename = vtf.TmtFilenames[tmtIdx]; if (tmtFilename != "NULL") { using (Scripts.System.FastBinaryReader br = VirtualFilesystem.Instance.GetFileStream(tmtFilename)) { uint one = br.ReadUInt32(); uint zero1 = br.ReadUInt32(); uint zero2 = br.ReadUInt32(); uint zero3 = br.ReadUInt32(); uint zero4 = br.ReadUInt32(); uint two = br.ReadUInt32(); uint two2 = br.ReadUInt32(); uint four = br.ReadUInt32(); uint zero5 = br.ReadUInt32(); uint zero6 = br.ReadUInt32(); float tenFloat = br.ReadSingle(); float zero7 = br.ReadSingle(); float zero8 = br.ReadSingle(); float zero9 = br.ReadSingle(); float zero10 = br.ReadSingle(); float zero11 = br.ReadSingle(); Tmt tmt = new Tmt { TextureNames = new List <string>() }; while (br.Position < br.Length) { string textureName = br.ReadCString(8); tmt.TextureNames.Add(textureName); } vtf.Tmts.Add(tmtFilename.Substring(3), tmt); } } } return(vtf); }
public static Texture2D ReadVqmTexture(string filename, Color32[] palette) { if (TextureCache.TryGetValue(filename, out Texture2D texture)) { return(texture); } using (Scripts.System.FastBinaryReader br = VirtualFilesystem.Instance.GetFileStream(filename)) { int width = br.ReadInt32(); int height = br.ReadInt32(); int pixels = width * height; texture = new Texture2D(width, height, TextureFormat.ARGB32, true) { filterMode = FilterMode.Bilinear, wrapMode = TextureWrapMode.Repeat }; string cbkFile = br.ReadCString(12); int unk1 = br.ReadInt32(); bool hasTransparency = false; if (VirtualFilesystem.Instance.FileExists(cbkFile)) { Color32[] pixelBuffer = new Color32[pixels]; using (Scripts.System.FastBinaryReader cbkBr = VirtualFilesystem.Instance.GetFileStream(cbkFile)) { int x = 0; int y = 0; int byteIndex = 0; long brLength = br.Length - br.Position; long cbkStart = cbkBr.Position; while (byteIndex < brLength) { ushort index = br.ReadUInt16(); byteIndex += sizeof(ushort); if ((index & 0x8000) == 0) { cbkBr.Position = cbkStart + 4 + index * 16; byte[] cbkData = cbkBr.ReadBytes(16); for (int sy = 0; sy < 4; sy++) { for (int sx = 0; sx < 4; sx++) { byte paletteIndex = cbkData[sx * 4 + sy]; if (paletteIndex == 0xFF) { hasTransparency = true; } Color32 color = paletteIndex == 0xFF ? Transparent : palette[paletteIndex]; int pixelIndex = y * width + sx * width + x + sy; if (pixelIndex < pixels) { pixelBuffer[pixelIndex] = color; } } } } else { int paletteIndex = index & 0xFF; if (paletteIndex == 0xFF) { hasTransparency = true; } Color32 color = paletteIndex == 0xFF ? Transparent : palette[paletteIndex]; for (int sy = 0; sy < 4; sy++) { for (int sx = 0; sx < 4; sx++) { int pixelIndex = y * width + sx * width + x + sy; if (pixelIndex < pixels) { pixelBuffer[pixelIndex] = color; } } } } x += 4; if (x >= width) { x = 0; y += 4; } } } texture.SetPixels32(pixelBuffer); } else { Debug.LogWarning("CBK file not found: " + cbkFile); } if (hasTransparency) { texture.wrapMode = TextureWrapMode.Clamp; } texture.Apply(true); TextureCache.Add(filename, texture); return(texture); } }