diff --git a/include/SSystem/SComponent/c_m3d.h b/include/SSystem/SComponent/c_m3d.h index 6ff4ade49..390a55921 100644 --- a/include/SSystem/SComponent/c_m3d.h +++ b/include/SSystem/SComponent/c_m3d.h @@ -4,6 +4,7 @@ #include "MSL_C/math.h" #include "dolphin/types.h" #include "dolphin/mtx/vec.h" +#include "dolphin/mtx/mtx.h" class cM3dGAab; class cM3dGCps; @@ -85,6 +86,7 @@ f32 cM3d_lineVsPosSuisenCross(const cM3dGLin*, const Vec*, Vec*); f32 cM3d_lineVsPosSuisenCross(const Vec&, const Vec&, const Vec&, Vec*); int cM3d_2PlaneLinePosNearPos(const cM3dGPla&, const cM3dGPla&, const Vec*, Vec*); void cM3d_CrawVec(const Vec&, const Vec&, Vec*); +void cM3d_UpMtx_Base(const Vec&, const Vec&, MtxP); inline bool cM3d_IsZero(f32 f) { return fabsf(f) < G_CM3D_F_ABS_MIN; diff --git a/include/SSystem/SComponent/c_m3d_g_pla.h b/include/SSystem/SComponent/c_m3d_g_pla.h index 0f495e445..1962750c7 100644 --- a/include/SSystem/SComponent/c_m3d_g_pla.h +++ b/include/SSystem/SComponent/c_m3d_g_pla.h @@ -10,8 +10,9 @@ class cM3dGPla { public: /* 0x00 */ cXyz mNormal; /* 0x0C */ f32 mD; - /* 0x10 vtable */ + /* 0x10 */ /* vtable */ +public: cM3dGPla() {} void CalcAngleXz(short* pAngleX, short* pAngleY) const; void SetupNP0(const Vec&, const Vec&); @@ -20,8 +21,9 @@ public: return mD + VECDotProduct(&mNormal, p); } - const cXyz * GetNP() const { return &mNormal; } - float getCrossY(const cXyz& i_axis) const { + cXyz* GetNP() { return &mNormal; } + const cXyz* GetNP() const { return &mNormal; } + float getCrossY(const cXyz& i_axis) const { // fake inline return (-mNormal.x * i_axis.x - mNormal.z * i_axis.z - mD) / mNormal.y; } void getCrossY(const cXyz& i_axis, float* i_value) const { @@ -29,8 +31,22 @@ public: *i_value = getCrossY(i_axis); } } + f32 getSignedLenPos(const cXyz* param_1) const { + return cM3d_SignedLenPlaAndPos(this, param_1); + } virtual ~cM3dGPla() {} -}; + + // TODO + void GetD() const {} + void Set(const cM3dGPla*) {} + void SetupFrom3Vtx(const Vec*, const Vec*, const Vec*) {} + cM3dGPla(const cM3dGPla&) {} + cM3dGPla(const cXyz*, float) {} + void cross(const cM3dGLin&, Vec&) const {} + void getCrossYLessD(const Vec&, float*) const {} + void getCrossY_NonIsZero(const cXyz&) const {} + void operator=(const cM3dGPla&) {} +}; // Size: 0x14 #endif diff --git a/include/SSystem/SComponent/c_m3d_g_tri.h b/include/SSystem/SComponent/c_m3d_g_tri.h index adafbc76f..ae298a282 100644 --- a/include/SSystem/SComponent/c_m3d_g_tri.h +++ b/include/SSystem/SComponent/c_m3d_g_tri.h @@ -13,16 +13,42 @@ struct cM3dGTriS { }; class cM3dGTri : public cM3dGPla { - // private: public: - // cM3dGPla mPlane; - Vec mA; - Vec mB; - Vec mC; + /* 0x00 */ /* cM3dGPla */ + /* 0x14 */ Vec mA; + /* 0x20 */ Vec mB; + /* 0x2C */ Vec mC; +public: cM3dGTri() {} cM3dGTri(const Vec *pA, const Vec *pB, const Vec *pC); bool cross(const cM3dGCyl*, Vec*) const; -}; + + bool cross(const cM3dGLin* line, Vec* vec, bool param_3, bool param_4) const { + return cM3d_Cross_LinTri(line, this, vec, param_3, param_4); + } + void Up(f32 dist) { + Vec delta; + PSVECScale(&mNormal, &delta, dist); + PSVECAdd(&mA, &delta, &mA); + PSVECAdd(&mB, &delta, &mB); + PSVECAdd(&mC, &delta, &mC); + mD -= dist; + } + + // TODO + void Cross(const cM3dGCps&, Vec*) const {} + void Cross(const cM3dGCyl&, Vec*) const {} + void Cross(const cM3dGSph&, Vec*) const {} + void Cross(const cM3dGTri&, Vec*) const {} + cM3dGTri(const cM3dGTri&) {} + void crossX(const Vec*, f32*) const {} + void crossY(const Vec*) const {} + void crossZ(const Vec*, f32*) const {} + void setBg(const Vec*, const Vec*, const Vec*, const cM3dGPla*) {} + void setPos(const Vec*, const Vec*, const Vec*) {} + void setUp() {} + ~cM3dGTri() {} +}; // Size: 0x38 #endif diff --git a/include/SSystem/SComponent/c_xyz.h b/include/SSystem/SComponent/c_xyz.h index e202fb516..2c4d42c8a 100644 --- a/include/SSystem/SComponent/c_xyz.h +++ b/include/SSystem/SComponent/c_xyz.h @@ -138,6 +138,14 @@ struct cXyz : Vec { f32 getDotProduct(const Vec& other) const { return VECDotProduct(this, &other); } f32 inprod(const Vec& other) const { return getDotProduct(other); } + + // TODO + // void inprodXZ(const Vec&) const {} + // void isNearZeroSquare(const cXyz&) const {} + // void operator*=(const Vec&) {} + // void operator/=(float) {} + // void operator=(const cXyz&) {} + // void print(const char*) {} }; #endif /* C_XYZ_H */ diff --git a/include/d/actor/d_a_npc_md.h b/include/d/actor/d_a_npc_md.h index 5ba7a41e8..6b05d7fd4 100644 --- a/include/d/actor/d_a_npc_md.h +++ b/include/d/actor/d_a_npc_md.h @@ -243,13 +243,14 @@ public: s8 getArmRlocJntNum() { return m_armRloc_jnt_num; } s8 getArmLJntNum() { return m_armL_jnt_num; } s8 getArmLlocJntNum() { return m_armLloc_jnt_num; } + s8 getHairJntNum(int i) { return m_hair_jnt_nums[i]; } J3DModel* getModel() { return mpMorf->getModel(); } cXyz& getAttentionBasePos() { return m3094; } cXyz& getEyePos() { return m3088; } - void getPHairDist(int) {} - void getPHairPos(int) {} - void getPHairVec(int) {} + cXyz* getPHairPos(int i) { return &m3174[i]; } + cXyz* getPHairVec(int i) { return &m31D4[i]; } + f32* getPHairDist(int i) { return &m3264[i]; } cXyz* getPHairWall() { return m3234; } void incAttnSetCount() { @@ -258,9 +259,11 @@ public: } } + u8 checkBitHairMode(u8 bit) { return m3134 & bit; } + void setBitHairMode(u8 bit) { m3134 |= bit; } + void calcFlyingTimer() {} void checkBitEffectStatus(u8) {} - void checkBitHairMode(u8) {} void checkStatus(u32) {} void checkStatusCamTagIn() {} void checkStatusFly() {} @@ -269,7 +272,6 @@ public: void clearStatus(u32) {} void countPiyo2TalkCNT() {} void getFlyingTimer() {} - void getHairJntNum(int) {} void getPiyo2TalkCNT() {} void getTalkType() {} void isLightBodyHit() {} @@ -294,7 +296,6 @@ public: void onPlayerRoom() {} void onShipRide() {} void setBitEffectStatus(u8) {} - void setBitHairMode(u8) {} void setBitStatus(u32) {} void setEffectStatus(u8) {} void setFlyingTimer(s16) {} @@ -540,7 +541,8 @@ public: /* 0x3131 */ u8 m3131; /* 0x3132 */ s8 mActionStatus; /* 0x3133 */ u8 m3133; - /* 0x3134 */ u8 m3134[0x3136 - 0x3134]; + /* 0x3134 */ u8 m3134; + /* 0x3135 */ u8 m3135[0x3136 - 0x3135]; /* 0x3136 */ u8 m3136; /* 0x3137 */ u8 m3137; /* 0x3138 */ u8 m3138; @@ -564,7 +566,7 @@ public: /* 0x3174 */ cXyz m3174[8]; /* 0x31D4 */ cXyz m31D4[8]; /* 0x3234 */ cXyz m3234[4]; - /* 0x3264 */ u8 m3264[0x3284 - 0x3264]; + /* 0x3264 */ f32 m3264[8]; /* 0x3284 */ char mModelArcName[3]; /* 0x3287 */ u8 m3287[0x32A4 - 0x3287]; /* 0x32A4 */ cXyz m32A4; diff --git a/include/d/d_kankyo_wether.h b/include/d/d_kankyo_wether.h index f13a6e532..49b1cb7ab 100644 --- a/include/d/d_kankyo_wether.h +++ b/include/d/d_kankyo_wether.h @@ -364,5 +364,6 @@ void dKyw_pntwind_cut(WIND_INFLUENCE*); void dKyw_pwind_cylinder_set(WIND_INFLUENCE*); void dKyw_evt_wind_set(s16 i_windX, s16 i_windY); void dKyw_evt_wind_set_go(); +void dKyw_get_AllWind_vec(cXyz* param_0, cXyz* i_direction, f32* i_power); #endif /* D_KANKYO_WETHER_H */ diff --git a/include/m_Do/m_Do_mtx.h b/include/m_Do/m_Do_mtx.h index ee65636b6..82994d7ca 100644 --- a/include/m_Do/m_Do_mtx.h +++ b/include/m_Do/m_Do_mtx.h @@ -305,6 +305,12 @@ public: */ static void ZrotM(s16 z) { mDoMtx_ZrotM(now, z); } + /** + * Rotates the `now` matrix on the Z-axis + * @param z The rotation value + */ + static void ZrotS(s16 z) { mDoMtx_ZrotS(now, z); } + static void inverse() { MTXInverse(now, now); } static void inverseTranspose() { mDoMtx_inverseTranspose(now, now); } @@ -323,6 +329,14 @@ public: */ static void copy(const Mtx m) { MTXCopy(m, now); } + static void rotAxisRadS(const Vec* axis, f32 rad) { + MTXRotAxisRad(now, axis, rad); + } + + // TODO + static void quatS(const Quaternion*) {} + static void rYrotS(f32) {} + static Mtx now; static Mtx buffer[16]; static Mtx* next; diff --git a/src/d/actor/d_a_arrow_iceeff.cpp b/src/d/actor/d_a_arrow_iceeff.cpp index 5c26c989e..146e276f5 100644 --- a/src/d/actor/d_a_arrow_iceeff.cpp +++ b/src/d/actor/d_a_arrow_iceeff.cpp @@ -57,14 +57,14 @@ void daArrow_Iceeff_c::CreateInit() { f32 temp = 180.0f * i / 30.0f; s16 angle = cM_rndF(65536.0f); - mDoMtx_ZrotS(mDoMtx_stack_c::get(), cM_rndF(65536.0f)); - mDoMtx_XrotM(mDoMtx_stack_c::get(), cM_rndF(65536.0f)); - mDoMtx_YrotM(mDoMtx_stack_c::get(), cM_rndF(65536.0f)); + mDoMtx_stack_c::ZrotS(cM_rndF(65536.0f)); + mDoMtx_stack_c::XrotM(cM_rndF(65536.0f)); + mDoMtx_stack_c::YrotM(cM_rndF(65536.0f)); mDoMtx_stack_c::transM(temp * cM_ssin(angle), temp * cM_scos(angle), 0.0f); mDoMtx_stack_c::ZrotM(current.angle.z); mDoMtx_stack_c::XrotM(current.angle.x); mDoMtx_stack_c::YrotM(current.angle.y); - MTXCopy(mDoMtx_stack_c::get(), field_0x314[i]); + cMtx_copy(mDoMtx_stack_c::get(), field_0x314[i]); } } else { diff --git a/src/d/actor/d_a_npc_md.cpp b/src/d/actor/d_a_npc_md.cpp index 7dcf065dc..e2fab0b5a 100644 --- a/src/d/actor/d_a_npc_md.cpp +++ b/src/d/actor/d_a_npc_md.cpp @@ -13,6 +13,7 @@ #include "d/actor/d_a_player_main.h" #include "d/d_snap.h" #include "d/actor/d_a_ship.h" +#include "d/d_kankyo_wether.h" // Needed for the .data section to match. static f32 dummy1[3] = {1.0f, 1.0f, 1.0f}; @@ -553,8 +554,45 @@ static BOOL armNodeCallBack(J3DNode* node, int param_1) { } /* 0000160C-00001C60 .text hairCross__FP4cXyzP4cXyzP4cXyz */ -static void hairCross(cXyz*, cXyz*, cXyz*) { - /* Nonmatching */ +static BOOL hairCross(cXyz* i_r3, cXyz* i_r4, cXyz* i_r5) { + cM3dGTri r1_198(&i_r3[0], &i_r3[1], &i_r3[2]); + cM3dGTri r1_160(&i_r3[1], &i_r3[3], &i_r3[2]); + + cM3dGLin r1_144; + r1_144.SetStartEnd(*i_r4, *i_r5); + + cXyz r1_138; + if (r1_198.cross(&r1_144, &r1_138, true, false)) { + r1_198.Up(2.0f); + if (r1_198.cross(&r1_144, &r1_138, true, false)) { + f32 f31 = r1_198.getSignedLenPos(i_r4); + cXyz r1_12c = *r1_198.GetNP(); + cXyz r1_120 = *i_r4 + (r1_12c * -f31); + cXyz r1_e4 = (*i_r4 - *i_r5); + f32 f30 = r1_e4.abs(); + cXyz r1_108 = (r1_138 - r1_120); + r1_108.normalizeZP(); + r1_108 = r1_108 * sqrtf(f30 * f30 - f31 * f31); + *i_r5 = r1_120 + r1_108; + return TRUE; + } + } else if (r1_160.cross(&r1_144, &r1_138, true, false)) { + r1_160.Up(2.0f); + if (r1_160.cross(&r1_144, &r1_138, true, false)) { + f32 f31 = r1_160.getSignedLenPos(i_r4); + cXyz r1_12c = *r1_160.GetNP(); + cXyz r1_120 = *i_r4 + (r1_12c * -f31); + cXyz r1_e4 = (*i_r4 - *i_r5); + f32 f30 = r1_e4.abs(); + cXyz r1_108 = (r1_138 - r1_120); + r1_108.normalizeZP(); + r1_108 = r1_108 * sqrtf(f30 * f30 - f31 * f31); + *i_r5 = r1_120 + r1_108; + return TRUE; + } + } + + return FALSE; } /* 00001CBC-00001D0C .text hairTopNodeCallBack__FP7J3DNodei */ @@ -566,20 +604,133 @@ static BOOL hairTopNodeCallBack(J3DNode* node, int param_1) { J3DJoint* joint = (J3DJoint*)node; s32 jntNo = joint->getJntNo(); MtxP mtx = model->getAnmMtx(jntNo); - i_this->m3174[0].set(mtx[0][3], mtx[1][3], mtx[2][3]); + cXyz* hairTopPos = i_this->getPHairPos(0); + hairTopPos->set(mtx[0][3], mtx[1][3], mtx[2][3]); } } return TRUE; } /* 00001D0C-00001F5C .text vecChange__FP4cXyzP4cXyzs */ -static void vecChange(cXyz*, cXyz*, s16) { - /* Nonmatching */ +static void vecChange(cXyz* i_r3, cXyz* i_r4, s16 i_r5) { + if (!cM3d_IsZero(i_r3->abs())) { + if (!cM3d_IsZero(i_r4->abs())) { + cXyz r1_4c = i_r3->norm(); + cXyz r1_40 = i_r4->norm(); + f32 dot = r1_4c.inprod(r1_40); + if (dot < cM_scos(i_r5)) { + cXyz r1_34 = r1_4c.outprod(r1_40); + mDoMtx_stack_c::rotAxisRadS(&r1_34, cM_s2rad(i_r5)); + mDoMtx_stack_c::multVec(&r1_4c, i_r4); + } else { + *i_r4 = r1_40; + } + } + } } +static u8 HairModeMaskData[] = { + 0x01, + 0x02, + 0x04, + 0x08, + 0x10, + 0x20, + 0x40, + 0x80, +}; + +static s16 baseAngleX[] = { + 0x8000, + 0x9000, + 0xA000, + 0xB000, + 0xB000, + 0xC000, + 0xC000, + 0xC000, +}; + /* 00001F5C-0000240C .text hairNodeCallBack__FP7J3DNodei */ static BOOL hairNodeCallBack(J3DNode* node, int param_1) { - /* Nonmatching */ + if (!param_1) { + J3DModel* model = j3dSys.getModel(); + daNpc_Md_c* i_this = (daNpc_Md_c*)model->getUserArea(); + if (i_this) { + J3DJoint* joint = (J3DJoint*)node; + s32 jntNo = joint->getJntNo(); + for (int i = 1; i < 8; i++) { + if (i_this->getHairJntNum(i) != jntNo) { + continue; + } + + MtxP mtx = model->getAnmMtx(jntNo); + if (!i_this->checkBitHairMode(HairModeMaskData[i])) { + i_this->setBitHairMode(HairModeMaskData[i]); + cXyz* hairPos = i_this->getPHairPos(i); + hairPos->set(mtx[0][3], mtx[1][3], mtx[2][3]); + f32* hairDist = i_this->getPHairDist(i); + cXyz* r29 = i_this->getPHairVec(i); + *r29 = (*hairPos - *i_this->getPHairPos(i-1)); + *hairDist = r29->abs(); + break; + } + + cXyz* r25 = i_this->getPHairPos(i-1); + cXyz* r28 = i_this->getPHairPos(i); + cXyz* r24 = i_this->getPHairVec(i); + if (i <= 1) { + r28->x = mtx[0][3]; + r28->y = mtx[1][3]; + r28->z = mtx[2][3]; + *r24 = (*r28 - *r25); + break; + } + + f32* hairDist = i_this->getPHairDist(i); + cXyz* r22 = i_this->getPHairVec(i-1); + cXyz r1_e8; + cXyz r1_dc; + cXyz r1_d0 = *r28; + cXyz r1_c4 = r1_d0 - *r25; + r1_e8.set(0.0f, -1.0f, 0.0f); + r1_e8 *= l_HIO.m14C; + f32 power; + dKyw_get_AllWind_vec(&i_this->current.pos, &r1_dc, &power); + r1_e8 += r1_dc * power * 3.0f; + r1_c4 += r1_e8; + r1_c4 = r1_c4.normZP() * *hairDist; + vecChange(r22, &r1_c4, 0x1000); + *r24 = r1_c4 * *hairDist; + *r28 = *r24 + *r25; + if (hairCross(i_this->getPHairWall(), i_this->getPHairPos(1), r28)) { + *r24 = (*r28 - *r25); + r24->normalizeZP(); + r1_c4 = *r24; + *r28 = r1_c4 * *hairDist + *r25; + } + + s16 prevHaitJntNo = i_this->getHairJntNum(i-1); + cXyz r1_b8 = r22->normZP(); + Mtx r1_124; + cM3d_UpMtx_Base(r1_b8, r1_c4, r1_124); + Mtx r1_f4; + mDoMtx_copy(model->getAnmMtx(prevHaitJntNo), r1_f4); + r1_f4[0][3] = 0.0f; + r1_f4[1][3] = 0.0f; + r1_f4[2][3] = 0.0f; + mDoMtx_stack_c::copy(r1_f4); + mDoMtx_stack_c::revConcat(r1_124); + mDoMtx_copy(mDoMtx_stack_c::get(), mtx); + mtx[0][3] = r28->x; + mtx[1][3] = r28->y; + mtx[2][3] = r28->z; + cMtx_copy(mtx, J3DSys::mCurrentMtx); + break; + } + } + } + return TRUE; } static char* hairName[] = { @@ -683,7 +834,7 @@ BOOL daNpc_Md_c::createHeap() { if (m3138 != 7) { modelData = (J3DModelData*)dComIfG_getObjectRes(mModelArcName, "mdwing.bdl"); - JUT_ASSERT(2077, modelData != 0); + JUT_ASSERT(2083, modelData != 0); mpWingMorf = new mDoExt_McaMorf( modelData, @@ -2045,7 +2196,7 @@ BOOL daNpc_Md_c::draw() { mDoMtx_stack_c::transS(l_ms_light_local_start); mDoMtx_stack_c::YrotM(0x8000); f32 temp = mCps.GetAtVecP()->abs(); - mDoMtx_stack_c::scaleM(0.1f, 0.1f, temp * (1.0f/10000.0f)); + mDoMtx_stack_c::scaleM(0.1f, 0.1f, temp * (1.0f/9600.0f)); mDoMtx_stack_c::revConcat(mtx); m0B70.update(mDoMtx_stack_c::get(), 0xFF, 90.0f); dComIfGd_getXluList()->entryImm(&m0B70, 0x1F);