public static SuperObject Read(Reader reader, Pointer off_so, SuperObject parent = null) { MapLoader l = MapLoader.Loader; if (IsParsed(off_so)) { return(null); } bool isValidNode = true; SuperObject so = new SuperObject(off_so); l.superObjects.Add(so); // Global list of superobjects (all) if (parent != null) { so.parent = parent; } so.typeCode = reader.ReadUInt32(); // 0 - 4 so.off_data = Pointer.Read(reader); // 4 - 8 so.children = LinkedList <SuperObject> .ReadHeader(reader, Pointer.Current(reader), LinkedList.Type.Double); // 8 - 14 so.off_brother_next = Pointer.Read(reader); // 14 - 18 so.off_brother_prev = Pointer.Read(reader); // 18 - 1C so.off_parent = Pointer.Read(reader); // 1C - 20 so.off_matrix = Pointer.Read(reader); // 0x20->0x24 so.off_staticMatrix = Pointer.Read(reader); // other matrix so.globalMatrix = reader.ReadInt32(); // 0x28 -> 0x2C so.drawFlags = SuperObjectDrawFlags.Read(reader); so.flags = SuperObjectFlags.Read(reader); // 0x30->0x34 if (Settings.s.engineVersion == Settings.EngineVersion.R3) { reader.ReadUInt32(); // Visual Bounding Volume? } Pointer off_boundingVolume = Pointer.Read(reader); //l.print("SuperObject T" + so.typeCode + ": " + off_so + " - " + so.off_matrix); Pointer.DoAt(ref reader, so.off_matrix, () => { so.matrix = Matrix.Read(reader, so.off_matrix); }); /*Pointer.DoAt(ref reader, so.off_matrix2, () => { * so.matrix2 = Matrix.Read(reader, so.off_matrix2); * if (so.matrix == null) { * pos = so.matrix2.GetPosition(convertAxes: true); * rot = so.matrix2.GetRotation(convertAxes: true); * scale = so.matrix2.GetScale(convertAxes: true); * } * });*/ so.type = GetSOType(so.typeCode); switch (so.type) { case Type.IPO: Pointer.DoAt(ref reader, so.off_data, () => { so.data = IPO.Read(reader, so.off_data, so); }); break; case Type.IPO_2: Pointer.DoAt(ref reader, so.off_data, () => { l.print("IPO with code 0x40 at offset " + so.off_data); so.data = IPO.Read(reader, so.off_data, so); }); break; case Type.PhysicalObject: if (!Settings.s.loadFromMemory) { Pointer.DoAt(ref reader, so.off_data, () => { so.data = PhysicalObject.Read(reader, so.off_data, so); }); } break; case Type.Perso: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Perso.Read(reader, so.off_data, so); }); break; case Type.World: so.data = World.New(so); //print("parsing world superobject with " + num_children + " children"); break; case Type.Sector: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Sector.Read(reader, so.off_data, so); }); break; case Type.GeometricObject: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Visual.GeometricObject.Read(reader, so.off_data); }); break; case Type.GeometricShadowObject: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Visual.GeometricShadowObject.Read(reader, so.off_data, so); }); break; default: l.print("Unknown SO type " + so.typeCode + " at " + so.offset + " - " + so.off_data); //isValidNode = false; break; } Pointer.DoAt(ref reader, off_boundingVolume, () => { //l.print(so.type + " - " + so.offset + " - " + off_boundingVolume); if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal) { so.boundingVolumeTT = GeometricObjectCollide.Read(reader, off_boundingVolume, isBoundingVolume: true); } else { so.boundingVolume = BoundingVolume.Read(reader, off_boundingVolume, so.flags.HasFlag(SuperObjectFlags.Flags.BoundingBoxInsteadOfSphere) ? BoundingVolume.Type.Box : BoundingVolume.Type.Sphere); } }); if (isValidNode) { so.children.ReadEntries(ref reader, (off_child) => { SuperObject child = SuperObject.FromOffsetOrRead(off_child, reader, parent: so); child.parent = so; return(child); }, LinkedList.Flags.HasHeaderPointers); } return(so); }
public static SuperObject Read(Reader reader, Pointer off_so, SuperObject parent = null) { MapLoader l = MapLoader.Loader; if (IsParsed(off_so)) { return(null); } bool isValidNode = true; SuperObject so = new SuperObject(off_so); l.superObjects.Add(so); // Global list of superobjects (all) if (parent != null) { so.parent = parent; } so.typeCode = reader.ReadUInt32(); // 0 - 4 so.off_data = Pointer.Read(reader); // 4 - 8 so.children = LinkedList <SuperObject> .ReadHeader(reader, Pointer.Current(reader), LinkedList.Type.Double); // 8 - 14 so.off_brother_next = Pointer.Read(reader); // 14 - 18 so.off_brother_prev = Pointer.Read(reader); // 18 - 1C so.off_parent = Pointer.Read(reader); // 1C - 20 so.off_matrix = Pointer.Read(reader); // 0x20->0x24 so.off_staticMatrix = Pointer.Read(reader); // other matrix so.globalMatrix = reader.ReadInt32(); // 0x28 -> 0x2C so.drawFlags = SuperObjectDrawFlags.Read(reader); so.flags = SuperObjectFlags.Read(reader); // 0x30->0x34 if (Settings.s.engineVersion == Settings.EngineVersion.R3) { reader.ReadUInt32(); } Pointer off_boundingVolume = Pointer.Read(reader); //l.print("SuperObject T" + so.typeCode + ": " + off_so + " - " + so.off_matrix); //R3Pointer.Read(reader); // a copy of the matrix right after, at least in R3GC Vector3 pos = Vector3.zero; Vector3 scale = Vector3.one; Quaternion rot = Quaternion.identity; Pointer.DoAt(ref reader, so.off_matrix, () => { so.matrix = Matrix.Read(reader, so.off_matrix); pos = so.matrix.GetPosition(convertAxes: true); rot = so.matrix.GetRotation(convertAxes: true); scale = so.matrix.GetScale(convertAxes: true); }); /*Pointer.DoAt(ref reader, so.off_matrix2, () => { * so.matrix2 = Matrix.Read(reader, so.off_matrix2); * if (so.matrix == null) { * pos = so.matrix2.GetPosition(convertAxes: true); * rot = so.matrix2.GetRotation(convertAxes: true); * scale = so.matrix2.GetScale(convertAxes: true); * } * });*/ so.type = GetSOType(so.typeCode); switch (so.type) { case Type.IPO: Pointer.DoAt(ref reader, so.off_data, () => { so.data = IPO.Read(reader, so.off_data, so); }); break; case Type.IPO_2: Pointer.DoAt(ref reader, so.off_data, () => { l.print("IPO with code 0x40 at offset " + so.off_data); so.data = IPO.Read(reader, so.off_data, so); }); break; case Type.PhysicalObject: if (!Settings.s.loadFromMemory) { Pointer.DoAt(ref reader, so.off_data, () => { so.data = PhysicalObject.Read(reader, so.off_data, so); }); } break; case Type.Perso: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Perso.Read(reader, so.off_data, so); }); break; case Type.World: so.data = World.New(so); //print("parsing world superobject with " + num_children + " children"); break; case Type.Sector: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Sector.Read(reader, so.off_data, so); }); break; case Type.GeometricObject: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Visual.GeometricObject.Read(reader, so.off_data); }); break; case Type.GeometricShadowObject: Pointer.DoAt(ref reader, so.off_data, () => { so.data = Visual.GeometricShadowObject.Read(reader, so.off_data, so); }); break; default: l.print("Unknown SO type " + so.typeCode + " at " + so.offset + " - " + so.off_data); //isValidNode = false; break; } Pointer.DoAt(ref reader, off_boundingVolume, () => { //l.print(off_boundingVolume); so.boundingVolume = BoundingVolume.Read(reader, off_boundingVolume, so.flags.HasFlag(SuperObjectFlags.Flags.BoundingBoxInsteadOfSphere) ? BoundingVolume.Type.Box : BoundingVolume.Type.Sphere); }); if (so.Gao != null) { if (parent != null && parent.Gao != null) { so.Gao.transform.parent = parent.Gao.transform; } so.Gao.transform.localPosition = pos; so.Gao.transform.localRotation = rot; so.Gao.transform.localScale = scale; SuperObjectComponent soc = so.Gao.AddComponent <SuperObjectComponent>(); so.Gao.layer = LayerMask.NameToLayer("SuperObject"); soc.so = so; if (so.boundingVolume != null) { if (so.boundingVolume.type == BoundingVolume.Type.Box) { BoxCollider collider = so.Gao.AddComponent <BoxCollider>(); collider.center = so.boundingVolume.Center; collider.center -= so.Gao.transform.position; collider.size = so.boundingVolume.Size; } else { SphereCollider collider = so.Gao.AddComponent <SphereCollider>(); collider.center = so.boundingVolume.Center; collider.radius = so.boundingVolume.sphereRadius; } } } if (isValidNode) { so.children.ReadEntries(ref reader, (off_child) => { SuperObject child = SuperObject.Read(reader, off_child, so); child.parent = so; return(child); }, LinkedList.Flags.HasHeaderPointers); } return(so); }