예제 #1
0
        public static PhysicalObject Read(EndianBinaryReader reader, Pointer offset)
        {
            PhysicalObject po = new PhysicalObject(offset);

            // Header
            po.off_visualSet            = Pointer.Read(reader);
            po.off_collideSet           = Pointer.Read(reader);
            po.off_visualBoundingVolume = Pointer.Read(reader);
            if (MapLoader.Loader.mode == MapLoader.Mode.Rayman2PC)
            {
                po.off_collideBoundingVolume = po.off_visualBoundingVolume;
                reader.ReadUInt32();
            }
            else
            {
                po.off_collideBoundingVolume = Pointer.Read(reader);
            }

            // Parse visual set
            if (po.off_visualSet != null)
            {
                Pointer.Goto(ref reader, po.off_visualSet);
                reader.ReadUInt32(); // 0
                ushort numberOfLOD = reader.ReadUInt16();
                ushort type        = reader.ReadUInt16();
                for (uint i = 0; i < numberOfLOD; i++)
                {
                    // if distance > the float at this offset, game engine uses next LOD if there is one
                    VisualSetLOD lod             = new VisualSetLOD();
                    Pointer      off_LODDistance = Pointer.Read(reader);
                    lod.off_data = Pointer.Read(reader);
                    reader.ReadUInt32(); // always 0?
                    reader.ReadUInt32(); // always 0?
                    if (off_LODDistance != null)
                    {
                        Pointer off_current = Pointer.Goto(ref reader, off_LODDistance);
                        lod.LODdistance = reader.ReadSingle();
                        Pointer.Goto(ref reader, off_current);
                    }
                    if (lod.off_data != null)
                    {
                        Pointer off_current = Pointer.Goto(ref reader, lod.off_data);
                        switch (type)
                        {
                        case 0:
                            lod.obj = MeshObject.Read(reader, po, lod.off_data);
                            MeshObject m = ((MeshObject)lod.obj);
                            if (m.name != "Mesh")
                            {
                                po.Gao.name = "[PO] " + m.name;
                            }
                            m.gao.transform.parent = po.Gao.transform;
                            break;

                        case 1:
                            lod.obj = UnknownGeometricObject.Read(reader, po, lod.off_data);
                            break;

                        default:
                            MapLoader.Loader.print("unknown type " + type + " at offset: " + offset);
                            break;
                        }
                        Pointer.Goto(ref reader, off_current);
                    }
                    po.visualSet.Add(lod);
                }
            }

            // Parse collide set
            if (po.off_collideSet != null)
            {
                Pointer.Goto(ref reader, po.off_collideSet);
                uint    u1       = reader.ReadUInt32(); // 0
                uint    u2       = reader.ReadUInt32(); // 0
                uint    u3       = reader.ReadUInt32(); // 0
                Pointer off_mesh = Pointer.Read(reader);
                if (off_mesh != null)
                {
                    //R3Loader.Loader.print("Collide mesh offset: " + off_mesh);
                    Pointer.Goto(ref reader, off_mesh);
                    po.collideMesh = CollideMeshObject.Read(reader, po, off_mesh);
                    po.collideMesh.gao.transform.parent = po.Gao.transform;
                }
                //R3Loader.Loader.print("Collide set: " + po.off_collideSet + " - vol: " + po.off_visualBoundingVolume);
            }
            MapLoader.Loader.physicalObjects.Add(po);
            return(po);
        }