Пример #1
0
 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;
         }
     }
 }
Пример #2
0
        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);
        }