mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-08-04 00:38:59 -04:00
Reorganize library code into libs/ (#3119)
* Reorganize files into libs/{dolphin,JSystem,PowerPC_EABI_Support,revolution,TRK_MINNOW_DOLPHIN}
* Update configure.py and project.py for new libs structure
* Refactor `#include <dolphin/x.h>` -> `<x.h>`
* Remove `__REVOLUTION_SDK__` forwards from dolphin
* Fix dolphin/ references in revolution
* Wrap `#include <dolphin.h>` in `!__REVOLUTION_SDK__`
* Always build TRK against dolphin headers
* Resolve revolution SDK header resolution issues
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,38 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAChildShape.h"
|
||||
#include "JSystem/JParticle/JPAParticle.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include <gx.h>
|
||||
#include <os.h>
|
||||
|
||||
void JPARegistChildPrmEnv(JPAEmitterWorkData* work) {
|
||||
JPAChildShape* csp = work->mpRes->getCsp();
|
||||
JPABaseEmitter* emtr = work->mpEmtr;
|
||||
GXColor prm, env;
|
||||
csp->getPrmClr(&prm);
|
||||
csp->getEnvClr(&env);
|
||||
prm.r = COLOR_MULTI(prm.r, emtr->mGlobalPrmClr.r);
|
||||
prm.g = COLOR_MULTI(prm.g, emtr->mGlobalPrmClr.g);
|
||||
prm.b = COLOR_MULTI(prm.b, emtr->mGlobalPrmClr.b);
|
||||
prm.a = COLOR_MULTI(prm.a, emtr->mGlobalPrmClr.a);
|
||||
env.r = COLOR_MULTI(env.r, emtr->mGlobalEnvClr.r);
|
||||
env.g = COLOR_MULTI(env.g, emtr->mGlobalEnvClr.g);
|
||||
env.b = COLOR_MULTI(env.b, emtr->mGlobalEnvClr.b);
|
||||
GXSetTevColor(GX_TEVREG0, prm);
|
||||
GXSetTevColor(GX_TEVREG1, env);
|
||||
}
|
||||
|
||||
void JPACalcChildAlphaOut(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
f32 anm = (1.0f - ptcl->mTime) * 255.0f;
|
||||
OSf32tou8(&anm, &ptcl->mPrmColorAlphaAnm);
|
||||
}
|
||||
|
||||
void JPACalcChildScaleOut(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
ptcl->mParticleScaleX = ptcl->mScaleOut * (1.0f - ptcl->mTime);
|
||||
ptcl->mParticleScaleY = ptcl->mAlphaWaveRandom * (1.0f - ptcl->mTime);
|
||||
}
|
||||
|
||||
JPAChildShape::JPAChildShape(u8 const* pData) {
|
||||
mpData = (JPAChildShapeData*)pData;
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPADynamicsBlock.h"
|
||||
#include "JSystem/JMath/JMATrigonometric.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
|
||||
void JPAVolumePoint(JPAEmitterWorkData* work) {
|
||||
work->mVolumeCalcData.mVolumePos.zero();
|
||||
work->mVolumeCalcData.mVelOmni.set(work->mpEmtr->get_r_zh(), work->mpEmtr->get_r_zh(),
|
||||
work->mpEmtr->get_r_zh());
|
||||
work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVelOmni.x, 0.0f,
|
||||
work->mVolumeCalcData.mVelOmni.z);
|
||||
}
|
||||
|
||||
void JPAVolumeLine(JPAEmitterWorkData* work) {
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) {
|
||||
work->mVolumeCalcData.mVolumePos.set(
|
||||
0.0f, 0.0f,
|
||||
work->mVolumeSize * ((work->mVolumeEmitIdx / (work->mEmitCount - 1.0f) - 0.5f)));
|
||||
work->mVolumeEmitIdx++;
|
||||
} else {
|
||||
work->mVolumeCalcData.mVolumePos.set(0.0f, 0.0f,
|
||||
work->mVolumeSize * work->mpEmtr->get_r_zh());
|
||||
}
|
||||
|
||||
work->mVolumeCalcData.mVelOmni.set(0.0f, 0.0f,
|
||||
work->mVolumeCalcData.mVolumePos.z * work->mGlobalScl.z);
|
||||
work->mVolumeCalcData.mVelAxis.set(0.0f, 0.0f, work->mVolumeCalcData.mVolumePos.z);
|
||||
}
|
||||
|
||||
// NONMATCHING regalloc. Could be issue with mul asm implementations
|
||||
void JPAVolumeCircle(JPAEmitterWorkData* work) {
|
||||
s16 theta;
|
||||
f32 distance;
|
||||
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) {
|
||||
theta = (s16)((work->mVolumeEmitIdx << 16) / work->mEmitCount);
|
||||
theta = theta * work->mVolumeSweep;
|
||||
work->mVolumeEmitIdx++;
|
||||
} else {
|
||||
theta = work->mVolumeSweep * work->mpEmtr->get_r_ss();
|
||||
}
|
||||
|
||||
distance = work->mpEmtr->get_r_f();
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedDensity)) {
|
||||
distance = 1.0f - (distance * distance);
|
||||
}
|
||||
|
||||
distance = work->mVolumeSize * (work->mVolumeMinRad + distance * (1.0f - work->mVolumeMinRad));
|
||||
work->mVolumeCalcData.mVolumePos.set(distance * JMASSin(theta), 0.0f,
|
||||
distance * JMASCos(theta));
|
||||
work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl);
|
||||
work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f,
|
||||
work->mVolumeCalcData.mVolumePos.z);
|
||||
}
|
||||
|
||||
void JPAVolumeCube(JPAEmitterWorkData* work) {
|
||||
work->mVolumeCalcData.mVolumePos.set(work->mpEmtr->get_r_zh() * work->mVolumeSize,
|
||||
work->mpEmtr->get_r_zh() * work->mVolumeSize,
|
||||
work->mpEmtr->get_r_zh() * work->mVolumeSize);
|
||||
work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl);
|
||||
work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f, work->mVolumeCalcData.mVolumePos.z);
|
||||
}
|
||||
|
||||
static void JPAVolumeSphere(JPAEmitterWorkData* work) {
|
||||
s16 phi, r28;
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) {
|
||||
phi = u16(work->mVolumeX * 0x8000 / (work->mDivNumber - 1) + 0x4000);
|
||||
u16 r26 = u16(work->mVolumeAngleNum * 0x10000 / (work->mVolumeAngleMax - 1));
|
||||
r28 = f32(r26) * work->mVolumeSweep + 0x8000;
|
||||
work->mVolumeAngleNum++;
|
||||
if (work->mVolumeAngleNum == work->mVolumeAngleMax) {
|
||||
work->mVolumeAngleNum = 0;
|
||||
work->mVolumeX++;
|
||||
if (work->mVolumeX * 2 < work->mDivNumber) {
|
||||
work->mVolumeAngleMax = work->mVolumeAngleMax != 1 ?
|
||||
work->mVolumeAngleMax + 4 : work->mVolumeAngleMax + 3;
|
||||
} else {
|
||||
work->mVolumeAngleMax = work->mVolumeAngleMax != 4 ? work->mVolumeAngleMax - 4 : 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
phi = work->mpEmtr->get_r_ss() >> 1;
|
||||
r28 = work->mVolumeSweep * work->mpEmtr->get_r_ss();
|
||||
}
|
||||
|
||||
f32 f31 = work->mpEmtr->get_r_f();
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedDensity)) {
|
||||
f31 = 1.0f - f31 * f31 * f31;
|
||||
}
|
||||
f31 = work->mVolumeSize * (work->mVolumeMinRad + f31 * (1.0f - work->mVolumeMinRad));
|
||||
work->mVolumeCalcData.mVolumePos.set(f31 * JMASCos(phi) * JMASSin(r28), -f31 * JMASSin(phi),
|
||||
f31 * JMASCos(phi) * JMASCos(r28));
|
||||
work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl);
|
||||
work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f,
|
||||
work->mVolumeCalcData.mVolumePos.z);
|
||||
}
|
||||
|
||||
static void JPAVolumeCylinder(JPAEmitterWorkData* work) {
|
||||
s16 r30 = work->mVolumeSweep * work->mpEmtr->get_r_ss();
|
||||
f32 f31 = work->mpEmtr->get_r_f();
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedDensity)) {
|
||||
f31 = 1.0f - f31 * f31;
|
||||
}
|
||||
f31 = work->mVolumeSize * (work->mVolumeMinRad + f31 * (1.0f - work->mVolumeMinRad));
|
||||
work->mVolumeCalcData.mVolumePos.set(
|
||||
f31 * JMASSin(r30), work->mVolumeSize * work->mpEmtr->get_r_zp(), f31 * JMASCos(r30));
|
||||
work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl);
|
||||
work->mVolumeCalcData.mVelAxis.set(work->mVolumeCalcData.mVolumePos.x, 0.0f,
|
||||
work->mVolumeCalcData.mVolumePos.z);
|
||||
}
|
||||
|
||||
static void JPAVolumeTorus(JPAEmitterWorkData* work) {
|
||||
s16 theta = work->mVolumeSweep * work->mpEmtr->get_r_ss();
|
||||
s16 phi = work->mpEmtr->get_r_ss();
|
||||
f32 rad = work->mVolumeSize * work->mVolumeMinRad;
|
||||
work->mVolumeCalcData.mVelAxis.set(rad * JMASSin(theta) * JMASCos(phi), rad * JMASSin(phi),
|
||||
rad * JMASCos(theta) * JMASCos(phi));
|
||||
work->mVolumeCalcData.mVolumePos.set(
|
||||
work->mVolumeCalcData.mVelAxis.x + work->mVolumeSize * JMASSin(theta),
|
||||
work->mVolumeCalcData.mVelAxis.y,
|
||||
work->mVolumeCalcData.mVelAxis.z + work->mVolumeSize * JMASCos(theta));
|
||||
work->mVolumeCalcData.mVelOmni.mul(work->mVolumeCalcData.mVolumePos, work->mGlobalScl);
|
||||
}
|
||||
|
||||
JPADynamicsBlock::JPADynamicsBlock(u8 const* data) {
|
||||
mpData = (const JPADynamicsBlockData*)data;
|
||||
init();
|
||||
}
|
||||
|
||||
enum {
|
||||
VOL_Cube = 0x00,
|
||||
VOL_Sphere = 0x01,
|
||||
VOL_Cylinder = 0x02,
|
||||
VOL_Torus = 0x03,
|
||||
VOL_Point = 0x04,
|
||||
VOL_Circle = 0x05,
|
||||
VOL_Line = 0x06,
|
||||
};
|
||||
|
||||
void JPADynamicsBlock::init() {
|
||||
switch (getVolumeType()) {
|
||||
case VOL_Cube:
|
||||
mpCalcVolumeFunc = &JPAVolumeCube;
|
||||
break;
|
||||
case VOL_Sphere:
|
||||
mpCalcVolumeFunc = &JPAVolumeSphere;
|
||||
break;
|
||||
case VOL_Cylinder:
|
||||
mpCalcVolumeFunc = &JPAVolumeCylinder;
|
||||
break;
|
||||
case VOL_Torus:
|
||||
mpCalcVolumeFunc = &JPAVolumeTorus;
|
||||
break;
|
||||
case VOL_Point:
|
||||
mpCalcVolumeFunc = &JPAVolumePoint;
|
||||
break;
|
||||
case VOL_Circle:
|
||||
mpCalcVolumeFunc = &JPAVolumeCircle;
|
||||
break;
|
||||
case VOL_Line:
|
||||
mpCalcVolumeFunc = &JPAVolumeLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JPADynamicsBlock::create(JPAEmitterWorkData* work) {
|
||||
if (work->mpEmtr->checkStatus(JPAEmtrStts_RateStepEmit)) {
|
||||
s32 emitCount = 0;
|
||||
|
||||
if (work->mpEmtr->checkFlag(JPADynFlag_FixedInterval)) {
|
||||
emitCount = getVolumeType() == VOL_Sphere ? 4 * getDivNumber() * getDivNumber() + 2 : getDivNumber();
|
||||
|
||||
work->mVolumeEmitIdx = 0;
|
||||
} else {
|
||||
f32 newPtclCount =
|
||||
work->mpEmtr->mRate * (getRateRndm() * work->mpEmtr->get_r_zp() + 1.0f);
|
||||
emitCount = work->mpEmtr->mEmitCount += newPtclCount;
|
||||
work->mpEmtr->mEmitCount -= emitCount;
|
||||
|
||||
if (work->mpEmtr->checkStatus(JPAEmtrStts_FirstEmit) && 0.0f < newPtclCount &&
|
||||
newPtclCount < 1.0f)
|
||||
emitCount = 1;
|
||||
}
|
||||
|
||||
work->mEmitCount = emitCount;
|
||||
if (work->mpEmtr->checkStatus(JPAEmtrStts_StopEmit)) {
|
||||
emitCount = 0;
|
||||
}
|
||||
|
||||
JPABaseParticle* ptcl = NULL;
|
||||
s32 createCount = emitCount;
|
||||
while (createCount > 0) {
|
||||
ptcl = work->mpEmtr->createParticle();
|
||||
if (ptcl == NULL)
|
||||
break;
|
||||
createCount--;
|
||||
}
|
||||
}
|
||||
|
||||
if (++work->mpEmtr->mRateStepTimer >= (work->mpEmtr->mRateStep + 1)) {
|
||||
work->mpEmtr->mRateStepTimer -= work->mpEmtr->mRateStep + 1;
|
||||
work->mpEmtr->setStatus(JPAEmtrStts_RateStepEmit);
|
||||
} else {
|
||||
work->mpEmtr->clearStatus(JPAEmtrStts_RateStepEmit);
|
||||
}
|
||||
|
||||
work->mpEmtr->clearStatus(JPAEmtrStts_FirstEmit);
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include "JSystem/JParticle/JPAEmitterManager.h"
|
||||
#include "JSystem/JParticle/JPAParticle.h"
|
||||
#include "JSystem/JParticle/JPAResourceManager.h"
|
||||
#include "JSystem/JParticle/JPABaseShape.h"
|
||||
#include <types.h>
|
||||
|
||||
JPAEmitterCallBack::~JPAEmitterCallBack() {
|
||||
}
|
||||
|
||||
void JPABaseEmitter::init(JPAEmitterManager* param_0, JPAResource* param_1) {
|
||||
mpEmtrMgr = param_0;
|
||||
pRes = param_1;
|
||||
pRes->getDyn()->getEmitterScl(&mLocalScl);
|
||||
pRes->getDyn()->getEmitterTrs(&mLocalTrs);
|
||||
pRes->getDyn()->getEmitterDir(&mLocalDir);
|
||||
mLocalDir.normalize();
|
||||
pRes->getDyn()->getEmitterRot(&mLocalRot);
|
||||
mMaxFrame = pRes->getDyn()->getMaxFrame();
|
||||
mLifeTime = pRes->getDyn()->getLifetime();
|
||||
mVolumeSize = pRes->getDyn()->getVolumeSize();
|
||||
mRate = pRes->getDyn()->getRate();
|
||||
mRateStep = pRes->getDyn()->getRateStep();
|
||||
mVolumeSweep = pRes->getDyn()->getVolumeSweep();
|
||||
mVolumeMinRad = pRes->getDyn()->getVolumeMinRad();
|
||||
mAwayFromCenterSpeed = pRes->getDyn()->getInitVelOmni();
|
||||
mAwayFromAxisSpeed = pRes->getDyn()->getInitVelAxis();
|
||||
mDirSpeed = pRes->getDyn()->getInitVelDir();
|
||||
mSpread = pRes->getDyn()->getInitVelDirSp();
|
||||
mRndmDirSpeed = pRes->getDyn()->getInitVelRndm();
|
||||
mAirResist = pRes->getDyn()->getAirRes();
|
||||
mRndm.set_seed(mpEmtrMgr->pWd->mRndm.get_rndm_u());
|
||||
MTXIdentity(mGlobalRot);
|
||||
mGlobalScl.set(1.0f, 1.0f, 1.0f);
|
||||
mGlobalTrs.zero();
|
||||
mGlobalPScl.set(1.0f, 1.0f);
|
||||
mGlobalPrmClr.r = mGlobalPrmClr.g = mGlobalPrmClr.b = mGlobalPrmClr.a = mGlobalEnvClr.r = mGlobalEnvClr.g = mGlobalEnvClr.b = mGlobalEnvClr.a = 0xff;
|
||||
param_1->getBsp()->getPrmClr(&mPrmClr);
|
||||
param_1->getBsp()->getEnvClr(&mEnvClr);
|
||||
mpUserWork = 0;
|
||||
mScaleOut = 1.0f;
|
||||
mEmitCount = 0.0f;
|
||||
initStatus(0x30);
|
||||
mDrawTimes = 1;
|
||||
mTick = 0;
|
||||
mWaitTime = 0;
|
||||
mRateStepTimer = 0;
|
||||
mTexAnmIdx = 0;
|
||||
}
|
||||
|
||||
JPABaseParticle* JPABaseEmitter::createParticle() {
|
||||
if (mpPtclPool->getNum() != 0) {
|
||||
JPANode<JPABaseParticle>* node = mpPtclPool->pop_front();
|
||||
mAlivePtclBase.push_front(node);
|
||||
pRes->getDyn()->calc(mpEmtrMgr->pWd);
|
||||
node->getObject()->init_p(mpEmtrMgr->pWd);
|
||||
return node->getObject();
|
||||
} else {
|
||||
JUT_WARN(128, "%s", "JPA : Can NOT create particle more\n");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JPABaseParticle* JPABaseEmitter::createChild(JPABaseParticle* parent) {
|
||||
if (mpPtclPool->getNum() != 0) {
|
||||
JPANode<JPABaseParticle>* node = mpPtclPool->pop_front();
|
||||
mAlivePtclChld.push_front(node);
|
||||
node->getObject()->init_c(mpEmtrMgr->pWd, parent);
|
||||
return node->getObject();
|
||||
} else {
|
||||
JUT_WARN(151, "%s", "JPA : Can NOT create child particle more\n")
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void JPABaseEmitter::deleteAllParticle() {
|
||||
while (mAlivePtclBase.getNum())
|
||||
mpPtclPool->push_front(mAlivePtclBase.pop_back());
|
||||
while (mAlivePtclChld.getNum())
|
||||
mpPtclPool->push_front(mAlivePtclChld.pop_back());
|
||||
}
|
||||
|
||||
bool JPABaseEmitter::processTillStartFrame() {
|
||||
if (mWaitTime >= pRes->getDyn()->getStartFrame())
|
||||
return true;
|
||||
|
||||
if (!checkStatus(2)) {
|
||||
mWaitTime++;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JPABaseEmitter::processTermination() {
|
||||
if (checkStatus(0x100)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mMaxFrame == 0) {
|
||||
return false;
|
||||
}
|
||||
if (mMaxFrame < 0) {
|
||||
setStatus(8);
|
||||
return getParticleNumber() == 0;
|
||||
}
|
||||
if (mTick >= mMaxFrame) {
|
||||
setStatus(8);
|
||||
if (checkStatus(0x40)) {
|
||||
return 0;
|
||||
}
|
||||
return getParticleNumber() == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void JPABaseEmitter::calcEmitterGlobalPosition(JGeometry::TVec3<f32>* dst) const {
|
||||
Mtx mtx;
|
||||
MTXScale(mtx, mGlobalScl.x, mGlobalScl.y, mGlobalScl.z);
|
||||
MTXConcat(mGlobalRot, mtx, mtx);
|
||||
mtx[0][3] = mGlobalTrs.x;
|
||||
mtx[1][3] = mGlobalTrs.y;
|
||||
mtx[2][3] = mGlobalTrs.z;
|
||||
MTXMultVec(mtx, &mLocalTrs, dst);
|
||||
}
|
||||
|
||||
u32 JPABaseEmitter::getCurrentCreateNumber() const {
|
||||
return mpEmtrMgr->pWd->mEmitCount;
|
||||
}
|
||||
|
||||
u8 JPABaseEmitter::getDrawCount() const {
|
||||
return mpEmtrMgr->pWd->mDrawCount;
|
||||
}
|
||||
|
||||
bool JPABaseEmitter::loadTexture(u8 no, GXTexMapID texMapID) {
|
||||
JUT_ASSERT(286, pRes->texNum > no);
|
||||
mpEmtrMgr->pWd->mpResMgr->load(pRes->getTexIdx(no), texMapID);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAEmitterManager.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include "JSystem/JParticle/JPAParticle.h"
|
||||
#include "JSystem/JParticle/JPAResourceManager.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include <gx.h>
|
||||
|
||||
JPAEmitterManager::JPAEmitterManager(u32 i_ptclNum, u32 i_emtrNum, JKRHeap* pHeap, u8 i_gidMax,
|
||||
u8 i_ridMax) {
|
||||
emtrNum = i_emtrNum;
|
||||
ptclNum = i_ptclNum;
|
||||
gidMax = i_gidMax;
|
||||
ridMax = i_ridMax;
|
||||
|
||||
JUT_ASSERT(40, emtrNum && ptclNum && gidMax && ridMax);
|
||||
|
||||
JPABaseEmitter* p_emtr_link = new (pHeap, 0) JPABaseEmitter[emtrNum];
|
||||
JUT_ASSERT(44, p_emtr_link);
|
||||
for (u32 i = 0; i < emtrNum; i++)
|
||||
mFreeEmtrList.prepend(&p_emtr_link[i].mLink);
|
||||
|
||||
JPANode<JPABaseParticle>* p_ptcl_node = new (pHeap, 0) JPANode<JPABaseParticle>[ptclNum];
|
||||
JUT_ASSERT(51, p_ptcl_node);
|
||||
for (u32 i = 0; i < ptclNum; i++)
|
||||
mPtclPool.push_back(&p_ptcl_node[i]);
|
||||
|
||||
pEmtrUseList = new (pHeap, 0) JSUList<JPABaseEmitter>[gidMax];
|
||||
JUT_ASSERT(58, pEmtrUseList);
|
||||
pResMgrAry = new (pHeap, 0) JPAResourceManager*[ridMax];
|
||||
JUT_ASSERT(62, pResMgrAry)
|
||||
for (int i = 0; i < ridMax; i++) {
|
||||
pResMgrAry[i] = NULL;
|
||||
}
|
||||
|
||||
pWd = new (pHeap, 0) JPAEmitterWorkData();
|
||||
JUT_ASSERT(67, pWd);
|
||||
}
|
||||
|
||||
JPABaseEmitter* JPAEmitterManager::createSimpleEmitterID(JGeometry::TVec3<f32> const& pos,
|
||||
u16 resID, u8 group_id, u8 res_mgr_id,
|
||||
JPAEmitterCallBack* emtrCB,
|
||||
JPAParticleCallBack* ptclCB) {
|
||||
JUT_ASSERT(88, group_id < gidMax);
|
||||
JUT_ASSERT(89, res_mgr_id < ridMax);
|
||||
JUT_ASSERT(90, pResMgrAry[res_mgr_id] != NULL);
|
||||
JPAResource* pRes = pResMgrAry[res_mgr_id]->getResource(resID);
|
||||
|
||||
if (pRes == NULL) {
|
||||
JUT_WARN_DEVICE(94, 3, "JPA : User Index %d is NOT exist\n", resID);
|
||||
} else if (mFreeEmtrList.getNumLinks() == 0) {
|
||||
JUT_WARN_DEVICE(97, 3, "JPA : Can NOT create emitter more\n");
|
||||
} else {
|
||||
JSULink<JPABaseEmitter>* pLink = mFreeEmtrList.getFirst();
|
||||
mFreeEmtrList.remove(pLink);
|
||||
pEmtrUseList[group_id].append(pLink);
|
||||
JPABaseEmitter* emtr = pLink->getObject();
|
||||
emtr->init(this, pRes);
|
||||
emtr->mpPtclPool = &mPtclPool;
|
||||
emtr->mpEmtrCallBack = emtrCB;
|
||||
emtr->mpPtclCallBack = ptclCB;
|
||||
emtr->mGroupID = group_id;
|
||||
emtr->mResMgrID = res_mgr_id;
|
||||
emtr->mGlobalTrs.set(pos);
|
||||
return emtr;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void JPAEmitterManager::calc(u8 group_id) {
|
||||
JUT_ASSERT(154, group_id < gidMax);
|
||||
JSULink<JPABaseEmitter>* pNext = NULL;
|
||||
for (JSULink<JPABaseEmitter>* pLink = pEmtrUseList[group_id].getFirst();
|
||||
pLink != pEmtrUseList[group_id].getEnd(); pLink = pNext) {
|
||||
pNext = pLink->getNext();
|
||||
|
||||
JPABaseEmitter* emtr = pLink->getObject();
|
||||
|
||||
if (emtr->pRes->calc(pWd, emtr) && !emtr->checkStatus(0x200))
|
||||
forceDeleteEmitter(emtr);
|
||||
}
|
||||
}
|
||||
|
||||
void JPAEmitterManager::draw(JPADrawInfo const* drawInfo, u8 group_id) {
|
||||
JUT_ASSERT(192, group_id < gidMax);
|
||||
drawInfo->getCamMtx(pWd->mPosCamMtx);
|
||||
drawInfo->getPrjMtx(pWd->mPrjMtx);
|
||||
calcYBBCam();
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXEnableTexOffsets(GX_TEXCOORD0, GX_TRUE, GX_TRUE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD1, GX_TRUE, GX_TRUE);
|
||||
GXEnableTexOffsets(GX_TEXCOORD2, GX_TRUE, GX_TRUE);
|
||||
GXSetCullMode(GX_CULL_NONE);
|
||||
GXSetCoPlanar(GX_FALSE);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||
GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetCurrentMtx(GX_PNMTX0);
|
||||
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE,
|
||||
GX_AF_NONE);
|
||||
GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE,
|
||||
GX_AF_NONE);
|
||||
GXSetNumChans(0);
|
||||
|
||||
for (JSULink<JPABaseEmitter>* pLink = pEmtrUseList[group_id].getFirst();
|
||||
pLink != pEmtrUseList[group_id].getEnd(); pLink = pLink->getNext()) {
|
||||
JPABaseEmitter* emtr = pLink->getObject();
|
||||
if (!emtr->checkStatus(0x04)) {
|
||||
pWd->mpResMgr = pResMgrAry[emtr->mResMgrID];
|
||||
emtr->pRes->draw(pWd, emtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JPAEmitterManager::forceDeleteAllEmitter() {
|
||||
for (u8 i = 0; i < gidMax; i++)
|
||||
forceDeleteGroupEmitter(i);
|
||||
}
|
||||
|
||||
void JPAEmitterManager::forceDeleteGroupEmitter(u8 group_id) {
|
||||
JUT_ASSERT(288, group_id < gidMax);
|
||||
while (pEmtrUseList[group_id].getNumLinks())
|
||||
forceDeleteEmitter(pEmtrUseList[group_id].getLast()->getObject());
|
||||
}
|
||||
|
||||
void JPAEmitterManager::forceDeleteEmitter(JPABaseEmitter* emtr) {
|
||||
emtr->deleteAllParticle();
|
||||
emtr->setStatus(0x300);
|
||||
pEmtrUseList[emtr->getGroupID()].remove(&emtr->mLink);
|
||||
mFreeEmtrList.prepend(&emtr->mLink);
|
||||
}
|
||||
|
||||
void JPAEmitterManager::entryResourceManager(JPAResourceManager* resMgr, u8 resMgrID) {
|
||||
JUT_ASSERT_MSG_F(325, resMgrID < ridMax && (pResMgrAry[resMgrID]) == NULL,
|
||||
"res_id %d res_id_max %d array[%d] = %x", resMgrID, ridMax, resMgrID,
|
||||
pResMgrAry[resMgrID]);
|
||||
pResMgrAry[resMgrID] = resMgr;
|
||||
}
|
||||
|
||||
void JPAEmitterManager::clearResourceManager(u8 res_mgr_id) {
|
||||
JUT_ASSERT(339, res_mgr_id < ridMax);
|
||||
for (u8 i = 0; i < gidMax; i++) {
|
||||
JSULink<JPABaseEmitter>* pNext = NULL;
|
||||
for (JSULink<JPABaseEmitter>* pLink = pEmtrUseList[i].getFirst();
|
||||
pLink != pEmtrUseList[i].getEnd(); pLink = pNext) {
|
||||
pNext = pLink->getNext();
|
||||
|
||||
if (res_mgr_id == pLink->getObject()->getResourceManagerID())
|
||||
forceDeleteEmitter(pLink->getObject());
|
||||
}
|
||||
}
|
||||
|
||||
pResMgrAry[res_mgr_id] = NULL;
|
||||
}
|
||||
|
||||
void JPAEmitterManager::calcYBBCam() {
|
||||
JGeometry::TVec3<float> v(0.0f, pWd->mPosCamMtx[1][1], pWd->mPosCamMtx[2][1]);
|
||||
JUT_ASSERT(367, !v.isZero());
|
||||
v.normalize();
|
||||
pWd->mYBBCamMtx[0][0] = 1.0f;
|
||||
pWd->mYBBCamMtx[0][1] = 0.0f;
|
||||
pWd->mYBBCamMtx[0][2] = 0.0f;
|
||||
pWd->mYBBCamMtx[0][3] = pWd->mPosCamMtx[0][3];
|
||||
pWd->mYBBCamMtx[1][0] = 0.0f;
|
||||
pWd->mYBBCamMtx[1][1] = v.y;
|
||||
pWd->mYBBCamMtx[1][2] = -v.z;
|
||||
pWd->mYBBCamMtx[1][3] = pWd->mPosCamMtx[1][3];
|
||||
pWd->mYBBCamMtx[2][0] = 0.0f;
|
||||
pWd->mYBBCamMtx[2][1] = v.z;
|
||||
pWd->mYBBCamMtx[2][2] = v.y;
|
||||
pWd->mYBBCamMtx[2][3] = pWd->mPosCamMtx[2][3];
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAExTexShape.h"
|
||||
#include "JSystem/JParticle/JPAResourceManager.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include <gx.h>
|
||||
|
||||
void JPALoadExTex(JPAEmitterWorkData* work) {
|
||||
JPAExTexShape* ets = work->mpRes->getEts();
|
||||
|
||||
GXTexCoordID secTexCoordID = GX_TEXCOORD1;
|
||||
if (ets->isUseIndirect()) {
|
||||
GXSetTexCoordGen(secTexCoordID, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
work->mpResMgr->load(work->mpRes->getTexIdx(ets->getIndTexIdx()), GX_TEXMAP2);
|
||||
secTexCoordID = GX_TEXCOORD2;
|
||||
}
|
||||
|
||||
if (ets->isUseSecTex()) {
|
||||
GXSetTexCoordGen(secTexCoordID, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
work->mpResMgr->load(work->mpRes->getTexIdx(ets->getSecTexIdx()), GX_TEXMAP3);
|
||||
}
|
||||
}
|
||||
|
||||
JPAExTexShape::JPAExTexShape(u8 const* data) {
|
||||
mpData = (const JPAExTexShapeData*)data;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAExtraShape.h"
|
||||
#include "JSystem/JMath/JMATrigonometric.h"
|
||||
#include "JSystem/JParticle/JPAParticle.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include <os.h>
|
||||
|
||||
void JPACalcScaleX(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
if (work->mScaleAnm < esp->getScaleInTiming()) {
|
||||
ptcl->mParticleScaleX =
|
||||
ptcl->mScaleOut * (esp->getScaleIncRateX() * work->mScaleAnm + esp->getScaleInValueX());
|
||||
} else if (work->mScaleAnm > esp->getScaleOutTiming()) {
|
||||
ptcl->mParticleScaleX =
|
||||
ptcl->mScaleOut *
|
||||
(esp->getScaleDecRateX() * (work->mScaleAnm - esp->getScaleOutTiming()) + 1.0f);
|
||||
} else {
|
||||
ptcl->mParticleScaleX = ptcl->mScaleOut;
|
||||
}
|
||||
}
|
||||
|
||||
void JPACalcScaleY(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
if (work->mScaleAnm < esp->getScaleInTiming()) {
|
||||
ptcl->mParticleScaleY =
|
||||
ptcl->mScaleOut * (esp->getScaleIncRateY() * work->mScaleAnm + esp->getScaleInValueY());
|
||||
} else if (work->mScaleAnm > esp->getScaleOutTiming()) {
|
||||
ptcl->mParticleScaleY =
|
||||
ptcl->mScaleOut *
|
||||
(esp->getScaleDecRateY() * (work->mScaleAnm - esp->getScaleOutTiming()) + 1.0f);
|
||||
} else {
|
||||
ptcl->mParticleScaleY = ptcl->mScaleOut;
|
||||
}
|
||||
}
|
||||
|
||||
void JPACalcScaleCopy(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
ptcl->mParticleScaleY = ptcl->mParticleScaleX;
|
||||
}
|
||||
|
||||
void JPACalcScaleAnmNormal(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
work->mScaleAnm = ptcl->mTime;
|
||||
}
|
||||
|
||||
void JPACalcScaleAnmRepeatX(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
work->mScaleAnm = (ptcl->mAge % esp->getScaleAnmCycleX()) / (f32)esp->getScaleAnmCycleX();
|
||||
}
|
||||
|
||||
void JPACalcScaleAnmRepeatY(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
work->mScaleAnm = (ptcl->mAge % esp->getScaleAnmCycleY()) / (f32)esp->getScaleAnmCycleY();
|
||||
}
|
||||
|
||||
void JPACalcScaleAnmReverseX(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
f32 cycle = ptcl->mAge / esp->getScaleAnmCycleX() & 1;
|
||||
f32 base = (ptcl->mAge % esp->getScaleAnmCycleX()) / (f32)esp->getScaleAnmCycleX();
|
||||
work->mScaleAnm = base + cycle * (1.0f - base * 2.0f);
|
||||
}
|
||||
|
||||
void JPACalcScaleAnmReverseY(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
f32 cycle = ptcl->mAge / esp->getScaleAnmCycleY() & 1;
|
||||
f32 base = (ptcl->mAge % esp->getScaleAnmCycleY()) / (f32)esp->getScaleAnmCycleY();
|
||||
work->mScaleAnm = base + cycle * (1.0f - base * 2.0f);
|
||||
}
|
||||
|
||||
void JPACalcAlphaAnm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
f32 alpha = 0.0f;
|
||||
if (ptcl->mTime < esp->getAlphaInTiming()) {
|
||||
alpha = 255.0f * (esp->getAlphaInValue() + esp->getAlphaIncRate() * ptcl->mTime);
|
||||
} else if (ptcl->mTime > esp->getAlphaOutTiming()) {
|
||||
alpha = 255.0f * ((ptcl->mTime - esp->getAlphaOutTiming()) * esp->getAlphaDecRate() +
|
||||
esp->getAlphaBaseValue());
|
||||
} else {
|
||||
alpha = 255.0f * esp->getAlphaBaseValue();
|
||||
}
|
||||
OSf32tou8(&alpha, &ptcl->mPrmColorAlphaAnm);
|
||||
}
|
||||
|
||||
void JPACalcAlphaFlickAnm(JPAEmitterWorkData* work, JPABaseParticle* ptcl) {
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
f32 alpha = 0.0f;
|
||||
if (ptcl->mTime < esp->getAlphaInTiming()) {
|
||||
alpha = (esp->getAlphaInValue() + esp->getAlphaIncRate() * ptcl->mTime);
|
||||
} else if (ptcl->mTime > esp->getAlphaOutTiming()) {
|
||||
alpha = ((ptcl->mTime - esp->getAlphaOutTiming()) * esp->getAlphaDecRate() +
|
||||
esp->getAlphaBaseValue());
|
||||
} else {
|
||||
alpha = esp->getAlphaBaseValue();
|
||||
}
|
||||
f32 wave = JMASSin(ptcl->mAlphaWaveRandom * ptcl->mAge * 16384.0f * (1.0f - esp->getAlphaFreq()));
|
||||
alpha *= (1.0f + esp->getAlphaAmp() * (wave - 1.0f) * 0.5f) * 255.0f;
|
||||
OSf32tou8(&alpha, &ptcl->mPrmColorAlphaAnm);
|
||||
}
|
||||
|
||||
JPAExtraShape::JPAExtraShape(u8 const* data) {
|
||||
mpData = (const JPAExtraShapeData*)data;
|
||||
init();
|
||||
}
|
||||
|
||||
void JPAExtraShape::init() {
|
||||
mAlphaIncRate = (getAlphaInTiming() != 0.0f) ?
|
||||
(getAlphaBaseValue() - getAlphaInValue()) / getAlphaInTiming() :
|
||||
1.0f;
|
||||
mAlphaDecRate = (getAlphaOutTiming() != 1.0f) ?
|
||||
(getAlphaOutValue() - getAlphaBaseValue()) / (1.0f - getAlphaOutTiming()) :
|
||||
1.0f;
|
||||
|
||||
if (getScaleInTiming() != 0.0f) {
|
||||
mScaleIncRateX = (1.0f - getScaleInValueX()) / getScaleInTiming();
|
||||
mScaleIncRateY = (1.0f - getScaleInValueY()) / getScaleInTiming();
|
||||
} else {
|
||||
mScaleIncRateX = mScaleIncRateY = 1.0f;
|
||||
}
|
||||
|
||||
if (getScaleOutTiming() != 1.0f) {
|
||||
mScaleDecRateX = (getScaleOutValueX() - 1.0f) / (1.0f - getScaleOutTiming());
|
||||
mScaleDecRateY = (getScaleOutValueY() - 1.0f) / (1.0f - getScaleOutTiming());
|
||||
} else {
|
||||
mScaleDecRateX = mScaleDecRateY = 1.0f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAFieldBlock.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include "JSystem/JParticle/JPAParticle.h"
|
||||
|
||||
void JPAFieldBase::calcAffect(JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
JGeometry::TVec3<f32> vec = mAccel;
|
||||
if (!ptcl->checkStatus(4) && block->checkStatus(0x78)) {
|
||||
vec.scale(calcFadeAffect(block, ptcl->mTime));
|
||||
}
|
||||
|
||||
switch (block->getAddType()) {
|
||||
case 0:
|
||||
ptcl->mVelType0.add(vec);
|
||||
break;
|
||||
case 1:
|
||||
ptcl->mVelType1.add(vec);
|
||||
break;
|
||||
case 2:
|
||||
ptcl->mVelType2.add(vec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f32 JPAFieldBase::calcFadeAffect(JPAFieldBlock* block, f32 time) const {
|
||||
f32 fade = 1.0f;
|
||||
if ((block->checkStatus(8) && time < block->getEnTime())
|
||||
|| (block->checkStatus(0x10) && time >= block->getDisTime()))
|
||||
{
|
||||
fade = 0.0f;
|
||||
} else if (block->checkStatus(0x40) && time >= block->getFadeOutTime()) {
|
||||
fade = (block->getDisTime() - time) * block->getFadeOutRate();
|
||||
} else if (block->checkStatus(0x20) && time < block->getFadeInTime()) {
|
||||
fade = (time - block->getEnTime()) * block->getFadeInRate();
|
||||
}
|
||||
return fade;
|
||||
}
|
||||
|
||||
void JPAFieldGravity::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
if (block->checkStatus(2)) {
|
||||
mAccel.scale(block->getMag(), block->getDir());
|
||||
} else {
|
||||
MTXMultVecSR(work->mRotationMtx, &block->getDir(), &mAccel);
|
||||
mAccel.scale(block->getMag());
|
||||
}
|
||||
}
|
||||
|
||||
void JPAFieldGravity::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
|
||||
void JPAFieldAir::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
JGeometry::TVec3<f32> vec;
|
||||
vec.normalize(block->getDir());
|
||||
if (block->checkStatus(2)) {
|
||||
mAccel.scale(block->getMag(), vec);
|
||||
} else {
|
||||
MTXMultVecSR(work->mRotationMtx, &vec, &mAccel);
|
||||
mAccel.scale(block->getMag());
|
||||
}
|
||||
}
|
||||
|
||||
void JPAFieldAir::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
calcAffect(block, ptcl);
|
||||
if (block->checkStatus(4)) {
|
||||
f32 len = ptcl->mVelType1.length();
|
||||
if (len > block->getMagRndm()) {
|
||||
ptcl->mVelType1.scale(block->getMagRndm() / len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JPAFieldMagnet::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
mDir.sub(block->getPos(), work->mEmitterPos);
|
||||
MTXMultVecSR(work->mRotationMtx, &mDir, &mDir);
|
||||
}
|
||||
|
||||
void JPAFieldMagnet::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
mAccel.sub(mDir, ptcl->mLocalPosition);
|
||||
mAccel.setLength(block->getMag());
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
|
||||
void JPAFieldNewton::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
mDir.sub(block->getPos(), work->mEmitterPos);
|
||||
MTXMultVecSR(work->mRotationMtx, &mDir, &mDir);
|
||||
mCutoff = block->getVal1() * block->getVal1();
|
||||
}
|
||||
|
||||
void JPAFieldNewton::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
mAccel.sub(mDir, ptcl->mLocalPosition);
|
||||
f32 len_sq = mAccel.squared();
|
||||
if (len_sq > mCutoff) {
|
||||
mAccel.setLength(mCutoff * (block->getMag() * 10.0f) / len_sq);
|
||||
} else {
|
||||
mAccel.setLength(block->getMag() * 10.0f);
|
||||
}
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
|
||||
void JPAFieldVortex::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
MTXMultVecSR(work->mGlobalRot, &block->getDir(), &field_0x10);
|
||||
field_0x10.normalize();
|
||||
field_0x1c = block->getPos().z * block->getPos().z;
|
||||
field_0x20 = 1.0f / field_0x1c;
|
||||
}
|
||||
|
||||
void JPAFieldVortex::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
JGeometry::TVec3<f32> vec;
|
||||
vec.scale(field_0x10.dot(ptcl->mLocalPosition), field_0x10);
|
||||
vec.sub(ptcl->mLocalPosition, vec);
|
||||
f32 mag = vec.squared();
|
||||
if (mag > field_0x1c) {
|
||||
mag = block->getMagRndm();
|
||||
} else {
|
||||
mag *= field_0x20;
|
||||
mag = (1.0f - mag) * block->getMag() + mag * block->getMagRndm();
|
||||
}
|
||||
vec.normalize();
|
||||
mAccel.cross(vec, field_0x10);
|
||||
mAccel.scale(mag);
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
|
||||
void JPAFieldConvection::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
JGeometry::TVec3<f32> vec1, vec2;
|
||||
vec2.cross(block->getPos(), block->getDir());
|
||||
vec1.cross(block->getDir(), vec2);
|
||||
MTXMultVecSR(work->mGlobalRot, &vec1, &field_0x10);
|
||||
MTXMultVecSR(work->mGlobalRot, &block->getDir(), &field_0x1c);
|
||||
MTXMultVecSR(work->mGlobalRot, &vec2, &field_0x28);
|
||||
field_0x10.normalize();
|
||||
field_0x1c.normalize();
|
||||
field_0x28.normalize();
|
||||
}
|
||||
|
||||
void JPAFieldConvection::calc(JPAEmitterWorkData* work, JPAFieldBlock* block,
|
||||
JPABaseParticle* ptcl) {
|
||||
JGeometry::TVec3<f32> vec1, vec2, vec3;
|
||||
vec1.scale(field_0x10.dot(ptcl->mLocalPosition), field_0x10);
|
||||
vec3.scale(field_0x28.dot(ptcl->mLocalPosition), field_0x28);
|
||||
vec1.add(vec3);
|
||||
vec1.setLength(vec1, block->getVal1());
|
||||
vec2.sub(ptcl->mLocalPosition, vec1);
|
||||
vec3.cross(field_0x1c, vec1);
|
||||
mAccel.cross(vec3, vec2);
|
||||
mAccel.setLength(block->getMag());
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
|
||||
void JPAFieldRandom::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
if (ptcl->mAge == 0 || (block->getCycle() != 0 && ptcl->mAge % block->getCycle() == 0)) {
|
||||
JPABaseEmitter* emtr = work->mpEmtr;
|
||||
mAccel.set(emtr->get_r_zh(), emtr->get_r_zh(), emtr->get_r_zh());
|
||||
mAccel.scale(block->getMag());
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
}
|
||||
|
||||
void JPAFieldDrag::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
if (!ptcl->checkStatus(4)) {
|
||||
f32 fade = calcFadeAffect(block, ptcl->mTime);
|
||||
ptcl->mDrag *= 1.0f - fade * (1.0f - block->getMag());
|
||||
} else {
|
||||
ptcl->mDrag *= block->getMag();
|
||||
}
|
||||
}
|
||||
|
||||
void JPAFieldSpin::prepare(JPAEmitterWorkData* work, JPAFieldBlock* block) {
|
||||
JGeometry::TVec3<f32> axis;
|
||||
MTXMultVecSR(work->mGlobalRot, &block->getDir(), &axis);
|
||||
axis.normalize();
|
||||
Mtx mtx;
|
||||
MTXRotAxisRad(mtx, &axis, block->getMag());
|
||||
field_0x10.set(mtx[0][0], mtx[1][0], mtx[2][0]);
|
||||
field_0x1c.set(mtx[0][1], mtx[1][1], mtx[2][1]);
|
||||
field_0x28.set(mtx[0][2], mtx[1][2], mtx[2][2]);
|
||||
}
|
||||
|
||||
void JPAFieldSpin::calc(JPAEmitterWorkData* work, JPAFieldBlock* block, JPABaseParticle* ptcl) {
|
||||
Mtx mtx;
|
||||
mtx[0][0] = field_0x10.x;
|
||||
mtx[1][0] = field_0x10.y;
|
||||
mtx[2][0] = field_0x10.z;
|
||||
mtx[0][1] = field_0x1c.x;
|
||||
mtx[1][1] = field_0x1c.y;
|
||||
mtx[2][1] = field_0x1c.z;
|
||||
mtx[0][2] = field_0x28.x;
|
||||
mtx[1][2] = field_0x28.y;
|
||||
mtx[2][2] = field_0x28.z;
|
||||
mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.0f;
|
||||
Vec vec;
|
||||
MTXMultVecSR(mtx, &ptcl->mLocalPosition, &vec);
|
||||
mAccel.set(vec.x - ptcl->mLocalPosition.x, vec.y - ptcl->mLocalPosition.y,
|
||||
vec.z - ptcl->mLocalPosition.z);
|
||||
calcAffect(block, ptcl);
|
||||
}
|
||||
|
||||
JPAFieldBlock::JPAFieldBlock(u8 const* data, JKRHeap* heap)
|
||||
: mpData((const JPAFieldBlockData*)data) {
|
||||
init(heap);
|
||||
}
|
||||
|
||||
void JPAFieldBlock::init(JKRHeap* heap) {
|
||||
mFadeInRate = getFadeInTime() - getEnTime();
|
||||
if (mFadeInRate == 0.0f) {
|
||||
mFadeInRate = 1.0f;
|
||||
} else {
|
||||
mFadeInRate = 1.0f / mFadeInRate;
|
||||
}
|
||||
|
||||
mFadeOutRate = getDisTime() - getFadeOutTime();
|
||||
if (mFadeOutRate == 0.0f) {
|
||||
mFadeOutRate = 1.0f;
|
||||
} else {
|
||||
mFadeOutRate = 1.0f / mFadeOutRate;
|
||||
}
|
||||
|
||||
getPosOrig(&mPos);
|
||||
getDirOrig(&mDir);
|
||||
mMag = getMagOrig();
|
||||
|
||||
switch (getType()) {
|
||||
case FIELD_GRAVITY:
|
||||
pFld = new (heap, 0) JPAFieldGravity();
|
||||
break;
|
||||
case FIELD_AIR:
|
||||
pFld = new (heap, 0) JPAFieldAir();
|
||||
break;
|
||||
case FIELD_MAGNET:
|
||||
pFld = new (heap, 0) JPAFieldMagnet();
|
||||
break;
|
||||
case FIELD_NEWTON:
|
||||
pFld = new (heap, 0) JPAFieldNewton();
|
||||
break;
|
||||
case FIELD_VORTEX:
|
||||
pFld = new (heap, 0) JPAFieldVortex();
|
||||
break;
|
||||
case FIELD_RANDOM:
|
||||
pFld = new (heap, 0) JPAFieldRandom();
|
||||
break;
|
||||
case FIELD_DRAG:
|
||||
pFld = new (heap, 0) JPAFieldDrag();
|
||||
break;
|
||||
case FIELD_CONVECTION:
|
||||
pFld = new (heap, 0) JPAFieldConvection();
|
||||
break;
|
||||
case FIELD_SPIN:
|
||||
pFld = new (heap, 0) JPAFieldSpin();
|
||||
break;
|
||||
default:
|
||||
pFld = NULL;
|
||||
JUT_WARN(483, "JPA : WRONG ID (%d) in field data\n", getType());
|
||||
break;
|
||||
}
|
||||
JUT_ASSERT(485, pFld != 0);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAKeyBlock.h"
|
||||
#include "JSystem/JParticle/JPAMath.h"
|
||||
|
||||
JPAKeyBlock::JPAKeyBlock(const u8* data)
|
||||
: mDataStart(data)
|
||||
, field_0x4(reinterpret_cast<const float*>(&data[0xC]))
|
||||
{
|
||||
}
|
||||
|
||||
f32 JPAKeyBlock::calc(float p1) {
|
||||
if (isLoop()) {
|
||||
int v1 = (int)getKeyData()[(getKeyNum() - 1) * 4] + 1;
|
||||
// p1 -= (v1 * ((int)p1 / v1));
|
||||
int v2 = ((int)p1 / v1);
|
||||
p1 = p1 - (v2 * v1);
|
||||
}
|
||||
return JPACalcKeyAnmValue(p1, getKeyNum(), getKeyData());
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAMath.h"
|
||||
#include "JSystem/JMath/JMATrigonometric.h"
|
||||
#include "JSystem/J2DGraph/J2DAnimation.h"
|
||||
|
||||
// Probably some local function needed to change float literal order
|
||||
static f32 floatDummyFunc() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
void JPAGetDirMtx(JGeometry::TVec3<f32> const& param_0, f32 (*param_1)[4]) {
|
||||
JGeometry::TVec3<float> local_78(param_0.y, -param_0.x, 0.0f);
|
||||
f32 len = local_78.length();
|
||||
|
||||
if (len <= JGeometry::TUtil<f32>::epsilon()) {
|
||||
local_78.zero();
|
||||
} else {
|
||||
local_78.scale(1.0f / len);
|
||||
}
|
||||
f32 xsquared = local_78.x * local_78.x;
|
||||
f32 ysquared = local_78.y * local_78.y;
|
||||
f32 xlen = local_78.x * len;
|
||||
f32 ylen = local_78.y * len;
|
||||
f32 fVar5 = (1.0f - param_0.z) * (local_78.x * local_78.y);
|
||||
param_1[0][0] = xsquared + param_0.z * (1.0f - xsquared);
|
||||
param_1[0][1] = fVar5;
|
||||
param_1[0][2] = -ylen;
|
||||
param_1[0][3] = 0.0f;
|
||||
param_1[1][0] = fVar5;
|
||||
param_1[1][1] = ysquared + param_0.z * (1.0f - ysquared);
|
||||
param_1[1][2] = xlen;
|
||||
param_1[1][3] = 0.0f;
|
||||
param_1[2][0] = ylen;
|
||||
param_1[2][1] = -xlen;
|
||||
param_1[2][2] = param_0.z;
|
||||
param_1[2][3] = 0.0f;
|
||||
}
|
||||
|
||||
void JPAGetYZRotateMtx(s16 angleY, s16 angleZ, f32 (*param_2)[4]) {
|
||||
f32 cosy = JMASCos(angleY);
|
||||
f32 cosz = JMASCos(angleZ);
|
||||
f32 siny = JMASSin(angleY);
|
||||
f32 sinz = JMASSin(angleZ);
|
||||
param_2[0][0] = (cosy * cosz);
|
||||
param_2[0][1] = -sinz;
|
||||
param_2[0][2] = (siny * cosz);
|
||||
param_2[1][0] = (cosy * sinz);
|
||||
param_2[1][1] = cosz;
|
||||
param_2[1][2] = (siny * sinz);
|
||||
param_2[2][0] = -siny;
|
||||
param_2[2][2] = cosy;
|
||||
param_2[0][3] = param_2[1][3] = param_2[2][1] = param_2[2][3] = 0.0f;
|
||||
}
|
||||
|
||||
void JPAGetXYZRotateMtx(s16 x, s16 y, s16 z, Mtx mtx) {
|
||||
f32 cosx = JMASCos(x);
|
||||
f32 cosy = JMASCos(y);
|
||||
f32 cosz = JMASCos(z);
|
||||
f32 sinx = JMASSin(x);
|
||||
f32 siny = JMASSin(y);
|
||||
f32 sinz = JMASSin(z);
|
||||
mtx[0][0] = cosy * cosz;
|
||||
mtx[1][0] = cosy * sinz;
|
||||
mtx[2][0] = -siny;
|
||||
mtx[2][1] = sinx * cosy;
|
||||
mtx[2][2] = cosx * cosy;
|
||||
f32 f30 = cosx * sinz;
|
||||
f32 f29 = sinx * cosz;
|
||||
mtx[0][1] = f29 * siny - f30;
|
||||
mtx[1][2] = f30 * siny - f29;
|
||||
f30 = sinx * sinz;
|
||||
f29 = cosx * cosz;
|
||||
mtx[0][2] = f30 + f29 * siny;
|
||||
mtx[1][1] = f29 + f30 * siny;
|
||||
mtx[0][3] = mtx[1][3] = mtx[2][3] = 0.0f;
|
||||
}
|
||||
|
||||
void JPASetRMtxTVecfromMtx(f32 const (*param_0)[4], f32 (*param_1)[4],
|
||||
JGeometry::TVec3<f32>* param_2) {
|
||||
JGeometry::TVec3<f32> dummy;
|
||||
JPASetRMtxSTVecfromMtx(param_0, param_1, &dummy, param_2);
|
||||
}
|
||||
|
||||
void JPASetRMtxSTVecfromMtx(f32 const (*param_0)[4], f32 (*param_1)[4],
|
||||
JGeometry::TVec3<f32>* param_2, JGeometry::TVec3<f32>* param_3) {
|
||||
JGeometry::TVec3<float> aTStack_54(param_0[0][0], param_0[1][0], param_0[2][0]);
|
||||
param_2->x = aTStack_54.length();
|
||||
aTStack_54.set(param_0[0][1], param_0[1][1], param_0[2][1]);
|
||||
param_2->y = aTStack_54.length();
|
||||
aTStack_54.set(param_0[0][2], param_0[1][2], param_0[2][2]);
|
||||
param_2->z = aTStack_54.length();
|
||||
MTXIdentity(param_1);
|
||||
if (param_2->x != 0.0f) {
|
||||
f32 fVar5 = 1.0f / param_2->x;
|
||||
param_1[0][0] = param_0[0][0] * fVar5;
|
||||
param_1[1][0] = param_0[1][0] * fVar5;
|
||||
param_1[2][0] = param_0[2][0] * fVar5;
|
||||
}
|
||||
if (param_2->y != 0.0f) {
|
||||
f32 fVar5 = 1.0f / param_2->y;
|
||||
param_1[0][1] = param_0[0][1] * fVar5;
|
||||
param_1[1][1] = param_0[1][1] * fVar5;
|
||||
param_1[2][1] = param_0[2][1] * fVar5;
|
||||
}
|
||||
if (param_2->z != 0.0f) {
|
||||
f32 fVar5 = 1.0f / param_2->z;
|
||||
param_1[0][2] = param_0[0][2] * fVar5;
|
||||
param_1[1][2] = param_0[1][2] * fVar5;
|
||||
param_1[2][2] = param_0[2][2] * fVar5;
|
||||
}
|
||||
param_3->set(param_0[0][3], param_0[1][3], param_0[2][3]);
|
||||
}
|
||||
|
||||
f32 JPACalcKeyAnmValue(f32 param_0, u16 param_1, f32 const* param_2) {
|
||||
if (param_0 < param_2[0]) {
|
||||
return param_2[1];
|
||||
}
|
||||
int ind = param_1 - 1;
|
||||
if (param_2[ind * 4] <= param_0) {
|
||||
return param_2[ind * 4 + 1];
|
||||
}
|
||||
int x = param_1;
|
||||
while (x > 1) {
|
||||
u32 uVar3 = x / 2;
|
||||
if (param_0 >= param_2[uVar3 * 4]) {
|
||||
param_2 += uVar3 * 4;
|
||||
x -= uVar3;
|
||||
} else {
|
||||
x = uVar3;
|
||||
}
|
||||
}
|
||||
return JMAHermiteInterpolation(param_0, param_2[0], param_2[1],
|
||||
param_2[3], param_2[4],
|
||||
param_2[5], param_2[6]);
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAParticle.h"
|
||||
#include "JSystem/JParticle/JPABaseShape.h"
|
||||
#include "JSystem/JParticle/JPAChildShape.h"
|
||||
#include "JSystem/JParticle/JPAEmitter.h"
|
||||
#include "JSystem/JParticle/JPAEmitterManager.h"
|
||||
#include "JSystem/JParticle/JPAExtraShape.h"
|
||||
|
||||
JPAParticleCallBack::~JPAParticleCallBack() {
|
||||
/* empty function */
|
||||
}
|
||||
|
||||
void JPABaseParticle::init_p(JPAEmitterWorkData* work) {
|
||||
JPABaseEmitter* emtr = work->mpEmtr;
|
||||
JPAExtraShape* esp = work->mpRes->getEsp();
|
||||
JPABaseShape* bsp = work->mpRes->getBsp();
|
||||
JPADynamicsBlock* dyn = work->mpRes->getDyn();
|
||||
|
||||
mAge = -1;
|
||||
mLifeTime = (1.0f - dyn->getLifetimeRndm() * emtr->get_r_f()) * emtr->mLifeTime;
|
||||
mTime = 0.0f;
|
||||
|
||||
initStatus(0);
|
||||
MTXMultVecSR(work->mGlobalSR, &work->mVolumeCalcData.mVolumePos, &mLocalPosition);
|
||||
if (emtr->checkFlag(8)) {
|
||||
setStatus(0x20);
|
||||
}
|
||||
|
||||
mOffsetPosition.set(work->mGlobalPos);
|
||||
mPosition.set(mOffsetPosition.x + mLocalPosition.x * work->mPublicScale.x,
|
||||
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
|
||||
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
|
||||
|
||||
JGeometry::TVec3<f32> velOmni;
|
||||
if (emtr->mAwayFromCenterSpeed) {
|
||||
velOmni.setLength(work->mVolumeCalcData.mVelOmni, emtr->mAwayFromCenterSpeed);
|
||||
} else {
|
||||
velOmni.zero();
|
||||
}
|
||||
|
||||
JGeometry::TVec3<f32> velAxis;
|
||||
if (emtr->mAwayFromAxisSpeed) {
|
||||
velAxis.setLength(work->mVolumeCalcData.mVelAxis, emtr->mAwayFromAxisSpeed);
|
||||
} else {
|
||||
velAxis.zero();
|
||||
}
|
||||
|
||||
JGeometry::TVec3<f32> velDir;
|
||||
if (emtr->mDirSpeed) {
|
||||
Mtx mtx;
|
||||
JPAGetYZRotateMtx(emtr->get_r_zp() * 0x8000 * emtr->mSpread, emtr->get_r_ss(), mtx);
|
||||
MTXConcat(work->mDirectionMtx, mtx, mtx);
|
||||
velDir.set(emtr->mDirSpeed * mtx[0][2],
|
||||
emtr->mDirSpeed * mtx[1][2],
|
||||
emtr->mDirSpeed * mtx[2][2]);
|
||||
} else {
|
||||
velDir.zero();
|
||||
}
|
||||
|
||||
JGeometry::TVec3<f32> velRndm;
|
||||
if (emtr->mRndmDirSpeed) {
|
||||
velRndm.set(emtr->mRndmDirSpeed * emtr->get_r_zh(),
|
||||
emtr->mRndmDirSpeed * emtr->get_r_zh(),
|
||||
emtr->mRndmDirSpeed * emtr->get_r_zh());
|
||||
} else {
|
||||
velRndm.zero();
|
||||
}
|
||||
|
||||
f32 ratio = emtr->get_r_zp() * dyn->getInitVelRatio() + 1.0f;
|
||||
mVelType1.set(ratio * (velOmni.x + velAxis.x + velDir.x + velRndm.x),
|
||||
ratio * (velOmni.y + velAxis.y + velDir.y + velRndm.y),
|
||||
ratio * (velOmni.z + velAxis.z + velDir.z + velRndm.z));
|
||||
|
||||
if (emtr->checkFlag(4)) {
|
||||
mVelType1.mul(emtr->mLocalScl);
|
||||
}
|
||||
MTXMultVecSR(work->mGlobalRot, &mVelType1, &mVelType1);
|
||||
|
||||
mVelType0.zero();
|
||||
|
||||
mMoment = 1.0f - dyn->getMomentRndm() * emtr->get_r_f();
|
||||
mDrag = 1.0f;
|
||||
field_0x78 = 0;
|
||||
|
||||
mBaseAxis.set(work->mGlobalRot[0][1], work->mGlobalRot[1][1], work->mGlobalRot[2][1]);
|
||||
|
||||
mPrmClr = emtr->mPrmClr;
|
||||
mEnvClr = emtr->mEnvClr;
|
||||
|
||||
mAnmRandom = emtr->get_r_f() * bsp->getLoopOfstValue();
|
||||
|
||||
if (esp != NULL && esp->isEnableScaleAnm()) {
|
||||
mParticleScaleX = mParticleScaleY = mScaleOut = emtr->mScaleOut * (emtr->get_r_zp() * esp->getScaleRndm() + 1.0f);
|
||||
} else {
|
||||
mParticleScaleX = mParticleScaleY = mScaleOut = emtr->mScaleOut;
|
||||
}
|
||||
|
||||
mPrmColorAlphaAnm = 0xff;
|
||||
|
||||
if (esp != NULL && esp->isEnableAlphaFlick()) {
|
||||
mAlphaWaveRandom = emtr->get_r_zp() * esp->getAlphaFreqRndm() + 1.0f;
|
||||
} else {
|
||||
mAlphaWaveRandom = 1.0f;
|
||||
}
|
||||
|
||||
if (esp != NULL) {
|
||||
if (esp->isEnableRotateAnm()) {
|
||||
mRotateAngle = esp->getRotateInitAngle() + esp->getRotateRndmAngle() * emtr->get_r_zh();
|
||||
mRotateSpeed = esp->getRotateInitSpeed() *
|
||||
(esp->getRotateRndmSpeed() * emtr->get_r_zp() + 1.0f);
|
||||
mRotateSpeed = emtr->get_r_zp() < esp->getRotateDirection() ?
|
||||
mRotateSpeed : (s16)-mRotateSpeed;
|
||||
} else {
|
||||
mRotateAngle = 0;
|
||||
mRotateSpeed = 0;
|
||||
}
|
||||
} else {
|
||||
mRotateAngle = 0;
|
||||
mRotateSpeed = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void JPABaseParticle::init_c(JPAEmitterWorkData* work, JPABaseParticle* parent) {
|
||||
JPABaseEmitter* emtr = work->mpEmtr;
|
||||
JPAChildShape* csp = work->mpRes->getCsp();
|
||||
|
||||
mAge = -1;
|
||||
mLifeTime = csp->getLife();
|
||||
mTime = 0.0f;
|
||||
initStatus(4);
|
||||
mLocalPosition.set(parent->mLocalPosition);
|
||||
|
||||
f32 pos_rndm = csp->getPosRndm();
|
||||
if (pos_rndm != 0.0f) {
|
||||
JGeometry::TVec3<f32> rnd(emtr->get_r_zh(), emtr->get_r_zh(), emtr->get_r_zh());
|
||||
rnd.setLength(pos_rndm * emtr->get_r_f());
|
||||
mLocalPosition.add(rnd);
|
||||
}
|
||||
|
||||
if (emtr->checkFlag(0x10)) {
|
||||
setStatus(0x20);
|
||||
}
|
||||
|
||||
mOffsetPosition.set(parent->mOffsetPosition);
|
||||
|
||||
f32 base_speed = csp->getBaseVel() * (csp->getBaseVelRndm() * emtr->get_r_zp() + 1.0f);
|
||||
JGeometry::TVec3<f32> base_vel(emtr->get_r_zp(), emtr->get_r_zp(), emtr->get_r_zp());
|
||||
base_vel.setLength(base_speed);
|
||||
mVelType1.scaleAdd(csp->getVelInhRate(), parent->mVelType1, base_vel);
|
||||
mVelType0.scale(csp->getVelInhRate(), parent->mVelType2);
|
||||
|
||||
mMoment = parent->mMoment;
|
||||
if (csp->isFieldAffected()) {
|
||||
mDrag = parent->mDrag;
|
||||
} else {
|
||||
setStatus(0x40);
|
||||
mDrag = 1.0f;
|
||||
}
|
||||
field_0x78 = parent->field_0x78;
|
||||
|
||||
mVelType2.set(mVelType0);
|
||||
f32 ratio = mMoment * mDrag;
|
||||
mVelocity.set(ratio * (mVelType1.x + mVelType2.x),
|
||||
ratio * (mVelType1.y + mVelType2.y),
|
||||
ratio * (mVelType1.z + mVelType2.z));
|
||||
|
||||
mBaseAxis.set(parent->mBaseAxis);
|
||||
|
||||
if (csp->isScaleInherited()) {
|
||||
mParticleScaleX = mScaleOut = parent->mParticleScaleX * csp->getScaleInhRate();
|
||||
mParticleScaleY = mAlphaWaveRandom = parent->mParticleScaleY * csp->getScaleInhRate();
|
||||
} else {
|
||||
mParticleScaleX = mScaleOut = mParticleScaleY = mAlphaWaveRandom = 1.0f;
|
||||
}
|
||||
|
||||
if (csp->isColorInherited()) {
|
||||
mPrmClr.r = parent->mPrmClr.r * csp->getColorInhRate();
|
||||
mPrmClr.g = parent->mPrmClr.g * csp->getColorInhRate();
|
||||
mPrmClr.b = parent->mPrmClr.b * csp->getColorInhRate();
|
||||
mEnvClr.r = parent->mEnvClr.r * csp->getColorInhRate();
|
||||
mEnvClr.g = parent->mEnvClr.g * csp->getColorInhRate();
|
||||
mEnvClr.b = parent->mEnvClr.b * csp->getColorInhRate();
|
||||
} else {
|
||||
csp->getPrmClr(&mPrmClr);
|
||||
csp->getEnvClr(&mEnvClr);
|
||||
}
|
||||
|
||||
mPrmColorAlphaAnm = 0xff;
|
||||
if (csp->isAlphaInherited()) {
|
||||
mPrmClr.a = COLOR_MULTI(parent->mPrmClr.a, parent->mPrmColorAlphaAnm)
|
||||
* csp->getAlphaInhRate();
|
||||
} else {
|
||||
mPrmClr.a = csp->getPrmAlpha();
|
||||
}
|
||||
|
||||
mRotateAngle = parent->mRotateAngle;
|
||||
if (csp->isRotateOn()) {
|
||||
mRotateSpeed = csp->getRotInitSpeed();
|
||||
} else {
|
||||
mRotateSpeed = 0;
|
||||
}
|
||||
|
||||
mTexAnmIdx = 0;
|
||||
}
|
||||
|
||||
bool JPABaseParticle::calc_p(JPAEmitterWorkData* work) {
|
||||
if (++mAge >= mLifeTime) {
|
||||
return true;
|
||||
}
|
||||
mTime = (f32)mAge / (f32)mLifeTime;
|
||||
|
||||
if (checkStatus(0x20)) {
|
||||
mOffsetPosition.set(work->mGlobalPos);
|
||||
}
|
||||
|
||||
mVelType2.zero();
|
||||
if (!checkStatus(0x40)) {
|
||||
work->mpRes->calcField(work, this);
|
||||
}
|
||||
mVelType2.add(mVelType0);
|
||||
mVelType1.scale(work->mpEmtr->mAirResist);
|
||||
f32 ratio = mMoment * mDrag;
|
||||
mVelocity.set(ratio * (mVelType1.x + mVelType2.x),
|
||||
ratio * (mVelType1.y + mVelType2.y),
|
||||
ratio * (mVelType1.z + mVelType2.z));
|
||||
|
||||
if (work->mpEmtr->mpPtclCallBack != NULL) {
|
||||
work->mpEmtr->mpPtclCallBack->execute(work->mpEmtr, this);
|
||||
}
|
||||
|
||||
if (checkStatus(2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
work->mpRes->calc_p(work, this);
|
||||
mRotateAngle += mRotateSpeed;
|
||||
|
||||
if (work->mpRes->getCsp() != NULL && canCreateChild(work)) {
|
||||
for (int i = work->mpRes->getCsp()->getRate(); i > 0; i--) {
|
||||
work->mpEmtr->createChild(this);
|
||||
}
|
||||
}
|
||||
|
||||
mLocalPosition.add(mVelocity);
|
||||
mPosition.set(mOffsetPosition.x + mLocalPosition.x * work->mPublicScale.x,
|
||||
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
|
||||
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JPABaseParticle::calc_c(JPAEmitterWorkData* work) {
|
||||
if (++mAge >= mLifeTime) {
|
||||
return true;
|
||||
}
|
||||
mTime = (f32)mAge / (f32)mLifeTime;
|
||||
|
||||
if (mAge != 0) {
|
||||
if (checkStatus(0x20)) {
|
||||
mOffsetPosition.set(work->mGlobalPos);
|
||||
}
|
||||
|
||||
mVelType1.y -= work->mpRes->getCsp()->getGravity();
|
||||
mVelType2.zero();
|
||||
if (!checkStatus(0x40)) {
|
||||
work->mpRes->calcField(work, this);
|
||||
}
|
||||
mVelType2.add(mVelType0);
|
||||
mVelType1.scale(work->mpEmtr->mAirResist);
|
||||
f32 ratio = mMoment * mDrag;
|
||||
mVelocity.set(ratio * (mVelType1.x + mVelType2.x),
|
||||
ratio * (mVelType1.y + mVelType2.y),
|
||||
ratio * (mVelType1.z + mVelType2.z));
|
||||
}
|
||||
|
||||
if (work->mpEmtr->mpPtclCallBack != NULL) {
|
||||
work->mpEmtr->mpPtclCallBack->execute(work->mpEmtr, this);
|
||||
}
|
||||
|
||||
if (checkStatus(2)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
work->mpRes->calc_c(work, this);
|
||||
mRotateAngle += mRotateSpeed;
|
||||
mLocalPosition.add(mVelocity);
|
||||
mPosition.set(mOffsetPosition.x + mLocalPosition.x * work->mPublicScale.x,
|
||||
mOffsetPosition.y + mLocalPosition.y * work->mPublicScale.y,
|
||||
mOffsetPosition.z + mLocalPosition.z * work->mPublicScale.z);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JPABaseParticle::canCreateChild(JPAEmitterWorkData* work) {
|
||||
JPAChildShape* csp = work->mpRes->getCsp();
|
||||
bool ret = false;
|
||||
int time = mAge - (int)((mLifeTime - 1) * csp->getTiming());
|
||||
if (time >= 0 && time % (csp->getStep() + 1) == 0) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
f32 JPABaseParticle::getWidth(JPABaseEmitter const* emtr) const {
|
||||
return mParticleScaleX * 2.0f * emtr->mpEmtrMgr->pWd->mGlobalPtclScl.x;
|
||||
}
|
||||
|
||||
f32 JPABaseParticle::getHeight(JPABaseEmitter const* emtr) const {
|
||||
return mParticleScaleY * 2.0f * emtr->mpEmtrMgr->pWd->mGlobalPtclScl.y;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,137 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAResourceLoader.h"
|
||||
#include "JSystem/JKernel/JKRHeap.h"
|
||||
#include "JSystem/JParticle/JPABaseShape.h"
|
||||
#include "JSystem/JParticle/JPAChildShape.h"
|
||||
#include "JSystem/JParticle/JPADynamicsBlock.h"
|
||||
#include "JSystem/JParticle/JPAExTexShape.h"
|
||||
#include "JSystem/JParticle/JPAExtraShape.h"
|
||||
#include "JSystem/JParticle/JPAFieldBlock.h"
|
||||
#include "JSystem/JParticle/JPAKeyBlock.h"
|
||||
#include "JSystem/JParticle/JPAResource.h"
|
||||
#include "JSystem/JParticle/JPAResourceManager.h"
|
||||
|
||||
static void dummy1() {
|
||||
JUT_WARN(0, "JPA : wrong version file %s\n");
|
||||
OS_REPORT("JPA : no jpa file\n");
|
||||
}
|
||||
|
||||
JPAResourceLoader::JPAResourceLoader(u8 const* data, JPAResourceManager* mgr) {
|
||||
if (*(u32*)(data + 4) == '2-10') {
|
||||
load_jpc(data, mgr);
|
||||
} else {
|
||||
JUT_WARN(48, "JPA : wrong version file\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void dummy2() {
|
||||
OS_REPORT("tex_num && \"a resource have to use one or more texture\"");
|
||||
OS_REPORT("p_res != 0");
|
||||
OS_REPORT("(p_res->ppFld != 0) || (p_res->fldNum == 0)");
|
||||
OS_REPORT("(p_res->ppKey != 0) || (p_res->keyNum == 0)");
|
||||
OS_REPORT("(p_res->texIdxTbl != 0) || (p_res->texNum == 0)");
|
||||
OS_REPORT("p_res->ppFld[fld_no] != 0");
|
||||
OS_REPORT("p_res->ppKey[key_no] != 0");
|
||||
OS_REPORT("p_res->pDyn != 0");
|
||||
OS_REPORT("p_res->pBsp != 0");
|
||||
OS_REPORT("p_res->pEsp != 0");
|
||||
OS_REPORT("p_res->pCsp != 0");
|
||||
OS_REPORT("p_res->pEts != 0");
|
||||
OS_REPORT("JPA : wrong type block in jpc file %x\n");
|
||||
}
|
||||
|
||||
struct JPAResourceHeader {
|
||||
/* 0x0 */ u16 mUsrIdx;
|
||||
/* 0x2 */ u16 mBlockNum;
|
||||
/* 0x4 */ u8 mFieldBlockNum;
|
||||
/* 0x5 */ u8 mKeyBlockNum;
|
||||
/* 0x6 */ u8 mTDB1Num;
|
||||
};
|
||||
|
||||
void JPAResourceLoader::load_jpc(u8 const* data, JPAResourceManager* p_res_mgr) {
|
||||
JKRHeap* heap = p_res_mgr->mpHeap;
|
||||
p_res_mgr->resMaxNum = *(u16*)(data + 8);
|
||||
p_res_mgr->texMaxNum = *(u16*)(data + 0xA);
|
||||
p_res_mgr->pResAry = new (heap, 0) JPAResource*[p_res_mgr->resMaxNum];
|
||||
p_res_mgr->pTexAry = new (heap, 0) JPATexture*[p_res_mgr->texMaxNum];
|
||||
JUT_ASSERT(199, (p_res_mgr->pResAry != NULL) && (p_res_mgr->pTexAry != 0));
|
||||
|
||||
u32 offset = 0x10;
|
||||
for (int i = 0; i < *(u16*)(data + 8); i++) {
|
||||
JPAResourceHeader* header = (JPAResourceHeader*)(data + offset);
|
||||
JPAResource* p_res = new (heap, 0) JPAResource();
|
||||
JUT_ASSERT(211, p_res != NULL);
|
||||
p_res->fldNum = header->mFieldBlockNum;
|
||||
p_res->ppFld = p_res->fldNum != 0 ?
|
||||
new (heap, 0) JPAFieldBlock*[p_res->fldNum] : NULL;
|
||||
JUT_ASSERT(216, (p_res->ppFld != NULL) || (p_res->fldNum == 0));
|
||||
p_res->keyNum = header->mKeyBlockNum;
|
||||
p_res->ppKey = p_res->keyNum != 0 ?
|
||||
new (heap, 0) JPAKeyBlock*[p_res->keyNum] : NULL;
|
||||
JUT_ASSERT(221, (p_res->ppKey != NULL) || (p_res->keyNum == 0));
|
||||
p_res->texNum = header->mTDB1Num;
|
||||
p_res->mpTDB1 = NULL;
|
||||
p_res->mUsrIdx = header->mUsrIdx;
|
||||
|
||||
offset += 8;
|
||||
u32 fld_no = 0;
|
||||
u32 key_no = 0;
|
||||
|
||||
for (int j = 0; j < header->mBlockNum; j++) {
|
||||
u32 magic = *(u32*)(data + offset);
|
||||
u32 size = *(u32*)(data + offset + 4);
|
||||
switch (magic) {
|
||||
case 'FLD1':
|
||||
p_res->ppFld[fld_no] = new (heap, 0) JPAFieldBlock(data + offset, heap);
|
||||
JUT_ASSERT(244, p_res->ppFld[fld_no] != NULL);
|
||||
fld_no++;
|
||||
break;
|
||||
case 'KFA1':
|
||||
p_res->ppKey[key_no] = new (heap, 0) JPAKeyBlock(data + offset);
|
||||
JUT_ASSERT(249, p_res->ppKey[key_no] != NULL);
|
||||
key_no++;
|
||||
break;
|
||||
case 'BEM1':
|
||||
p_res->pDyn = new (heap, 0) JPADynamicsBlock(data + offset);
|
||||
JUT_ASSERT(254, p_res->pDyn != NULL);
|
||||
break;
|
||||
case 'BSP1':
|
||||
p_res->pBsp = new (heap, 0) JPABaseShape(data + offset, heap);
|
||||
JUT_ASSERT(258, p_res->pBsp != NULL);
|
||||
break;
|
||||
case 'ESP1':
|
||||
p_res->pEsp = new (heap, 0) JPAExtraShape(data + offset);
|
||||
JUT_ASSERT(262, p_res->pEsp != NULL);
|
||||
break;
|
||||
case 'SSP1':
|
||||
p_res->pCsp = new (heap, 0) JPAChildShape(data + offset);
|
||||
JUT_ASSERT(266, p_res->pCsp != NULL);
|
||||
break;
|
||||
case 'ETX1':
|
||||
p_res->pEts = new (heap, 0) JPAExTexShape(data + offset);
|
||||
JUT_ASSERT(270, p_res->pEts != NULL);
|
||||
break;
|
||||
case 'TDB1':
|
||||
p_res->mpTDB1 = (const u16*)(data + offset + 8);
|
||||
break;
|
||||
default:
|
||||
JUT_WARN(275, "JPA : wrong type block in jpc file %d %x\n", header->mBlockNum, offset);
|
||||
break;
|
||||
}
|
||||
offset += size;
|
||||
}
|
||||
|
||||
p_res->init(heap);
|
||||
p_res_mgr->registRes(p_res);
|
||||
}
|
||||
|
||||
offset = *(u32*)(data + 0xC);
|
||||
for (int i = 0; i < *(u16*)(data + 0xA); i++) {
|
||||
u32 size = *(u32*)(data + offset + 4);
|
||||
JPATexture* p_tex = new (heap, 0) JPATexture(data + offset);
|
||||
JUT_ASSERT(298, p_tex != NULL);
|
||||
p_res_mgr->registTex(p_tex);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPAResourceManager.h"
|
||||
#include "JSystem/JParticle/JPADynamicsBlock.h"
|
||||
#include "JSystem/JParticle/JPAResource.h"
|
||||
#include <cstring>
|
||||
|
||||
struct JPAResourceLoader {
|
||||
JPAResourceLoader(u8 const*, JPAResourceManager*);
|
||||
};
|
||||
|
||||
JPAResourceManager::JPAResourceManager(void const* p_jpc, JKRHeap* pHeap) {
|
||||
pResAry = NULL;
|
||||
pTexAry = NULL;
|
||||
resMaxNum = 0;
|
||||
resRegNum = 0;
|
||||
texMaxNum = 0;
|
||||
texRegNum = 0;
|
||||
mpHeap = pHeap;
|
||||
JUT_ASSERT(49, (p_jpc != 0) && (pHeap != 0));
|
||||
JPAResourceLoader loader((u8 const*)p_jpc, this);
|
||||
}
|
||||
|
||||
JPAResource* JPAResourceManager::getResource(u16 usrIdx) const {
|
||||
for (u16 i = 0; i < resRegNum; i++)
|
||||
if (pResAry[i]->getUsrIdx() == usrIdx)
|
||||
return pResAry[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool JPAResourceManager::checkUserIndexDuplication(u16 usrIdx) const {
|
||||
for (s32 i = 0; i < resRegNum; i++)
|
||||
if (pResAry[i]->getUsrIdx() == usrIdx)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const ResTIMG* JPAResourceManager::swapTexture(ResTIMG const* img, char const* swapName) {
|
||||
const ResTIMG* ret = NULL;
|
||||
JUTTexture* tex = NULL;
|
||||
|
||||
for (s32 i = 0; i < texRegNum; i++) {
|
||||
if (strcmp(swapName, pTexAry[i]->getName()) == 0) {
|
||||
tex = pTexAry[i]->getJUTTexture();
|
||||
ret = tex->getTexInfo();
|
||||
tex->storeTIMG(img, (u8)0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JPAResourceManager::registRes(JPAResource* res) {
|
||||
JUT_ASSERT(151, resRegNum < resMaxNum);
|
||||
pResAry[resRegNum] = res;
|
||||
resRegNum++;
|
||||
}
|
||||
|
||||
void JPAResourceManager::registTex(JPATexture* tex) {
|
||||
JUT_ASSERT(166, texRegNum < texMaxNum);
|
||||
pTexAry[texRegNum] = tex;
|
||||
texRegNum++;
|
||||
}
|
||||
|
||||
u32 JPAResourceManager::getResUserWork(u16 usrIdx) const {
|
||||
u32 ret = 0;
|
||||
|
||||
JPAResource* res = getResource(usrIdx);
|
||||
if (res != NULL)
|
||||
ret = res->getDyn()->getResUserWork();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JParticle/JPATexture.h"
|
||||
|
||||
JPATexture::JPATexture(u8 const* pData) {
|
||||
mpData = (const JPATextureData*)pData;
|
||||
mTexture.storeTIMG(&mpData->mResTIMG, (u8)0);
|
||||
}
|
||||
|
||||
JPATexture::~JPATexture() {}
|
||||
Reference in New Issue
Block a user