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); }