From 12b821eca2e9dc073fd85018e433b5d3479637bd Mon Sep 17 00:00:00 2001 From: LagoLunatic Date: Wed, 27 Dec 2023 18:12:09 -0500 Subject: [PATCH] particle/JGeometry progress --- include/JSystem/JGeometry.h | 110 +++++++++---------------- include/JSystem/JParticle/JPAEmitter.h | 12 ++- include/d/d_particle.h | 6 +- include/dolphin/mtx/vec.h | 18 +--- src/JSystem/JParticle/JPADraw.cpp | 24 +----- src/d/d_particle.cpp | 57 ++++++++++--- 6 files changed, 101 insertions(+), 126 deletions(-) diff --git a/include/JSystem/JGeometry.h b/include/JSystem/JGeometry.h index 89391f18e..aa9113b63 100644 --- a/include/JSystem/JGeometry.h +++ b/include/JSystem/JGeometry.h @@ -30,8 +30,8 @@ struct TVec3 { }; template <> -struct TVec3 { - s16 x, y, z; +struct TVec3 : public SVec { + // s16 x, y, z; TVec3& operator=(const TVec3& b) { set(b.x, b.y, b.z); @@ -49,39 +49,14 @@ struct TVec3 { } }; -inline void setTVec3f(const f32* vec_a, f32* vec_b) { - const register f32* v_a = vec_a; - register f32* v_b = vec_b; - - register f32 a_x; - register f32 b_x; - - asm { - psq_l a_x, 0(v_a), 0, 0 - lfs b_x, 8(v_a) - psq_st a_x, 0(v_b), 0, 0 - stfs b_x, 8(v_b) - }; -} - -// Until we figure out TVec3 ctors -inline void setTVec3f(const Vec& vec_a, Vec& vec_b) { - setTVec3f(&vec_a.x, &vec_b.x); -} - -inline float fsqrt_step(float mag) { - f32 root = __frsqrte(mag); - return 0.5f * root * (3.0f - mag * (root * root)); -} - template <> -struct TVec3 { - f32 x; - f32 y; - f32 z; +struct TVec3 : public Vec { + // f32 x; + // f32 y; + // f32 z; inline TVec3(const Vec& i_vec) { - setTVec3f(&i_vec.x, &x); + set(i_vec); } TVec3() {} @@ -148,52 +123,38 @@ struct TVec3 { f32 normalize_broken() { f32 sq = squared(); - if (sq <= 3.814697e-06f) { + if (sq <= TUtil::epsilon()) { return 0.0f; } - f32 norm; - if (sq <= 0.0f) { - norm = sq; - } else { - norm = fsqrt_step(sq); - } + f32 norm = TUtil::inv_sqrt(sq); scale(norm); return norm; } f32 normalize() { f32 sq = squared(); - if (sq <= 3.814697e-06f) { + if (sq <= TUtil::epsilon()) { return 0.0f; } - f32 norm; - if (sq <= 0.0f) { - norm = sq; - } else { - norm = fsqrt_step(sq); - } + f32 norm = TUtil::inv_sqrt(sq); scale(1.0f / norm); return norm; } f32 normalize(const TVec3& other) { f32 sq = other.squared(); - if (sq <= 3.814697e-06f) { + if (sq <= TUtil::epsilon()) { zero(); return 0.0f; } - f32 norm; - if (sq <= 0.0f) { - norm = sq; - } else { - norm = fsqrt_step(sq); - } + f32 norm = TUtil::inv_sqrt(sq); scale(1.0f / norm, other); return norm; } f32 length() const { - return VECMag((Vec*)this); + f32 sqr = squared(); + return TUtil::sqrt(sqr); } void scale(register f32 sc) { @@ -233,7 +194,7 @@ struct TVec3 { } bool isZero() const { - return squared() <= 32.0f * 3.814697e-06f; + return squared() <= TUtil::epsilon(); } void cross(const TVec3& a, const TVec3& b) { @@ -242,15 +203,10 @@ struct TVec3 { void setLength(f32 len) { f32 sq = squared(); - if (sq <= 3.814697e-06f * 32.0f) { + if (sq <= TUtil::epsilon()) { return; } - f32 norm; - if (sq <= 0.0f) { - norm = sq; - } else { - norm = fsqrt_step(sq); - } + f32 norm = TUtil::inv_sqrt(sq); scale(norm * len); } @@ -336,11 +292,7 @@ struct TVec2 { f32 length() { f32 sqr = squared(); - if (sqr <= 0.0f) { - return sqr; - } - sqr *= fsqrt_step(sqr); - return sqr; + return TUtil::sqrt(sqr); } T x; @@ -408,14 +360,26 @@ struct TBox2 : TBox > { template struct TUtil { - static inline T clamp(T v, T min, T max) { - if (v < min) { - return min; + static inline f32 epsilon() { + return 3.81469727e-06f; + } + + static inline f32 sqrt(f32 mag) { + if (mag <= 0.0f) { + return mag; + } else { + f32 root = __frsqrte(mag); + return 0.5f * root * (3.0f - mag * (root * root)) * mag; } - if (v > max) { - return max; + } + + static inline f32 inv_sqrt(f32 mag) { + if (mag <= 0.0f) { + return mag; + } else { + f32 root = __frsqrte(mag); + return 0.5f * root * (3.0f - mag * (root * root)); } - return v; } }; diff --git a/include/JSystem/JParticle/JPAEmitter.h b/include/JSystem/JParticle/JPAEmitter.h index 0539a85ee..5c0d4d598 100644 --- a/include/JSystem/JParticle/JPAEmitter.h +++ b/include/JSystem/JParticle/JPAEmitter.h @@ -186,6 +186,7 @@ public: void setGlobalRotation(const JGeometry::TVec3& rot) { JPAGetXYZRotateMtx(rot.x, rot.y, rot.z, mGlobalRotation); } + void getGlobalTranslation(JGeometry::TVec3& out) const { out.set(mGlobalTranslation); } void setGlobalTranslation(f32 x, f32 y, f32 z) { mGlobalTranslation.set(x, y, z); } void setGlobalTranslation(const JGeometry::TVec3& trans) { mGlobalTranslation.set(trans); } void setGlobalScale(const JGeometry::TVec3& scale) { @@ -276,11 +277,9 @@ public: void getCamMtxPtr() {} void getChildParticleList() {} void getCurrentCreateNumber() const {} - void getEmitterAxis(JGeometry::TVec3&, JGeometry::TVec3&, JGeometry::TVec3&) const {} void getFovy() {} void getFrame() {} void getGlobalParticleScale(JGeometry::TVec3&) const {} - void getGlobalTranslation(JGeometry::TVec3&) const {} void getParticleList() {} void getRate() const {} void getgReRDirection(JGeometry::TVec3&) {} @@ -297,6 +296,15 @@ public: static JPAEmitterInfo emtrInfo; + void getEmitterAxis(JGeometry::TVec3& vec0, JGeometry::TVec3& vec1, JGeometry::TVec3& vec2) const { + // Not sure if this implementation is correct. It does seem to match for dPa_waveEcallBack::executeAfter, but + // a non-static function (const) only referencing a static variable is unusual, and this implementation isn't + // complex enough to match the size of the inline in the demo debug map (0x128 bytes). + vec0.set(emtrInfo.mEmitterGlobalRot[0][0], emtrInfo.mEmitterGlobalRot[1][0], emtrInfo.mEmitterGlobalRot[2][0]); + vec1.set(emtrInfo.mEmitterGlobalRot[0][1], emtrInfo.mEmitterGlobalRot[1][1], emtrInfo.mEmitterGlobalRot[2][1]); + vec2.set(emtrInfo.mEmitterGlobalRot[0][2], emtrInfo.mEmitterGlobalRot[1][2], emtrInfo.mEmitterGlobalRot[2][2]); + } + /* 0x000 */ VolumeFunc mVolumeFunc; /* 0x00C */ JGeometry::TVec3 mEmitterScale; /* 0x018 */ JGeometry::TVec3 mEmitterTranslation; diff --git a/include/d/d_particle.h b/include/d/d_particle.h index 168aae6e8..1a6da94ae 100644 --- a/include/d/d_particle.h +++ b/include/d/d_particle.h @@ -119,7 +119,7 @@ public: /* 0x1C */ cXyz mCollapsePos[2]; /* 0x34 */ cXyz* mpPos; /* 0x38 */ csXyz* mpRot; - /* 0x3C */ Vec mRotMtx[3]; + /* 0x3C */ JGeometry::TVec3 mRotMtx[3]; /* 0x60 */ JPABaseEmitter* mpBaseEmitter; }; @@ -330,8 +330,8 @@ public: dPa_setColorEcallBack(const GXColor& color) { mColor = color; } virtual ~dPa_setColorEcallBack() {} - virtual void draw(JPABaseEmitter*); - virtual void setup(JPABaseEmitter*, const cXyz*, const csXyz*, s8); + virtual void draw(JPABaseEmitter*) { GXSetTevColor(GX_TEVREG1, mColor); } + virtual void setup(JPABaseEmitter*, const cXyz*, const csXyz*, s8) {} public: /* 0x04 */ GXColor mColor; diff --git a/include/dolphin/mtx/vec.h b/include/dolphin/mtx/vec.h index 8870fc0fe..c361bb78a 100644 --- a/include/dolphin/mtx/vec.h +++ b/include/dolphin/mtx/vec.h @@ -40,21 +40,9 @@ inline void C_VECAdd(register const Vec* a, register const Vec* b, register Vec* } inline void C_VECSubtract(register const Vec* a, register const Vec* b, register Vec* ab) { - register f32 axy; - register f32 bxy; - register f32 az; - register f32 subz; - register f32 bz; - asm { - psq_l axy, 0(a), 0, 0 - psq_l bxy, 0(b), 0, 0 - ps_sub bxy, axy, bxy - psq_st bxy, 0(ab), 0, 0 - psq_l az, 8(a), 1, 0 - psq_l bz, 8(b), 1, 0 - ps_sub subz, az, bz - psq_st subz, 8(ab), 1, 0 - } + ab->x = a->x - b->x; + ab->y = a->y - b->y; + ab->z = a->z - b->z; } inline f32 C_VECSquareMag(const Vec* v) { diff --git a/src/JSystem/JParticle/JPADraw.cpp b/src/JSystem/JParticle/JPADraw.cpp index 851a34d46..b808441cd 100644 --- a/src/JSystem/JParticle/JPADraw.cpp +++ b/src/JSystem/JParticle/JPADraw.cpp @@ -643,25 +643,15 @@ void JPADraw::setDrawCalcVisitors(const JPADraw::JPADrawVisitorDefFlags& flags) /* 8026ADB0-8026B3DC .text setParticleClipBoard__7JPADrawFv */ void JPADraw::setParticleClipBoard() { - /* Nonmatching - top switch */ - switch (dc.pbsp->getType()) { case JPABaseShape::JPAType_Billboard: - break; case JPABaseShape::JPAType_DirBillboard: PSMTXIdentity(cb.mDrawMtx); break; case JPABaseShape::JPAType_YBillboard: loadYBBMtx(cb.mDrawMtxPtr); break; - case JPABaseShape::JPAType_Point: - case JPABaseShape::JPAType_Line: - case JPABaseShape::JPAType_Direction: - case JPABaseShape::JPAType_DirectionCross: - case JPABaseShape::JPAType_Stripe: - case JPABaseShape::JPAType_StripeCross: - case JPABaseShape::JPAType_Rotation: - case JPABaseShape::JPAType_RotationCross: + default: MTXCopy(cb.mDrawMtxPtr, cb.mDrawMtx); break; } @@ -739,25 +729,15 @@ void JPADraw::setParticleClipBoard() { /* 8026B3DC-8026B938 .text setChildClipBoard__7JPADrawFv */ void JPADraw::setChildClipBoard() { - /* Nonmatching - top switch */ - switch (dc.pssp->getType()) { case JPABaseShape::JPAType_Billboard: - break; case JPABaseShape::JPAType_DirBillboard: PSMTXIdentity(cb.mDrawMtx); break; case JPABaseShape::JPAType_YBillboard: loadYBBMtx(cb.mDrawMtxPtr); break; - case JPABaseShape::JPAType_Point: - case JPABaseShape::JPAType_Line: - case JPABaseShape::JPAType_Direction: - case JPABaseShape::JPAType_DirectionCross: - case JPABaseShape::JPAType_Stripe: - case JPABaseShape::JPAType_StripeCross: - case JPABaseShape::JPAType_Rotation: - case JPABaseShape::JPAType_RotationCross: + default: MTXCopy(cb.mDrawMtxPtr, cb.mDrawMtx); break; } diff --git a/src/d/d_particle.cpp b/src/d/d_particle.cpp index b1337e981..f2aec94dc 100644 --- a/src/d/d_particle.cpp +++ b/src/d/d_particle.cpp @@ -12,6 +12,11 @@ #include "SSystem/SComponent/c_malloc.h" #include "m_Do/m_Do_lib.h" +static f32 dummy_2100[3] = {1.0f, 1.0f, 1.0f}; +static f32 dummy_2080[3] = {1.0f, 1.0f, 1.0f}; + +static Vec dummy_3569; + /* 8007A4D8-8007A514 .text __ct__18dPa_modelEmitter_cFv */ dPa_modelEmitter_c::dPa_modelEmitter_c() { cNd_ForcedClear(this); @@ -557,8 +562,47 @@ void dPa_waveEcallBack::remove() { } /* 8007E2BC-8007E484 .text executeAfter__17dPa_waveEcallBackFP14JPABaseEmitter */ -void dPa_waveEcallBack::executeAfter(JPABaseEmitter*) { - /* Nonmatching */ +void dPa_waveEcallBack::executeAfter(JPABaseEmitter* emitter) { + /* Nonmatching - how to make TVec3 only exist in registers without being stored to the stack? */ + + emitter->getEmitterAxis(mRotMtx[0], mRotMtx[1], mRotMtx[2]); + + if (mState != 0) { + emitter->setDirectionalSpeed(0.0f); + if (mFadeTimer > 0) { + mFadeTimer--; + } else { + remove(); + } + return; + } + + JGeometry::TVec3 delta; + emitter->getGlobalTranslation(delta); // TODO + emitter->setGlobalTranslation(*mpPos); + delta.sub(*mpPos); // TODO + f32 vel = delta.length(); + if (vel >= mMaxParticleVelocity) { + vel = mMaxParticleVelocity; + } + f32 speed = mVelFade1 * vel * mVelFade2; + + JGeometry::TVec3 rot; + rot.x = 0; + rot.y = mpRot->y; + rot.z = 0; + emitter->setGlobalRotation(rot); + + if (fabsf(speed - mVel) > mVelSpeed) { + if (speed - mVel > 0.0f) { + speed = mVel + mVelSpeed; + } else { + speed = mVel - mVelSpeed; + } + } + + emitter->setDirectionalSpeed(speed); + mVel = speed; } /* 8007E484-8007E804 .text draw__17dPa_waveEcallBackFP14JPABaseEmitter */ @@ -647,12 +691,3 @@ void dPa_stripesEcallBack::setup(JPABaseEmitter*, const cXyz*, const csXyz*, s8) /* 8007FAE8-8007FAEC .text setup__22dPa_selectTexEcallBackFP14JPABaseEmitterPC4cXyzPC5csXyzSc */ void dPa_selectTexEcallBack::setup(JPABaseEmitter*, const cXyz*, const csXyz*, s8) { } - -/* 8007FF78-8007FFA8 .text draw__21dPa_setColorEcallBackFP14JPABaseEmitter */ -void dPa_setColorEcallBack::draw(JPABaseEmitter*) { - GXSetTevColor(GX_TEVREG1, mColor); -} - -/* 8007FFA8-8007FFAC .text setup__21dPa_setColorEcallBackFP14JPABaseEmitterPC4cXyzPC5csXyzSc */ -void dPa_setColorEcallBack::setup(JPABaseEmitter*, const cXyz*, const csXyz*, s8) { -}