JPAEmitter work

This commit is contained in:
Jasper St. Pierre
2023-11-18 16:44:42 -08:00
parent 6a7834cc2d
commit a9c6b0fca2
6 changed files with 158 additions and 64 deletions
+3 -19
View File
@@ -107,25 +107,9 @@ struct TVec3<f32> {
void zero() { x = y = z = 0.0f; }
void mul(const TVec3<f32>& a, const TVec3<f32>& b) {
register f32* dst = &x;
const register f32* srca = &a.x;
const register f32* srcb = &b.x;
register f32 a_x_y;
register f32 b_x_y;
register f32 x_y;
register f32 za;
register f32 zb;
register f32 z;
asm {
psq_l a_x_y, 0(srca), 0, 0
psq_l b_x_y, 0(srcb), 0, 0
ps_mul x_y, a_x_y, b_x_y
psq_st x_y, 0(dst), 0, 0
lfs za, 8(srca)
lfs zb, 8(srcb)
fmuls z, za, zb
stfs z, 8(dst)
};
x = a.x * b.x;
y = a.y * b.y;
z = a.z * b.z;
}
inline TVec3<f32>& operator+=(const TVec3<f32>& b) {
+1
View File
@@ -14,6 +14,7 @@ struct TRandom_fast_ {
}
u32 get_bit32(void) { return this->get(); }
u16 get_bit16(void) { return this->get() >> 16; }
// due to the float constant, having this function inlined adds that float to data,
// making it not match
+7 -2
View File
@@ -121,8 +121,8 @@ public:
/* 0x118 */ JGeometry::TVec3<f32> mVelOmni;
/* 0x124 */ JGeometry::TVec3<f32> mVelAxis;
/* 0x130 */ f32 mVolumeSize;
/* 0x134 */ u32 mVolumeEmitCount;
/* 0x138 */ u32 mVolumeEmitIdx;
/* 0x134 */ s32 mVolumeEmitCount;
/* 0x138 */ s32 mVolumeEmitIdx;
/* 0x13C */ u32 mVolumeEmitAngleCount;
/* 0x140 */ u32 mVolumeEmitXCount;
/* 0x144 */ u32 mVolumeEmitAngleMax;
@@ -240,6 +240,11 @@ public:
void initDrawMgr(JPATextureResource* texRes) { mDraw.initialize(this, texRes); }
void draw(MtxP cameraMtxP) { mDraw.draw(cameraMtxP); }
f32 getRandomF() { return mRandomSeed.get_ufloat_1(); }
f32 getRandomRF() { f32 x = mRandomSeed.get_ufloat_1(); return x + x - 1.0f; }
f32 getRandomSF() { return mRandomSeed.get_ufloat_1() - 0.5f; }
s16 getRandomSS() { return mRandomSeed.get_bit16(); }
static JPAEmitterInfo emtrInfo;
/* 0x000 */ VolumeFunc mVolumeFunc;
+2 -2
View File
@@ -37,11 +37,11 @@ public:
/* 0x04 */ JPABaseField * mpBaseField;
/* 0x08 */ JSULink<JPAFieldData> mLink;
/* 0x18 */ JGeometry::TVec3<f32> mVel;
/* 0x24 */ JGeometry::TVec3<f32> mAirPos;
/* 0x24 */ JGeometry::TVec3<f32> mLocalPos;
/* 0x30 */ f32 mAirMinDist;
/* 0x34 */ u32 field_0x34;
/* 0x38 */ u32 field_0x38;
/* 0x3C */ JGeometry::TVec3<f32> mAirDir;
/* 0x3C */ JGeometry::TVec3<f32> mLocalDir;
/* 0x48 */ f32 mMaxDistSq;
/* 0x4C */ f32 mFadeOutRate;
/* 0x50 */ f32 mFadeInRate;
+51 -17
View File
@@ -8,6 +8,7 @@
#include "JSystem/JParticle/JPAExtraShape.h"
#include "JSystem/JParticle/JPASweepShape.h"
#include "JSystem/JParticle/JPAKeyBlock.h"
#include "JSystem/JMath/JMATrigonometric.h"
#include "dolphin/mtx/mtx.h"
#include "dolphin/mtx/mtxvec.h"
@@ -15,33 +16,50 @@ JPAEmitterInfo JPABaseEmitter::emtrInfo;
/* 8025C128-8025C254 .text calcVolumePoint__14JPABaseEmitterFv */
void JPABaseEmitter::calcVolumePoint() {
/* Nonmatching */
emtrInfo.mVolumePos.z = 0.0f;
emtrInfo.mVolumePos.y = 0.0f;
emtrInfo.mVolumePos.x = 0.0f;
emtrInfo.mVelOmni.z = mRandomSeed.get_ufloat_1() - 0.5f;
emtrInfo.mVelOmni.y = mRandomSeed.get_ufloat_1() - 0.5f;
emtrInfo.mVelOmni.x = mRandomSeed.get_ufloat_1() - 0.5f;
emtrInfo.mVelAxis.x = mRandomSeed.get_ufloat_1() - 0.5f;
emtrInfo.mVelAxis.y = 0.0f;
emtrInfo.mVelAxis.z = mRandomSeed.get_ufloat_1() - 0.5f;
emtrInfo.mVolumePos.zero();
emtrInfo.mVelOmni.set(getRandomSF(), getRandomSF(), getRandomSF());
emtrInfo.mVelAxis.set(getRandomSF(), 0.0f, getRandomSF());
}
/* 8025C254-8025C394 .text calcVolumeLine__14JPABaseEmitterFv */
void JPABaseEmitter::calcVolumeLine() {
/* Nonmatching */
if (mDataFlag & 2) {
emtrInfo.mVolumePos.set(0.0f, 0.0f, emtrInfo.mVolumeSize * ((f32)emtrInfo.mVolumeEmitIdx / ((f32)emtrInfo.mVolumeEmitCount - 1.0f) - 0.5f));
emtrInfo.mVolumeEmitIdx++;
} else {
emtrInfo.mVolumePos.set(0.0f, 0.0f, emtrInfo.mVolumeSize * getRandomSF());
}
emtrInfo.mVelOmni.mul(emtrInfo.mVolumePos, emtrInfo.mEmitterGlobalScale);
emtrInfo.mVelAxis.set(emtrInfo.mVolumePos.x, 0.0f, emtrInfo.mVolumePos.z);
}
/* 8025C394-8025C538 .text calcVolumeCircle__14JPABaseEmitterFv */
void JPABaseEmitter::calcVolumeCircle() {
/* Nonmatching */
s16 angle;
if (mDataFlag & 0x02) {
s16 idx = (0x10000 * emtrInfo.mVolumeEmitIdx / emtrInfo.mVolumeEmitCount);
angle = idx * mVolumeSweep;
emtrInfo.mVolumeEmitIdx++;
} else {
angle = mVolumeSweep * getRandomSS();
}
f32 rad = getRandomF();
if (mDataFlag & 0x01)
rad = 1.0f - rad * rad;
rad = emtrInfo.mVolumeSize * (mVolumeMinRad + rad * (1.0f - mVolumeMinRad));
emtrInfo.mVolumePos.set(rad * JMASSin(angle), 0.0f, rad * JMASCos(angle));
emtrInfo.mVelOmni.mul(emtrInfo.mVolumePos, emtrInfo.mEmitterGlobalScale);
emtrInfo.mVelAxis.set(emtrInfo.mVolumePos.x, 0.0f, emtrInfo.mVolumePos.z);
}
/* 8025C538-8025C63C .text calcVolumeCube__14JPABaseEmitterFv */
void JPABaseEmitter::calcVolumeCube() {
/* Nonmatching */
emtrInfo.mVolumePos.set(emtrInfo.mVolumeSize * getRandomSF(), emtrInfo.mVolumeSize * getRandomSF(), emtrInfo.mVolumeSize * getRandomSF());
emtrInfo.mVelOmni.mul(emtrInfo.mVolumePos, emtrInfo.mEmitterGlobalScale);
emtrInfo.mVelAxis.set(emtrInfo.mVolumePos.x, 0.0f, emtrInfo.mVolumePos.z);
}
/* 8025C63C-8025C8A4 .text calcVolumeSphere__14JPABaseEmitterFv */
@@ -52,11 +70,27 @@ void JPABaseEmitter::calcVolumeSphere() {
/* 8025C8A4-8025CA28 .text calcVolumeCylinder__14JPABaseEmitterFv */
void JPABaseEmitter::calcVolumeCylinder() {
/* Nonmatching */
s16 angle = mVolumeSweep * getRandomSS();
f32 rad = getRandomF();
if (mDataFlag & 0x01)
rad = 1.0f - rad * rad;
rad = emtrInfo.mVolumeSize * (mVolumeMinRad + rad * (1.0f - mVolumeMinRad));
emtrInfo.mVolumePos.set(rad * JMASSin(angle), emtrInfo.mVolumeSize * getRandomRF(), rad * JMASCos(angle));
emtrInfo.mVelOmni.mul(emtrInfo.mVolumePos, emtrInfo.mEmitterGlobalScale);
emtrInfo.mVelAxis.set(emtrInfo.mVolumePos.x, 0.0f, emtrInfo.mVolumePos.z);
}
/* 8025CA28-8025CB54 .text calcVolumeTorus__14JPABaseEmitterFv */
void JPABaseEmitter::calcVolumeTorus() {
/* Nonmatching */
s16 angle1 = mVolumeSweep * getRandomSS();
s16 angle2 = getRandomSS();
f32 rad = mVolumeMinRad * emtrInfo.mVolumeSize;
emtrInfo.mVelAxis.set(rad * JMASSin(angle1) * JMASCos(angle2), rad * JMASSin(angle2), rad * JMASCos(angle1) * JMASCos(angle2));
emtrInfo.mVolumePos.set(emtrInfo.mVelAxis.x + emtrInfo.mVolumeSize * JMASSin(angle1), emtrInfo.mVelAxis.y, emtrInfo.mVelAxis.z + emtrInfo.mVolumeSize * JMASCos(angle1));
emtrInfo.mVelOmni.mul(emtrInfo.mVolumePos, emtrInfo.mEmitterGlobalScale);
}
/* 8025CB54-8025D0B0 .text create__14JPABaseEmitterFP20JPADataBlockLinkInfo */
@@ -275,7 +309,7 @@ void JPABaseEmitter::calcChild() {
/* 8025D8CC-8025DA90 .text calcKey__14JPABaseEmitterFv */
void JPABaseEmitter::calcKey() {
/* Nonmatching */
for (u32 i = 0; i < getEmitterDataBlockInfoPtr()->getKeyNum(); i++) {
for (s32 i = 0; i < getEmitterDataBlockInfoPtr()->getKeyNum(); i++) {
JPAKeyBlock* key = getEmitterDataBlockInfoPtr()->getKey()[i];
f32 tick = mTick;
const f32* dataPtr = key->getKeyDataPtr();
+94 -24
View File
@@ -8,6 +8,8 @@
#include "JSystem/JParticle/JPAParticle.h"
#include "JSystem/JParticle/JPAFieldBlock.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JMath/JMATrigonometric.h"
#include "dolphin/mtx/mtxvec.h"
JPAFieldContainer fc;
JPAEmitterInfo * JPAFieldData::pEmtrInfo;
@@ -82,93 +84,153 @@ bool JPABaseField::isItinRange(JPAFieldData* data, f32 v) {
}
/* 8025A344-8025A3E4 .text preCalc__15JPAGravityFieldFP12JPAFieldData */
void JPAGravityField::preCalc(JPAFieldData*) {
/* Nonmatching */
void JPAGravityField::preCalc(JPAFieldData* data) {
JPABaseField::preCalc(data);
if (data->mSttFlag & 0x02) {
f32 mag = data->mMag;
data->mVel.x = data->mDir.x * mag;
data->mVel.y = data->mDir.y * mag;
data->mVel.z = data->mDir.z * mag;
} else {
JGeometry::TVec3<f32> rotDir;
MTXMultVec(JPAFieldData::pEmtrInfo->mGlobalRot, data->mDir, rotDir);
f32 mag = data->mMag;
data->mVel.x = rotDir.x * mag;
data->mVel.y = rotDir.y * mag;
data->mVel.z = rotDir.z * mag;
}
}
/* 8025A3E4-8025A404 .text calc__15JPAGravityFieldFP12JPAFieldDataP15JPABaseParticle */
void JPAGravityField::calc(JPAFieldData*, JPABaseParticle*) {
/* Nonmatching */
void JPAGravityField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
calcVel(data, ptcl);
}
/* 8025A404-8025A510 .text preCalc__11JPAAirFieldFP12JPAFieldData */
void JPAAirField::preCalc(JPAFieldData*) {
/* Nonmatching */
void JPAAirField::preCalc(JPAFieldData* data) {
JPABaseField::preCalc(data);
if (data->mSttFlag & 0x02) {
data->mLocalDir.set(data->mDir);
} else {
MTXMultVec(JPAFieldData::pEmtrInfo->mGlobalRot, data->mDir, data->mLocalDir);
}
f32 mag = data->mMag;
data->mVel.x = data->mLocalDir.x * mag;
data->mVel.y = data->mLocalDir.y * mag;
data->mVel.z = data->mLocalDir.z * mag;
if (data->mSttFlag & 0x01) {
data->mAirMinDist = JMASCos(data->mVal1 * 0xFFFF);
if (data->mSttFlag & 0x02) {
data->mLocalPos.set(data->mPos);
} else {
MTXMultVec(JPAFieldData::pEmtrInfo->mGlobalRot, data->mLocalPos, data->mPos);
}
}
}
/* 8025A510-8025A6EC .text calc__11JPAAirFieldFP12JPAFieldDataP15JPABaseParticle */
void JPAAirField::calc(JPAFieldData*, JPABaseParticle*) {
void JPAAirField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025A6EC-8025A788 .text preCalc__14JPAMagnetFieldFP12JPAFieldData */
void JPAMagnetField::preCalc(JPAFieldData*) {
/* Nonmatching */
void JPAMagnetField::preCalc(JPAFieldData* data) {
JPABaseField::preCalc(data);
if (data->mSttFlag & 0x02) {
data->mLocalPos.set(data->mPos);
} else {
const JGeometry::TVec3<f32>& emtrTrans = JPAFieldData::pEmtrInfo->mEmitterTranslation;
data->mLocalPos.x = data->mPos.x - emtrTrans.x;
data->mLocalPos.y = data->mPos.y - emtrTrans.y;
data->mLocalPos.z = data->mPos.z - emtrTrans.z;
MTXMultVec(JPAFieldData::pEmtrInfo->mGlobalRot, data->mLocalPos, data->mLocalPos);
}
}
/* 8025A788-8025A8AC .text calc__14JPAMagnetFieldFP12JPAFieldDataP15JPABaseParticle */
void JPAMagnetField::calc(JPAFieldData*, JPABaseParticle*) {
void JPAMagnetField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
if (data->mSttFlag & 0x02) {
data->mVel.x = data->mLocalPos.x - ptcl->mPosition.x;
data->mVel.y = data->mLocalPos.y - ptcl->mPosition.y;
data->mVel.z = data->mLocalPos.z - ptcl->mPosition.z;
} else {
data->mVel.x = data->mLocalPos.x - ptcl->mLocalPosition.x;
data->mVel.y = data->mLocalPos.y - ptcl->mLocalPosition.y;
data->mVel.z = data->mLocalPos.z - ptcl->mLocalPosition.z;
}
data->mVel.normalize();
calcVel(data, ptcl);
}
/* 8025A8AC-8025A954 .text preCalc__14JPANewtonFieldFP12JPAFieldData */
void JPANewtonField::preCalc(JPAFieldData*) {
/* Nonmatching */
void JPANewtonField::preCalc(JPAFieldData* data) {
JPABaseField::preCalc(data);
if (data->mSttFlag & 0x02) {
data->mLocalPos.set(data->mPos);
} else {
const JGeometry::TVec3<f32>& emtrTrans = JPAFieldData::pEmtrInfo->mEmitterTranslation;
data->mLocalPos.x = data->mPos.x - emtrTrans.x;
data->mLocalPos.y = data->mPos.y - emtrTrans.y;
data->mLocalPos.z = data->mPos.z - emtrTrans.z;
MTXMultVec(JPAFieldData::pEmtrInfo->mGlobalRot, data->mLocalPos, data->mLocalPos);
}
data->mVal2 = data->mVal1 * data->mVal1;
}
/* 8025A954-8025ABB8 .text calc__14JPANewtonFieldFP12JPAFieldDataP15JPABaseParticle */
void JPANewtonField::calc(JPAFieldData*, JPABaseParticle*) {
void JPANewtonField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025ABB8-8025ACA0 .text preCalc__14JPAVortexFieldFP12JPAFieldData */
void JPAVortexField::preCalc(JPAFieldData*) {
void JPAVortexField::preCalc(JPAFieldData* data) {
/* Nonmatching */
}
/* 8025ACA0-8025AE04 .text calc__14JPAVortexFieldFP12JPAFieldDataP15JPABaseParticle */
void JPAVortexField::calc(JPAFieldData*, JPABaseParticle*) {
void JPAVortexField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025AE04-8025B114 .text preCalc__18JPAConvectionFieldFP12JPAFieldData */
void JPAConvectionField::preCalc(JPAFieldData*) {
void JPAConvectionField::preCalc(JPAFieldData* data) {
/* Nonmatching */
}
/* 8025B114-8025B3CC .text calc__18JPAConvectionFieldFP12JPAFieldDataP15JPABaseParticle */
void JPAConvectionField::calc(JPAFieldData*, JPABaseParticle*) {
void JPAConvectionField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025B3CC-8025B50C .text calc__14JPARandomFieldFP12JPAFieldDataP15JPABaseParticle */
void JPARandomField::calc(JPAFieldData*, JPABaseParticle*) {
void JPARandomField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025B50C-8025B584 .text init__12JPADragFieldFP12JPAFieldDataP15JPABaseParticle */
void JPADragField::init(JPAFieldData*, JPABaseParticle*) {
void JPADragField::init(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025B584-8025B5F4 .text calc__12JPADragFieldFP12JPAFieldDataP15JPABaseParticle */
void JPADragField::calc(JPAFieldData*, JPABaseParticle*) {
void JPADragField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025B5F4-8025B718 .text preCalc__12JPASpinFieldFP12JPAFieldData */
void JPASpinField::preCalc(JPAFieldData*) {
void JPASpinField::preCalc(JPAFieldData* data) {
/* Nonmatching */
}
/* 8025B718-8025B7F8 .text calc__12JPASpinFieldFP12JPAFieldDataP15JPABaseParticle */
void JPASpinField::calc(JPAFieldData*, JPABaseParticle*) {
void JPASpinField::calc(JPAFieldData* data, JPABaseParticle* ptcl) {
/* Nonmatching */
}
/* 8025B7F8-8025B960 .text initField__15JPAFieldManagerFP20JPADataBlockLinkInfoP14JPAEmitterInfo */
void JPAFieldManager::initField(JPADataBlockLinkInfo* dataInfo, JPAEmitterInfo* emtrInfo) {
/* Nonmatching */
u8 fieldNum = dataInfo->getFieldNum();
JPAFieldBlock** fieldBlock = dataInfo->getField();
for (u8 i = 0; i < fieldNum; i++) {
@@ -219,8 +281,16 @@ void JPAFieldManager::calc(JPABaseParticle* ptcl) {
/* Nonmatching */
for (JSULink<JPAFieldData>* link = mList.getFirst(); link != NULL; link = link->getNext()) {
JPAFieldData* data = link->getObject();
if (data->mSttFlag & 0x80) {
// This isn't quite right, probably a TVec3 inline?
f32 z = ptcl->mPosition.z - data->mPos.z; z *= z;
f32 x = ptcl->mPosition.x - data->mPos.x; x *= x;
f32 y = ptcl->mPosition.y - data->mPos.y; y *= y;
f32 dist = z + y + x;
if (!data->mpBaseField->isItinRange(data, dist))
continue;
}
data->mpBaseField->calc(data, ptcl);
// more to do here
}
}