MapCheck better

This commit is contained in:
Roman Sandu committed 2026-10-26 03:16:55 +03:00
1 parent f77383ccfb
commit 8c847193f3
6 files changed
+324 -261

No files matched your search

+37 -17
View File
@@ -18,10 +18,11 @@ public:
TBGCheckList* getNext() { return mNext; }
const TBGCheckList* getNext() const { return mNext; }
void setNext(TBGCheckList* v) { mNext = v; }
const TBGCheckData* getData() const { return mData; }
public:
/* 0x4 */ TBGCheckList* mNext;
/* 0x8 */ TBGCheckData* unk8;
/* 0x8 */ TBGCheckData* mData;
};
class TBGCheckListWarp : public TBGCheckList {
@@ -48,9 +49,18 @@ public:
TBGCheckListRoot() { }
// fabricated
const TBGCheckList* getGroundList() const { return unk0[0].getNext(); }
const TBGCheckList* getWallList() const { return unk0[2].getNext(); }
const TBGCheckList* getRoofList() const { return unk0[1].getNext(); }
const TBGCheckList* getGroundList() const
{
return unk0[BG_PLANE_TYPE_GROUND].getNext();
}
const TBGCheckList* getWallList() const
{
return unk0[BG_PLANE_TYPE_WALL].getNext();
}
const TBGCheckList* getRoofList() const
{
return unk0[BG_PLANE_TYPE_ROOF].getNext();
}
public:
/* 0x0 */ TBGCheckList unk0[3];
@@ -108,6 +118,10 @@ struct TBGWallCheckRecord {
mFlags = flags;
}
// fabricated
const JGeometry::TVec3<f32>& getCenter() const { return mCenter; }
int getMaxResults() const { return mMaxResults; }
/* 0x0 */ JGeometry::TVec3<f32> mCenter;
/* 0xC */ f32 mRadius;
/* 0x10 */ int mMaxResults;
@@ -173,14 +187,20 @@ public:
// fabricated
u32 getEntrySize(u16 entry_id) const { return unk40 - unk42[entry_id]; }
const TBGCheckListRoot& getGridRoot14(int x, int z) const
int getCellIndex(int x, int z) const { return x + z * mGridSizeX; }
const TBGCheckListRoot& getStaticCheckList(int x, int z) const
{
return unk14[x + z * unk8];
return mStaticGrid[getCellIndex(x, z)];
}
const TBGCheckListRoot& getGridRoot18(int x, int z) const
const TBGCheckListRoot& getMoveCheckList(int x, int z) const
{
return unk18[x + z * unk8];
return mMoveGrid[getCellIndex(x, z)];
}
// fabricated
int worldToGridX(f32 x) const { return (x + mGridExtentX) * (1.0f / 1024); }
int worldToGridZ(f32 z) const { return (z + mGridExtentY) * (1.0f / 1024); }
int gridToWorldX(int x) const { return x * 1024.0f - mGridExtentX; }
int gridToWorldZ(int z) const { return z * 1024.0f - mGridExtentY; }
void setGroundPlane(TMapCheckGroundPlane* plane) { mGroundPlane = plane; }
TBGCheckData* getCheckDataPoolTop() { return &unk28[unk34]; }
@@ -188,20 +208,20 @@ public:
public:
/* 0x0 */ f32 mGridExtentX;
/* 0x4 */ f32 mGridExtentY;
/* 0x8 */ int unk8;
/* 0xC */ int unkC;
/* 0x10 */ int unk10;
/* 0x14 */ TBGCheckListRoot* unk14;
/* 0x18 */ TBGCheckListRoot* unk18;
/* 0x8 */ int mGridSizeX;
/* 0xC */ int mGridSizeZ;
/* 0x10 */ int mGridCellNum;
/* 0x14 */ TBGCheckListRoot* mStaticGrid;
/* 0x18 */ TBGCheckListRoot* mMoveGrid;
/* 0x1C */ u32 unk1C;
/* 0x20 */ u32 unk20;
/* 0x24 */ u32 unk24;
/* 0x28 */ TBGCheckData* unk28;
/* 0x2C */ TBGCheckList* unk2C;
/* 0x30 */ TBGCheckListWarp* unk30;
/* 0x2C */ TBGCheckList* mCheckListPool;
/* 0x30 */ TBGCheckListWarp* mWarpCheckListPool;
/* 0x34 */ u32 unk34;
/* 0x38 */ u32 unk38;
/* 0x3C */ u32 unk3C;
/* 0x38 */ u32 mStaticListUsed;
/* 0x3C */ u32 mMoveListTop;
/* 0x40 */ u16 unk40;
/* 0x42 */ u16 unk42[256];
/* 0x242 */ u16 unk242;
+7 -1
View File
@@ -7,6 +7,12 @@ class TLiveActor;
class JSUMemoryInputStream;
// fabricated
enum BGPlaneType {
BG_PLANE_TYPE_GROUND = 0,
BG_PLANE_TYPE_ROOF = 1,
BG_PLANE_TYPE_WALL = 2,
};
enum BGCheckFlagBits {
BG_CHECK_FLAG_X_FACING = 0x8,
BG_CHECK_FLAG_ILLEGAL = 0x10,
@@ -131,7 +137,7 @@ public:
return mFlags & BG_CHECK_FLAG_ILLEGAL ? true : false;
}
f32 getActiveJumpPower() const;
u32 getPlaneType();
BGPlaneType getPlaneType();
void setVertex(const JGeometry::TVec3<f32>& point1,
const JGeometry::TVec3<f32>& point2,
const JGeometry::TVec3<f32>& point3);
+141 -102
View File
@@ -28,16 +28,14 @@ inline static bool someUnknownInline(TBGCheckData* r31, TBGWallCheckRecord* r29)
&& r31->isWaterSurface())
return false;
f32 cx = r29->mCenter.x;
f32 cy = r29->mCenter.y;
f32 cz = r29->mCenter.z;
f32 nx = r31->getNormal().x;
f32 ny = r31->getNormal().y;
f32 nz = r31->getNormal().z;
f32 d = r31->getPlaneDistance();
f32 d = r31->getPlaneDistance();
f32 signedDist = d + (cx * nx + cy * ny + cz * nz);
f32 signedDist
= d
+ (r29->mCenter.x * r31->getNormal().x
+ r29->mCenter.y * r31->getNormal().y + cz * r31->getNormal().z);
if (signedDist < -radius || radius < signedDist)
return false;
@@ -47,20 +45,23 @@ inline static bool someUnknownInline(TBGCheckData* r31, TBGWallCheckRecord* r29)
f32 y3 = r31->getPoint3().y;
if (r31->checkFlag(BG_CHECK_FLAG_X_FACING)) {
if (nx > 0.0f) {
if (r31->getNormal().x > 0.0f) {
cz = -cz;
f32 z1 = -r31->getPoint1().z;
f32 z2 = -r31->getPoint2().z;
f32 z3 = -r31->getPoint3().z;
if (skewProduct(y1 - cy, z1 - cz, y2 - y1, z2 - z1) > 1.0f)
if (skewProduct(y1 - r29->mCenter.y, z1 - cz, y2 - y1, z2 - z1)
> 1.0f)
return false;
if (skewProduct(y2 - cy, z2 - cz, y3 - y2, z3 - z2) > 1.0f)
if (skewProduct(y2 - r29->mCenter.y, z2 - cz, y3 - y2, z3 - z2)
> 1.0f)
return false;
if (skewProduct(y3 - cy, z3 - cz, y1 - y3, z1 - z3) > 1.0f)
if (skewProduct(y3 - r29->mCenter.y, z3 - cz, y1 - y3, z1 - z3)
> 1.0f)
return false;
} else {
cz = -cz;
@@ -69,49 +70,64 @@ inline static bool someUnknownInline(TBGCheckData* r31, TBGWallCheckRecord* r29)
f32 z2 = -r31->getPoint2().z;
f32 z3 = -r31->getPoint3().z;
if (skewProduct(y1 - cy, z1 - cz, y2 - y1, z2 - z1) < -1.0f)
if (skewProduct(y1 - r29->mCenter.y, z1 - cz, y2 - y1, z2 - z1)
< -1.0f)
return false;
if (skewProduct(y2 - cy, z2 - cz, y3 - y2, z3 - z2) < -1.0f)
if (skewProduct(y2 - r29->mCenter.y, z2 - cz, y3 - y2, z3 - z2)
< -1.0f)
return false;
if (skewProduct(y3 - cy, z3 - cz, y1 - y3, z1 - z3) < -1.0f)
if (skewProduct(y3 - r29->mCenter.y, z3 - cz, y1 - y3, z1 - z3)
< -1.0f)
return false;
}
} else {
if (nz > 0.0f) {
if (r31->getNormal().z > 0.0f) {
f32 x1 = r31->getPoint1().x;
f32 x2 = r31->getPoint2().x;
f32 x3 = r31->getPoint3().x;
if (skewProduct(y1 - cy, x1 - cx, y2 - y1, x2 - x1) > 1.0f)
if (skewProduct(y1 - r29->mCenter.y, x1 - r29->mCenter.x, y2 - y1,
x2 - x1)
> 1.0f)
return false;
if (skewProduct(y2 - cy, x2 - cx, y3 - y2, x3 - x2) > 1.0f)
if (skewProduct(y2 - r29->mCenter.y, x2 - r29->mCenter.x, y3 - y2,
x3 - x2)
> 1.0f)
return false;
if (skewProduct(y3 - cy, x3 - cx, y1 - y3, x1 - x3) > 1.0f)
if (skewProduct(y3 - r29->mCenter.y, x3 - r29->mCenter.x, y1 - y3,
x1 - x3)
> 1.0f)
return false;
} else {
f32 x1 = r31->getPoint1().x;
f32 x2 = r31->getPoint2().x;
f32 x3 = r31->getPoint3().x;
if (skewProduct(y1 - cy, x1 - cx, y2 - y1, x2 - x1) < -1.0f)
if (skewProduct(y1 - r29->mCenter.y, x1 - r29->mCenter.x, y2 - y1,
x2 - x1)
< -1.0f)
return false;
if (skewProduct(y2 - cy, x2 - cx, y3 - y2, x3 - x2) < -1.0f)
if (skewProduct(y2 - r29->mCenter.y, x2 - r29->mCenter.x, y3 - y2,
x3 - x2)
< -1.0f)
return false;
if (skewProduct(y3 - cy, x3 - cx, y1 - y3, x1 - x3) < -1.0f)
if (skewProduct(y3 - r29->mCenter.y, x3 - r29->mCenter.x, y1 - y3,
x1 - x3)
< -1.0f)
return false;
}
}
if (!(flags & TBGWallCheckRecord::DONT_MOVE_XZ)) {
f32 d = radius - signedDist;
r29->mCenter.x += d * r31->getNormal().x;
r29->mCenter.z += d * r31->getNormal().z;
f32 push = radius - signedDist;
r29->mCenter.x += push * r31->getNormal().x;
r29->mCenter.z += push * r31->getNormal().z;
}
return true;
@@ -123,68 +139,71 @@ int TMapCollisionData::checkWallList(const TBGCheckList* param_1,
if (!param_1)
return 0;
TBGCheckData* data;
f32 f27 = param_2->mCenter.y;
// param_1: r28
// param_2: r29
int r30 = 0;
int num = 0;
while (param_1) {
TBGCheckData* r31 = param_1->unk8;
param_1 = param_1->mNext;
data = param_1->mData;
param_1 = param_1->mNext;
if (r31->mMinY > f27)
if (data->mMinY > f27)
continue;
if (r31->mMaxY < f27)
return r30;
if (data->mMaxY < f27)
return num;
if (!someUnknownInline(r31, param_2))
if (!someUnknownInline(data, param_2))
continue;
++r30;
param_2->mResultWalls[param_2->mResultWallsNum] = r31;
++num;
param_2->mResultWalls[param_2->mResultWallsNum] = data;
++param_2->mResultWallsNum;
if (param_2->mResultWallsNum >= param_2->mMaxResults)
return r30;
return num;
}
return r30;
return num;
}
int TMapCollisionData::checkWalls(TBGWallCheckRecord* param_1) const
int TMapCollisionData::checkWalls(TBGWallCheckRecord* record) const
{
param_1->mResultWallsNum = 0;
if (param_1->mCenter.x < -mGridExtentX || mGridExtentX <= param_1->mCenter.x
|| param_1->mCenter.z < -mGridExtentY
|| mGridExtentY <= param_1->mCenter.z)
record->mResultWallsNum = 0;
if (record->getCenter().x < -mGridExtentX
|| mGridExtentX <= record->getCenter().x
|| record->getCenter().z < -mGridExtentY
|| mGridExtentY <= record->getCenter().z)
return 0;
int gridX = (param_1->mCenter.x + mGridExtentX) * (1.0f / 1024);
int gridZ = (param_1->mCenter.z + mGridExtentY) * (1.0f / 1024);
int gridX = worldToGridX(record->getCenter().x);
int gridZ = worldToGridZ(record->getCenter().z);
int iVar6
= checkWallList(getGridRoot18(gridX, gridZ).getWallList(), param_1);
int num
= checkWallList(getMoveCheckList(gridX, gridZ).getWallList(), record);
if (num >= record->getMaxResults())
return num;
if (iVar6 >= param_1->mMaxResults)
return iVar6;
iVar6 += checkWallList(getGridRoot14(gridX, gridZ).getWallList(), param_1);
return iVar6;
num += checkWallList(getStaticCheckList(gridX, gridZ).getWallList(),
record);
return num;
}
f32 TMapCollisionData::checkRoofList(f32 x, f32 y, f32 z, u8 param_4,
const TBGCheckList* head,
const TBGCheckData** result)
{
const TBGCheckData* data;
while (head) {
const TBGCheckData* data = head->unk8;
head = head->mNext;
data = head->getData();
head = head->getNext();
if (param_4 & 0x4 && data->isWaterThrough())
if ((param_4 & IGNORE_WATER_THROUGH) && data->isWaterThrough())
continue;
if ((data->mPoint1.z - z) * (data->mPoint2.x - data->mPoint1.x)
- (data->mPoint1.x - x) * (data->mPoint2.z - data->mPoint1.z)
f32 x1 = data->getPoint1().x;
f32 z1 = data->getPoint1().z;
if ((z1 - z) * (data->mPoint2.x - x1)
- (x1 - x) * (data->mPoint2.z - z1)
> 1.0f)
continue;
@@ -193,8 +212,8 @@ f32 TMapCollisionData::checkRoofList(f32 x, f32 y, f32 z, u8 param_4,
> 1.0f)
continue;
if ((data->mPoint3.z - z) * (data->mPoint1.x - data->mPoint3.x)
- (data->mPoint3.x - x) * (data->mPoint1.z - data->mPoint3.z)
if ((data->mPoint3.z - z) * (x1 - data->mPoint3.x)
- (data->mPoint3.x - x) * (z1 - data->mPoint3.z)
> 1.0f)
continue;
@@ -221,16 +240,18 @@ f32 TMapCollisionData::checkRoof(f32 x, f32 y, f32 z, u8 flags,
return 9999999.0f;
}
int gridX = (x + mGridExtentX) * (1.0f / 1024);
int gridZ = (z + mGridExtentY) * (1.0f / 1024);
int gridX = worldToGridX(x);
int gridZ = worldToGridZ(z);
const TBGCheckData* local_4c;
f32 dVar5 = checkRoofList(
x, y, z, flags, getGridRoot18(gridX, gridZ).getRoofList(), &local_4c);
f32 dVar5 = checkRoofList(x, y, z, flags,
getMoveCheckList(gridX, gridZ).getRoofList(),
&local_4c);
const TBGCheckData* local_50;
f32 dVar6 = checkRoofList(
x, y, z, flags, getGridRoot14(gridX, gridZ).getRoofList(), &local_50);
f32 dVar6 = checkRoofList(x, y, z, flags,
getStaticCheckList(gridX, gridZ).getRoofList(),
&local_50);
if (dVar5 < dVar6) {
*result = local_4c;
@@ -246,7 +267,7 @@ f32 TMapCollisionData::checkGroundList(f32 x, f32 y, f32 z, u8 flags,
const TBGCheckData** result)
{
while (head) {
const TBGCheckData* data = head->unk8;
const TBGCheckData* data = head->getData();
head = head->getNext();
if (data->mMinY > y)
@@ -258,8 +279,11 @@ f32 TMapCollisionData::checkGroundList(f32 x, f32 y, f32 z, u8 flags,
if ((flags & IGNORE_WATER_SURFACE) && data->isWaterSurface())
continue;
if ((data->mPoint1.z - z) * (data->mPoint2.x - data->mPoint1.x)
- (data->mPoint1.x - x) * (data->mPoint2.z - data->mPoint1.z)
f32 x1 = data->getPoint1().x;
f32 z1 = data->getPoint1().z;
if ((z1 - z) * (data->mPoint2.x - x1)
- (x1 - x) * (data->mPoint2.z - z1)
< -1.0f)
continue;
@@ -268,8 +292,8 @@ f32 TMapCollisionData::checkGroundList(f32 x, f32 y, f32 z, u8 flags,
< -1.0f)
continue;
if ((data->mPoint3.z - z) * (data->mPoint1.x - data->mPoint3.x)
- (data->mPoint3.x - x) * (data->mPoint1.z - data->mPoint3.z)
if ((data->mPoint3.z - z) * (x1 - data->mPoint3.x)
- (data->mPoint3.x - x) * (z1 - data->mPoint3.z)
< -1.0f)
continue;
@@ -296,16 +320,18 @@ f32 TMapCollisionData::checkGround(f32 x, f32 y, f32 z, u8 flags,
return -32767.0f;
}
int gridX = (x + mGridExtentX) * (1.0f / 1024);
int gridZ = (z + mGridExtentY) * (1.0f / 1024);
int gridX = worldToGridX(x);
int gridZ = worldToGridZ(z);
const TBGCheckData* local_60;
f32 dVar5 = checkGroundList(
x, y, z, flags, getGridRoot18(gridX, gridZ).getGroundList(), &local_60);
f32 dVar5 = checkGroundList(x, y, z, flags,
getMoveCheckList(gridX, gridZ).getGroundList(),
&local_60);
const TBGCheckData* local_64;
f32 dVar6 = checkGroundList(
x, y, z, flags, getGridRoot14(gridX, gridZ).getGroundList(), &local_64);
x, y, z, flags, getStaticCheckList(gridX, gridZ).getGroundList(),
&local_64);
if (mGroundPlane != nullptr) {
const TBGCheckData* local_68;
@@ -391,8 +417,8 @@ static const TBGCheckData* intersectLineList(const TBGCheckList* head,
JGeometry::TVec3<f32>* hit_pos)
{
while (head) {
TBGCheckData* data = head->unk8;
head = head->mNext;
const TBGCheckData* data = head->getData();
head = head->getNext();
if (bgIntersectLine(data, start, end, front_only, hit_pos))
return data;
@@ -401,13 +427,24 @@ static const TBGCheckData* intersectLineList(const TBGCheckList* head,
return nullptr;
}
static inline f32 crossFrom(const JGeometry::TVec2<f32>& origin,
const JGeometry::TVec2<f32>& p,
const JGeometry::TVec2<f32>& q)
{
JGeometry::TVec2<f32> dq = q;
JGeometry::TVec2<f32> dp = p;
dq -= origin;
dp -= origin;
return dp.cross(dq);
}
static bool LineInLineXZ(const JGeometry::TVec2<f32>& a0,
const JGeometry::TVec2<f32>& a1,
const JGeometry::TVec2<f32>& b0,
const JGeometry::TVec2<f32>& b1)
{
if ((b0 - a0).cross(a1 - a0) * (b1 - a0).cross(a1 - a0) <= 0.0f
&& (a0 - b0).cross(b1 - b0) * (a1 - b0).cross(b1 - b0) <= 0.0f)
if (crossFrom(a0, b1, a1) * crossFrom(a0, b0, a1) <= 0.0f
&& crossFrom(b0, a1, b1) * crossFrom(b0, a0, b1) <= 0.0f)
return true;
return false;
@@ -417,12 +454,12 @@ const TBGCheckData* TMapCollisionData::intersectLine(
const JGeometry::TVec3<f32>& start, const JGeometry::TVec3<f32>& end,
bool front_only, JGeometry::TVec3<f32>* hit_pos) const
{
JGeometry::TVec2<f32> startXZ(start.x, start.z);
JGeometry::TVec2<f32> endXZ(end.x, end.z);
int minXi = startXZ.x;
int maxXi = endXZ.x;
int minZi = startXZ.y;
int maxZi = endXZ.y;
int gridX;
int gridZ;
int minXi = start.x;
int minZi = start.z;
int maxXi = end.x;
int maxZi = end.z;
if (minXi > maxXi) {
int tmp = minXi;
minXi = maxXi;
@@ -435,23 +472,25 @@ const TBGCheckData* TMapCollisionData::intersectLine(
maxZi = tmp;
}
int minGridZ = (int)((minZi + mGridExtentY) * (1.0f / 1024));
int minGridX = (int)((minXi + mGridExtentX) * (1.0f / 1024));
int maxGridX = (int)((maxXi + mGridExtentX) * (1.0f / 1024));
int maxGridZ = (int)((maxZi + mGridExtentY) * (1.0f / 1024));
int minGridX = worldToGridX(minXi);
int minGridZ = worldToGridZ(minZi);
int maxGridX = worldToGridX(maxXi);
int maxGridZ = worldToGridZ(maxZi);
for (int gridZ = minGridZ; gridZ <= maxGridZ; ++gridZ) {
for (int gridX = minGridX; gridX <= maxGridX; ++gridX) {
JGeometry::TVec2<f32> startXZ(start.x, start.z);
JGeometry::TVec2<f32> endXZ(end.x, end.z);
for (gridZ = minGridZ; gridZ <= maxGridZ; ++gridZ) {
for (gridX = minGridX; gridX <= maxGridX; ++gridX) {
if (gridX != minGridX || gridZ != minGridZ) {
JGeometry::TVec2<f32> corners[4];
corners[0].set((s32)(gridX * 1024.0f - mGridExtentX),
(s32)(gridZ * 1024.0f - mGridExtentY));
corners[1].set((s32)((gridX + 1) * 1024.0f - mGridExtentX),
(s32)(gridZ * 1024.0f - mGridExtentY));
corners[2].set((s32)(gridX * 1024.0f - mGridExtentX),
(s32)((gridZ + 1) * 1024.0f - mGridExtentY));
corners[3].set((s32)((gridX + 1) * 1024.0f - mGridExtentX),
(s32)((gridZ + 1) * 1024.0f - mGridExtentY));
corners[0].set<f32>(gridToWorldX(gridX), gridToWorldZ(gridZ));
corners[1].set<f32>(gridToWorldX(gridX + 1),
gridToWorldZ(gridZ));
corners[2].set<f32>(gridToWorldX(gridX),
gridToWorldZ(gridZ + 1));
corners[3].set<f32>(gridToWorldX(gridX + 1),
gridToWorldZ(gridZ + 1));
if (!LineInLineXZ(startXZ, endXZ, corners[1], corners[0])
&& !LineInLineXZ(startXZ, endXZ, corners[2], corners[0])
@@ -461,19 +500,19 @@ const TBGCheckData* TMapCollisionData::intersectLine(
}
const TBGCheckData* hit = intersectLineList(
getGridRoot14(gridX, gridZ).unk0[0].getNext(), start, end,
getStaticCheckList(gridX, gridZ).getGroundList(), start, end,
front_only, hit_pos);
if (hit)
return hit;
hit = intersectLineList(
getGridRoot14(gridX, gridZ).unk0[2].getNext(), start, end,
getStaticCheckList(gridX, gridZ).getWallList(), start, end,
front_only, hit_pos);
if (hit)
return hit;
hit = intersectLineList(
getGridRoot14(gridX, gridZ).unk0[1].getNext(), start, end,
getStaticCheckList(gridX, gridZ).getRoofList(), start, end,
front_only, hit_pos);
if (hit)
return hit;
+53 -51
View File
@@ -12,13 +12,12 @@ TMapCollisionData* gpMapCollisionData;
TBGCheckList::TBGCheckList()
: mNext(nullptr)
, unk8(0)
, mData(nullptr)
{
}
// TODO: inline deferred or nah?
TBGCheckListWarp::TBGCheckListWarp()
: unkC(0)
: unkC(nullptr)
, unk10(0)
, unk12(0)
{
@@ -26,53 +25,28 @@ TBGCheckListWarp::TBGCheckListWarp()
void TMapCollisionData::initGrid(TBGCheckListRoot* roots)
{
int x = unk10;
int x = mGridCellNum;
while (x--) {
roots->unk0[0].setNext(nullptr);
roots->unk0[1].setNext(nullptr);
roots->unk0[2].setNext(nullptr);
roots->unk0[BG_PLANE_TYPE_GROUND].setNext(nullptr);
roots->unk0[BG_PLANE_TYPE_ROOF].setNext(nullptr);
roots->unk0[BG_PLANE_TYPE_WALL].setNext(nullptr);
roots++;
}
}
void TMapCollisionData::initMoveCollision()
{
unk3C = unk20 - 1;
memset(unk18, 0, unk10 * sizeof(*unk18));
mMoveListTop = unk20 - 1;
memset(mMoveGrid, 0, mGridCellNum * sizeof(*mMoveGrid));
}
void TMapCollisionData::initAllCheckDataAndList() { }
void TMapCollisionData::init(JSUMemoryInputStream& stream)
void TMapCollisionData::initAllCheckDataAndList()
{
s32 value;
stream >> value;
unk8 = value;
stream >> value;
unkC = value;
stream >> value;
unk1C = value;
stream >> value;
unk20 = value;
stream >> value;
unk24 = value;
initGrid(mStaticGrid);
mGridExtentX = (unk8 / 2) * 1024.0f;
mGridExtentY = (unkC / 2) * 1024.0f;
unk10 = unk8 * unkC;
unk14 = new TBGCheckListRoot[unk10];
unk18 = new TBGCheckListRoot[unk10];
unk28 = new TBGCheckData[unk1C];
unk2C = new TBGCheckList[unk20];
unk30 = new TBGCheckListWarp[unk24];
initGrid(unk14);
unk34 = 0;
unk38 = 0;
unk40 = 0;
unk34 = 0;
mStaticListUsed = 0;
unk40 = 0;
initMoveCollision();
@@ -80,30 +54,58 @@ void TMapCollisionData::init(JSUMemoryInputStream& stream)
unk42[i] = 9999;
}
void TMapCollisionData::init(JSUMemoryInputStream& stream)
{
s32 value;
stream >> value;
mGridSizeX = value;
stream >> value;
mGridSizeZ = value;
stream >> value;
unk1C = value;
stream >> value;
unk20 = value;
stream >> value;
unk24 = value;
mGridExtentX = (mGridSizeX / 2) * 1024.0f;
mGridExtentY = (mGridSizeZ / 2) * 1024.0f;
mGridCellNum = mGridSizeX * mGridSizeZ;
mStaticGrid = new TBGCheckListRoot[mGridCellNum];
mMoveGrid = new TBGCheckListRoot[mGridCellNum];
unk28 = new TBGCheckData[unk1C];
mCheckListPool = new TBGCheckList[unk20];
mWarpCheckListPool = new TBGCheckListWarp[unk24];
initAllCheckDataAndList();
}
TMapCollisionData::TMapCollisionData()
: mGridExtentX(0.0f)
, mGridExtentY(0.0f)
, unk8(0)
, unkC(0)
, unk10(0)
, unk14(nullptr)
, unk18(nullptr)
, mGridSizeX(0)
, mGridSizeZ(0)
, mGridCellNum(0)
, mStaticGrid(nullptr)
, mMoveGrid(nullptr)
, unk1C(0)
, unk20(0)
, unk24(0)
, unk28(nullptr)
, unk2C(nullptr)
, unk30(nullptr)
, mCheckListPool(nullptr)
, mWarpCheckListPool(nullptr)
, unk34(0)
, unk38(0)
, unk3C(0)
, mStaticListUsed(0)
, mMoveListTop(0)
, unk40(0)
, unk242(0)
, mGroundPlane(nullptr)
{
JGeometry::TVec3<float> v1(-32767.0f, -32767.0f, -32767.0f);
JGeometry::TVec3<float> v2(-32767.0f, -32767.0f, 32767.0f);
JGeometry::TVec3<float> v3(32767.0f, -32767.0f, 32767.0f);
JGeometry::TVec3<f32> v1(-32767.0f, -32767.0f, -32767.0f);
JGeometry::TVec3<f32> v2(-32767.0f, -32767.0f, 32767.0f);
JGeometry::TVec3<f32> v3(32767.0f, -32767.0f, 32767.0f);
mIllegalCheckData.setVertex(v1, v2, v3);
mIllegalCheckData.mBGType = 0;
mIllegalCheckData.mFlags |= BG_CHECK_FLAG_ILLEGAL;
+5 -5
View File
@@ -16,23 +16,23 @@ f32 TBGCheckData::getActiveJumpPower() const
return mData;
}
u32 TBGCheckData::getPlaneType()
BGPlaneType TBGCheckData::getPlaneType()
{
if (isEverythingButMapObjectsThrough())
return 0;
return BG_PLANE_TYPE_GROUND;
if (mNormal.y > 0.2f)
return 0;
return BG_PLANE_TYPE_GROUND;
if (mNormal.y < -0.2f)
return 1;
return BG_PLANE_TYPE_ROOF;
if (mNormal.x < -0.707f || 0.707f < mNormal.x)
mFlags |= BG_CHECK_FLAG_X_FACING;
else
mFlags &= ~BG_CHECK_FLAG_X_FACING;
return 2;
return BG_PLANE_TYPE_WALL;
}
TBGCheckData::TBGCheckData()
+81 -85
View File
@@ -21,42 +21,39 @@ u32 TMapCollisionData::getEntryID()
return result;
}
#pragma dont_inline on
TBGCheckList* TMapCollisionData::allocCheckList(int kind, int count)
{
TBGCheckList* result;
switch (kind) {
case TMapCollisionBase::KIND_MOVE:
result = &unk2C[unk3C];
unk3C -= count;
result = &mCheckListPool[mMoveListTop];
mMoveListTop -= count;
break;
case TMapCollisionBase::KIND_WARP:
result = &unk30[unk40];
result = &mWarpCheckListPool[unk40];
unk40 += count;
break;
default:
result = &unk2C[unk38];
unk38 += count;
result = &mCheckListPool[mStaticListUsed];
mStaticListUsed += count;
break;
}
return result;
}
#pragma dont_inline off
TBGCheckList* TMapCollisionData::getListRoot(int i, int j, int kind,
int param_4) const
int planeType) const
{
switch (kind) {
case TMapCollisionBase::KIND_WARP:
case TMapCollisionBase::KIND_STATIC:
return &unk14[j + i * unk8].unk0[param_4];
return &mStaticGrid[getCellIndex(j, i)].unk0[planeType];
case TMapCollisionBase::KIND_MOVE:
return &unk18[j + i * unk8].unk0[param_4];
return &mMoveGrid[getCellIndex(j, i)].unk0[planeType];
}
return nullptr;
}
#pragma dont_inline on
static void addAfterPreNode(int param_1, int param_2, TBGCheckList* param_3,
TBGCheckList* param_4, int kind)
{
@@ -80,9 +77,9 @@ static TBGCheckList* addWallNode(TBGCheckList* param_1, TBGCheckData* param_2)
TBGCheckList* next;
while (param_1->getNext()) {
next = param_1->getNext();
if (param_2->mMaxY > next->unk8->mMaxY
|| (param_2->mMaxY == next->unk8->mMaxY
&& param_2->mMinY > next->unk8->mMinY))
if (param_2->mMaxY > next->mData->mMaxY
|| (param_2->mMaxY == next->mData->mMaxY
&& param_2->mMinY > next->mData->mMinY))
return param_1;
param_1 = next;
}
@@ -94,9 +91,9 @@ static TBGCheckList* addRoofNode(TBGCheckList* param_1, TBGCheckData* param_2)
TBGCheckList* next;
while (param_1->getNext()) {
next = param_1->getNext();
if (param_2->mMaxY < next->unk8->mMaxY
|| (param_2->mMaxY == next->unk8->mMaxY
&& param_2->mMinY < next->unk8->mMinY))
if (param_2->mMaxY < next->mData->mMaxY
|| (param_2->mMaxY == next->mData->mMaxY
&& param_2->mMinY < next->mData->mMinY))
return param_1;
param_1 = next;
}
@@ -108,109 +105,108 @@ static TBGCheckList* addGroundNode(TBGCheckList* param_1, TBGCheckData* param_2)
TBGCheckList* next;
while (param_1->getNext()) {
next = param_1->getNext();
if (param_2->mMinY > next->unk8->mMinY
|| (param_2->mMinY == next->unk8->mMinY
&& param_2->mMaxY > next->unk8->mMaxY))
if (param_2->mMinY > next->mData->mMinY
|| (param_2->mMinY == next->mData->mMinY
&& param_2->mMaxY > next->mData->mMaxY))
return param_1;
param_1 = next;
}
return param_1;
}
#pragma dont_inline off
void TMapCollisionData::addCheckDataToList(int i, int j, int param_3,
int param_4, TBGCheckData* param_5)
int planeType, TBGCheckData* param_5)
{
TBGCheckList* list = getListRoot(i, j, param_3, param_4);
TBGCheckList* list = getListRoot(i, j, param_3, planeType);
TBGCheckList* list2;
switch (param_4) {
case 0:
switch (planeType) {
case BG_PLANE_TYPE_GROUND:
list2 = addGroundNode(list, param_5);
break;
case 1:
case BG_PLANE_TYPE_ROOF:
list2 = addRoofNode(list, param_5);
break;
case 2:
case BG_PLANE_TYPE_WALL:
list2 = addWallNode(list, param_5);
break;
}
TBGCheckList* list3 = allocCheckList(param_3, 1);
list3->unk8 = param_5;
list3->mData = param_5;
addAfterPreNode(j, i, list2, list3, param_3);
}
bool TMapCollisionData::getGridArea(const TBGCheckData* param_1, int param_2,
int* param_3, int* param_4, int* param_5,
int* param_6)
bool TMapCollisionData::getGridArea(const TBGCheckData* data, int plane_type,
int* grid_min_x, int* grid_min_z,
int* grid_max_x, int* grid_max_z)
{
f32 minX = MsMin(param_1->mPoint1.x,
MsMin(param_1->mPoint2.x, param_1->mPoint3.x));
f32 minZ = MsMin(param_1->mPoint1.z,
MsMin(param_1->mPoint3.z, param_1->mPoint2.z));
f32 minX = MsMin(data->getPoint1().x,
MsMin(data->getPoint2().x, data->getPoint3().x));
f32 minZ = MsMin(data->getPoint1().z,
MsMin(data->getPoint2().z, data->getPoint3().z));
f32 maxX = MsMax(param_1->mPoint1.x,
MsMax(param_1->mPoint2.x, param_1->mPoint3.x));
f32 maxZ = MsMax(param_1->mPoint1.z,
MsMax(param_1->mPoint2.z, param_1->mPoint3.z));
f32 maxX = MsMax(data->getPoint1().x,
MsMax(data->getPoint2().x, data->getPoint3().x));
f32 maxZ = MsMax(data->getPoint1().z,
MsMax(data->getPoint2().z, data->getPoint3().z));
if (maxX < -mGridExtentX || maxZ < -mGridExtentY || minX > mGridExtentX
|| minZ > mGridExtentY)
return false;
if (param_2 == 2) {
if (plane_type == BG_PLANE_TYPE_WALL) {
minX -= 80.0f;
minZ -= 80.0f;
maxX += 80.0f;
maxZ += 80.0f;
}
*param_3 = (minX + mGridExtentX) * 0.0009765625f;
if (*param_3 < 0)
*param_3 = 0;
*grid_min_x = worldToGridX(minX);
if (*grid_min_x < 0)
*grid_min_x = 0;
*param_5 = (maxX + mGridExtentX) * 0.0009765625f;
if (*param_5 >= unk8)
*param_5 = unk8 - 1;
*grid_max_x = worldToGridX(maxX);
if (*grid_max_x >= mGridSizeX)
*grid_max_x = mGridSizeX - 1;
*param_4 = (minZ + mGridExtentY) * 0.0009765625f;
if (*param_4 < 0)
*param_4 = 0;
*grid_min_z = worldToGridZ(minZ);
if (*grid_min_z < 0)
*grid_min_z = 0;
*param_6 = (maxZ + mGridExtentY) * 0.0009765625f;
if (*param_6 >= unkC)
*param_6 = unkC - 1;
*grid_max_z = worldToGridZ(maxZ);
if (*grid_max_z >= mGridSizeZ)
*grid_max_z = mGridSizeZ - 1;
return true;
}
void TMapCollisionData::addCheckDataToGrid(TBGCheckData* param_1, int kind)
void TMapCollisionData::addCheckDataToGrid(TBGCheckData* data, int kind)
{
int iVar7 = param_1->getPlaneType();
int local_ac;
int local_b4;
int local_b0;
int local_b8;
if (getGridArea(param_1, iVar7, &local_ac, &local_b4, &local_b0,
&local_b8)) {
for (int i = local_b4; i <= local_b8; ++i) {
for (int j = local_ac; j <= local_b0; ++j) {
int planeType = data->getPlaneType();
int gridMinX;
int gridMinZ;
int gridMaxX;
int gridMaxZ;
if (getGridArea(data, planeType, &gridMinX, &gridMinZ, &gridMaxX,
&gridMaxZ)) {
for (int z = gridMinZ; z <= gridMaxZ; ++z) {
for (int x = gridMinX; x <= gridMaxX; ++x) {
if (kind == TMapCollisionBase::KIND_MOVE) {
addCheckDataToList(i, j, kind, iVar7, param_1);
} else if (iVar7 != 2) {
int iVar1 = (i + 1) * 1024.0f - mGridExtentY;
int iVar2 = (i * 1024.0f) - mGridExtentY;
int iVar3 = (j + 1) * 1024.0f - mGridExtentX;
int iVar4 = j * 1024.0f - mGridExtentX;
if (polygonIsInGrid(iVar4, iVar2, iVar3, iVar1, param_1))
addCheckDataToList(i, j, kind, iVar7, param_1);
addCheckDataToList(z, x, kind, planeType, data);
} else if (planeType != BG_PLANE_TYPE_WALL) {
f32 maxZ = gridToWorldZ(z + 1);
f32 maxX = gridToWorldX(x + 1);
f32 minZ = gridToWorldZ(z);
f32 minX = gridToWorldX(x);
if (polygonIsInGrid(minX, minZ, maxX, maxZ, data))
addCheckDataToList(z, x, kind, planeType, data);
} else {
int iVar1 = (i + 1) * 1024.0f - mGridExtentY;
int iVar2 = (i * 1024.0f) - mGridExtentY;
int iVar3 = (j + 1) * 1024.0f - mGridExtentX;
int iVar4 = j * 1024.0f - mGridExtentX;
if (polygonIsInGrid(iVar4 - 80.0f, iVar2 - 80.0f,
iVar3 + 80.0f, iVar1 + 80.0f, param_1))
addCheckDataToList(i, j, kind, iVar7, param_1);
f32 maxZ = gridToWorldZ(z + 1);
f32 maxX = gridToWorldX(x + 1);
f32 minZ = gridToWorldZ(z);
f32 minX = gridToWorldX(x);
if (polygonIsInGrid(minX - 80.0f, minZ - 80.0f,
maxX + 80.0f, maxZ + 80.0f, data))
addCheckDataToList(z, x, kind, planeType, data);
}
}
}
@@ -220,26 +216,26 @@ void TMapCollisionData::addCheckDataToGrid(TBGCheckData* param_1, int kind)
void TMapCollisionData::removeCheckListNode(s32 start, s32 end)
{
for (s32 i = start; i < end; ++i) {
TBGCheckListWarp* curr = &unk30[i];
TBGCheckListWarp* curr = &mWarpCheckListPool[i];
curr->getPreNode()->setNext(curr->getNext());
if (curr->getNext() != nullptr)
curr->getNext()->setPreNode(curr->getPreNode());
curr->unk8 = nullptr;
curr->mData = nullptr;
}
}
void TMapCollisionData::updateCheckListNode(s32 param_1, s32 param_2,
s32 param_3)
{
TBGCheckListWarp* l = &unk30[param_3];
TBGCheckListWarp* r = &unk30[param_1];
TBGCheckListWarp* end = &unk30[param_3 + param_2];
TBGCheckListWarp* l = &mWarpCheckListPool[param_3];
TBGCheckListWarp* r = &mWarpCheckListPool[param_1];
TBGCheckListWarp* end = &mWarpCheckListPool[param_3 + param_2];
// TODO: I think this is a fakematch.
u32 offset = ((u32)l - (u32)r);
for (int i = param_1; i < param_1 + param_2; ++i) {
TBGCheckListWarp* warp2 = &unk30[i];
TBGCheckListWarp* warp2 = &mWarpCheckListPool[i];
TBGCheckListWarp* warp3 = (TBGCheckListWarp*)warp2->getNext();
if (l <= warp3 && warp3 < end)
warp2->setNext((TBGCheckListWarp*)((char*)warp3 - offset));
@@ -250,7 +246,7 @@ void TMapCollisionData::updateCheckListNode(s32 param_1, s32 param_2,
}
for (int i = param_1; i < param_1 + param_2; ++i) {
TBGCheckListWarp* warp4 = &unk30[i];
TBGCheckListWarp* warp4 = &mWarpCheckListPool[i];
warp4->getPreNode()->setNext(warp4);
if (warp4->getNext())
warp4->getNext()->setPreNode(warp4);
@@ -280,7 +276,7 @@ void TMapCollisionData::removeCheckListData(u16 start, s32 count)
unk40 -= count;
memmove(&unk30[rangeStart], &unk30[rangeEnd],
memmove(&mWarpCheckListPool[rangeStart], &mWarpCheckListPool[rangeEnd],
(unk40 + count - rangeStart) * sizeof(TBGCheckListWarp));
updateCheckListNode(rangeStart, unk40 - rangeStart, rangeEnd);