// I don't even know what this is yet here I am parsing it
        public static PatchGeometricObject Read(Reader reader, PhysicalObject po, Pointer offset)
        {
            MapLoader l = MapLoader.Loader;
            //Debug.LogWarning("Unknown object @ " + offset);
            PatchGeometricObject patch = new PatchGeometricObject(po, offset);

            patch.off_geometricObject = Pointer.Read(reader);

            patch.num_properties = reader.ReadUInt32();
            patch.off_properties = Pointer.Read(reader);
            Pointer.DoAt(ref reader, patch.off_properties, () => {
                patch.properties = new PatchGeometricObjectProperty[patch.num_properties];
                for (int i = 0; i < patch.num_properties; i++)
                {
                    patch.properties[i]            = new PatchGeometricObjectProperty();
                    patch.properties[i].ind_vertex = reader.ReadUInt16();
                    patch.properties[i].unk        = reader.ReadUInt16();
                    float x = reader.ReadSingle();
                    float z = reader.ReadSingle();
                    float y = reader.ReadSingle();
                    patch.properties[i].pos = new Vector3(x, y, z);
                    //l.print(mod.off_geometricObject + ": " + mod.properties[i].ind_vertex + " - " + mod.properties[i].unk + " - " + mod.properties[i].pos);
                }
            });

            /*Pointer.DoAt(ref reader, mod.off_geometricObject, () => {
             *  mod.mesh = GeometricObject.Read(reader, mod.off_geometricObject);
             *  mod.mesh.Gao.name += " - " + mod.offset;
             * });*/
            return(patch);
        }
