private static void ReadMeshFromATO(Reader reader, GeometricObject m) { // Revolution only: Before creating the gameobject, read the actual model data from the ATO if (Settings.s.game == Settings.Game.R2Revolution) { MapLoader l = MapLoader.Loader; List <GeometricObject> meshObjects = new List <GeometricObject>(); for (uint i = 0; i < m.num_elements; i++) { if (m.element_types[i] == 1) { R2PS2Loader ps2l = (R2PS2Loader)l; meshObjects.Add(ps2l.ato.meshes[ps2l.ato.meshes.Length - 1 - ps2l.meshesRead - meshObjects.Count]); } } if (meshObjects.Count > 0) { int currentSubblock = 0; int curNumVertices = 0; bool tryMapping = true; if (m.vertices == null) { m.num_vertices = (ushort)meshObjects.Sum(mesh => mesh.num_vertices); m.vertices = new Vector3[m.num_vertices]; m.normals = new Vector3[m.num_vertices]; tryMapping = false; } for (int i = 0; i < meshObjects.Count; i++) { GeometricObject mo = meshObjects[i]; while (currentSubblock < m.num_elements && m.element_types[currentSubblock] != 1) { currentSubblock++; } GeometricObjectElementTriangles me = (GeometricObjectElementTriangles)m.elements[currentSubblock]; GeometricObjectElementTriangles moe = ((GeometricObjectElementTriangles)mo.elements[0]); if (!tryMapping) { Array.Copy(mo.vertices, 0, m.vertices, curNumVertices, mo.num_vertices); if (mo.normals != null) { Array.Copy(mo.normals, 0, m.normals, curNumVertices, mo.num_vertices); } me.OPT_mapping_vertices = Enumerable.Range(curNumVertices, mo.num_vertices).ToArray(); curNumVertices += mo.num_vertices; } else { me.OPT_mapping_vertices = new int[moe.OPT_num_mapping_entries]; for (int j = 0; j < mo.vertices.Length; j++) { me.OPT_mapping_vertices[j] = Array.IndexOf(m.vertices, mo.vertices[j]); if (me.OPT_mapping_vertices[j] == -1 || me.OPT_mapping_vertices[j] != Array.IndexOf(m.vertices, mo.vertices[j])) { Debug.LogError("Failed matching vertices between Renderware and OpenSpace"); } } } me.OPT_disconnectedTriangles = moe.OPT_disconnectedTriangles; me.OPT_num_disconnectedTriangles = moe.OPT_num_disconnectedTriangles; me.triangles = null; me.num_triangles = 0; me.num_uvMaps = moe.num_uvMaps; me.num_uvs = moe.num_uvs; me.uvs = moe.uvs; me.OPT_mapping_uvs = moe.OPT_mapping_uvs; me.OPT_num_mapping_entries = moe.OPT_num_mapping_entries; me.vertexColors = moe.vertexColors; currentSubblock++; if (me.lightmap_index != -1) { R2PS2Loader ps2l = ((R2PS2Loader)l); string id_r = me.lightmap_index.ToString("D3") + "." + 0; //l.print(id_r + " - " + me.num_disconnected_triangles + " - " + m.num_vertices + " - " + mo.num_vertices); Texture2D lm = ps2l.GetLightmap(id_r); if (me.visualMaterial != null) { if (lm != null) { string id_g = me.lightmap_index.ToString("D3") + "." + 1; string id_b = me.lightmap_index.ToString("D3") + "." + 2; Texture2D lm_g = ps2l.GetLightmap(id_g); Texture2D lm_b = ps2l.GetLightmap(id_b); if (lm_g != null && lm_b != null) { for (int j = 0; j < lm.width; j++) { for (int k = 0; k < lm.height; k++) { Color r = lm.GetPixel(j, k); Color g = lm_g.GetPixel(j, k); Color b = lm_b.GetPixel(j, k); lm.SetPixel(j, k, new Color(r.a, g.a, b.a, 1f)); } } lm.Apply(); } } else { lm = new Texture2D(1, 1); lm.SetPixel(0, 0, Color.white); lm.wrapMode = TextureWrapMode.Clamp; lm.filterMode = FilterMode.Bilinear; lm.Apply(); } Vector2[] lightmapUVs = new Vector2[mo.num_vertices]; Pointer.DoAt(ref reader, ps2l.off_lightmapUV[me.lightmap_index], () => { for (int j = 0; j < mo.num_vertices; j++) { lightmapUVs[j] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } }); me.AddLightmap(lm, lightmapUVs); } } } ((R2PS2Loader)l).meshesRead += (uint)meshObjects.Count; } } }
public static GeometricObjectElementSprites Read(Reader reader, Pointer offset, GeometricObject m) { MapLoader l = MapLoader.Loader; GeometricObjectElementSprites s = new GeometricObjectElementSprites(offset, m); s.name = "Sprite @ pos " + offset; //l.print(s.name); if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { if (Settings.s.platform == Settings.Platform.DC) { s.off_sprites = offset; s.num_sprites = 1; } else { s.off_sprites = Pointer.Read(reader); s.num_sprites = reader.ReadUInt16(); reader.ReadInt16(); // -1 if (Settings.s.game != Settings.Game.R2Revolution) { reader.ReadUInt32(); if (Settings.s.game != Settings.Game.LargoWinch) { reader.ReadUInt32(); } } } } else { s.num_sprites = (ushort)reader.ReadUInt32(); s.off_sprites = Pointer.Read(reader); reader.ReadUInt32(); } if (Settings.s.game == Settings.Game.R2Revolution) { Pointer.DoAt(ref reader, s.off_sprites, () => { s.sprites = new IndexedSprite[s.num_sprites]; for (uint i = 0; i < s.num_sprites; i++) { s.sprites[i] = new IndexedSprite(); uint type = reader.ReadUInt32(); s.sprites[i].info_scale = new Vector2(reader.ReadSingle(), reader.ReadSingle()); if (type == 0x20) { // Light cookie sprite uint index = reader.ReadUInt32(); R2PS2Loader ps2l = MapLoader.Loader as R2PS2Loader; s.sprites[i].visualMaterial = ps2l.lightCookieMaterial.Clone(); s.sprites[i].visualMaterial.diffuseCoef = ps2l.lightCookieColors[index]; } else { s.sprites[i].off_material = Pointer.Read(reader); if (s.sprites[i].off_material != null) { s.sprites[i].visualMaterial = VisualMaterial.FromOffsetOrRead(s.sprites[0].off_material, reader); } } } }); } else if (Settings.s.platform == Settings.Platform.DC) { s.sprites = new IndexedSprite[1]; s.sprites[0] = new IndexedSprite(); s.sprites[0].off_material = Pointer.Read(reader); if (s.sprites[0].off_material != null) { s.sprites[0].visualMaterial = VisualMaterial.FromOffsetOrRead(s.sprites[0].off_material, reader); } s.sprites[0].info_scale = new Vector2(reader.ReadSingle(), reader.ReadSingle()); reader.ReadUInt16(); s.sprites[0].centerPoint = reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt16(); reader.ReadUInt16(); } else { if (s.off_sprites != null) { Pointer.Goto(ref reader, s.off_sprites); s.sprites = new IndexedSprite[s.num_sprites]; for (uint i = 0; i < s.num_sprites; i++) { s.sprites[i] = new IndexedSprite(); if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal) { reader.ReadUInt32(); } s.sprites[i].off_info = Pointer.Read(reader); s.sprites[i].size = new Vector2(reader.ReadSingle(), reader.ReadSingle()); if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { if (Settings.s.game != Settings.Game.LargoWinch) { s.sprites[i].constraint = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].uv1 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); s.sprites[i].uv2 = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } s.sprites[i].centerPoint = reader.ReadUInt16(); reader.ReadUInt16(); if (Settings.s.engineVersion < Settings.EngineVersion.R3) { reader.ReadUInt32(); } } if (s.sprites[i].off_info != null) { Pointer off_current = Pointer.Goto(ref reader, s.sprites[i].off_info); reader.ReadUInt32(); Pointer.Read(reader); Pointer.Read(reader); Pointer off_info_scale = Pointer.Read(reader); Pointer off_info_unknown = Pointer.Read(reader); s.sprites[i].off_material_pointer = Pointer.Read(reader); Pointer.Goto(ref reader, off_current); Pointer.DoAt(ref reader, off_info_scale, () => { s.sprites[i].info_scale = new Vector2(reader.ReadSingle(), reader.ReadSingle()); }); Pointer.DoAt(ref reader, off_info_unknown, () => { s.sprites[i].info_unknown = new Vector2(reader.ReadSingle(), reader.ReadSingle()); }); if (s.sprites[i].off_material_pointer != null) { off_current = Pointer.Goto(ref reader, s.sprites[i].off_material_pointer); s.sprites[i].off_material = Pointer.Read(reader); if (s.sprites[i].off_material != null) { if (Settings.s.engineVersion < Settings.EngineVersion.R3) { s.sprites[i].gameMaterial = GameMaterial.FromOffsetOrRead(s.sprites[i].off_material, reader); s.sprites[i].visualMaterial = s.sprites[i].gameMaterial.visualMaterial; } else { s.sprites[i].visualMaterial = VisualMaterial.FromOffsetOrRead(s.sprites[i].off_material, reader); } } Pointer.Goto(ref reader, off_current); } } } } } return(s); }