Esempio n. 1
0
        internal static ResourceNode TryParse(DataSource source)
        {
            CollisionHeader *header = (CollisionHeader *)source.Address;

            if ((header->_numPoints < 0) || (header->_numPlanes < 0) || (header->_numObjects < 0) || (header->_unk1 < 0))
            {
                return(null);
            }

            if ((header->_pointOffset != 0x28) ||
                (header->_planeOffset >= source.Length) || (header->_planeOffset <= header->_pointOffset) ||
                (header->_objectOffset >= source.Length) || (header->_objectOffset <= header->_planeOffset))
            {
                return(null);
            }

            int *sPtr = header->_pad;

            for (int i = 0; i < 5; i++)
            {
                if (sPtr[i] != 0)
                {
                    return(null);
                }
            }

            return(new CollisionNode());
        }
Esempio n. 2
0
        public override void OnRebuild(VoidPtr address, int length, bool force)
        {
            CollisionHeader *header = (CollisionHeader *)address;

            *header = new CollisionHeader(_pointCount, _planeCount, _objects.Count, _unk1);

            BVec2 *    pPoint = header->Points;
            ColPlane * pPlane = header->Planes;
            ColObject *pObj   = header->Objects;

            int iPoint = 0, iPlane = 0;
            int lind, rind, llink, rlink, tmp;
            int cPoint, cPlane;

            lind = 0; rind = 0;

            CollisionPlane current, next;
            CollisionLink  link;

            foreach (CollisionObject obj in _objects)
            {
                //Sets bounds and entry indices
                obj.Prepare();

                cPoint = iPoint;
                cPlane = iPlane;
                foreach (CollisionPlane plane in obj._planes)
                {
                    if (plane._encodeIndex != -1)
                    {
                        continue;
                    }
                    current = next = plane;

Top:
                    //Update variables, moving to next plane and links
                    llink   = current._encodeIndex;
                    current = next;
                    next    = null;
                    rlink   = -1;

                    //Get left point index, and encode where necessary
                    if ((link = current._linkLeft)._encodeIndex == -1)
                    {
                        pPoint[link._encodeIndex = lind = iPoint++] = link._rawValue;
                    }
                    else
                    {
                        lind = link._encodeIndex;
                    }

                    //Get right point index and encode.
                    if ((link = current._linkRight)._encodeIndex == -1)
                    {
                        pPoint[link._encodeIndex = rind = iPoint++] = link._rawValue;
                    }
                    else
                    {
                        rind = link._encodeIndex;
                    }

                    //Right-link planes by finding next available
                    if (link != null)
                    {
                        foreach (CollisionPlane p in link._members)
                        {
                            if ((p == current) || (p._linkLeft != link))
                            {
                                continue; //We only want to go left-to-right!
                            }
                            //Determine if entry has been encoded yet
                            if ((tmp = p._encodeIndex) != -1)
                            {
                                if (pPlane[tmp]._link1 != -1)
                                {
                                    continue; //Already linked, try again
                                }
                                else
                                {
                                    pPlane[rlink = tmp]._link1 = (short)iPlane; //Left link, which means the end!
                                }
                            }
                            else
                            {
                                next  = p;
                                rlink = iPlane + 1;
                            }

                            break;
                        }
                    }

                    //Create entry
                    pPlane[current._encodeIndex = iPlane++] = new ColPlane(lind, rind, llink, rlink, current._type, current._flags2, current._flags, current._material);

                    //Traverse
                    if (next != null)
                    {
                        goto Top;
                    }
                }

                *pObj++ = new ColObject(cPlane, iPlane - cPlane, cPoint, iPoint - cPoint, obj._boxMin, obj._boxMax, obj._modelName, obj._boneName,
                                        obj._unk1, obj._unk2, obj._unk3, obj._flags, obj._unk5, obj._unk6, obj._boneIndex);
            }
        }