Exemple #2
0
        public static GeometricObject Read(Reader reader, Pointer offset, RadiosityLOD radiosity = null, PatchGeometricObject mod = null)
        {
            MapLoader l = MapLoader.Loader;
            //l.print("Geometric Object: " + offset);
            GeometricObject m = new GeometricObject(offset);

            m.radiosity = radiosity;
            if (Settings.s.game == Settings.Game.LargoWinch)
            {
                uint flags = reader.ReadUInt32();
                m.num_vertices      = reader.ReadUInt16();
                m.num_elements      = reader.ReadUInt16();
                m.off_element_types = Pointer.Read(reader);
                m.off_elements      = Pointer.Read(reader);
                m.off_vertices      = Pointer.Read(reader);
                m.off_normals       = Pointer.Read(reader);
                m.sphereRadius      = reader.ReadSingle();           // bounding volume radius
                float sphereX = reader.ReadSingle();                 // x
                float sphereZ = reader.ReadSingle();                 // z
                float sphereY = reader.ReadSingle();                 // y
                m.sphereCenter = new Vector3(sphereX, sphereY, sphereZ);
                m.lookAtMode   = reader.ReadUInt32();
            }
            else if (Settings.s.game == Settings.Game.R2Revolution)
            {
                m.off_element_types = Pointer.Read(reader);
                m.off_elements      = Pointer.Read(reader);
                uint flags = reader.ReadUInt32();
                m.sphereRadius = reader.ReadSingle();                // bounding volume radius
                float sphereX = reader.ReadSingle();                 // x
                float sphereZ = reader.ReadSingle();                 // z
                float sphereY = reader.ReadSingle();                 // y
                m.sphereCenter = new Vector3(sphereX, sphereY, sphereZ);
                m.off_mapping  = Pointer.Read(reader);
                m.num_vertices = reader.ReadUInt16();
                m.num_elements = reader.ReadUInt16();
                m.off_vertices = Pointer.Read(reader);
                m.off_normals  = Pointer.Read(reader);
                m.lookAtMode   = flags & 3;
            }
            else
            {
                if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal)
                {
                    m.num_vertices = (ushort)reader.ReadUInt32();
                }
                m.off_vertices = Pointer.Read(reader);
                m.off_normals  = Pointer.Read(reader);
                if (Settings.s.engineVersion < Settings.EngineVersion.R3)
                {
                    m.off_materials = Pointer.Read(reader);
                }
                else
                {
                    m.off_blendWeights = Pointer.Read(reader);
                }
                if (Settings.s.mode != Settings.Mode.RaymanArenaGC &&
                    Settings.s.mode != Settings.Mode.RaymanArenaGCDemo_2002_03_07 &&
                    Settings.s.game != Settings.Game.RM &&
                    Settings.s.mode != Settings.Mode.DonaldDuckPKGC &&
                    !(Settings.s.platform == Settings.Platform.PS2 && Settings.s.engineVersion == Settings.EngineVersion.R3))
                {
                    reader.ReadInt32();
                }
                if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal)
                {
                    m.num_elements = (ushort)reader.ReadUInt32();
                }
                m.off_element_types = Pointer.Read(reader);
                m.off_elements      = Pointer.Read(reader);
                if (Settings.s.engineVersion == Settings.EngineVersion.R2)
                {
                    reader.ReadInt32();
                    reader.ReadInt32();
                }
                reader.ReadInt32();
                if (Settings.s.engineVersion > Settings.EngineVersion.Montreal)
                {
                    m.off_parallelBoxes = Pointer.Read(reader);
                }
                else
                {
                    reader.ReadInt32();
                }
                if (Settings.s.game == Settings.Game.Dinosaur)
                {
                    reader.ReadInt32();
                    reader.ReadInt32();
                    reader.ReadInt32();
                }
                if (Settings.s.engineVersion > Settings.EngineVersion.Montreal)
                {
                    m.lookAtMode = reader.ReadUInt32();
                    //if (m.lookAtMode != 0) l.print(m.lookAtMode);
                    m.num_vertices = reader.ReadUInt16();
                    m.num_elements = reader.ReadUInt16();
                    reader.ReadUInt16();
                    m.num_parallelBoxes = reader.ReadUInt16();
                    m.sphereRadius      = reader.ReadSingle();               // bounding volume radius
                    float sphereX = reader.ReadSingle();                     // x
                    float sphereZ = reader.ReadSingle();                     // z
                    float sphereY = reader.ReadSingle();                     // y
                    m.sphereCenter = new Vector3(sphereX, sphereY, sphereZ);
                    reader.ReadInt32();
                    if (Settings.s.engineVersion == Settings.EngineVersion.R3)
                    {
                        reader.ReadInt32();
                        if (!(Settings.s.platform == Settings.Platform.PS2 && (Settings.s.game == Settings.Game.RM || Settings.s.game == Settings.Game.RA)))
                        {
                            reader.ReadInt16();
                            if (Settings.s.platform == Settings.Platform.PS2)
                            {
                                reader.ReadInt16();
                                reader.ReadUInt32();
                            }
                        }
                    }
                }
                else
                {
                    reader.ReadInt32();
                    reader.ReadInt32();
                    m.sphereRadius = reader.ReadSingle();                    // bounding volume radius
                    float sphereX = reader.ReadSingle();                     // x
                    float sphereZ = reader.ReadSingle();                     // z
                    float sphereY = reader.ReadSingle();                     // y
                    m.sphereCenter = new Vector3(sphereX, sphereY, sphereZ);
                }
            }
            m.name = "Mesh @ " + offset;
            if (Settings.s.hasNames)
            {
                m.name = reader.ReadString(0x32);
            }
            if (Settings.s.platform == Settings.Platform.PS2 && Settings.s.engineVersion >= Settings.EngineVersion.R3)
            {
                reader.Align(0x4);
                reader.ReadUInt32();
                reader.ReadUInt32();
                m.optimizedObject = new Pointer <PS2OptimizedSDCStructure>(reader, resolve: false);
                reader.ReadUInt32();
                reader.ReadUInt32();
                if (Settings.s.game == Settings.Game.R3)
                {
                    m.ps2IsSinus = reader.ReadUInt32();
                }
            }
            // Vertices
            Pointer.DoAt(ref reader, m.off_vertices, () => {
                m.vertices = new Vector3[m.num_vertices];
                for (int i = 0; i < m.num_vertices; i++)
                {
                    float x       = reader.ReadSingle();
                    float z       = reader.ReadSingle();
                    float y       = reader.ReadSingle();
                    m.vertices[i] = new Vector3(x, y, z);
                }
            });
            if (mod != null)
            {
                for (int i = 0; i < mod.num_properties; i++)
                {
                    PatchGeometricObjectProperty prop = mod.properties[i];
                    if (prop.ind_vertex < m.vertices.Length)
                    {
                        m.vertices[prop.ind_vertex] += prop.pos;
                    }
                }
            }
            // Normals
            Pointer.DoAt(ref reader, m.off_normals, () => {
                m.normals = new Vector3[m.num_vertices];
                for (int i = 0; i < m.num_vertices; i++)
                {
                    float x      = reader.ReadSingle();
                    float z      = reader.ReadSingle();
                    float y      = reader.ReadSingle();
                    m.normals[i] = new Vector3(x, y, z);
                }
            });
            Pointer.DoAt(ref reader, m.off_blendWeights, () => {
                m.blendWeights = new float[4][];

                /*reader.ReadUInt32(); // 0
                 * R3Pointer off_blendWeightsStart = R3Pointer.Read(reader);
                 * R3Pointer.Goto(ref reader, off_blendWeightsStart);*/
                for (int i = 0; i < 4; i++)
                {
                    Pointer off_blendWeights = Pointer.Read(reader);
                    Pointer.DoAt(ref reader, off_blendWeights, () => {
                        m.blendWeights[i] = new float[m.num_vertices];
                        for (int j = 0; j < m.num_vertices; j++)
                        {
                            m.blendWeights[i][j] = reader.ReadSingle();
                        }
                    });
                }
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
            });
            Pointer.DoAt(ref reader, m.off_mapping, () => {
                // Revolution only
                reader.ReadUInt32();
                Pointer.Read(reader);
                Pointer off_mappingBlocks = Pointer.Read(reader);
                Pointer.Read(reader);
                Pointer.Read(reader);
                ushort num_mappingBlocks = reader.ReadUInt16();
                reader.ReadUInt16();
                Pointer.DoAt(ref reader, off_mappingBlocks, () => {
                    m.mapping = new int[num_mappingBlocks][];
                    for (int i = 0; i < num_mappingBlocks; i++)
                    {
                        Pointer off_mapping = Pointer.Read(reader);
                        Pointer.DoAt(ref reader, off_mapping, () => {
                            m.mapping[i] = new int[m.num_vertices];
                            for (int j = 0; j < m.num_vertices; j++)
                            {
                                m.mapping[i][j] = reader.ReadUInt16();
                                if (m.mapping[i][j] >= m.num_vertices)
                                {
                                    l.print(m.offset);
                                }
                            }
                        });
                    }
                });
            });
            // Read element types & initialize arrays
            Pointer.Goto(ref reader, m.off_element_types);
            m.element_types = new ushort[m.num_elements];
            m.elements      = new IGeometricObjectElement[m.num_elements];
            for (uint i = 0; i < m.num_elements; i++)
            {
                m.element_types[i] = reader.ReadUInt16();
            }
            // Process elements
            for (uint i = 0; i < m.num_elements; i++)
            {
                Pointer.Goto(ref reader, m.off_elements + (i * 4));
                Pointer block_offset = Pointer.Read(reader);
                Pointer.Goto(ref reader, block_offset);
                switch (m.element_types[i])
                {
                case 1:     // Material
                    m.elements[i] = GeometricObjectElementTriangles.Read(reader, block_offset, m);
                    break;

                case 3:     // Sprite
                    m.elements[i] = GeometricObjectElementSprites.Read(reader, block_offset, m);
                    break;

                case 13:
                case 15:
                    m.bones       = DeformSet.Read(reader, block_offset, m);
                    m.elements[i] = m.bones;
                    break;

                default:
                    m.elements[i] = null;

                    /*1 = indexedtriangles
                     * 2 = facemap
                     * 3 = sprite
                     * 4 = TMesh
                     * 5 = points
                     * 6 = lines
                     * 7 = spheres
                     * 8 = alignedboxes
                     * 9 = cones
                     * 13 = deformationsetinfo*/
                    l.print("Unknown geometric element type " + m.element_types[i] + " at offset " + block_offset);
                    break;
                }
            }
            ReadMeshFromATO(reader, m);
            if (Settings.s.platform == Settings.Platform.PS2 && Settings.s.engineVersion == Settings.EngineVersion.R3)
            {
                m.optimizedObject?.Resolve(reader, onPreRead: opt => opt.isSinus = m.ps2IsSinus);
                m.ReadMeshFromSDC();
            }
            //m.InitGameObject();
            return(m);
        }
        public IGeometricObject Clone()
        {
            PatchGeometricObject lodObj = (PatchGeometricObject)MemberwiseClone();

            return(lodObj);
        }