Пример #1
0
        public static List <SuperObject> Read(EndianBinaryReader reader, Pointer off_so, bool parseSiblings = true, bool parseChildren = true, SuperObject parent = null)
        {
            MapLoader          l            = MapLoader.Loader;
            List <SuperObject> superObjects = new List <SuperObject>();

            if (IsParsed(off_so))
            {
                return(null);
            }
            bool isFirstNode    = true;
            bool hasNextBrother = false;
            bool isValidNode    = true;

            while (isFirstNode || (hasNextBrother && parseSiblings))
            {
                SuperObject so = new SuperObject(off_so);
                superObjects.Add(so);   // Local list of superobjects (only this & siblings)
                l.superObjects.Add(so); // Global list of superobjects (all)
                if (parent != null)
                {
                    parent.children.Add(so);
                    so.parent = parent;
                }
                hasNextBrother      = false;
                so.type             = reader.ReadUInt32();
                so.off_data         = Pointer.Read(reader);
                so.off_child_first  = Pointer.Read(reader);
                so.off_child_last   = Pointer.Read(reader);
                so.num_children     = reader.ReadUInt32();
                so.off_brother_next = Pointer.Read(reader);
                so.off_brother_prev = Pointer.Read(reader);
                so.off_parent       = Pointer.Read(reader);
                so.off_matrix       = Pointer.Read(reader);
                //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;
                if (so.off_matrix != null)
                {
                    Pointer curPos = Pointer.Goto(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.Goto(ref reader, curPos);
                }
                switch (so.type)
                {
                case 0x20:     // IPO
                    Pointer.Goto(ref reader, so.off_data);
                    so.data = IPO.Read(reader, so.off_data, so);
                    break;

                case 0x40:     // IPO
                    l.print("IPO with code 0x40 at offset " + String.Format("0x{0:X}", so.offset.offset));
                    Pointer.Goto(ref reader, so.off_data);
                    so.data = IPO.Read(reader, so.off_data, so);
                    break;

                case 0x02:     // e.o.
                    Pointer.Goto(ref reader, so.off_data);
                    so.data = Perso.Read(reader, so.off_data, so);
                    break;

                case 0x01:     // world superobject
                    so.data = World.New(so);
                    //print("parsing world superobject with " + num_children + " children");
                    break;

                case 0x04:     // sector
                    Pointer.Goto(ref reader, so.off_data);
                    so.data = Sector.Read(reader, so.off_data, so);
                    break;

                default:
                    l.print("Unknown SO type " + so.type + " at offset " + String.Format("0x{0:X}", so.offset.offset));
                    isValidNode = false;
                    break;
                }
                if (so.Gao != null)
                {
                    if (parent != null)
                    {
                        so.Gao.transform.parent = parent.Gao.transform;
                    }
                    so.Gao.transform.localPosition = pos;
                    so.Gao.transform.localRotation = rot;
                    so.Gao.transform.localScale    = scale;
                }
                isFirstNode = false;
                if (isValidNode)
                {
                    if (parseChildren && so.num_children > 0 && so.off_child_first != null)
                    {
                        //if (type == 0x01) print("parsing children now");
                        Pointer off_current = Pointer.Goto(ref reader, so.off_child_first);
                        SuperObject.Read(reader, so.off_child_first, true, true, so);
                        //R3Pointer.Goto(ref reader, off_current);
                    }
                    if (so.off_brother_next != null && !IsParsed(so.off_brother_next))
                    {
                        hasNextBrother = true;
                        Pointer.Goto(ref reader, so.off_brother_next);
                        off_so = so.off_brother_next;
                    }
                }
            }
            return(superObjects);
        }