public static IPO Read(Reader reader, Pointer offset, SuperObject so) { MapLoader l = MapLoader.Loader; IPO ipo = new IPO(offset, so); ipo.off_data = Pointer.Read(reader); ipo.off_radiosity = Pointer.Read(reader); ipo.name = "IPO @ " + offset; // TODO: Read radiosity on all platforms. Currently crashes on Xbox 360 //ipo.radiosity = l.FromOffsetOrRead<Radiosity>(reader, ipo.off_radiosity); if (Settings.s.engineVersion >= Settings.EngineVersion.R3) { reader.ReadUInt32(); ipo.off_portalCamera = Pointer.Read(reader); reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); if (Settings.s.hasNames) { ipo.name = reader.ReadString(0x32); } } Pointer.DoAt(ref reader, ipo.off_data, () => { ipo.data = PhysicalObject.Read(reader, ipo.off_data, so: ipo.superObject, radiosity: ipo.radiosity); }); /*Pointer.DoAt(ref reader, ipo.off_portalCamera, () => { * ipo.portalCamera = SuperObject.FromOffsetOrRead(reader, * });*/ return(ipo); }
public static SuperObject FromOffsetOrRead(Pointer offset, Reader reader, SuperObject parent = null) { if (offset == null) { return(null); } SuperObject so = FromOffset(offset); if (so == null) { Pointer.DoAt(ref reader, offset, () => { so = SuperObject.Read(reader, offset, parent: parent); }); } return(so); }
public static IPO Read(Reader reader, Pointer offset, SuperObject so) { MapLoader l = MapLoader.Loader; IPO ipo = new IPO(offset, so); ipo.off_data = Pointer.Read(reader); ipo.off_radiosity = Pointer.Read(reader); ipo.name = "IPO @ " + offset; if (Settings.s.engineVersion >= Settings.EngineVersion.R3) { reader.ReadUInt32(); ipo.off_portalCamera = Pointer.Read(reader); reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); if (Settings.s.hasNames) { ipo.name = reader.ReadString(0x32); } } Pointer.DoAt(ref reader, ipo.off_data, () => { ipo.data = PhysicalObject.Read(reader, ipo.off_data); if (ipo.data != null) { /*if (ipo.data.visualSet != null) { * foreach (Visual.VisualSetLOD lod in ipo.data.visualSet) { * if (lod.obj.Gao != null) { * StaticBatchingUtility.Combine(lod.obj.Gao); * } * } * }*/ ipo.data.Gao.transform.parent = ipo.Gao.transform; } }); /*Pointer.DoAt(ref reader, ipo.off_portalCamera, () => { * ipo.portalCamera = SuperObject.FromOffsetOrRead(reader, * });*/ /*if (ipo.data != null && ipo.data.visualSet.Count > 0) { * if (ipo.data.visualSet[0].obj is R3Mesh) { * GameObject meshGAO = ((R3Mesh)ipo.data.visualSet[0].obj).gao; * meshGAO.transform.parent = ipo.Gao.transform; * } * }*/ return(ipo); }
public Sector(Pointer offset, SuperObject so) { this.offset = offset; this.superObject = so; }
public static Sector Read(Reader reader, Pointer offset, SuperObject so) { MapLoader l = MapLoader.Loader; Sector s = new Sector(offset, so); s.name = "Sector @ " + offset + ", SPO @ " + so.offset; //l.print(s.name); if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal) { if (Settings.s.game == Settings.Game.TTSE) { reader.ReadUInt32(); // always 1 or 0. whether the sector is active or not? } Pointer off_collideObj = Pointer.Read(reader); Pointer.DoAt(ref reader, off_collideObj, () => { //CollideMeshObject collider = CollideMeshObject.Read(reader, off_collideObj); // This has the exact same structure as a CollideMeshObject but with a sector superobject as material for the collieMeshElements }); LinkedList <int> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Double); // "environments list" LinkedList <int> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Double); // "surface list" } s.persos = LinkedList <Perso> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Double); s.staticLights = LinkedList <LightInfo> .Read(ref reader, Pointer.Current(reader), (off_element) => { LightInfo li = l.FromOffsetOrRead <LightInfo>(reader, off_element); if (li != null) { li.containingSectors.Add(s); } return(li); }, flags : LinkedList.Flags.ElementPointerFirst | LinkedList.Flags.ReadAtPointer | ((Settings.s.hasLinkedListHeaderPointers) ? LinkedList.Flags.HasHeaderPointers : LinkedList.Flags.NoPreviousPointersForDouble), type : LinkedList.Type.Minimize ); s.dynamicLights = LinkedList <int> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Double); if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal) { LinkedList <int> .ReadHeader(reader, Pointer.Current(reader)); // "streams list", probably related to water } s.neighbors = LinkedList <NeighborSector> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Minimize); s.sectors_unk1 = LinkedList <NeighborSector> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Minimize); s.sectors_unk2 = LinkedList <Sector> .ReadHeader(reader, Pointer.Current(reader), type : LinkedList.Type.Minimize); LinkedList <int> .ReadHeader(reader, Pointer.Current(reader)); // Placeholder LinkedList <int> .ReadHeader(reader, Pointer.Current(reader)); // Placeholder if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { s.sectorBorder = BoundingVolume.Read(reader, Pointer.Current(reader), BoundingVolume.Type.Box); reader.ReadUInt32(); if (Settings.s.game == Settings.Game.R2Revolution || Settings.s.game == Settings.Game.LargoWinch) { s.isSectorVirtual = reader.ReadByte(); reader.ReadByte(); s.sectorPriority = reader.ReadByte(); reader.ReadByte(); } else { s.isSectorVirtual = reader.ReadByte(); reader.ReadByte(); reader.ReadByte(); s.sectorPriority = reader.ReadByte(); if (Settings.s.engineVersion <= Settings.EngineVersion.R2) { s.off_skyMaterial = Pointer.Read(reader); s.skyMaterial = VisualMaterial.FromOffsetOrRead(s.off_skyMaterial, reader); } else { reader.ReadUInt32(); } reader.ReadByte(); if (Settings.s.hasNames) { s.name = reader.ReadString(0x104); l.print(s.name); } } } else { if (Settings.s.engineVersion == Settings.EngineVersion.Montreal) { reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); } if (Settings.s.game != Settings.Game.TTSE) { reader.ReadUInt32(); } Pointer off_name = Pointer.Read(reader); Pointer.DoAt(ref reader, off_name, () => { s.name = reader.ReadNullDelimitedString() + " @ " + offset; }); } /*if(num_subsectors_unk > 0 && off_subsector_unk_first != null) { // only for father sector * R3Pointer off_subsector_next = off_subsector_unk_first; * for (int i = 0; i < num_subsectors_unk; i++) { * R3Pointer.Goto(ref reader, off_subsector_next); * R3Pointer off_subsector = R3Pointer.Read(reader); * off_subsector_next = R3Pointer.Read(reader); * R3Pointer off_subsector_prev = R3Pointer.Read(reader); * R3Pointer off_sector_start = R3Pointer.Read(reader); * if (off_subsector != null) { * sect.neighborsPointers.Add(off_subsector); * } * } * }*/ l.sectors.Add(s); return(s); }
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); }
public static Perso Read(Reader reader, Pointer offset, SuperObject so) { MapLoader l = MapLoader.Loader; Perso p = new Perso(offset, so); //l.print("Perso " + offset); l.persos.Add(p); p.off_3dData = Pointer.Read(reader); // 0x0 p.off_stdGame = Pointer.Read(reader); // 4 Standard Game info p.off_dynam = Pointer.Read(reader); // 0x8 Dynam if (Settings.s.engineVersion == Settings.EngineVersion.Montreal) { reader.ReadUInt32(); } p.off_brain = Pointer.Read(reader); // 0xC p.off_camera = Pointer.Read(reader); // 0x10 is Camera in Rayman 2 p.off_collSet = Pointer.Read(reader); // 0x14 collset p.off_msWay = Pointer.Read(reader); // 0x18 p.off_msLight = Pointer.Read(reader); // 0x1C - MSLight if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal) { reader.ReadUInt32(); } p.off_sectInfo = Pointer.Read(reader); // 0x20 // Pointer to struct that points to active sector reader.ReadUInt32(); // 0x24 reader.ReadUInt32(); if (Settings.s.game == Settings.Game.RA || Settings.s.game == Settings.Game.RM) { reader.ReadUInt32(); } if (Settings.s.engineVersion < Settings.EngineVersion.R3) { reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); reader.ReadUInt32(); } Pointer.DoAt(ref reader, p.off_3dData, () => { p.p3dData = Perso3dData.Read(reader, p.off_3dData); }); Pointer.DoAt(ref reader, p.off_stdGame, () => { p.stdGame = StandardGame.Read(reader, p.off_stdGame); if (Settings.s.hasObjectTypes) { p.nameFamily = p.stdGame.GetName(0); p.nameModel = p.stdGame.GetName(1); p.namePerso = p.stdGame.GetName(2); } else { p.nameFamily = "Family" + p.stdGame.objectTypes[0]; p.nameModel = "Model" + p.stdGame.objectTypes[1]; p.namePerso = "Instance" + p.stdGame.objectTypes[2]; if (p.p3dData != null && p.p3dData.family != null && p.p3dData.family.name == null) { p.p3dData.family.name = p.nameFamily; p.p3dData.family.family_index = p.stdGame.objectTypes[0]; if (UnitySettings.CreateFamilyGameObjects && p.p3dData.family.Gao != null) { p.p3dData.family.Gao.name = "[Family] " + p.nameFamily; } } } }); l.print("[" + p.nameFamily + "] " + p.nameModel + " | " + p.namePerso + " - offset: " + offset + " superObject offset: " + (so != null?so.offset.ToString():"null")); if (Settings.s.engineVersion > Settings.EngineVersion.Montreal && Settings.s.game != Settings.Game.R2Revolution) { Pointer.DoAt(ref reader, p.off_dynam, () => { p.dynam = Dynam.Read(reader, p.off_dynam); }); } Pointer.DoAt(ref reader, p.off_brain, () => { p.brain = Brain.Read(reader, p.off_brain); if (p.brain != null && p.brain.mind != null && p.brain.mind.AI_model != null && p.nameModel != null) { p.brain.mind.AI_model.name = p.nameModel; } }); /*if (l.mode == MapLoader.Mode.Rayman2PC && off_msWay != null) { * MS_Way is always empty at start, instead check DsgVars for graphs * Pointer off_current = Pointer.Goto(ref reader, off_msWay); * * p.msWay = MSWay.Read(reader, off_msWay); * Pointer.Goto(ref reader, off_current); * * // Graph read? * if (p.msWay.graph != null) { * GameObject go_msWay = new GameObject("MSWay"); * go_msWay.transform.SetParent(p.Gao.transform); * * GameObject go_graph = new GameObject("Graph"); * go_graph.transform.SetParent(go_msWay.transform); * * int nodeNum = 0; * foreach (GraphNode node in p.msWay.graph.nodeList) { * GameObject go_graphNode = new GameObject("GraphNode[" + nodeNum + "].WayPoint"); * go_graphNode.transform.position.Set(node.wayPoint.position.x, node.wayPoint.position.y, node.wayPoint.position.z); * go_graphNode.transform.SetParent(go_graph.transform); * nodeNum++; * } * } * }*/ if (p.p3dData != null && p.p3dData.family != null) { if (p.p3dData.off_objectList != null && p.p3dData.family.GetIndexOfPhysicalList(p.p3dData.off_objectList) == -1) { ObjectList ol = ObjectList.FromOffsetOrRead(p.p3dData.off_objectList, reader); p.p3dData.family.AddNewPhysicalList(ol); /*if (ol != null) { * p.p3dData.family.AddNewPhysicalList(ol); * ol.Gao.transform.SetParent(p.p3dData.family.Gao.transform); * }*/ } if (p.p3dData.off_objectListInitial != null && p.p3dData.family.GetIndexOfPhysicalList(p.p3dData.off_objectListInitial) == -1) { ObjectList ol = ObjectList.FromOffsetOrRead(p.p3dData.off_objectListInitial, reader); p.p3dData.family.AddNewPhysicalList(ol); /*if (ol != null) { * p.p3dData.family.AddNewPhysicalList(ol); * ol.Gao.transform.SetParent(p.p3dData.family.Gao.transform); * }*/ } if (p.brain != null && p.brain.mind != null && p.brain.mind.AI_model != null && !(Settings.s.engineVersion == Settings.EngineVersion.R3 && Settings.s.loadFromMemory)) // Weird bug for R3 memory loading // Add physical objects tables hidden in scripts { AIModel ai = p.brain.mind.AI_model; if (ai.behaviors_normal != null) { for (int i = 0; i < ai.behaviors_normal.Length; i++) { if (ai.behaviors_normal[i].scripts != null) { for (int j = 0; j < ai.behaviors_normal[i].scripts.Length; j++) { List <ScriptNode> nodes = p.brain.mind.AI_model.behaviors_normal[i].scripts[j].scriptNodes; foreach (ScriptNode node in nodes) { if (node.param_ptr != null && node.nodeType == ScriptNode.NodeType.ObjectTableRef) { ObjectList ol = ObjectList.FromOffsetOrRead(node.param_ptr, reader); ol.unknownFamilyName = p.p3dData.family.name; ol.AddToFamilyLists(p); } } } } } } if (ai.behaviors_reflex != null) { for (int i = 0; i < ai.behaviors_reflex.Length; i++) { if (ai.behaviors_reflex[i].scripts != null) { for (int j = 0; j < ai.behaviors_reflex[i].scripts.Length; j++) { List <ScriptNode> nodes = p.brain.mind.AI_model.behaviors_reflex[i].scripts[j].scriptNodes; foreach (ScriptNode node in nodes) { if (node.param_ptr != null && node.nodeType == ScriptNode.NodeType.ObjectTableRef) { ObjectList ol = ObjectList.FromOffsetOrRead(node.param_ptr, reader); ol.unknownFamilyName = p.p3dData.family.name; ol.AddToFamilyLists(p); } } } } } } if (ai.macros != null) { for (int i = 0; i < ai.macros.Length; i++) { if (ai.macros[i].script != null) { List <ScriptNode> nodes = p.brain.mind.AI_model.macros[i].script.scriptNodes; foreach (ScriptNode node in nodes) { if (node.param_ptr != null && node.nodeType == ScriptNode.NodeType.ObjectTableRef) { ObjectList ol = ObjectList.FromOffsetOrRead(node.param_ptr, reader); ol.unknownFamilyName = p.p3dData.family.name; ol.AddToFamilyLists(p); } } } } } } if (p.p3dData.family.GetIndexOfPhysicalList(p.p3dData.off_objectList) != -1) { p.p3dData.objectList = ObjectList.FromOffset(p.p3dData.off_objectList); } } Pointer.DoAt(ref reader, p.off_collSet, () => { p.collset = CollSet.Read(reader, p, p.off_collSet); }); Pointer.DoAt(ref reader, p.off_sectInfo, () => { p.sectInfo = PersoSectorInfo.Read(reader, p.off_sectInfo); }); return(p); }
public Perso(Pointer offset, SuperObject so) { this.offset = offset; this.superObject = so; }
public static PhysicalObject Read(Reader reader, Pointer offset, SuperObject so = null) { PhysicalObject po = new PhysicalObject(offset, so); //MapLoader.Loader.print("PO @ " + offset); // Header po.off_visualSet = Pointer.Read(reader); po.off_collideSet = Pointer.Read(reader); po.off_visualBoundingVolume = Pointer.Read(reader); if (Settings.s.engineVersion > Settings.EngineVersion.TT && Settings.s.game != Settings.Game.LargoWinch) { if (Settings.s.engineVersion < Settings.EngineVersion.R3) { po.off_collideBoundingVolume = po.off_visualBoundingVolume; reader.ReadUInt32(); } else { po.off_collideBoundingVolume = Pointer.Read(reader); } } // Parse visual set Pointer.DoAt(ref reader, po.off_visualSet, () => { ushort numberOfLOD = 1; po.visualSetType = 0; if (Settings.s.game == Settings.Game.LargoWinch) { po.visualSet = new VisualSetLOD[1]; po.visualSet[0] = new VisualSetLOD(); po.visualSet[0].obj = null; po.visualSet[0].off_data = po.off_visualSet; po.visualSet[0].LODdistance = 5f; } else if (Settings.s.game == Settings.Game.R2Revolution) { po.visualSet = new VisualSetLOD[1]; po.visualSet[0] = new VisualSetLOD(); po.visualSet[0].obj = MapLoader.Loader.meshObjects.FirstOrDefault(p => p.offset == po.off_visualSet); po.visualSet[0].off_data = po.off_visualSet; po.visualSet[0].LODdistance = 5f; } else { if (Settings.s.platform != Settings.Platform.DC) { reader.ReadUInt32(); // 0 numberOfLOD = reader.ReadUInt16(); //if (numberOfLOD > 1) MapLoader.Loader.print("Found a PO with " + numberOfLOD + " levels of detail @ " + offset); po.visualSetType = reader.ReadUInt16(); if (numberOfLOD > 0) { Pointer off_LODDistances = Pointer.Read(reader); Pointer off_LODDataOffsets = Pointer.Read(reader); reader.ReadUInt32(); // always 0? RLI table offset if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { reader.ReadUInt32(); // always 0? number of RLI } po.visualSet = new VisualSetLOD[numberOfLOD]; for (uint i = 0; i < numberOfLOD; i++) { po.visualSet[i] = new VisualSetLOD(); } Pointer.DoAt(ref reader, off_LODDistances, () => { for (uint i = 0; i < numberOfLOD; i++) { // if distance > the float at this offset, game engine uses next LOD if there is one po.visualSet[i].LODdistance = reader.ReadSingle(); } }); Pointer.DoAt(ref reader, off_LODDataOffsets, () => { for (uint i = 0; i < numberOfLOD; i++) { po.visualSet[i].off_data = Pointer.Read(reader); } }); } } else { // Platform = Dreamcast Pointer.Read(reader); // Material pointer? Pointer off_data = Pointer.Read(reader); reader.ReadUInt32(); // always 0? reader.ReadUInt32(); // always 0? po.visualSet = new VisualSetLOD[1]; po.visualSet[0].off_data = off_data; po.visualSet[0].LODdistance = 5f; } } for (uint i = 0; i < numberOfLOD; i++) { Pointer.DoAt(ref reader, po.visualSet[i].off_data, () => { switch (po.visualSetType) { case 0: if (po.visualSet[i].obj == null) { po.visualSet[i].obj = GeometricObject.Read(reader, po.visualSet[i].off_data); } GeometricObject m = ((GeometricObject)po.visualSet[i].obj); if (m.name != "Mesh") { po.Gao.name = "[PO] " + m.name; } break; case 1: if (po.visualSet[i].obj == null) { po.visualSet[i].obj = MeshModificationObject.Read(reader, po, po.visualSet[i].off_data); } MeshModificationObject mod = po.visualSet[i].obj as MeshModificationObject; if (mod != null && mod.mesh != null && mod.mesh.name != "Mesh") { po.Gao.name = "[PO] " + mod.mesh.name; } break; default: MapLoader.Loader.print("unknown type " + po.visualSetType + " at offset: " + offset); break; } if (po.visualSet[i].obj.Gao != null) { po.visualSet[i].obj.Gao.transform.parent = po.Gao.transform; } }); } if (numberOfLOD > 1) { float bestLOD = po.visualSet.Min(v => v.LODdistance); foreach (VisualSetLOD lod in po.visualSet) { if (lod.obj.Gao != null && lod.LODdistance != bestLOD) { lod.obj.Gao.SetActive(false); } } } }); // Parse collide set Pointer.DoAt(ref reader, po.off_collideSet, () => { if (Settings.s.game == Settings.Game.R2Revolution) { // Read collide mesh object here directly po.collideMesh = GeometricObjectCollide.Read(reader, po.off_collideSet); po.collideMesh.gao.transform.parent = po.Gao.transform; } else { // Read collide set containing collide mesh uint u1 = reader.ReadUInt32(); // 0, zdm uint u2 = reader.ReadUInt32(); // 0, zdd uint u3 = reader.ReadUInt32(); // 0, zde Pointer off_zdr = Pointer.Read(reader); Pointer.DoAt(ref reader, off_zdr, () => { po.collideMesh = GeometricObjectCollide.Read(reader, off_zdr); po.collideMesh.gao.transform.parent = po.Gao.transform; }); } }); MapLoader.Loader.physicalObjects.Add(po); return(po); }
public PhysicalObject(Pointer offset, SuperObject so = null) { this.offset = offset; this.superObject = so; visualSet = new VisualSetLOD[0]; }
public static PhysicalObject Read(Reader reader, Pointer offset, SuperObject so = null, Radiosity radiosity = null) { PhysicalObject po = new PhysicalObject(offset, so); //MapLoader.Loader.print("PO @ " + offset); // Header po.off_visualSet = Pointer.Read(reader); po.off_collideSet = Pointer.Read(reader); po.off_visualBoundingVolume = Pointer.Read(reader); if (Settings.s.engineVersion > Settings.EngineVersion.TT && Settings.s.game != Settings.Game.LargoWinch) { if (Settings.s.engineVersion < Settings.EngineVersion.R3) { po.off_collideBoundingVolume = po.off_visualBoundingVolume; reader.ReadUInt32(); } else { po.off_collideBoundingVolume = Pointer.Read(reader); } } // Parse visual set Pointer.DoAt(ref reader, po.off_visualSet, () => { ushort numberOfLOD = 1; po.visualSetType = 0; if (Settings.s.game == Settings.Game.LargoWinch) { po.visualSet = new VisualSetLOD[1]; po.visualSet[0] = new VisualSetLOD(); po.visualSet[0].obj = null; po.visualSet[0].off_data = po.off_visualSet; po.visualSet[0].LODdistance = 5f; } else if (Settings.s.game == Settings.Game.R2Revolution) { po.visualSet = new VisualSetLOD[1]; po.visualSet[0] = new VisualSetLOD(); po.visualSet[0].obj = MapLoader.Loader.meshObjects.FirstOrDefault(p => p.offset == po.off_visualSet); po.visualSet[0].off_data = po.off_visualSet; po.visualSet[0].LODdistance = 5f; } else { if (Settings.s.platform != Settings.Platform.DC) { reader.ReadUInt32(); // 0 numberOfLOD = reader.ReadUInt16(); //if (numberOfLOD > 1) MapLoader.Loader.print("Found a PO with " + numberOfLOD + " levels of detail @ " + offset); po.visualSetType = reader.ReadUInt16(); if (numberOfLOD > 0) { Pointer off_LODDistances = Pointer.Read(reader); Pointer off_LODDataOffsets = Pointer.Read(reader); reader.ReadUInt32(); // always 0? RLI table offset if (Settings.s.engineVersion > Settings.EngineVersion.Montreal) { reader.ReadUInt32(); // always 0? number of RLI } po.visualSet = new VisualSetLOD[numberOfLOD]; for (uint i = 0; i < numberOfLOD; i++) { po.visualSet[i] = new VisualSetLOD(); } Pointer.DoAt(ref reader, off_LODDistances, () => { for (uint i = 0; i < numberOfLOD; i++) { // if distance > the float at this offset, game engine uses next LOD if there is one po.visualSet[i].LODdistance = reader.ReadSingle(); } }); Pointer.DoAt(ref reader, off_LODDataOffsets, () => { for (uint i = 0; i < numberOfLOD; i++) { po.visualSet[i].off_data = Pointer.Read(reader); } }); } } else { // Platform = Dreamcast Pointer.Read(reader); // Material pointer? Pointer off_data = Pointer.Read(reader); reader.ReadUInt32(); // always 0? reader.ReadUInt32(); // always 0? po.visualSet = new VisualSetLOD[1]; po.visualSet[0].off_data = off_data; po.visualSet[0].LODdistance = 5f; } } int radiosityLODIndex = 0; for (uint i = 0; i < numberOfLOD; i++) { Pointer.DoAt(ref reader, po.visualSet[i].off_data, () => { switch (po.visualSetType) { case 0: if (po.visualSet[i].obj == null) { po.visualSet[i].obj = GeometricObject.Read(reader, po.visualSet[i].off_data, radiosity: radiosity?.lod?[radiosityLODIndex++]); } break; case 1: if (po.visualSet[i].obj == null) { po.visualSet[i].obj = PatchGeometricObject.Read(reader, po, po.visualSet[i].off_data); } break; default: MapLoader.Loader.print("unknown type " + po.visualSetType + " at offset: " + offset); break; } }); } }); // Parse collide set Pointer.DoAt(ref reader, po.off_collideSet, () => { if (Settings.s.game == Settings.Game.R2Revolution) { // Read collide mesh object here directly po.collideMesh = GeometricObjectCollide.Read(reader, po.off_collideSet); } else { // Read collide set containing collide mesh uint u1 = reader.ReadUInt32(); // 0, zdm uint u2 = reader.ReadUInt32(); // 0, zdd uint u3 = reader.ReadUInt32(); // 0, zde Pointer off_zdr = Pointer.Read(reader); Pointer.DoAt(ref reader, off_zdr, () => { po.collideMesh = GeometricObjectCollide.Read(reader, off_zdr); }); } }); MapLoader.Loader.physicalObjects.Add(po); return(po); }
public static World New(SuperObject so) { return(new World(so)); }
public World(SuperObject so) { this.superObject = so; }