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()); }
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); } }