Пример #1
0
        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);
        }
Пример #2
0
        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);
        }