Files
ss/include/nw4r/g3d/g3d_scnobj.h
T
Elijah Thomas 9c3c480b24 g3d source (#123)
* g3d_calcvtx

GetData seems to have changed -> dwarf says r is a local and using ofs_to_ptr didnt work

* g3d_light and g3d_fog

sdata2 splits and func ordering

* g3d_scnproc

* g3d_init

* g3d_scnmdl

* g3d_scnmdlsmpl

* g3d_scnroot

* g3d_scnobj

* g3d_res* progress

* g3d_resmdl OK

* g3d_restev OK

* g3d_resmat OK

* g3d_resvtx and g3d_restex OK

* g3d_resnode OK

* g3d_resanm OK

* g3d_resanmchr Progress

* the rest of g3d_res* OK

* g3d_anmvis OK

* g3d_anmclr OK

* Some Splitting

* more OK, Inline Issue in g3d_anmtexsrt

* g3d_obj, g3d_anmobj, g3d_gpu, g3d_tmem, g3d_cpu OK

* g3d_state OK

* g3d/dcc OK

* Include fixup

* More Fixups

* g3d_camera OK

* g3d_draw OK

* g3d_calcworld OK

* g3d_calcworld actually OK

* g3d_workmem, g3d_dcc OK

* g3d_calcview OK

* g3d_anmtexsrt OK with DONT_INLINE

* g3d_transform OK (Feels Cheaty)

* g3d_resanmchr OK

* g3d_draw1mat1shp Close

* g3d_draw1mat1shp OK (Thanks Lago!). Ran symbol applying script
2025-03-16 11:26:15 -04:00

452 lines
14 KiB
C++

#ifndef NW4R_G3D_SCN_OBJ_H
#define NW4R_G3D_SCN_OBJ_H
#include <nw4r/types_nw4r.h>
#include "nw4r/g3d/g3d_obj.h"
#include "nw4r/math.h" // IWYU pragma: export
namespace nw4r {
namespace g3d {
extern const math::FRUSTUM *gpCullingFrustum;
enum ResMdlDrawMode {
RESMDL_DRAWMODE_SORT_OPA_NONE = 0,
RESMDL_DRAWMODE_SORT_OPA_Z = (1 << 0),
RESMDL_DRAWMODE_SORT_XLU_NONE = 0,
RESMDL_DRAWMODE_SORT_XLU_Z = (1 << 1),
RESMDL_DRAWMODE_IGNORE_MATERIAL = (1 << 2),
RESMDL_DRAWMODE_FORCE_LIGHTOFF = (1 << 3),
RESMDL_DRAWMODE_NOPPCSYNC = (1 << 4),
RESMDL_DRAWMODE_DEFAULT = RESMDL_DRAWMODE_SORT_XLU_Z,
REDMDL_DRAWMODE_SORT_NONE = 0,
RESMDL_DRAWMODE_SORT_Z = RESMDL_DRAWMODE_SORT_OPA_Z | RESMDL_DRAWMODE_SORT_XLU_Z,
};
/******************************************************************************
*
* ScnObj
*
******************************************************************************/
// Forward declarations
class IScnObjCallback;
class ScnObj : public G3dObj {
public:
enum ForEachResult {
FOREACHRESULT_OK,
FOREACHRESULT_CONTINUE,
FOREACHRESULT_RETURN,
FOREACHRESULT_GOBACK
};
typedef ForEachResult (*ForEachFunc)(ScnObj *pParent, void *pInfo);
enum ScnObjMtxType {
MTX_LOCAL,
MTX_WORLD,
MTX_VIEW,
MTX_TYPE_MAX
};
enum ScnObjBoundingVolumeType {
BOUNDINGVOLUME_AABB_LOCAL,
BOUNDINGVOLUME_AABB_WORLD,
BOUNDINGVOLUME_MAX
};
#define OPT(KEY, VALUE) OPTION_##KEY = (0x00000 | (VALUE))
enum ScnObjOption {
OPT(NONE, 0),
OPT(DISABLE_GATHER_SCNOBJ, 1),
OPT(DISABLE_CALC_WORLD, 2),
OPT(DISABLE_CALC_MAT, 3),
OPT(DISABLE_CALC_VTX, 4),
OPT(DISABLE_CALC_VIEW, 5),
OPT(DISABLE_DRAW_OPA, 6),
OPT(DISABLE_DRAW_XLU, 7),
OPT(DISABLE_UPDATEFRAME, 8),
OPT(ENABLE_CULLING, 9),
};
#undef OPT
enum Timing {
CALLBACK_TIMING_A = (1 << 0),
CALLBACK_TIMING_B = (1 << 1),
CALLBACK_TIMING_C = (1 << 2)
};
enum ExecOp {
EXECOP_CALC_WORLD = (1 << 0),
EXECOP_CALC_MAT = (1 << 1),
EXECOP_CALC_VIEW = (1 << 2),
EXECOP_DRAW_OPA = (1 << 4),
EXECOP_DRAW_XLU = (1 << 5)
};
public:
explicit ScnObj(MEMAllocator *pAllocator);
virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC
virtual ~ScnObj(); // at 0x10
virtual ForEachResult ForEach(ForEachFunc pFunc, void *pInfo,
bool postOrder) = 0; // at 0x1C
virtual bool SetScnObjOption(u32 option, u32 value); // at 0x20
virtual bool GetScnObjOption(u32 option, u32 *pValue) const; // at 0x24
virtual f32 GetValueForSortOpa() const; // at 0x28
virtual f32 GetValueForSortXlu() const; // at 0x2C
virtual void CalcWorldMtx(const math::MTX34 *pParent,
u32 *pParam); // at 0x30
void CalcViewMtx(const math::MTX34 *pCamera);
bool SetMtx(ScnObjMtxType type, const math::MTX34 *pMtx);
bool SetMtx(ScnObjMtxType type, const math::MTX34 &rMtx);
bool GetMtx(ScnObjMtxType type, math::MTX34 *pMtx) const;
const math::MTX34 *GetMtxPtr(ScnObjMtxType type) const {
return &mMtxArray[type];
}
void SetPriorityDrawOpa(int prio);
int GetPriorityDrawOpa() const {
return mPriorityDrawOpa;
}
void SetPriorityDrawXlu(int prio);
int GetPriorityDrawXlu() const {
return mPriorityDrawXlu;
}
void EnableScnObjCallbackTiming(Timing timing);
void DisableScnObjCallbackTiming(Timing timing);
void EnableScnObjCallbackExecOp(ExecOp op);
bool SetBoundingVolume(ScnObjBoundingVolumeType type, const math::AABB *pAABB);
bool GetBoundingVolume(ScnObjBoundingVolumeType type, math::AABB *pAABB) const;
bool SetBoundingVolume(const math::AABB *pAABB) {
return SetBoundingVolume(BOUNDINGVOLUME_AABB_LOCAL, pAABB);
}
void SetCallback(IScnObjCallback *cb) {
mpFuncObjExec = cb;
}
IScnObjCallback *GetScnObjCallback() {
return mpFuncObjExec;
}
protected:
enum ScnObjFlag {
SCNOBJFLAG_DISABLE_CALC_WORLD = (1 << 0),
SCNOBJFLAG_DISABLE_CALC_MAT = (1 << 1),
SCNOBJFLAG_DISABLE_CALC_VTX = (1 << 2),
SCNOBJFLAG_DISABLE_CALC_VIEW = (1 << 3),
SCNOBJFLAG_DISABLE_GATHER_SCNOBJ = (1 << 4),
SCNOBJFLAG_DISABLE_DRAW_OPA = (1 << 5),
SCNOBJFLAG_DISABLE_DRAW_XLU = (1 << 6),
SCNOBJFLAG_DISABLE_UPDATEFRAME = (1 << 7),
SCNOBJFLAG_IGNORE_ANMCHR_TRANS = (1 << 8),
SCNOBJFLAG_ENABLE_CULLING = (1 << 28),
SCNOBJFLAG_NOT_GATHER_DRAW_OPA = (1 << 29),
SCNOBJFLAG_NOT_GATHER_DRAW_XLU = (1 << 30),
SCNOBJFLAG_MTX_LOCAL_IDENTITY = (1 << 31),
SCNOBJFLAG_DISABLE_DRAW = SCNOBJFLAG_DISABLE_DRAW_OPA | SCNOBJFLAG_DISABLE_DRAW_XLU
};
protected:
void SetScnObjFlag(ScnObjFlag flag, u32 on) {
if (on) {
mScnObjFlags |= flag;
} else {
mScnObjFlags &= ~flag;
}
}
u32 TestScnObjFlag(ScnObjFlag flag) const {
return (mScnObjFlags & flag) != 0;
}
bool IsG3dProcDisabled(u32 task) const {
if (task < __G3DPROC_OPTIONAL_END && ((1 << (task - 1)) & mScnObjFlags)) {
return true;
}
return false;
}
/**
* Defined elsewhere to resolve circular dependency with IScnObjCallback
*/
inline void CheckCallback_CALC_VIEW(Timing timing, u32 param, void *pInfo);
inline void CheckCallback_CALC_MAT(Timing timing, u32 param, void *pInfo);
inline void CheckCallback_CALC_WORLD(Timing timing, u32 param, void *pInfo);
inline void CheckCallback_DRAW_OPA(Timing timing, u32 param, void *pInfo);
inline void CheckCallback_DRAW_XLU(Timing timing, u32 param, void *pInfo);
protected:
math::MTX34 mMtxArray[MTX_TYPE_MAX]; // at 0xC
math::AABB mAABB[BOUNDINGVOLUME_MAX]; // at 0x9C
private:
u32 mScnObjFlags; // at 0xCC
u8 mPriorityDrawOpa; // at 0xD0
u8 mPriorityDrawXlu; // at 0xD1
u8 PADDING_0xD2; // at 0xD2
u8 PADDING_0xD3; // at 0xD3
IScnObjCallback *mpFuncObjExec; // at 0xD4
u8 mCallbackTiming; // at 0xD8
u8 mCallbackDeleteOption; // at 0xD9
u16 mCallbackExecOpMask; // at 0xDA
NW4R_G3D_RTTI_DECL_DERIVED(ScnObj, G3dObj);
};
/******************************************************************************
*
* IScnObjGather
*
******************************************************************************/
class IScnObjGather {
public:
typedef bool (*LessThanFunc)(const ScnObj *pLhs, const ScnObj *pRhs);
enum CullingStatus {
CULLINGSTATUS_INTERSECT,
CULLINGSTATUS_INSIDE,
CULLINGSTATUS_OUTSIDE,
CULLINGSTATUS_NOTEST
};
enum CheckStatus {
CHECKSTATUS_GATHER_SCNOBJ,
CHECKSTATUS_IGNORE_SCNOBJ
};
public:
virtual ~IScnObjGather() {} // at 0x8
virtual CullingStatus Add(ScnObj *pObj, bool opa, bool xlu) = 0; // at 0xC
virtual void Clear() = 0; // at 0x10
virtual void ZSort() = 0; // at 0x14
virtual void Sort() = 0; // at 0x18
virtual void Sort(LessThanFunc pOpaFunc,
LessThanFunc pXluFunc) = 0; // at 0x1C
virtual void DrawOpa(ResMdlDrawMode *pForceMode) = 0; // at 0x20
virtual void DrawXlu(ResMdlDrawMode *pForceMode) = 0; // at 0x24
};
/******************************************************************************
*
* IScnObjCallback
*
******************************************************************************/
class IScnObjCallback {
public:
virtual ~IScnObjCallback() {} // at 0x8
virtual void
ExecCallback_CALC_WORLD(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) {
} // at 0xC
virtual void
ExecCallback_CALC_MAT(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) {
} // at 0x10
virtual void
ExecCallback_CALC_VIEW(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) {
} // at 0x14
virtual void
ExecCallback_DRAW_OPA(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) {
} // at 0x18
virtual void
ExecCallback_DRAW_XLU(ScnObj::Timing /* timing */, ScnObj * /* pObj */, u32 /* param */, void * /* pInfo */) {
} // at 0x1C
};
/******************************************************************************
*
* ScnObj implementation
*
******************************************************************************/
void ScnObj::CheckCallback_CALC_VIEW(Timing timing, u32 param, void *pInfo) {
if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_CALC_VIEW) && (mCallbackTiming & timing)) {
mpFuncObjExec->ExecCallback_CALC_VIEW(timing, this, param, pInfo);
}
}
void ScnObj::CheckCallback_CALC_MAT(Timing timing, u32 param, void *pInfo) {
if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_CALC_MAT) && (mCallbackTiming & timing)) {
mpFuncObjExec->ExecCallback_CALC_MAT(timing, this, param, pInfo);
}
}
void ScnObj::CheckCallback_CALC_WORLD(Timing timing, u32 param, void *pInfo) {
if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_CALC_WORLD) && (mCallbackTiming & timing)) {
mpFuncObjExec->ExecCallback_CALC_WORLD(timing, this, param, pInfo);
}
}
void ScnObj::CheckCallback_DRAW_OPA(Timing timing, u32 param, void *pInfo) {
if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_DRAW_OPA) && (mCallbackTiming & timing)) {
mpFuncObjExec->ExecCallback_DRAW_OPA(timing, this, param, pInfo);
}
}
void ScnObj::CheckCallback_DRAW_XLU(Timing timing, u32 param, void *pInfo) {
if (mpFuncObjExec != NULL && (mCallbackExecOpMask & EXECOP_DRAW_XLU) && (mCallbackTiming & timing)) {
mpFuncObjExec->ExecCallback_DRAW_XLU(timing, this, param, pInfo);
}
}
/******************************************************************************
*
* ScnLeaf
*
******************************************************************************/
class ScnLeaf : public ScnObj {
public:
enum ScaleProperty {
NOT_SCALED,
UNIFORM_SCALED,
NONUNIFORM_SCALED,
};
#define OPT(KEY, VALUE) OPTION_##KEY = (0x10000 | (VALUE))
enum ScnLeafOption {
OPT(NONE, 0),
OPT(DISABLE_DRAW_ALL, 1),
};
#undef OPT
public:
explicit ScnLeaf(MEMAllocator *pAllocator) : ScnObj(pAllocator), mScale(1.0f, 1.0f, 1.0f) {}
virtual void G3dProc(u32 task, u32 param, void *pInfo) = 0; // at 0xC
virtual ~ScnLeaf() {} // at 0x10
virtual ForEachResult ForEach(ForEachFunc pFunc, void *pInfo,
bool postOrder); // at 0x1C
virtual bool SetScnObjOption(u32 option, u32 value); // at 0x20
virtual bool GetScnObjOption(u32 option, u32 *pValue) const; // at 0x24
virtual void CalcWorldMtx(const math::MTX34 *pParent,
u32 *pParam); // at 0x30
ScaleProperty GetScaleProperty() const;
inline void SetScale(f32 x, f32 y, f32 z) {
mScale.x = x;
mScale.y = y;
mScale.z = z;
}
inline void SetScale(const math::VEC3 &scale) {
mScale = scale;
}
inline void GetScale(math::VEC3 *scale) const {
if (scale) {
*scale = mScale;
}
}
protected:
void DefG3dProcScnLeaf(u32 task, u32 param, void *pInfo);
private:
math::VEC3 mScale; // at 0xDC
NW4R_G3D_RTTI_DECL_DERIVED(ScnLeaf, ScnObj);
};
/******************************************************************************
*
* ScnGroup
*
******************************************************************************/
class ScnGroup : public ScnObj {
public:
ScnGroup(MEMAllocator *pAllocator, ScnObj **ppObj, u32 capacity);
virtual void G3dProc(u32 task, u32 param, void *pInfo); // at 0xC
virtual ~ScnGroup(); // at 0x10
virtual ForEachResult ForEach(ForEachFunc pFunc, void *pInfo,
bool postOrder); // at 0x1C
virtual bool Insert(u32 idx, ScnObj *pObj); // at 0x34
virtual ScnObj *Remove(u32 idx); // at 0x38
virtual bool Remove(ScnObj *pObj); // at 0x3C
ScnObj **Begin() {
return mpScnObjArray;
}
ScnObj **End() {
return mpScnObjArray + mNumScnObj;
}
ScnObj *operator[](u32 idx) {
return mpScnObjArray[idx];
}
u32 Size() const {
return mNumScnObj;
}
bool Empty() const {
return mNumScnObj == 0;
}
bool PushBack(ScnObj *pObj) {
return Insert(mNumScnObj, pObj);
}
ScnObj *PopBack() {
if (!Empty()) {
return Remove(Size() - 1);
}
return NULL;
}
void Clear() {
while (!Empty()) {
PopBack();
}
}
protected:
void DefG3dProcScnGroup(u32 task, u32 param, void *pInfo);
private:
void ScnGroup_G3DPROC_GATHER_SCNOBJ(u32 param, IScnObjGather *pCollection);
void ScnGroup_G3DPROC_CALC_WORLD(u32 param, const math::MTX34 *pParent);
void ScnGroup_G3DPROC_CALC_MAT(u32 param, void *pInfo);
void ScnGroup_G3DPROC_CALC_VIEW(u32 param, const math::MTX34 *pCamera);
private:
ScnObj **mpScnObjArray; // at 0xDC
u32 mSizeScnObj; // at 0xE0
u32 mNumScnObj; // at 0xE4
NW4R_G3D_RTTI_DECL_DERIVED(ScnGroup, ScnObj);
};
} // namespace g3d
} // namespace nw4r
#endif