diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 0a953cd1..9dbe76f7 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2072,7 +2072,7 @@ fn_80050010 = .text:0x80050010; // type:function size:0x4 fn_80050020 = .text:0x80050020; // type:function size:0x8 fn_80050030 = .text:0x80050030; // type:function size:0x1A8 fn_800501E0 = .text:0x800501E0; // type:function size:0x40 -__dt__14UnkPlayerClassFv = .text:0x80050220; // type:function size:0x40 +__dt__7mQuat_cFv = .text:0x80050220; // type:function size:0x40 AcNpcKyuiBase__initStates = .text:0x80050260; // type:function size:0x1E0 fn_80050440 = .text:0x80050440; // type:function size:0x58 AcNpcKyuiBase__dtor = .text:0x800504A0; // type:function size:0x5C @@ -2640,7 +2640,7 @@ timingC__22daPlBaseMainCallback_cFPQ34nw4r4math5MTX34Q34nw4r3g3d6ResMdl = .text: play__16daPlBaseAnmChr_cFv = .text:0x8005D2E0; // type:function size:0x34 isFinished__16daPlBaseAnmChr_cFv = .text:0x8005D320; // type:function size:0x80 timingB__22daPlBaseHeadCallback_cFUlPQ34nw4r3g3d13WorldMtxManipQ34nw4r3g3d6ResMdl = .text:0x8005D3A0; // type:function size:0x8 -ExecCallbackC__27daPlBaseCalcWorldCallback_cFPQ34nw4r4math5MTX34Q34nw4r3g3d6ResMdlPQ34nw4r3g3d16FuncObjCalcWorld = .text:0x8005D3B0; // type:function size:0x30 +ExecCallbackC__23daPlBaseHandsCallback_cFPQ34nw4r4math5MTX34Q34nw4r3g3d6ResMdlPQ34nw4r3g3d16FuncObjCalcWorld = .text:0x8005D3B0; // type:function size:0x30 fn_8005D3E0 = .text:0x8005D3E0; // type:function size:0x28 freeFrmHeap__19daPlayerModelBase_cFP16mHeapAllocator_c = .text:0x8005D410; // type:function size:0x60 allocFrmHeap__19daPlayerModelBase_cFP16mHeapAllocator_cUlPCc = .text:0x8005D470; // type:function size:0x58 @@ -2663,30 +2663,30 @@ initShieldModel__19daPlayerModelBase_cFv = .text:0x8005E490; // type:function si updateShieldModel__19daPlayerModelBase_cFv = .text:0x8005E750; // type:function size:0xC8 createGenericSmdl__19daPlayerModelBase_cFQ34nw4r3g3d6ResMdlRQ23m3d6smdl_cP12mAllocator_cUl = .text:0x8005E820; // type:function size:0x68 createGenericMdl__19daPlayerModelBase_cFQ34nw4r3g3d6ResMdlRQ23m3d5mdl_cP12mAllocator_cUl = .text:0x8005E890; // type:function size:0x68 -fn_8005E900 = .text:0x8005E900; // type:function size:0x11C -fn_8005EA20 = .text:0x8005EA20; // type:function size:0xA0 -fn_8005EAC0__19daPlayerModelBase_cFv = .text:0x8005EAC0; // type:function size:0x274 -someDivingHrabbingStuff__19daPlayerModelBase_cFv = .text:0x8005ED40; // type:function size:0x4 -vt_0x308__19daPlayerModelBase_cFv = .text:0x8005ED50; // type:function size:0xC -fn_8005ED60__19daPlayerModelBase_cFv = .text:0x8005ED60; // type:function size:0x7B0 -vt_0x2E0__19daPlayerModelBase_cFv = .text:0x8005F510; // type:function size:0x4 +applyWorldRotationMaybe__19daPlayerModelBase_cFPQ34nw4r4math5MTX344mAng4mAng4mAngP7mVec3_cb = .text:0x8005E900; // type:function size:0x11C +applyWorldRotationMaybe__19daPlayerModelBase_cFPQ34nw4r3g3d13WorldMtxManip4mAng4mAng4mAngP7mVec3_cb = .text:0x8005EA20; // type:function size:0xA0 +adjustMainModelChrAnm__19daPlayerModelBase_cFQ219daPlayerModelBase_c21PlayerMainModelNode_ePQ34nw4r3g3d12ChrAnmResult = .text:0x8005EAC0; // type:function size:0x274 +transformModelCenter__19daPlayerModelBase_cFP6mMtx_c = .text:0x8005ED40; // type:function size:0x4 +getArmZRot__19daPlayerModelBase_cFl = .text:0x8005ED50; // type:function size:0xC +adjustMainModelWorldMtx__19daPlayerModelBase_cFQ219daPlayerModelBase_c21PlayerMainModelNode_ePQ34nw4r3g3d13WorldMtxManip = .text:0x8005ED60; // type:function size:0x7B0 +transformBackbone1__19daPlayerModelBase_cFPQ34nw4r3g3d13WorldMtxManip = .text:0x8005F510; // type:function size:0x4 vt_0x30C__19daPlayerModelBase_cFR7mVec3_c = .text:0x8005F520; // type:function size:0x24 isMPPose__19daPlayerModelBase_cFv = .text:0x8005F550; // type:function size:0x8 isOnTightRope__19daPlayerModelBase_cFv = .text:0x8005F560; // type:function size:0x8 isOnVines__19daPlayerModelBase_cFv = .text:0x8005F570; // type:function size:0x8 -fn_8005F580 = .text:0x8005F580; // type:function size:0x88 -fn_8005F610 = .text:0x8005F610; // type:function size:0xD4 -fn_8005F6F0 = .text:0x8005F6F0; // type:function size:0x194 -fn_8005F890__19daPlayerModelBase_cFv = .text:0x8005F890; // type:function size:0x2C0 -vt_0x2E8__19daPlayerModelBase_cFv = .text:0x8005FB50; // type:function size:0x8 +updateMainBlend1__19daPlayerModelBase_cFf = .text:0x8005F580; // type:function size:0x88 +updateMainBlend2__19daPlayerModelBase_cFfb = .text:0x8005F610; // type:function size:0xD4 +updateBlendWeights__19daPlayerModelBase_cFQ219daPlayerModelBase_c21PlayerMainModelNode_e = .text:0x8005F6F0; // type:function size:0x194 +fn_8005F890__19daPlayerModelBase_cFPQ34nw4r4math5MTX34 = .text:0x8005F890; // type:function size:0x2C0 +vt_0x2E8__19daPlayerModelBase_cFPQ34nw4r4math5MTX34PCUsb = .text:0x8005FB50; // type:function size:0x8 vt_0x304__19daPlayerModelBase_cCFv = .text:0x8005FB60; // type:function size:0xC -isOnClawTargetMaybe__19daPlayerModelBase_cFiR4mAngR4mAng = .text:0x8005FB70; // type:function size:0x14 +isOnClawTargetMaybe__19daPlayerModelBase_cFlR4mAngR4mAng = .text:0x8005FB70; // type:function size:0x14 fn_8005FB90 = .text:0x8005FB90; // type:function size:0x220 -mainModeltimingA__19daPlayerModelBase_cFUlPQ34nw4r3g3d12ChrAnmResultRQ34nw4r3g3d6ResMdl = .text:0x8005FDB0; // type:function size:0x4 -mainModeltimingB__19daPlayerModelBase_cFUlPQ34nw4r3g3d13WorldMtxManipRQ34nw4r3g3d6ResMdl = .text:0x8005FDC0; // type:function size:0x78 -mainModelTimingC__19daPlayerModelBase_cFPQ34nw4r4math5MTX34RQ34nw4r3g3d6ResMdl = .text:0x8005FE40; // type:function size:0x4C -fn_8005FE90 = .text:0x8005FE90; // type:function size:0xA8 -fn_8005FF40 = .text:0x8005FF40; // type:function size:0x118 +mainModelTimingA__19daPlayerModelBase_cFUlPQ34nw4r3g3d12ChrAnmResult = .text:0x8005FDB0; // type:function size:0x4 +mainModelTimingB__19daPlayerModelBase_cFUlPQ34nw4r3g3d13WorldMtxManip = .text:0x8005FDC0; // type:function size:0x78 +mainModelTimingC__19daPlayerModelBase_cFPQ34nw4r4math5MTX34 = .text:0x8005FE40; // type:function size:0x4C +handsCallbackC__19daPlayerModelBase_cFPQ34nw4r4math5MTX34Q34nw4r3g3d6ResMdlPQ34nw4r3g3d16FuncObjCalcWorld = .text:0x8005FE90; // type:function size:0xA8 +headModelTimingB__19daPlayerModelBase_cFUlPQ34nw4r3g3d13WorldMtxManip = .text:0x8005FF40; // type:function size:0x118 setTransformAndCalc__19daPlayerModelBase_cFRQ23m3d9scnLeaf_cPC6mMtx_c = .text:0x80060060; // type:function size:0x40 fn_800600A0 = .text:0x800600A0; // type:function size:0xD4 fn_80060180 = .text:0x80060180; // type:function size:0xB0 @@ -2708,8 +2708,8 @@ fn_80060B30 = .text:0x80060B30; // type:function size:0xCC fn_80060C00 = .text:0x80060C00; // type:function size:0xE0 fn_80060CE0 = .text:0x80060CE0; // type:function size:0x64 fn_80060D50 = .text:0x80060D50; // type:function size:0x54 -fn_80060DB0 = .text:0x80060DB0; // type:function size:0x29C -fn_80061050 = .text:0x80061050; // type:function size:0x1B0 +updateModelColliders__19daPlayerModelBase_cFv = .text:0x80060DB0; // type:function size:0x29C +updateCachedPositions__19daPlayerModelBase_cFv = .text:0x80061050; // type:function size:0x1B0 fn_80061200 = .text:0x80061200; // type:function size:0x210 fn_80061410__19daPlayerModelBase_cFv = .text:0x80061410; // type:function size:0x6C alwaysRet0__19daPlayerModelBase_cFv = .text:0x80061480; // type:function size:0x8 @@ -2729,7 +2729,7 @@ canBlockAttack__19daPlayerModelBase_cFv = .text:0x80061570; // type:function siz __dt__19daPlayerModelBase_cFv = .text:0x80061580; // type:function size:0x254 __dt__16daPlBaseAnmChr_cFv = .text:0x800617E0; // type:function size:0x58 __dt__24daPlBaseScnObjCallback_cFv = .text:0x80061840; // type:function size:0x40 -__dt__27daPlBaseCalcWorldCallback_cFv = .text:0x80061880; // type:function size:0x40 +__dt__23daPlBaseHandsCallback_cFv = .text:0x80061880; // type:function size:0x40 __dt__Q34nw4r3g3d18ICalcWorldCallbackFv = .text:0x800618C0; // type:function size:0x40 __dt__22daPlBaseHeadCallback_cFv = .text:0x80061900; // type:function size:0x58 __dt__22daPlBaseMainCallback_cFv = .text:0x80061960; // type:function size:0x58 @@ -11891,7 +11891,7 @@ fn_801D8290 = .text:0x801D8290; // type:function size:0x46C fn_801D8700 = .text:0x801D8700; // type:function size:0x134 fn_801D8840 = .text:0x801D8840; // type:function size:0x2B8 fn_801D8B00 = .text:0x801D8B00; // type:function size:0x230 -__ct__14UnkPlayerClassFv = .text:0x801D8D30; // type:function size:0x4 +__ct__7mQuat_cFv = .text:0x801D8D30; // type:function size:0x4 fn_801D8D40 = .text:0x801D8D40; // type:function size:0xB90 fn_801D98D0 = .text:0x801D98D0; // type:function size:0x37C fn_801D9C50 = .text:0x801D9C50; // type:function size:0x4 @@ -17577,7 +17577,7 @@ getMatID__Q23m3d6bmdl_cCFPCc = .text:0x802E9300; // type:function size:0x3C getNodeID__Q23m3d6bmdl_cCFPCc = .text:0x802E9340; // type:function size:0x3C getNodeWorldMtx__Q23m3d6bmdl_cCFUlPQ34nw4r4math5MTX34 = .text:0x802E9380; // type:function size:0xA8 getNodeWorldMtxMultVecZero__Q23m3d6bmdl_cCFUlRQ34nw4r4math4VEC3 = .text:0x802E9430; // type:function size:0x5C -getNodeWorldMtxMultVec__Q23m3d6bmdl_cCFUlRQ34nw4r4math4VEC3RQ34nw4r4math4VEC3 = .text:0x802E9490; // type:function size:0x60 +getNodeWorldMtxMultVec__Q23m3d6bmdl_cCFUlRCQ34nw4r4math4VEC3RQ34nw4r4math4VEC3 = .text:0x802E9490; // type:function size:0x60 setAnm__Q23m3d6bmdl_cFRQ23m3d6banm_c = .text:0x802E94F0; // type:function size:0x15C play__Q23m3d6bmdl_cFv = .text:0x802E9650; // type:function size:0x20 getResMdl__Q23m3d6bmdl_cCFv = .text:0x802E9670; // type:function size:0x80 @@ -17848,7 +17848,7 @@ ZrotM__6mMtx_cFRC4mAng = .text:0x802F1990; // type:function size:0x4C ZXYrotS__6mMtx_cFRC4mAngRC4mAngRC4mAng = .text:0x802F19E0; // type:function size:0x60 ZXYrotM__6mMtx_cFRC4mAngRC4mAngRC4mAng = .text:0x802F1A40; // type:function size:0x60 mMtx__XYZrotS = .text:0x802F1AA0; // type:function size:0x60 -mMtx__ZYXrotM = .text:0x802F1B00; // type:function size:0x60 +ZYXrotM__6mMtx_cFRC4mAngRC4mAngRC4mAng = .text:0x802F1B00; // type:function size:0x60 toRot__6mMtx_cCFR7mAng3_c = .text:0x802F1B60; // type:function size:0xDC fn_802F1C40__6mMtx_cFll = .text:0x802F1C40; // type:function size:0x220 makeRotationFromVecs__6mMtx_cFRC7mVec3_cRC7mVec3_cf = .text:0x802F1E60; // type:function size:0x58 @@ -30817,7 +30817,7 @@ lbl_8050D9E4 = .data:0x8050D9E4; // type:object size:0xC lbl_8050D9F0 = .data:0x8050D9F0; // type:object size:0x10 __vt__19daPlayerModelBase_c = .data:0x8050DA00; // type:object size:0x310 __vt__22daPlBaseHeadCallback_c = .data:0x8050DD10; // type:object size:0x18 -__vt__27daPlBaseCalcWorldCallback_c = .data:0x8050DD28; // type:object size:0x18 +__vt__23daPlBaseHandsCallback_c = .data:0x8050DD28; // type:object size:0x18 __vt__16daPlBaseAnmChr_c = .data:0x8050DD40; // type:object size:0x18 __vt__22daPlBaseMainCallback_c = .data:0x8050DD58; // type:object size:0x18 __vt__13daPlBaseMdl_c = .data:0x8050DD70; // type:object size:0x2C diff --git a/include/d/a/d_a_player.h b/include/d/a/d_a_player.h index 15cbd195..ff858d70 100644 --- a/include/d/a/d_a_player.h +++ b/include/d/a/d_a_player.h @@ -28,6 +28,7 @@ #include "nw4r/g3d/res/g3d_resanmtexsrt.h" #include "nw4r/g3d/res/g3d_resfile.h" #include "nw4r/g3d/res/g3d_resmdl.h" +#include "nw4r/math/math_types.h" #include "toBeSorted/file_manager.h" #include "toBeSorted/stage_render_stuff.h" @@ -104,6 +105,10 @@ public: ); void setBlendNodeRange(u16, u16, f32); + nw4r::g3d::ChrAnmResult *getNodeResult(u16 node) { + return mCallback.getNodeResult(node); + } + private: /* 0x24 */ daPlBaseMdlCallback_c mCallback; /* 0x58 */ u8 field_0x58; @@ -137,7 +142,7 @@ private: /* 0x36 */ u8 field_0x36; }; -class daPlBaseCalcWorldCallback_c : public nw4r::g3d::ICalcWorldCallback { +class daPlBaseHandsCallback_c : public nw4r::g3d::ICalcWorldCallback { public: virtual void ExecCallbackC( nw4r::math::MTX34 *pMtxArray, nw4r::g3d::ResMdl mdl, @@ -826,14 +831,21 @@ public: PLAYER_MAIN_NODE_BACKBONE_2 = 2, PLAYER_MAIN_NODE_HEAD = 4, PLAYER_MAIN_NODE_POD = 5, + PLAYER_MAIN_NODE_SHOULDER_L = 6, PLAYER_MAIN_NODE_ARM_L1 = 7, PLAYER_MAIN_NODE_ARM_L2 = 8, PLAYER_MAIN_NODE_HAND_L = 9, + PLAYER_MAIN_NODE_WEAPON_L = 10, + PLAYER_MAIN_NODE_SHOULDER_R = 11, PLAYER_MAIN_NODE_ARM_R1 = 12, PLAYER_MAIN_NODE_ARM_R2 = 13, PLAYER_MAIN_NODE_HAND_R = 14, + PLAYER_MAIN_NODE_WEAPON_R = 15, PLAYER_MAIN_NODE_WAIST = 16, + PLAYER_MAIN_NODE_TOE_L = 21, + PLAYER_MAIN_NODE_TOE_R = 26, + PLAYER_MAIN_NODE_FSKIRT_L1 = 27, PLAYER_MAIN_NODE_FSKIRT_R1 = 29, @@ -843,7 +855,23 @@ public: PLAYER_MAIN_NODE_RSKIRT_R2 = 34, }; - void fn_8005F890(); + // Alink.arc > g3d > model.brres > 3DModels(NW4R) > al_head > Bones > ... + enum PlayerHeadModelNode_e { + PLAYER_HEAD_NODE_HAIR_L = 1, + PLAYER_HEAD_NODE_HAIR_R1 = 2, + PLAYER_HEAD_NODE_HAIR_R2 = 3, + PLAYER_HEAD_NODE_MOMI_L = 4, + PLAYER_HEAD_NODE_MOMI_R = 5, + PLAYER_HEAD_NODE_MOMI_Z_CAP_1 = 6, + }; + + // Alink.arc > g3d > model.brres > 3DModels(NW4R) > al_hands > Bones > ... + enum PlayerHandsModelNode_e { + PLAYER_HANDS_NODE_HAND_L = 1, + PLAYER_HANDS_NODE_HAND_R = 2, + }; + + void fn_8005F890(nw4r::math::MTX34 *); void fn_80061410(); static void freeFrmHeap(mHeapAllocator_c *allocator); @@ -879,10 +907,10 @@ public: /* vt 0x2E0 */ virtual void transformBackbone1(nw4r::g3d::WorldMtxManip *) {} /* vt 0x2E4 */ virtual void transformModelCenter(mMtx_c *) {} - /* vt 0x2E8 */ virtual bool vt_0x2E8() { + /* vt 0x2E8 */ virtual bool vt_0x2E8(nw4r::math::MTX34 *, const u16 *, bool) { return true; } - /* vt 0x2EC */ virtual void isOnClawTargetMaybe(UNKWORD, mAng &a1, mAng &a2) { + /* vt 0x2EC */ virtual void isOnClawTargetMaybe(s32 arm, mAng &a1, mAng &a2) { a1.setR(0); a2.setR(0); } @@ -921,7 +949,7 @@ public: return field_0x12F4; } /* vt 0x0EC */ virtual const mVec3_c &vt_0x0EC() const override { - return field_0x1294; + return mHeadTranslation; } /* vt 0x0F0 */ virtual const mVec3_c &vt_0x0F0() const override { return mTranslationHand[1]; @@ -963,6 +991,9 @@ public: mSwordAndMoreStates &= ~mask; } + void updateModelColliders(); + void updateCachedPositions(); + // Model callbacks - dropping the mdl argument, apparently void mainModelTimingA(u32 nodeId, nw4r::g3d::ChrAnmResult *result); void adjustMainModelChrAnm(PlayerMainModelNode_e nodeId, nw4r::g3d::ChrAnmResult *result); @@ -971,9 +1002,15 @@ public: void adjustMainModelWorldMtx(PlayerMainModelNode_e nodeId, nw4r::g3d::WorldMtxManip *result); void mainModelTimingC(nw4r::math::MTX34 *result); + void headModelTimingB(u32 nodeId, nw4r::g3d::WorldMtxManip *result); - void fn_8005E900(mMtx_c *, mAng, mAng, mAng, mVec3_c *, bool); - void fn_8005EA20(nw4r::g3d::WorldMtxManip*, mAng, mAng, mAng, mVec3_c *, bool); + void handsCallbackC(nw4r::math::MTX34 *pMtxArray, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *pFuncObj); + + void updateBlendWeights(PlayerMainModelNode_e nodeId); + void updateMainBlend1(f32 blend); + void updateMainBlend2(f32 blend, bool save); + void applyWorldRotationMaybe(nw4r::math::MTX34 *result, mAng x, mAng y, mAng z, mVec3_c *off, bool order); + void applyWorldRotationMaybe(nw4r::g3d::WorldMtxManip *result, mAng x, mAng y, mAng z, mVec3_c *off, bool order); static const PlayerAnimation sAnimations[443]; static const u8 sShieldDurabilities[10]; @@ -993,7 +1030,7 @@ protected: /* 0x3E0 */ daPlBaseMdl_c mMainMdl; /* 0x440 */ daPlBaseMainCallback_c mMainBodyCallback; /* 0x448 */ m3d::mdl_c mHeadMdl; - /* 0x46C */ daPlBaseHeadCallback_c mheadCallback; + /* 0x46C */ daPlBaseHeadCallback_c mHeadCallback; /* 0x474 */ m3d::smdl_c mFaceMdl; /* 0x490 */ m3d::anmChr_c mFaceAnmChr; /* 0x4C8 */ void *mpAnmCharBuffer; @@ -1003,7 +1040,7 @@ protected: /* 0x528 */ void *mpTexSrtBuffer; /* 0x52C */ m3d::anmChr_c mHeadAnmChr; /* 0x564 */ m3d::smdl_c mHandsMdl; - /* 0x580 */ daPlBaseCalcWorldCallback_c mCalcWorldCallback; + /* 0x580 */ daPlBaseHandsCallback_c mCalcWorldCallback; /* 0x588 */ daPlBaseScnObjCallback_c mScnObjCallback; /* 0x598 */ m3d::smdl_c mSwordMdl; /* 0x5B4 */ m3d::anmMatClr_c mSwordAnmMatClr; @@ -1039,6 +1076,7 @@ protected: /* 0x1216 */ s8 mCapMatId; /* 0x1217 */ s8 mSkinMatId; /* 0x1218 */ u8 mSkywardStrikeChargeDuration; + /* 0x1219 */ u8 field_0x1219; /* 0x121A */ u16 mAnimations[6]; /* 0x1226 */ u16 mFaceAnmChrIdx1; /* 0x1228 */ u16 mFaceAnmChrIdx2; @@ -1049,7 +1087,12 @@ protected: /* 0x1232 */ u16 mBreakingEffect; /* 0x1234 */ mAng mWaistZRot; /* 0x1236 */ mAng mWaistYRot; - /* 0x1238 */ u8 _0x1238[0x125C - 0x1238]; + /* 0x1238 */ mAng field_0x1238[5]; + /* 0x1242 */ mAng field_0x1242[5]; + /* 0x124C */ u8 _0x124C[0x1256 - 0x124C]; + /* 0x1256 */ mAng field_0x1256; + /* 0x1258 */ mAng field_0x1258; + /* 0x125A */ mAng field_0x125A; /* 0x125C */ mAng mRSkirtR1Rot; /* 0x125E */ mAng mRSkirtL1Rot; /* 0x1260 */ mAng mRightHandRotation; @@ -1059,27 +1102,27 @@ protected: /* 0x1268 */ mAng field_0x1268; /* 0x126A */ mAng field_0x126A; /* 0x126C */ mAng field_0x126C; - /* 0x126E */ u8 _0x126C[0x1278 - 0x126E]; + /* 0x1270 */ f32 field_0x1270; + /* 0x1274 */ f32 field_0x1274; /* 0x1278 */ f32 field_0x1278; /* 0x127C */ mVec3_c field_0x127C; /* 0x1288 */ mVec3_c mCenterTranslation; - /* 0x1294 */ mVec3_c field_0x1294; - /* 0x12A0 */ mVec3_c field_0x12A0; + /* 0x1294 */ mVec3_c mHeadTranslation; + /* 0x12A0 */ mVec3_c mPositionAboveLink; /* 0x12AC */ mVec3_c mTranslationHand[2]; /* 0x12C4 */ mVec3_c mTranslationWeapon[2]; /* 0x12DC */ mVec3_c mToeTranslation[2]; /* 0x12F4 */ mVec3_c field_0x12F4; - /* 0x1300 */ UnkPlayerClass mUnk_0x1300[4]; + /* 0x1300 */ mQuat_c field_0x1300[4]; /* 0x1340 */ mQuat_c mQuat1; /* 0x1350 */ mQuat_c mQuat2; /* 0x1360 */ dAcRef_c mRef; // not sure about the class /* 0x136C */ mAng *field_0x136C; /* 0x1370 */ mAng *field_0x1370; + /* 0x1374 */ mAng *field_0x1374; // x3 + /* 0x1378 */ mAng *field_0x1378; // x3 }; -// The split between daPlBase_c and dAcPy_c is somewhere after -// member offset 0x1368 and before 0x137C - class dAcPy_c : public daPlayerModelBase_c { public: dAcPy_c(); @@ -1095,7 +1138,7 @@ public: /* vt 0x318 */ virtual void vt_0x318(); protected: - /* 0x1372 */ u8 _0x1374[0x4564 - 0x1374]; + /* 0x137C */ u8 _0x137C[0x4564 - 0x137C]; /* 0x4564 */ f32 field_0x4564; public: diff --git a/include/m/m3d/m_bmdl.h b/include/m/m3d/m_bmdl.h index ee9d1920..7cacd67d 100644 --- a/include/m/m3d/m_bmdl.h +++ b/include/m/m3d/m_bmdl.h @@ -22,7 +22,7 @@ public: int getNodeID(const char *name) const; bool getNodeWorldMtx(u32 p1, nw4r::math::MTX34 *out) const; bool getNodeWorldMtxMultVecZero(u32 p1, nw4r::math::VEC3 &out) const; - bool getNodeWorldMtxMultVec(u32, nw4r::math::VEC3 &, nw4r::math::VEC3 &) const; + bool getNodeWorldMtxMultVec(u32, const nw4r::math::VEC3 &, nw4r::math::VEC3 &) const; nw4r::g3d::ResMdl getResMdl() const; nw4r::g3d::ResMat getResMat(u32 index) const; @@ -40,7 +40,7 @@ public: bool getBounds(mVec3_c *min, mVec3_c *max) const; private: - banm_c *mpCurrentAnm; + /* 0x18 */ banm_c *mpCurrentAnm; }; } // namespace m3d diff --git a/include/m/m3d/m_mdl.h b/include/m/m3d/m_mdl.h index 047b91af..a0833038 100644 --- a/include/m/m3d/m_mdl.h +++ b/include/m/m3d/m_mdl.h @@ -43,6 +43,10 @@ public: mpBaseCallback = cb; } + nw4r::g3d::ChrAnmResult *getNodeResult(u16 node) { + return &mpNodes[node]; + } + protected: /* 0x04 */ calcRatio_c mCalcRatio; /* 0x20 */ int mNumNode; @@ -66,9 +70,9 @@ public: private: /** If we allocated the callback ourselves, this is what we need to free */ - mdlCallback_c *mpOwnedCallback; + /* 0x1C */ mdlCallback_c *mpOwnedCallback; /** The actual callback to use */ - mdlCallback_c *mpCallback; + /* 0x20 */ mdlCallback_c *mpCallback; }; } // namespace m3d diff --git a/include/m/m_angle.h b/include/m/m_angle.h index a227f3f0..fd9fa6a6 100644 --- a/include/m/m_angle.h +++ b/include/m/m_angle.h @@ -56,6 +56,10 @@ struct mAng { mVal -= other.mVal; return *this; } + mAng &operator*=(const s32 &other) { + mVal *= other; + return *this; + } s32 step(s16 target, s32 steps, s16 max, s16 min); diff --git a/src/d/d_player_mdl.cpp b/src/d/d_player_mdl.cpp index 877afba6..1a770290 100644 --- a/src/d/d_player_mdl.cpp +++ b/src/d/d_player_mdl.cpp @@ -25,8 +25,10 @@ #include "nw4r/g3d/res/g3d_resmdl.h" #include "nw4r/g3d/res/g3d_resshp.h" #include "nw4r/math/math_arithmetic.h" +#include "nw4r/math/math_types.h" #include "rvl/CX/cx.h" #include "rvl/GX/GXTypes.h" +#include "rvl/MTX/mtxvec.h" #include "sized_string.h" #include "toBeSorted/cx_util.h" #include "toBeSorted/file_manager.h" @@ -230,11 +232,15 @@ bool daPlBaseAnmChr_c::isFinished() { return false; } -void daPlBaseHeadCallback_c::timingB(u32, nw4r::g3d::WorldMtxManip *, nw4r::g3d::ResMdl) {} +void daPlBaseHeadCallback_c::timingB(u32 nodeId, nw4r::g3d::WorldMtxManip *result, nw4r::g3d::ResMdl) { + mpPlayer->headModelTimingB(nodeId, result); +} -void daPlBaseCalcWorldCallback_c::ExecCallbackC( +void daPlBaseHandsCallback_c::ExecCallbackC( nw4r::math::MTX34 *pMtxArray, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *pFuncObj -) {} +) { + mpPlayer->handsCallbackC(pMtxArray, mdl, pFuncObj); +} void daPlayerModelBase_c::freeFrmHeap(mHeapAllocator_c *allocator) { EGG::Heap::toFrmHeap(allocator->getHeap())->free(0x1 | 0x2); @@ -309,8 +315,8 @@ void daPlayerModelBase_c::loadBodyModels() { mMainMdl.setCallback(&mMainBodyCallback); mMainBodyCallback.setPlayer(this); - mHeadMdl.setCallback(&mheadCallback); - mheadCallback.setPlayer(this); + mHeadMdl.setCallback(&mHeadCallback); + mHeadCallback.setPlayer(this); mScnCallback1.attach(mMainMdl); mScnCallback2.attach(mHeadMdl); @@ -491,11 +497,11 @@ void daPlayerModelBase_c::initSwordModel() { const char *pod = sSwordPods[sCurrentSword]; nw4r::g3d::ResMdl sheathMdl = mSwordRes.GetResMdl(pod); - createGenericSmdl(sheathMdl, mSheathMdl, &heap_allocator, 0x800); + createGenericSmdl(sheathMdl, mSheathMdl, &mSwordAllocator, 0x800); mScnCallback4.attach(mSheathMdl); nw4r::g3d::ResMdl swordMdl = mSwordRes.GetResMdl(swordName); - createGenericSmdl(swordMdl, mSwordMdl, &heap_allocator, 0x810); + createGenericSmdl(swordMdl, mSwordMdl, &mSwordAllocator, 0x810); mSwordMdl.setPriorityDraw(0x84, 0x7F); nw4r::g3d::ResAnmClr swordAnmClr = mAlinkRes.GetResAnmClr("appearance"); nw4r::g3d::ResMdl swordResMdl = mSwordMdl.getResMdl(); @@ -623,6 +629,41 @@ bool daPlayerModelBase_c::createGenericMdl( return ok; } +void daPlayerModelBase_c::applyWorldRotationMaybe( + nw4r::math::MTX34 *result, mAng x, mAng y, mAng z, mVec3_c *off, bool order +) { + mVec3_c v; + v.x = result->_03; + v.y = result->_13; + v.z = result->_23; + mMtx_c work; + if (off != nullptr) { + MTXTrans(work, off->x, off->y, off->z); + } else { + MTXTrans(work, v.x, v.y, v.z); + } + work.YrotM(rotation.y); + if (order) { + work.ZYXrotM(x, y, z); + } else { + work.ZXYrotM(x, y, z); + } + work.YrotM(-rotation.y); + mMtx_c translateBack; + translateBack.transS(-v.x, -v.y, -v.z); + MTXConcat(work, translateBack, work); + MTXConcat(work, *result, *result); +} + +void daPlayerModelBase_c::applyWorldRotationMaybe( + nw4r::g3d::WorldMtxManip *result, mAng x, mAng y, mAng z, mVec3_c *off, bool order +) { + mMtx_c mtx; + result->GetMtx(mtx); + applyWorldRotationMaybe(mtx, x, y, z, off, order); + result->SetMtxUnchecked(mtx); +} + void daPlayerModelBase_c::adjustMainModelChrAnm(PlayerMainModelNode_e nodeId, nw4r::g3d::ChrAnmResult *result) { mMtx_c mtx; result->GetMtx(mtx); @@ -674,17 +715,16 @@ void daPlayerModelBase_c::adjustMainModelWorldMtx(PlayerMainModelNode_e nodeId, mtx.YrotM(-rotation.y); mMtx_c mtx2; mtx2.YrotS(rotation.y); - mtx += mtx2; + MTXConcat(mtx2, mtx, mtx); mMtx_c orig; result->GetMtx(orig); - mVec3_c origTrans(orig.m[0][3], orig.m[1][3], orig.m[2][3]); - orig += mtx; - orig.m[0][3] = origTrans.x; - orig.m[1][3] = origTrans.y; - orig.m[2][3] = origTrans.z; + mVec3_c origTrans; + orig.getTranslation(origTrans); + MTXConcat(mtx, orig, orig); + orig.setTranslation(origTrans); if (nodeId == PLAYER_MAIN_NODE_ARM_R1) { - fn_8005E900(&orig, 1500, 0, 0, nullptr, false); + applyWorldRotationMaybe(orig, 1500, 0, 0, nullptr, false); } result->SetMtxUnchecked(orig); } else if (mAnimations[3] == 0xE0 && nodeId == PLAYER_MAIN_NODE_ARM_R2) { @@ -693,73 +733,292 @@ void daPlayerModelBase_c::adjustMainModelWorldMtx(PlayerMainModelNode_e nodeId, mtx.YrotM(-rotation.y); mMtx_c mtx2; mtx2.YrotS(rotation.y); - mtx += mtx2; + MTXConcat(mtx2, mtx, mtx); mMtx_c orig; result->GetMtx(orig); - mVec3_c origTrans(orig.m[0][3], orig.m[1][3], orig.m[2][3]); - orig += mtx; - orig.m[0][3] = origTrans.x; - orig.m[1][3] = origTrans.y; - orig.m[2][3] = origTrans.z; + mVec3_c origTrans; + orig.getTranslation(origTrans); + MTXConcat(mtx, orig, orig); + orig.setTranslation(origTrans); result->SetMtxUnchecked(orig); } else if (nodeId == PLAYER_MAIN_NODE_BACKBONE_1) { transformBackbone1(result); - fn_8005EA20(result, field_0x1268 >> 1, field_0x126A * 0.4f + getArmZRot(2), field_0x126C, nullptr, false); + applyWorldRotationMaybe( + result, field_0x1268 >> 1, field_0x126A * 0.4f + getArmZRot(2), field_0x126C, nullptr, false + ); } else if (nodeId == PLAYER_MAIN_NODE_BACKBONE_2) { - fn_8005EA20(result, field_0x1268 >> 1, field_0x126A * 0.6f + getArmZRot(2), 0, nullptr, false); + applyWorldRotationMaybe(result, field_0x1268 >> 1, field_0x126A * 0.6f + getArmZRot(2), 0, nullptr, false); } else if (nodeId == PLAYER_MAIN_NODE_FSKIRT_L1 && *field_0x136C != 0) { mVec3_c v; vt_0x30C(v); if (*field_0x136C < 0) { v.z *= -1.0f; - } - fn_8005EA20(result, v.x * *field_0x136C, 0, v.z * *field_0x136C, nullptr, true); - } else if (nodeId == PLAYER_MAIN_NODE_FSKIRT_R1 && field_0x1370) { + applyWorldRotationMaybe(result, v.x * *field_0x136C, 0, v.z * *field_0x136C, nullptr, true); + } else if (nodeId == PLAYER_MAIN_NODE_FSKIRT_R1 && *field_0x1370) { mVec3_c v; vt_0x30C(v); if (*field_0x1370 > 0) { v.z *= -1.0f; - } - fn_8005EA20(result, v.x * *field_0x1370, 0, v.z * *field_0x1370, nullptr, true); + applyWorldRotationMaybe(result, v.x * *field_0x1370, 0, v.z * *field_0x1370, nullptr, true); } else if (nodeId == PLAYER_MAIN_NODE_POD) { - mAng a1 = 0; - mAng a2 = getArmZRot(2); - - fn_8005EA20(result, field_0x1268 / 2, field_0x126A * 0.6f + a1, a1, nullptr, false); + if (field_0x1258 != 0) { + mMtx_c mtx; + mtx.YrotS(field_0x125A); + mtx.XrotM(field_0x1258); + mtx.YrotM(-field_0x125A); + mMtx_c orig; + result->GetMtx(orig); + mVec3_c origTrans; + orig.getTranslation(origTrans); + MTXConcat(mtx, orig, orig); + orig.setTranslation(origTrans); + result->SetMtxUnchecked(orig); + } + if (field_0x1268 < 0) { + applyWorldRotationMaybe(result, -(field_0x1268 >> 1), 0, 0, nullptr, false); + } } else if ((nodeId == PLAYER_MAIN_NODE_ARM_R2 || nodeId == PLAYER_MAIN_NODE_HAND_R) && isMPPose()) { - mAng a1 = 0; - mAng a2 = getArmZRot(2); + mMtx_c mtx; + mtx.makeQ(mQuat2); + mtx.YrotM(-rotation.y); + mMtx_c mtx2; + mtx2.YrotS(rotation.y); + MTXConcat(mtx2, mtx, mtx); - fn_8005EA20(result, field_0x1268 / 2, field_0x126A * 0.6f + a1, a1, nullptr, false); + mMtx_c orig; + result->GetMtx(orig); + mVec3_c origTrans; + orig.getTranslation(origTrans); + MTXConcat(mtx, orig, orig); + orig.setTranslation(origTrans); + result->SetMtxUnchecked(orig); + } else if (nodeId == PLAYER_MAIN_NODE_HAND_R || nodeId == PLAYER_MAIN_NODE_HAND_L) { + if (isOnTightRope()) { + // TODO: I'd like this to be a neat ternary... + // nodeId == PLAYER_MAIN_NODE_HAND_R ? -5461 : -7282; + mAng rot; + rot.setR(-7282); + if (nodeId == PLAYER_MAIN_NODE_HAND_R) { + rot.setR(-5461); + } + applyWorldRotationMaybe(result, rot, 0, 0, nullptr, false); + } else if (isOnVines()) { + // TODO what even is this + mAng v1 = -3277; + mAng v2 = 910; + if (nodeId == PLAYER_MAIN_NODE_HAND_R) { + v1 *= -1; + v2 *= -1; + } + applyWorldRotationMaybe(result, 0xec17, v1, v2, nullptr, true); + } } - - // Just getting weak functions to appear here - mVec3_c v; - vt_0x30C(v); - isMPPose(); - isOnTightRope(); - isOnVines(); } -void daPlayerModelBase_c::fn_8005F890() { - // Just getting weak functions to appear here - vt_0x2E8(); - vt_0x304(); - mAng a1, a2; - isOnClawTargetMaybe(0, a1, a2); +void daPlayerModelBase_c::updateMainBlend1(f32 blend) { + // TODO document numbers + mAnmChrBlend.setWeight(1, (1.0f - blend) * (1.0f - field_0x1274)); + mAnmChrBlend.setWeight(3, (1.0f - blend) * field_0x1274); + mAnmChrBlend.setWeight(5, blend); +} + +void daPlayerModelBase_c::updateMainBlend2(f32 blend, bool save) { + // TODO document numbers + f32 blend4 = 1.0f - mAnmChrBlend.getWeight(4); + mAnmChrBlend.setWeight(0, blend4 * (1.0f - blend)); + mAnmChrBlend.setWeight(2, blend4 * blend); + f32 blend5 = 1.0f - mAnmChrBlend.getWeight(5); + mAnmChrBlend.setWeight(1, blend5 * (1.0f - blend)); + mAnmChrBlend.setWeight(3, blend5 * blend); + if (save) { + field_0x1274 = blend; + } +} + +void daPlayerModelBase_c::updateBlendWeights(PlayerMainModelNode_e nodeId) { + switch (field_0x1219) { + case 9: + if (nodeId == PLAYER_MAIN_NODE_CENTER) { + updateMainBlend2(field_0x1274, false); + } else if (nodeId == PLAYER_MAIN_NODE_WEAPON_R) { + if (field_0x1274 < 0.5f) { + updateMainBlend2(0.0f, false); + } else { + updateMainBlend2(1.0f, false); + } + } + break; + case 1: + if (nodeId == PLAYER_MAIN_NODE_CENTER) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_POD) { + updateMainBlend1(field_0x1270); + } + break; + case 4: + if (nodeId == PLAYER_MAIN_NODE_CENTER) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_WEAPON_L) { + updateMainBlend1(field_0x1270); + } + break; + case 2: + if (nodeId == PLAYER_MAIN_NODE_WEAPON_L) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_WEAPON_R) { + updateMainBlend1(field_0x1270); + } + break; + case 3: + if (nodeId == PLAYER_MAIN_NODE_POD) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_WEAPON_L) { + updateMainBlend1(field_0x1270); + } + break; + case 5: + if (nodeId == PLAYER_MAIN_NODE_HEAD) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_POD) { + updateMainBlend1(field_0x1270); + } + break; + case 7: + if (nodeId == PLAYER_MAIN_NODE_CENTER) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_HEAD) { + updateMainBlend1(1.0f); + } else if (nodeId == PLAYER_MAIN_NODE_POD) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_WEAPON_R) { + updateMainBlend1(1.0f); + } + break; + case 6: + if (nodeId == PLAYER_MAIN_NODE_HEAD) { + updateMainBlend2(0.0f, false); + } else if (nodeId == PLAYER_MAIN_NODE_POD) { + updateMainBlend2(0.0f, false); + } + break; + case 8: + if (nodeId == PLAYER_MAIN_NODE_HEAD) { + updateMainBlend1(0.0f); + } else if (nodeId == PLAYER_MAIN_NODE_POD) { + updateMainBlend1(field_0x1270); + } + break; + } +} + +void daPlayerModelBase_c::fn_8005F890(nw4r::math::MTX34 *result) { + // Probably related to IK? + static const u16 sNodeIdsArms1[] = {PLAYER_MAIN_NODE_ARM_L1, PLAYER_MAIN_NODE_ARM_R1}; + static const Vec sArmVecs[] = { + {29.0f, 0.0f, 0.0f}, + {26.5f, 0.0f, 0.0f}, + { 0.0f, 0.0f, 0.0f} + }; + + nw4r::g3d::ResMdl mdl = mMainMdl.getResMdl(); + + if (vt_0x2E8(result, sNodeIdsArms1, false)) { + mVec3_c swordOffset; + if (checkCurrentAction(/* SWORD_IN_DIAL */ 0x86) || checkCurrentAction(/* ON_BIRD */ 0x8A)) { + swordOffset = vt_0x304() * 0.5f; + } else { + swordOffset = mVec3_c::Zero; + } + + mVec3_c dstVec; + // (1) For some reason the compiler sets up pointers to stack vars here... + for (s32 arm = 0; arm < 2; arm++) { + mAng rot1; + mAng rot2; + isOnClawTargetMaybe(arm, rot1, rot2); + u16 armNode = sNodeIdsArms1[arm]; + mVec3_c *dst = nullptr; + mAng *angs; + if (arm == 0) { + angs = field_0x1374; + } else { + angs = field_0x1378; + } + nw4r::math::MTX34 *targetMtx; + // Walk down the arm bones and transform the whole thing again? + for (s32 i = 0; i < 3; i++) { + u32 mtxId = mdl.GetResNode(armNode).GetMtxID(); + targetMtx = &result[mtxId]; + applyWorldRotationMaybe(targetMtx, rot1, rot2, angs[i], dst, false); + mVec3_c v; + v.x = sArmVecs[i].x; + v.y = sArmVecs[i].y; + v.z = sArmVecs[i].z; + MTXMultVec(*targetMtx, v, dstVec); + if (i != 2 && arm == 1) { + // sword hand + dstVec -= swordOffset; + } + dst = &dstVec; + armNode++; + } + mVec3_c translate; + mMainMdl.getNodeResult(armNode)->GetTranslate(translate); + MTXMultVec(*targetMtx, translate, *dst); + // (2) ... here it stores the passed-by-value angles to the stack, + // then calls GetResNode and uses the previously set up pointers as arguments? + applyWorldRotationMaybe(&result[mdl.GetResNode(armNode).GetMtxID()], rot1, rot2, angs[2], &dstVec, false); + } + } } void daPlayerModelBase_c::mainModelTimingA(u32 nodeId, nw4r::g3d::ChrAnmResult *result) { adjustMainModelChrAnm((PlayerMainModelNode_e)nodeId, result); } -void daPlayerModelBase_c::mainModelTimingB(u32 nodeId, nw4r::g3d::WorldMtxManip *result) {} +void daPlayerModelBase_c::mainModelTimingB(u32 nodeId, nw4r::g3d::WorldMtxManip *result) { + adjustMainModelWorldMtx((PlayerMainModelNode_e)nodeId, result); + if (field_0x1219 != 0) { + if (nodeId == PLAYER_MAIN_NODE_CENTER || nodeId == PLAYER_MAIN_NODE_POD || + nodeId == PLAYER_MAIN_NODE_WEAPON_L || nodeId == PLAYER_MAIN_NODE_HEAD || + nodeId == PLAYER_MAIN_NODE_WEAPON_R) { + updateBlendWeights((PlayerMainModelNode_e)nodeId); + } + } +} void daPlayerModelBase_c::mainModelTimingC(nw4r::math::MTX34 *result) {} +void daPlayerModelBase_c::handsCallbackC( + nw4r::math::MTX34 *pMtxArray, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *pFuncObj +) { + mMainMdl.getNodeWorldMtx(PLAYER_MAIN_NODE_HAND_L, &pMtxArray[mdl.GetResNode(PLAYER_HANDS_NODE_HAND_L).GetMtxID()]); + mMainMdl.getNodeWorldMtx(PLAYER_MAIN_NODE_HAND_R, &pMtxArray[mdl.GetResNode(PLAYER_HANDS_NODE_HAND_R).GetMtxID()]); +} + +void daPlayerModelBase_c::headModelTimingB(u32 nodeId, nw4r::g3d::WorldMtxManip *result) { + if (nodeId >= PLAYER_HEAD_NODE_MOMI_Z_CAP_1) { + mMtx_c mtx; + result->GetMtx(mtx); + mVec3_c v; + mtx.getTranslation(v); + mMtx_c rot; + rot.makeQ(field_0x1300[nodeId - 6]); + MTXConcat(rot, mtx, mtx); + mtx.setTranslation(v); + result->SetMtxUnchecked(mtx); + } else if (nodeId >= PLAYER_HEAD_NODE_HAIR_L) { + mAng oldYRot = rotation.y; + rotation.y = field_0x1256; + u32 idx = nodeId - 1; + applyWorldRotationMaybe(result, field_0x1238[idx], 0, field_0x1242[idx], nullptr, false); + rotation.y = oldYRot; + } +} + void daPlayerModelBase_c::setTransformAndCalc(m3d::scnLeaf_c &lf, const mMtx_c *mtx) { if (mtx != nullptr) { lf.setLocalMtx(*mtx); @@ -835,6 +1094,80 @@ nw4r::g3d::ResAnmTexSrt daPlayerModelBase_c::getExternalAnmTexSrt(const char *na return result; } +void daPlayerModelBase_c::updateModelColliders() { + mVec3_c bodyTranslation; + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_CENTER, bodyTranslation); + + mVec3_c bottom; + bottom = ((mToeTranslation[0] + mToeTranslation[1]) * 0.5f + bodyTranslation) * 0.5f; + f32 f = mToeTranslation[0].y > mToeTranslation[1].y ? mToeTranslation[1].y : mToeTranslation[0].y; + f32 height; + if (bodyTranslation.y > f) { + height = bodyTranslation.y - f; + bottom.y = f; + } else { + bottom.y = bodyTranslation.y; + height = f - bodyTranslation.y; + } + + if (height < 60.0f) { + bottom.y -= (60.0f - height) * 0.5f; + height = 60.0f; + } + mCcCyls[0].SetC(bottom); + mCcCyls[0].SetH(height); + + if (!checkActionFlagsCont(0x20000)) { + bottom = (bodyTranslation + mHeadTranslation) * 0.5f; + } + + if (bodyTranslation.y > mHeadTranslation.y) { + height = bodyTranslation.y - mHeadTranslation.y; + bottom.y = mHeadTranslation.y; + } else { + bottom.y = bodyTranslation.y; + height = mHeadTranslation.y - bodyTranslation.y; + } + + if (height < 60.0f) { + bottom.y -= (60.0f - height) * 0.5f; + height = 60.0f; + } + + mCcCyls[2].SetC(bottom); + mCcCyls[2].SetH(height); + + bottom = (mCcCyls[0].GetC() + mCcCyls[2].GetC()) * 0.5f; + f32 midH = (mCcCyls[0].GetH() + mCcCyls[2].GetH()) * 0.5f; + + mCcCyls[1].SetC(bottom); + mCcCyls[1].SetH(midH); +} + +void daPlayerModelBase_c::updateCachedPositions() { + static const Vec sPos1 = {12.0f, -8.0f, 0.0f}; + mMainMdl.getNodeWorldMtxMultVec(PLAYER_MAIN_NODE_HEAD, sPos1, poscopy2); + static const Vec sPosAboveLink = {0.0f, -8.0f, 0.0f}; + mMainMdl.getNodeWorldMtxMultVec(PLAYER_MAIN_NODE_HEAD, sPosAboveLink, mPositionAboveLink); + static const Vec sHeadPos = {0.0f, -28.0f, 0.0f}; + mMainMdl.getNodeWorldMtxMultVec(PLAYER_MAIN_NODE_HEAD, sHeadPos, mHeadTranslation); + + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_TOE_L, mToeTranslation[0]); + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_TOE_R, mToeTranslation[1]); + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_HAND_L, mTranslationHand[0]); + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_HAND_R, mTranslationHand[1]); + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_WEAPON_L, mTranslationWeapon[0]); + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_WEAPON_R, mTranslationWeapon[1]); + mMainMdl.getNodeWorldMtxMultVecZero(PLAYER_MAIN_NODE_CENTER, mCenterTranslation); + + if (checkCurrentAction(/* DOWSE_LOOK */ 0x68)) { + mVec3_c v(0.0f, 18.0f, 0.0f); + v.rotX(field_0x1268); + v.rotY(rotation.y + field_0x126A); + poscopy2 += v; + } +} + void daPlayerModelBase_c::fn_80061410() { // Just getting weak functions to appear here alwaysRet0(); diff --git a/src/m/m3d/m_bmdl.cpp b/src/m/m3d/m_bmdl.cpp index 916d6440..2515e856 100644 --- a/src/m/m3d/m_bmdl.cpp +++ b/src/m/m3d/m_bmdl.cpp @@ -39,7 +39,7 @@ bool bmdl_c::getNodeWorldMtxMultVecZero(u32 p1, nw4r::math::VEC3 &out) const { } } -bool bmdl_c::getNodeWorldMtxMultVec(u32 p1, nw4r::math::VEC3 &in, nw4r::math::VEC3 &out) const { +bool bmdl_c::getNodeWorldMtxMultVec(u32 p1, const nw4r::math::VEC3 &in, nw4r::math::VEC3 &out) const { nw4r::math::MTX34 mtx; if (!getNodeWorldMtx(p1, &mtx)) { return false; diff --git a/src/m/m3d/m_shadow.cpp b/src/m/m3d/m_shadow.cpp index 903ca14f..da0246ef 100644 --- a/src/m/m3d/m_shadow.cpp +++ b/src/m/m3d/m_shadow.cpp @@ -514,17 +514,14 @@ bool mShadowChild_c::setGeom(const GXTexObj *texObj, const mMtx_c &mtx, const mQ } void mShadowChild_c::updateMtx() { - const mQuat_c &q = GetQuat(); - const mVec3_c &pos = GetPosition(); + // NONMATCHING + field_0x13C = mQuat.w; - Set0x13C(q.w); - - mVec3_c a(q.v); - - a += pos * GetOffset(); - - mVec3_c b(q.v); - b -= pos * Get0x13C(); + mVec3_c a(mQuat.v.x, mQuat.v.y, mQuat.v.z); + a += mPositionMaybe * GetOffset(); + + mVec3_c b(mQuat.v.x, mQuat.v.y, mQuat.v.z); + b -= mPositionMaybe * field_0x13C; const mVec3_c *up; if (cM::isZero((a - b).squareMagXZ())) { @@ -536,17 +533,16 @@ void mShadowChild_c::updateMtx() { mMtx_c mtx; C_MTXLookAt(mtx.m, a, *up, b); - const f32 f = Get0x13C(); + f32 f = field_0x13C; mFrustum.set(f, -f, -f, f, f, f + GetOffset(), mtx, true); } void mShadowChild_c::drawMdl() { - // Equivalent, but stack problems and regswaps using namespace nw4r; - mMtx_c mtx; + Mtx44 mtx; GXSetTevColor(GX_TEVREG0, sColors[mColorChanIdx]); - C_MTXOrtho(mtx.m, field_0x13C, -field_0x13C, -field_0x13C, field_0x13C, 0.0f, 100.0f + (-mFrustum.mFar)); - GXSetProjection(mtx.m, GX_ORTHOGRAPHIC); + C_MTXOrtho(mtx, field_0x13C, -field_0x13C, -field_0x13C, field_0x13C, 0.0f, 100.0f + (-mFrustum.mFar)); + GXSetProjection(mtx, GX_ORTHOGRAPHIC); g3d::G3DState::Invalidate(0x7FF); mMtx_c &viewMtx = mFrustum.mView; @@ -571,7 +567,7 @@ void mShadowChild_c::drawMdl() { g3d::DrawResMdlReplacement *pRep = mdl2 ? &mdl2->GetDrawResMdlReplacement() : nullptr; g3d::DrawResMdlDirectly( - resMdl, viewPosArray, nullptr, nullptr, mdl2->GetByteCode(g3d::ScnMdlSimple::BYTE_CODE_DRAW_OPA), + resMdl, viewPosArray, nullptr, nullptr, mdl->GetByteCode(g3d::ScnMdlSimple::BYTE_CODE_DRAW_OPA), nullptr, pRep, g3d::RESMDL_DRAWMODE_FORCE_LIGHTOFF | g3d::RESMDL_DRAWMODE_IGNORE_MATERIAL ); GXInvalidateVtxCache();