Files
sms/include/Map/MapCollisionData.hpp
Roman Sandu d9521bbb35 TVec3 but no UB (#382)
* TVec3 but no UB

* formatting

* TMario::pulling closer

* Small fixes
2026-11-01 17:09:52 +03:00

234 lines
6.5 KiB
C++

#ifndef MAP_MAP_COLLISION_DATA_HPP
#define MAP_MAP_COLLISION_DATA_HPP
#include <JSystem/JGeometry.hpp>
#include <Map/MapData.hpp>
class JSUMemoryInputStream;
class TBGCheckData;
class TMapCheckGroundPlane;
class TBGCheckList {
public:
TBGCheckList();
virtual void setPreNode(TBGCheckList*) { }
// fabricated
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* mData;
};
class TBGCheckListWarp : public TBGCheckList {
public:
TBGCheckListWarp();
virtual void setPreNode(TBGCheckList* node)
{
// TODO: maybe unkC is TBGCheckList*?
unkC = (TBGCheckListWarp*)node;
}
// fabricated
TBGCheckListWarp* getPreNode() { return unkC; }
public:
/* 0xC */ TBGCheckListWarp* unkC;
/* 0x10 */ s16 unk10;
/* 0x12 */ s16 unk12;
};
class TBGCheckListRoot {
public:
TBGCheckListRoot() { }
// fabricated
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];
};
/**
* @brief Temporary struct used for querying for collisions with walls.
* Given a sphere of radius mRadius located at mCenter, finds up to 4
* walls (triangles) that intersect with it while respecting ignore flags
* and returns the intersecting walls via mResultWalls and mResultWallsNum.
* By default, also modifies X and Z of mCenter to "move" the sphere outside of
* each returned wall. This is done in-order and only guarantees that the LAST
* of the walls returned will not intersect with the sphere if placed at the
* updated position. Walls other than the last one MIGHT intersect it.
*/
struct TBGWallCheckRecord {
enum {
IGNORE_WATER_SURFACE = 0x1,
DONT_MOVE_XZ = 0x2,
IGNORE_WATER_THROUGH = 0x4,
};
// TODO: the constructors are 99% wrong, need to analyze a bunch of
// use-cases. Maybe this was a plain old struct with no methods?
// fabricated
TBGWallCheckRecord() { }
// fabricated
TBGWallCheckRecord(f32 x, f32 y, f32 z, f32 radius, u32 max_results,
u32 flags)
: mCenter(x, y, z)
, mRadius(radius)
, mMaxResults(max_results)
, mFlags(flags)
{
}
// fabricated
TBGWallCheckRecord(const JGeometry::TVec3<f32>& center, f32 radius,
u32 max_results, u32 flags)
: mCenter(center)
, mRadius(radius)
, mMaxResults(max_results)
, mFlags(flags)
{
}
// fabricated
void set(f32 x, f32 y, f32 z, f32 radius, u32 max_results, u32 flags)
{
mCenter.set(x, y, z);
mRadius = radius;
mMaxResults = max_results;
mFlags = flags;
}
// fabricated
const JGeometry::TVec3<f32>& getCenter() const { return mCenter; }
int getMaxResults() const { return mMaxResults; }
TBGCheckData* getResultWall(int index) const { return mResultWalls[index]; }
public:
/* 0x0 */ JGeometry::TVec3<f32> mCenter;
/* 0xC */ f32 mRadius;
/* 0x10 */ int mMaxResults;
/* 0x14 */ int mResultWallsNum;
/* 0x18 */ u32 mFlags;
/* 0x1C */ TBGCheckData* mResultWalls[4];
};
class TMapCollisionData;
extern TMapCollisionData* gpMapCollisionData;
class TMapCollisionData {
public:
enum {
IGNORE_WATER_SURFACE = 0x1,
IGNORE_WATER_THROUGH = 0x4,
};
// fabricated
static TMapCollisionData* getInstance() { return gpMapCollisionData; }
TMapCollisionData();
bool polygonIsInGrid(f32, f32, f32, f32, TBGCheckData*);
const TBGCheckData* intersectLine(const JGeometry::TVec3<f32>&,
const JGeometry::TVec3<f32>&, bool,
JGeometry::TVec3<f32>*) const;
f32 checkGround(f32 x, f32 y, f32 z, u8 flags,
const TBGCheckData** result) const;
static f32 checkGroundList(f32 x, f32 y, f32 z, u8 flags,
const TBGCheckList*,
const TBGCheckData** result);
f32 checkRoof(f32 x, f32 y, f32 z, u8 flags,
const TBGCheckData** result) const;
static f32 checkRoofList(f32 x, f32 y, f32 z, u8 flags, const TBGCheckList*,
const TBGCheckData** result);
int checkWalls(TBGWallCheckRecord*) const;
static int checkWallList(const TBGCheckList*, TBGWallCheckRecord*);
void init(JSUMemoryInputStream&);
void initAllCheckDataAndList();
void initMoveCollision();
void initGrid(TBGCheckListRoot*);
void removeCheckListData(u16 start, s32 count);
void updateCheckListNode(s32, s32, s32);
void removeCheckListNode(s32, s32);
void addCheckDataToGrid(TBGCheckData*, int);
bool getGridArea(const TBGCheckData*, int, int*, int*, int*, int*);
void addCheckDataToList(int, int, int, int, TBGCheckData*);
TBGCheckList* getListRoot(int, int, int, int) const;
TBGCheckList* allocCheckList(int type, int count);
u32 getEntryID();
TBGCheckData* allocCheckData(u32 count);
static TBGCheckData mIllegalCheckData;
// fabricated
u32 getEntrySize(u16 entry_id) const { return unk40 - unk42[entry_id]; }
int getCellIndex(int x, int z) const { return x + z * mGridSizeX; }
const TBGCheckListRoot& getStaticCheckList(int x, int z) const
{
return mStaticGrid[getCellIndex(x, z)];
}
const TBGCheckListRoot& getMoveCheckList(int x, int z) const
{
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]; }
public:
/* 0x0 */ f32 mGridExtentX;
/* 0x4 */ f32 mGridExtentY;
/* 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* mCheckListPool;
/* 0x30 */ TBGCheckListWarp* mWarpCheckListPool;
/* 0x34 */ u32 unk34;
/* 0x38 */ u32 mStaticListUsed;
/* 0x3C */ u32 mMoveListTop;
/* 0x40 */ u16 unk40;
/* 0x42 */ u16 unk42[256];
/* 0x242 */ u16 unk242;
/* 0x244 */ TMapCheckGroundPlane* mGroundPlane;
};
#endif