diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index a23f47c7..1c73867d 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2284,6 +2284,7 @@ egg/gfx/eggLightTextureMgr.cpp: egg/gfx/eggModelEx.cpp: .text start:0x804AE650 end:0x804AEC20 + .rodata start:0x804FBD08 end:0x804FBD50 .data start:0x8056F110 end:0x8056F120 .sdata start:0x80574F48 end:0x80574F60 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3cb741c6..ae89f5f3 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -26423,10 +26423,10 @@ attachPalette__Q23EGG7TextureFPQ23EGG7Palette = .text:0x8049CD60; // type:functi initTexObj__Q23EGG7TextureFv = .text:0x8049CDA0; // type:function size:0xF0 initTexObj__Q23EGG7TextureF7_GXTlut = .text:0x8049CE90; // type:function size:0xF8 load__Q23EGG7TextureF11_GXTexMapID = .text:0x8049CF90; // type:function size:0x54 -FUN_8049cff0 = .text:0x8049CFF0; // type:function size:0x12C -FUN_8049d120 = .text:0x8049D120; // type:function size:0x590 +__ct__Q23EGG9AnalizeDLFQ34nw4r3g3d6ResShp = .text:0x8049CFF0; // type:function size:0x12C +step__Q23EGG9AnalizeDLFv = .text:0x8049D120; // type:function size:0x590 FUN_8049d6b0 = .text:0x8049D6B0; // type:function size:0xB8 -FUN_8049d770 = .text:0x8049D770; // type:function size:0x8 +getVtxResult__Q23EGG9AnalizeDLCFv = .text:0x8049D770; // type:function size:0x8 FUN_8049d780 = .text:0x8049D780; // type:function size:0x40 configure__Q23EGG10CapTextureFv = .text:0x8049D7C0; // type:function size:0x7C capture__Q23EGG10CapTextureFUsUsbi = .text:0x8049D840; // type:function size:0x184 @@ -26564,12 +26564,12 @@ __sinit_\eggFrustum_cpp = .text:0x804A6830; // type:function size:0x24 scope:loc FUN_804a6860 = .text:0x804A6860; // type:function size:0x104 FUN_804a6970 = .text:0x804A6970; // type:function size:0x34 setUpLightSet__Q23EGG10G3DUtilityFRQ34nw4r3g3d12LightSettingQ34nw4r3g3d9ResAnmScni = .text:0x804A69B0; // type:function size:0x1E8 -FUN_804a6ba0 = .text:0x804A6BA0; // type:function size:0x104 -FUN_804a6cb0 = .text:0x804A6CB0; // type:function size:0x104 -FUN_804a6dc0 = .text:0x804A6DC0; // type:function size:0x144 +searchStringResNode__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6BA0; // type:function size:0x104 +searchStringResMat__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6CB0; // type:function size:0x104 +searchStringResTexPlttInfo__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMdlPCcPUsUl = .text:0x804A6DC0; // type:function size:0x144 SetTexture__Q23EGG10G3DUtilityFQ34nw4r3g3d6ResMatPQ44nw4r3g3d6ScnMdl15CopiedMatAccessPCcP9_GXTexObjbPQ33EGG10G3DUtility16SetTextureResultii = .text:0x804A6F10; // type:function size:0x350 FUN_804a7260 = .text:0x804A7260; // type:function size:0x31C -FUN_804a7580 = .text:0x804A7580; // type:function size:0x30 +GetWorldMtxArray__Q23EGG10G3DUtilityFii = .text:0x804A7580; // type:function size:0x30 __dt__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75B0; // type:function size:0x40 __ct__Q33EGG9GfxEngine13ConfigurationFv = .text:0x804A75F0; // type:function size:0x154 beginDrawView__Q23EGG15GlobalDrawStateFUsRCQ34nw4r4math5MTX34RCQ23EGG6Screen = .text:0x804A7750; // type:function size:0x3C @@ -26686,7 +26686,7 @@ GetBinary__Q23EGG29IBinaryCFPv = .text:0x804AE430; // type __ct__Q23EGG7ModelExFPQ34nw4r3g3d6ScnObj = .text:0x804AE650; // type:function size:0x1C8 getShapeMinMax__Q23EGG7ModelExFUsPQ34nw4r4math4VEC3PQ34nw4r4math4VEC3b = .text:0x804AE820; // type:function size:0x228 calcWorld__Q23EGG7ModelExCFPQ34nw4r4math5MTX34PCQ34nw4r4math5MTX34 = .text:0x804AEA50; // type:function size:0xF0 -getResMdl__Q23EGG7ModelExCFUs = .text:0x804AEB40; // type:function size:0x48 +getResMdl__Q23EGG7ModelExCFv = .text:0x804AEB40; // type:function size:0x48 getResShp__Q23EGG7ModelExCFUs = .text:0x804AEB90; // type:function size:0x90 __ct__Q23EGG14PostEffectBaseFv = .text:0x804AEC20; // type:function size:0x5C draw__Q23EGG14PostEffectBaseFff = .text:0x804AEC80; // type:function size:0x94 diff --git a/configure.py b/configure.py index cb7cacf2..55351e1e 100644 --- a/configure.py +++ b/configure.py @@ -888,7 +888,7 @@ config.libs = [ Object(NonMatching, "egg/gfx/eggLightObject.cpp"), Object(NonMatching, "egg/gfx/eggLightTexture.cpp"), Object(Matching, "egg/gfx/eggLightTextureMgr.cpp"), - Object(NonMatching, "egg/gfx/eggModelEx.cpp"), + Object(Matching, "egg/gfx/eggModelEx.cpp"), Object(Matching, "egg/gfx/eggPostEffectBase.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlur.cpp"), Object(Matching, "egg/gfx/eggPostEffectBlurGather.cpp"), diff --git a/include/egg/gfx/eggAnalizeDL.h b/include/egg/gfx/eggAnalizeDL.h new file mode 100644 index 00000000..cb7d2c14 --- /dev/null +++ b/include/egg/gfx/eggAnalizeDL.h @@ -0,0 +1,36 @@ +#ifndef EGG_ANALIZE_DL_H +#define EGG_ANALIZE_DL_H + +#include "nw4r/g3d/res/g3d_resshp.h" + +namespace EGG { + +class AnalizeDL { +public: + enum Status { + STATUS_NONE, + + STATUS_VTX = 4, + STATUS_ERROR = 6, + }; + + struct VtxResult { + /* 0x00 */ s32 mMtxIdx; + /* 0x04 */ u8 _0x04[4]; + /* 0x08 */ Vec field_0x08; + }; + +private: + u8 _0x000[0x1E4 - 0x000]; + +public: + AnalizeDL(nw4r::g3d::ResShp shp); + virtual ~AnalizeDL() {} + + Status step(); + const VtxResult &getVtxResult() const; +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggG3DUtility.h b/include/egg/gfx/eggG3DUtility.h index 15250313..7ad5a736 100644 --- a/include/egg/gfx/eggG3DUtility.h +++ b/include/egg/gfx/eggG3DUtility.h @@ -3,6 +3,7 @@ #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/res/g3d_resmat.h" +#include "nw4r/math/math_types.h" #include "rvl/MEM/mem_allocator.h" namespace EGG { @@ -20,12 +21,20 @@ public: }; static u32 SetTexture( - nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, GXTexObj *texObj, bool copy, - SetTextureResult *pResult, int param_7, int param_8 + nw4r::g3d::ResMat resMat, nw4r::g3d::ScnMdl::CopiedMatAccess *param_2, const char *name, GXTexObj *texObj, + bool copy, SetTextureResult *pResult, int param_7, int param_8 ); static void setUpLightSet(nw4r::g3d::LightSetting &, nw4r::g3d::ResAnmScn, int); + static nw4r::math::MTX34 *GetWorldMtxArray(int, int); + + static int searchStringResNode(nw4r::g3d::ResMdl, const char *, u16 *, u32); + static int searchStringResMat(nw4r::g3d::ResMdl, const char *, u16 *, u32); + static int searchStringResTexPlttInfo(nw4r::g3d::ResMdl, const char *, u16 *, u32); + + typedef int (*MdlSearch)(nw4r::g3d::ResMdl, const char *, u16 *, u32); + private: static MEMAllocator *sAllocator; }; diff --git a/include/egg/gfx/eggIScnProcModel.h b/include/egg/gfx/eggIScnProcModel.h new file mode 100644 index 00000000..254d4832 --- /dev/null +++ b/include/egg/gfx/eggIScnProcModel.h @@ -0,0 +1,24 @@ +#ifndef EGG_I_SCN_PROC_MODEL_H +#define EGG_I_SCN_PROC_MODEL_H + +#include "common.h" +#include "nw4r/math/math_types.h" + +namespace EGG { + +class IScnProcModel { +private: + /* 0x00 */ u8 _0x00[0x08]; + +public: + IScnProcModel() {} + virtual ~IScnProcModel() {} // at 0x8 + virtual void draw(bool, u32) = 0; // at 0xC + virtual UNKTYPE VF_0x10(UNKTYPE) = 0; // at 0x10 + virtual UNKTYPE VF_0x14(UNKTYPE) = 0; // at 0x14 + virtual void getMinMaxScnProcModel(nw4r::math::VEC3 *, nw4r::math::VEC3 *) const = 0; // at 0x18 +}; + +} // namespace EGG + +#endif diff --git a/include/egg/gfx/eggModelEx.h b/include/egg/gfx/eggModelEx.h index 5ef3fdb3..9e8aa23f 100644 --- a/include/egg/gfx/eggModelEx.h +++ b/include/egg/gfx/eggModelEx.h @@ -40,7 +40,7 @@ public: ModelEx(nw4r::g3d::ScnObj *); void getShapeMinMax(u16, nw4r::math::VEC3 *, nw4r::math::VEC3 *, bool); void calcWorld(nw4r::math::MTX34 *, const nw4r::math::MTX34 *worldMtx) const; - nw4r::g3d::ResMdl getResMdl(u16) const; + nw4r::g3d::ResMdl getResMdl() const; nw4r::g3d::ResShp getResShp(u16) const; nw4r::g3d::ScnMdl *getScnMdl() const { diff --git a/src/egg/gfx/eggModelEx.cpp b/src/egg/gfx/eggModelEx.cpp index cd28528f..6a6e4cd2 100644 --- a/src/egg/gfx/eggModelEx.cpp +++ b/src/egg/gfx/eggModelEx.cpp @@ -1,11 +1,19 @@ #include "egg/gfx/eggModelEx.h" #include "common.h" +#include "egg/gfx/eggAnalizeDL.h" +#include "egg/gfx/eggG3DUtility.h" +#include "egg/gfx/eggIScnProcModel.h" #include "nw4r/g3d/g3d_calcworld.h" #include "nw4r/g3d/g3d_scnmdl.h" #include "nw4r/g3d/g3d_scnmdl1mat1shp.h" #include "nw4r/g3d/g3d_scnmdlsmpl.h" +#include "nw4r/g3d/g3d_scnproc.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/g3d/res/g3d_resshp.h" +#include "nw4r/math/math_types.h" +#include "rvl/MTX/mtx.h" +#include "rvl/MTX/mtxvec.h" namespace EGG { @@ -25,7 +33,96 @@ ModelEx::ModelEx(g3d::ScnObj *obj) } } -void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool doCalcWorld) {} +static const f32 sFaceMin[] = {-22.61115f, -55.770135f, -45.93067f}; +static const f32 sFaceMax[] = {81.17467f, 49.677597f, 45.93065f}; + +static const f32 sNoneMin[] = {0.0f, 0.0f, 0.0f}; +static const f32 sNoneMax[] = {0.0f, 0.0f, 0.0f}; + +// Not sure what this was for but it didn't get stripped due to data pooling +static const G3DUtility::MdlSearch sMdlSearch[6] = { + G3DUtility::searchStringResNode, G3DUtility::searchStringResMat, G3DUtility::searchStringResTexPlttInfo, + G3DUtility::searchStringResNode, G3DUtility::searchStringResMat, G3DUtility::searchStringResTexPlttInfo, +}; + +void thisProbablyGotDeadStripped() { + sMdlSearch[0](g3d::ResMdl(nullptr), "", nullptr, 0); +} + +extern "C" s32 lbl_8057682C; + +void ModelEx::getShapeMinMax(u16 shapeIndex, math::VEC3 *pMin, math::VEC3 *pMax, bool doCalcWorld) { + switch (mType) { + case cType_ScnMdlSimple: + case cType_ScnMdl: + case cType_ScnMdl1Mat1Shp: { + g3d::ResShp shp = getResShp(shapeIndex); + lbl_8057682C = 0; + g3d::ResMdl mdl = getResMdl(); + math::MTX34 tmpMtx; + g3d::ResMdlInfo info = mdl.GetResMdlInfo(); + math::MTX34 *pMtxArr = G3DUtility::GetWorldMtxArray(info.GetNumPosNrmMtx() * sizeof(math::MTX34), 1); + if (doCalcWorld) { + PSMTXIdentity(tmpMtx); + calcWorld(pMtxArr, &tmpMtx); + } + + s32 defaultMatrixIdx = shp.ref().curMtxIdx; + AnalizeDL analyze(shp); + + bool firstIteration = true; + AnalizeDL::Status status; + while ((status = analyze.step()) != AnalizeDL::STATUS_ERROR) { + if (status != AnalizeDL::STATUS_VTX) { + continue; + } + + const AnalizeDL::VtxResult &result = analyze.getVtxResult(); + s32 mtxIdx = result.mMtxIdx; + if (mtxIdx == -1) { + mtxIdx = defaultMatrixIdx; + } + nw4r::math::VEC3 tmpVec; + PSMTXMultVec(pMtxArr[mtxIdx], &analyze.getVtxResult().field_0x08, tmpVec); + if (firstIteration) { + firstIteration = false; + *pMin = *pMax = tmpVec; + } else { + math::VEC3Minimize(pMin, pMin, &tmpVec); + math::VEC3Maximize(pMax, pMax, &tmpVec); + } + } + lbl_8057682C = 0; + break; + } + case cType_ScnProcModel: + static_cast(static_cast(mScnObj)->GetUserData()) + ->getMinMaxScnProcModel(pMin, pMax); + break; + case cType_ScnRfl: { + const f32 *min = sFaceMin; + const f32 *max = sFaceMax; + pMin->x = min[0]; + pMin->y = min[1]; + pMin->z = min[2]; + pMax->x = max[0]; + pMax->y = max[1]; + pMax->z = max[2]; + break; + } + + case cType_None: + const f32 *min = sNoneMin; + const f32 *max = sNoneMax; + pMin->x = min[0]; + pMin->y = min[1]; + pMin->z = min[2]; + pMax->x = max[0]; + pMax->y = max[1]; + pMax->z = max[2]; + break; + } +} void ModelEx::calcWorld(math::MTX34 *pWorldMtxArray, const math::MTX34 *worldMtx) const { switch (mType) { @@ -53,7 +150,7 @@ void ModelEx::calcWorld(math::MTX34 *pWorldMtxArray, const math::MTX34 *worldMtx } } -g3d::ResMdl ModelEx::getResMdl(u16) const { +g3d::ResMdl ModelEx::getResMdl() const { g3d::ScnMdlSimple *mdl = getScnMdlSimple(); if (mdl != nullptr) { return mdl->GetResMdl();