diff --git a/DataSpec/DNACommon/PART.hpp b/DataSpec/DNACommon/PART.hpp index 660ea6f77..806b35c18 100644 --- a/DataSpec/DNACommon/PART.hpp +++ b/DataSpec/DNACommon/PART.hpp @@ -23,7 +23,7 @@ struct GPSM : BigYAML IntElementFactory x10_PSWT; RealElementFactory x14_PSTS; VectorElementFactory x18_POFS; - IntElementFactory x1c_PMED; + IntElementFactory x1c_SEED; RealElementFactory x20_LENG; RealElementFactory x24_WIDT; IntElementFactory x28_MAXP; @@ -83,7 +83,6 @@ struct GPSM : BigYAML RealElementFactory x11c_LSLA; /* 0-00 additions */ - IntElementFactory x10_SEED; ChildResourceFactory xd8_SELC; union { @@ -271,8 +270,8 @@ struct GPSM : BigYAML case SBIG('PMLC'): xec_PMLC.read(r); break; - case SBIG('PMED'): - x1c_PMED.read(r); + case SBIG('SEED'): + x1c_SEED.read(r); break; case SBIG('PMOO'): x45_25_PMOO = r.readBool(nullptr); @@ -337,9 +336,6 @@ struct GPSM : BigYAML case SBIG('RSOP'): x30_31_RSOP = r.readBool(nullptr); break; - case SBIG('SEED'): - x10_SEED.read(r); - break; case SBIG('ADV1'): x10c_ADV1.read(r); break; @@ -396,12 +392,6 @@ struct GPSM : BigYAML xc_PSLT.write(w); w.leaveSubRecord(); } - if (x10_SEED) - { - w.enterSubRecord("SEED"); - x10_SEED.write(w); - w.leaveSubRecord(); - } if (x10_PSWT) { w.enterSubRecord("PSWT"); @@ -420,10 +410,10 @@ struct GPSM : BigYAML x18_POFS.write(w); w.leaveSubRecord(); } - if (x1c_PMED) + if (x1c_SEED) { - w.enterSubRecord("PMED"); - x1c_PMED.write(w); + w.enterSubRecord("SEED"); + x1c_SEED.write(w); w.leaveSubRecord(); } if (x20_LENG) @@ -804,16 +794,14 @@ struct GPSM : BigYAML __isz = x8_PSOV.binarySize(__isz + 4); if (xc_PSLT) __isz = xc_PSLT.binarySize(__isz + 4); - if (x10_SEED) - __isz = x10_SEED.binarySize(__isz + 4); if (x10_PSWT) __isz = x10_PSWT.binarySize(__isz + 4); if (x14_PSTS) __isz = x14_PSTS.binarySize(__isz + 4); if (x18_POFS) __isz = x18_POFS.binarySize(__isz + 4); - if (x1c_PMED) - __isz = x1c_PMED.binarySize(__isz + 4); + if (x1c_SEED) + __isz = x1c_SEED.binarySize(__isz + 4); if (x20_LENG) __isz = x20_LENG.binarySize(__isz + 4); if (x24_WIDT) @@ -1135,8 +1123,8 @@ struct GPSM : BigYAML case SBIG('PMLC'): xec_PMLC.read(r); break; - case SBIG('PMED'): - x1c_PMED.read(r); + case SBIG('SEED'): + x1c_SEED.read(r); break; case SBIG('PMOO'): r.readUint32Big(); @@ -1210,9 +1198,6 @@ struct GPSM : BigYAML r.readUint32Big(); x30_31_RSOP = r.readBool(); break; - case SBIG('SEED'): - x10_SEED.read(r); - break; case SBIG('ADV1'): x10c_ADV1.read(r); break; @@ -1270,11 +1255,6 @@ struct GPSM : BigYAML w.writeBytes((atInt8*)"PSLT", 4); xc_PSLT.write(w); } - if (x10_SEED) - { - w.writeBytes((atInt8*)"SEED", 4); - x10_SEED.write(w); - } if (x10_PSWT) { w.writeBytes((atInt8*)"PSWT", 4); @@ -1290,10 +1270,10 @@ struct GPSM : BigYAML w.writeBytes((atInt8*)"POFS", 4); x18_POFS.write(w); } - if (x1c_PMED) + if (x1c_SEED) { - w.writeBytes((atInt8*)"PMED", 4); - x1c_PMED.write(w); + w.writeBytes((atInt8*)"SEED", 4); + x1c_SEED.write(w); } if (x20_LENG) { diff --git a/Runtime/CLight.cpp b/Runtime/CLight.cpp index e69de29bb..7e64f9f9b 100644 --- a/Runtime/CLight.cpp +++ b/Runtime/CLight.cpp @@ -0,0 +1,24 @@ +#include "CLight.hpp" + +namespace Retro +{ + +CLight CLight::BuildDirectional(const Zeus::CVector3f& dir, const Zeus::CColor& color) +{ + return {}; +} + +CLight CLight::BuildSpot(const Zeus::CVector3f& pos, const Zeus::CVector3f& dir, + const Zeus::CColor& color, float angle) +{ + return {}; +} + +CLight CLight::BuildCustom(const Zeus::CVector3f& pos, const Zeus::CVector3f& dir, + const Zeus::CColor& color, float constAtt, float linearAtt, float quadAtt, + float intensity, float, float) +{ + return {}; +} + +} diff --git a/Runtime/CLight.hpp b/Runtime/CLight.hpp index e337ecf15..c6422bb9e 100644 --- a/Runtime/CLight.hpp +++ b/Runtime/CLight.hpp @@ -1,6 +1,9 @@ #ifndef __RETRO_CLIGHT_HPP__ #define __RETRO_CLIGHT_HPP__ +#include "CVector3f.hpp" +#include "CColor.hpp" + namespace Retro { @@ -23,7 +26,12 @@ enum class EFalloffType class CLight { public: - + static CLight BuildDirectional(const Zeus::CVector3f& dir, const Zeus::CColor& color); + static CLight BuildSpot(const Zeus::CVector3f& pos, const Zeus::CVector3f& dir, + const Zeus::CColor& color, float angle); + static CLight BuildCustom(const Zeus::CVector3f& pos, const Zeus::CVector3f& dir, + const Zeus::CColor& color, float constAtt, float linearAtt, float quadAtt, + float intensity, float, float); }; } diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index 08abe123d..4225839a7 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -46,24 +46,24 @@ void CElementGen::Initialize() g_StaticListInitialized = true; } -CElementGen::CElementGen(const TToken& gen) : x1c_genDesc(gen), x230_randState(x74) {} +CElementGen::CElementGen(const TToken& gen) : x1c_genDesc(gen), x230_randState(x74_randomSeed) {} CElementGen::CElementGen(const TToken& gen, EModelOrientationType orientType, EOptionalSystemFlags flags) : x1c_genDesc(gen), x28_orientType(orientType), - x226((flags & EOptionalSystemFlags::Two) != EOptionalSystemFlags::None), x230_randState(x74) + x226_enableOPTS((flags & EOptionalSystemFlags::Two) != EOptionalSystemFlags::None), x230_randState(x74_randomSeed) { CGenDescription* desc = x1c_genDesc.CastObj(); - CIntElement* pmedElem = desc->x1c_PMED.get(); - if (pmedElem) + CIntElement* seedElem = desc->x1c_SEED.get(); + if (seedElem) { - int pmedVal; - pmedElem->GetValue(x50_curFrame, pmedVal); - x74 = pmedVal; + int seedVal; + seedElem->GetValue(x50_curFrame, seedVal); + x74_randomSeed = seedVal; } - x230_randState.SetSeed(x74); + x230_randState.SetSeed(x74_randomSeed); ++g_ParticleSystemAliveCount; x224_25_LIT_ = desc->x44_29_LIT_; x224_26_AAPH = desc->x44_26_AAPH; @@ -94,11 +94,11 @@ CElementGen::CElementGen(const TToken& gen, for (int i=0 ; ixa4_IDTS.m_gen.GetObj(); - if (x226 && chDesc->x45_31_OPTS) + if (x226_enableOPTS && chDesc->x45_31_OPTS) break; x248_finishPartChildren.emplace_back(new CElementGen(desc->xa4_IDTS.m_gen, - EModelOrientationType::Normal, - x226 ? EOptionalSystemFlags::Two : EOptionalSystemFlags::One)); + EModelOrientationType::Normal, + x226_enableOPTS ? EOptionalSystemFlags::Two : EOptionalSystemFlags::One)); } } @@ -161,20 +161,20 @@ CElementGen::CElementGen(const TToken& gen, { int ltyp; ltypElem->GetValue(x50_curFrame, ltyp); - switch (ELightType(ltyp)) + switch (LightType(ltyp)) { - case ELightType::LocalAmbient: + case LightType::None: default: - x2dc_lightType = ELightType::LocalAmbient; + x2dc_lightType = LightType::None; break; - case ELightType::Directional: - x2dc_lightType = ELightType::Directional; + case LightType::Directional: + x2dc_lightType = LightType::Directional; break; - case ELightType::Custom: - x2dc_lightType = ELightType::Custom; + case LightType::Custom: + x2dc_lightType = LightType::Custom; break; - case ELightType::Spot: - x2dc_lightType = ELightType::Spot; + case LightType::Spot: + x2dc_lightType = LightType::Spot; break; } } @@ -292,7 +292,7 @@ bool CElementGen::InternalUpdate(double dt) UpdatePSTranslationAndOrientation(); UpdateChildParticleSystems(1 / 60.0); - if (x2dc_lightType != ELightType::LocalAmbient) + if (x2dc_lightType != LightType::None) UpdateLightParameters(); ++frameUpdateCount; @@ -305,10 +305,10 @@ bool CElementGen::InternalUpdate(double dt) x58_curSeconds = t; BuildParticleSystemBounds(); - x224_24 = false; + x224_24_translationDirty = false; double passedTime = t - x58_curSeconds; - x60 = 1.0 - passedTime * 60.0; + x60_timeDeltaScale = 1.0 - passedTime * 60.0; return false; } @@ -336,7 +336,6 @@ void CElementGen::UpdateExistingParticles() CElementGen::CParticle& particle = g_StaticParticleList[p->x0_partIdx]; if (particle.x0_endFrame < x50_curFrame) { - --g_ParticleAliveCount; g_StaticFreeList[++g_FreeIndex] = p->x0_partIdx; if (p+1 == x2c_particleLists.end()) { @@ -374,8 +373,8 @@ void CElementGen::UpdateExistingParticles() { if (x224_30_VMD1) { - Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); + Zeus::CVector3f xfVel = x1a8_orientationInverse * particle.x1c_vel; + Zeus::CVector3f xfPos = x1a8_orientationInverse * (particle.x4_pos - x7c_translation); err = vel1->GetValue(particleFrame, xfVel, xfPos); particle.x1c_vel = x178_orientation * xfVel; particle.x4_pos = x178_orientation * xfPos + x7c_translation; @@ -391,8 +390,8 @@ void CElementGen::UpdateExistingParticles() { if (x224_31_VMD2) { - Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); + Zeus::CVector3f xfVel = x1a8_orientationInverse * particle.x1c_vel; + Zeus::CVector3f xfPos = x1a8_orientationInverse * (particle.x4_pos - x7c_translation); err |= vel2->GetValue(particleFrame, xfVel, xfPos); particle.x1c_vel = x178_orientation * xfVel; particle.x4_pos = x178_orientation * xfPos + x7c_translation; @@ -408,8 +407,8 @@ void CElementGen::UpdateExistingParticles() { if (x225_24_VMD3) { - Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); + Zeus::CVector3f xfVel = x1a8_orientationInverse * particle.x1c_vel; + Zeus::CVector3f xfPos = x1a8_orientationInverse * (particle.x4_pos - x7c_translation); err |= vel3->GetValue(particleFrame, xfVel, xfPos); particle.x1c_vel = x178_orientation * xfVel; particle.x4_pos = x178_orientation * xfPos + x7c_translation; @@ -425,8 +424,8 @@ void CElementGen::UpdateExistingParticles() { if (x225_25_VMD4) { - Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); + Zeus::CVector3f xfVel = x1a8_orientationInverse * particle.x1c_vel; + Zeus::CVector3f xfPos = x1a8_orientationInverse * (particle.x4_pos - x7c_translation); err |= vel4->GetValue(particleFrame, xfVel, xfPos); particle.x1c_vel = x178_orientation * xfVel; particle.x4_pos = x178_orientation * xfPos + x7c_translation; @@ -488,7 +487,7 @@ void CElementGen::CreateNewParticles(int count) return; s16 staticIdx = g_StaticFreeList[g_FreeIndex]; - x2c_particleLists.push_back(staticIdx); + x2c_particleLists.emplace_back(staticIdx); ++x208_activeParticleCount; if (x28_orientType == EModelOrientationType::One) x3c_parentMatrices[x2c_particleLists.size()-1] = x178_orientation.buildMatrix3f(); @@ -512,14 +511,14 @@ void CElementGen::CreateNewParticles(int count) if (emtr) { emtr->GetValue(x210_curEmitterFrame, particle.x4_pos, particle.x1c_vel); - Zeus::CVector3f compXf1 = (xdc * x148) * x7c_translation; + Zeus::CVector3f compXf1 = (xdc_globalScaleTransformInverse * x148_localScaleTransformInverse) * x7c_translation; Zeus::CVector3f compXf2 = x178_orientation * particle.x4_pos; particle.x4_pos = compXf1 + compXf2 + x94_POFS; particle.x1c_vel = x178_orientation * particle.x1c_vel; } else { - Zeus::CVector3f compXf1 = (xdc * x148) * x7c_translation; + Zeus::CVector3f compXf1 = (xdc_globalScaleTransformInverse * x148_localScaleTransformInverse) * x7c_translation; particle.x4_pos = compXf1 + x94_POFS; particle.x1c_vel.zeroOut(); } @@ -575,14 +574,14 @@ void CElementGen::UpdatePSTranslationAndOrientation() psvm->GetValue(x50_curFrame, x218_PSIV, vel); if (vel != x7c_translation) { - x224_24 = true; + x224_24_translationDirty = true; x7c_translation = vel; } } Zeus::CVector3f v = x178_orientation * x218_PSIV; if (v != Zeus::CVector3f::skZero) - x224_24 = true; + x224_24_translationDirty = true; x7c_translation += v; CVectorElement* psov = desc->x8_PSOV.get(); @@ -613,7 +612,7 @@ void CElementGen::UpdatePSTranslationAndOrientation() CElementGen* CElementGen::ConstructChildParticleSystem(const TToken& desc) { CElementGen* ret = new CElementGen(desc, EModelOrientationType::Normal, - x226 ? EOptionalSystemFlags::Two : EOptionalSystemFlags::One); + x226_enableOPTS ? EOptionalSystemFlags::Two : EOptionalSystemFlags::One); ret->SetGlobalTranslation(x88_globalTranslation); ret->SetGlobalOrientation(x1d8_globalOrientation); ret->SetGlobalScale(xa0_globalScale); @@ -639,7 +638,7 @@ void CElementGen::UpdateChildParticleSystems(double dt) ncsy->GetValue(x50_curFrame, ncsyVal); CGenDescription* ictsDesc = icts.m_gen.GetObj(); - if (!(x226 && ictsDesc->x45_31_OPTS)) + if (!(x226_enableOPTS && ictsDesc->x45_31_OPTS)) { x234_activePartChildren.reserve(ncsyVal + x234_activePartChildren.size()); for (int i=0 ; ix45_31_OPTS)) + if (!(x226_enableOPTS && iitsDesc->x45_31_OPTS)) { CElementGen* chGen = ConstructChildParticleSystem(iits.m_gen); x234_activePartChildren.emplace_back(chGen); @@ -672,7 +671,7 @@ void CElementGen::UpdateChildParticleSystems(double dt) for (CSpawnSystemKeyframeData::CSpawnSystemKeyframeInfo& system : systems) { TLockedToken& token = system.GetToken(); - if (!(x226 && token.GetObj()->x45_31_OPTS)) + if (!(x226_enableOPTS && token.GetObj()->x45_31_OPTS)) { CElementGen* chGen = ConstructChildParticleSystem(token); x234_activePartChildren.emplace_back(chGen); @@ -708,7 +707,7 @@ void CElementGen::UpdateChildParticleSystems(double dt) { std::unique_ptr& ch = *p; - if ((x50_curFrame == x4c || x224_24) && x64_prevFrame != x50_curFrame) + if ((x50_curFrame == x4c_internalStartFrame || x224_24_translationDirty) && x64_prevFrame != x50_curFrame) { ch->SetTranslation(x7c_translation); ch->SetOrientation(x178_orientation); @@ -751,7 +750,7 @@ void CElementGen::UpdateChildParticleSystems(double dt) { std::unique_ptr& ch = *p; - if ((x50_curFrame == x270_SSSD || x224_24) && x64_prevFrame != x50_curFrame) + if ((x50_curFrame == x270_SSSD || x224_24_translationDirty) && x64_prevFrame != x50_curFrame) { Zeus::CVector3f trans = x7c_translation + x274_SSPO; ch->SetTranslation(trans); @@ -772,7 +771,7 @@ void CElementGen::UpdateChildParticleSystems(double dt) { std::unique_ptr& ch = *p; - if ((x50_curFrame == x290_SESD || x224_24) && x64_prevFrame != x50_curFrame) + if ((x50_curFrame == x290_SESD || x224_24_translationDirty) && x64_prevFrame != x50_curFrame) { Zeus::CVector3f trans = x7c_translation + x294_SEPO; ch->SetTranslation(trans); @@ -807,9 +806,9 @@ void CElementGen::UpdateLightParameters() switch (x2dc_lightType) { default: - case ELightType::LocalAmbient: - case ELightType::Directional: - case ELightType::Spot: + case LightType::None: + case LightType::Custom: + case LightType::Spot: { CVectorElement* loff = desc->x10c_LOFF.get(); if (loff) @@ -819,16 +818,16 @@ void CElementGen::UpdateLightParameters() if (lfor) lfor->GetValue(x50_curFrame, x304_LFOR); - if (x2dc_lightType == ELightType::Spot) + if (x2dc_lightType == LightType::Spot) { CRealElement* lsla = desc->x11c_LSLA.get(); if (lsla) lsla->GetValue(x50_curFrame, x308_LSLA); } } - case ELightType::Custom: + case LightType::Directional: { - if (x2dc_lightType != ELightType::Directional) + if (x2dc_lightType != LightType::Custom) { CVectorElement* ldir = desc->x110_LDIR.get(); if (ldir) @@ -900,7 +899,7 @@ void CElementGen::BuildParticleSystemBounds() if (GetParticleCount()) { Zeus::CVector3f scale = xa0_globalScale * x2c0_maxSize; - Zeus::CTransform xf = (xac * x1d8_globalOrientation) * x118; + Zeus::CTransform xf = (xac_globalScaleTransform * x1d8_globalOrientation) * x118_localScaleTransform; Zeus::CAABox box = Zeus::CAABox(x2a8_aabbMin, x2b4_aabbMax).getTransformedAABox(xf); Zeus::CVector3f min = box.m_min + x88_globalTranslation - scale; Zeus::CVector3f max = box.m_max + x88_globalTranslation + scale; @@ -1020,7 +1019,7 @@ void CElementGen::RenderModels() if (pmrt) pmrtConst = pmrt->IsFastConstant(); - Zeus::CVector3f trans = (xdc * x148) * x88_globalTranslation; + Zeus::CVector3f trans = (xdc_globalScaleTransformInverse * x148_localScaleTransformInverse) * x88_globalTranslation; Zeus::CTransform rot = Zeus::CTransform::Identity(); if (pmrtConst) @@ -1099,7 +1098,7 @@ void CElementGen::RenderModels() if (pmcl) pmcl->GetValue(partFrame, col); - CGraphics::SetModelMatrix((xac * partTrans) * x118); + CGraphics::SetModelMatrix((xac_globalScaleTransform * partTrans) * x118_localScaleTransform); if (desc->x45_24_PMUS) { @@ -1181,7 +1180,7 @@ void CElementGen::RenderParticles() Zeus::CTransform xf(CGraphics::g_ViewMatrix); Zeus::CTransform xf2 = xf.inverse() * x1d8_globalOrientation; - xf = ((Zeus::CTransform::Translate(x88_globalTranslation) * xac) * xf) * x118; + xf = ((Zeus::CTransform::Translate(x88_globalTranslation) * xac_globalScaleTransform) * xf) * x118_localScaleTransform; CGraphics::SetModelMatrix(xf); CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); @@ -1220,7 +1219,7 @@ void CElementGen::RenderParticles() for (CParticleListItem& item : x2c_particleLists) { CParticle& particle = g_StaticParticleList[item.x0_partIdx]; - item.x4_viewPoint = xf2 * ((particle.x4_pos - particle.x10_prevPos) * x60 + particle.x10_prevPos); + item.x4_viewPoint = xf2 * ((particle.x4_pos - particle.x10_prevPos) * x60_timeDeltaScale + particle.x10_prevPos); } std::sort(x2c_particleLists.begin(), x2c_particleLists.end(), @@ -1303,7 +1302,7 @@ void CElementGen::RenderParticles() if (desc->x44_28_SORT) viewPoint = item.x4_viewPoint; else - viewPoint = xf2 * ((particle.x4_pos - particle.x10_prevPos) * x60 + particle.x10_prevPos); + viewPoint = xf2 * ((particle.x4_pos - particle.x10_prevPos) * x60_timeDeltaScale + particle.x10_prevPos); if (!constTexr) { @@ -1383,7 +1382,7 @@ void CElementGen::RenderParticles() } Zeus::CVector3f dVec = particle.x4_pos - particle.x10_prevPos; - Zeus::CVector3f vec = dVec * x60 + particle.x10_prevPos; + Zeus::CVector3f vec = dVec * x60_timeDeltaScale + particle.x10_prevPos; Zeus::CVector3f mbspVec = dVec * mbspFac; float size = 0.5f * particle.x2c_lineLengthOrSize; if (0.f == particle.x30_lineWidthOrRota) @@ -1439,38 +1438,141 @@ void CElementGen::RenderParticles() void CElementGen::RenderParticlesIndirectTexture() { + CGenDescription* desc = x1c_genDesc.CastObj(); + + } -void CElementGen::SetOrientation(const Zeus::CTransform&) +void CElementGen::SetOrientation(const Zeus::CTransform& orientation) { + x178_orientation = orientation; + x1a8_orientationInverse = x178_orientation.inverse(); + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetOrientation(orientation); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetOrientation(orientation); + + for (const std::unique_ptr& ch : x260_swhcChildren) + ch->SetOrientation(orientation); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetOrientation(orientation); } -void CElementGen::SetTranslation(const Zeus::CVector3f&) +void CElementGen::SetTranslation(const Zeus::CVector3f& translation) { + x7c_translation = translation; + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetTranslation(translation); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetTranslation(translation); + + for (const std::unique_ptr& ch : x260_swhcChildren) + ch->SetTranslation(translation + x274_SSPO); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetTranslation(translation + x294_SEPO); } -void CElementGen::SetGlobalOrientation(const Zeus::CTransform&) +void CElementGen::SetGlobalOrientation(const Zeus::CTransform& rotation) { + x1d8_globalOrientation.setRotation(rotation); + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetGlobalOrientation(x1d8_globalOrientation); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetGlobalOrientation(x1d8_globalOrientation); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetGlobalOrientation(x1d8_globalOrientation); } -void CElementGen::SetGlobalTranslation(const Zeus::CVector3f&) +void CElementGen::SetGlobalTranslation(const Zeus::CVector3f& translation) { + x88_globalTranslation = translation; + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetGlobalTranslation(translation); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetGlobalTranslation(translation); + + for (const std::unique_ptr& ch : x260_swhcChildren) + ch->SetGlobalTranslation(translation); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetGlobalTranslation(translation); } -void CElementGen::SetGlobalScale(const Zeus::CVector3f&) +void CElementGen::SetGlobalScale(const Zeus::CVector3f& scale) { + xa0_globalScale = scale; + xac_globalScaleTransform = Zeus::CTransform::Scale(scale); + xdc_globalScaleTransformInverse = Zeus::CTransform::Scale(Zeus::CVector3f::skOne / scale); + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetGlobalScale(scale); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetGlobalScale(scale); + + for (const std::unique_ptr& ch : x260_swhcChildren) + ch->SetGlobalScale(scale); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetGlobalScale(scale); } -void CElementGen::SetLocalScale(const Zeus::CVector3f&) +void CElementGen::SetLocalScale(const Zeus::CVector3f& scale) { + x10c_localScale = scale; + x118_localScaleTransform = Zeus::CTransform::Scale(scale); + x148_localScaleTransformInverse = Zeus::CTransform::Scale(Zeus::CVector3f::skOne / scale); + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetLocalScale(scale); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetLocalScale(scale); } -void CElementGen::SetParticleEmission(bool) +void CElementGen::SetParticleEmission(bool enabled) { + x68_particleEmission = enabled; + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetParticleEmission(enabled); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetParticleEmission(enabled); + + for (const std::unique_ptr& ch : x260_swhcChildren) + ch->SetParticleEmission(enabled); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetParticleEmission(enabled); } -void CElementGen::SetModulationColor(const Zeus::CColor&) +void CElementGen::SetModulationColor(const Zeus::CColor& color) { + x30c_moduColor = color; + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->SetModulationColor(color); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->SetModulationColor(color); + + for (const std::unique_ptr& ch : x260_swhcChildren) + ch->SetModulationColor(color); + + for (const std::unique_ptr& ch : x280_elscChildren) + ch->SetModulationColor(color); } const Zeus::CTransform& CElementGen::GetOrientation() const @@ -1485,38 +1587,96 @@ const Zeus::CVector3f& CElementGen::GetTranslation() const const Zeus::CVector3f& CElementGen::GetGlobalScale() const { + return xa0_globalScale; } const Zeus::CColor& CElementGen::GetModulationColor() const { + return x30c_moduColor; } bool CElementGen::IsSystemDeletable() const { + for (const std::unique_ptr& ch : x234_activePartChildren) + if (!ch->IsSystemDeletable()) + return false; + + for (const std::unique_ptr& ch : x248_finishPartChildren) + if (!ch->IsSystemDeletable()) + return false; + + for (const std::unique_ptr& ch : x260_swhcChildren) + if (!ch->IsSystemDeletable()) + return false; + + for (const std::unique_ptr& ch : x280_elscChildren) + if (!ch->IsSystemDeletable()) + return false; + + if (x214_PSLT < x50_curFrame && x208_activeParticleCount == 0) + return true; + + return false; } std::pair CElementGen::GetBounds() const { + if (GetParticleCountAll() == 0) + return {Zeus::CAABox(), false}; + else + return {x2c4_systemBounds, true}; } u32 CElementGen::GetParticleCount() const { + return x208_activeParticleCount; } bool CElementGen::SystemHasLight() const { + return x2dc_lightType != LightType::None; } CLight CElementGen::GetLight() const { + switch (x2dc_lightType) + { + case LightType::Directional: + return CLight::BuildDirectional(x2f4_LDIR.normalized(), x2e0_LCLR * x2e4_LINT); + case LightType::Spot: + return CLight::BuildSpot(x2e8_LOFF, x2f4_LDIR.normalized(), x2e0_LCLR * x2e4_LINT, x308_LSLA); + default: + { + float quad = x300_falloffType == EFalloffType::Quadratic ? x304_LFOR : 0.f; + float linear = x300_falloffType == EFalloffType::Linear ? x304_LFOR : 0.f; + float constant = x300_falloffType == EFalloffType::Constant ? 1.f : 0.f; + return CLight::BuildCustom(x2e8_LOFF, {1.f, 0.f, 0.f}, x2e0_LCLR, + constant, linear, quad, x2e4_LINT, 0.f, 0.f); + } + } } void CElementGen::DestroyParticles() { + for (CParticleListItem& p : x2c_particleLists) + { + g_StaticFreeList[++g_FreeIndex] = p.x0_partIdx; + g_StaticParticleList[p.x0_partIdx].x0_endFrame = -1; + } + + x2c_particleLists.clear(); + x3c_parentMatrices.clear(); + + for (const std::unique_ptr& ch : x234_activePartChildren) + ch->DestroyParticles(); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ch->DestroyParticles(); } -void CElementGen::AddModifier(CWarp*) +void CElementGen::AddModifier(CWarp* mod) { + x8_modifierList.push_back(mod); } } diff --git a/Runtime/Particle/CElementGen.hpp b/Runtime/Particle/CElementGen.hpp index 65bdb52f6..e4261b869 100644 --- a/Runtime/Particle/CElementGen.hpp +++ b/Runtime/Particle/CElementGen.hpp @@ -10,6 +10,7 @@ #include "CLight.hpp" #include "CGraphics.hpp" #include "CRandom16.hpp" +#include "CWarp.hpp" namespace Retro { @@ -34,6 +35,13 @@ public: One, Two }; + enum class LightType + { + None = 0, + Custom = 1, + Directional = 2, + Spot = 3 + }; class CParticleListItem { friend class CElementGen; @@ -64,38 +72,39 @@ public: }; protected: CElementGen(const TToken& gen); + std::list x8_modifierList; TLockedToken x1c_genDesc; EModelOrientationType x28_orientType; std::vector x2c_particleLists; std::vector x3c_parentMatrices; - u32 x4c = 0; + u32 x4c_internalStartFrame = 0; u32 x50_curFrame = 0; double x58_curSeconds = 0.f; - float x60; + float x60_timeDeltaScale; u32 x64_prevFrame = -1; bool x68_particleEmission = true; float x6c_generatorRemainder = 0.f; int x70_MAXP = 0; - u16 x74 = 99; + u16 x74_randomSeed = 99; float x78_generatorRate = 1.f; Zeus::CVector3f x7c_translation; Zeus::CVector3f x88_globalTranslation; Zeus::CVector3f x94_POFS; Zeus::CVector3f xa0_globalScale = {1.f, 1.f, 1.f}; - Zeus::CTransform xac = Zeus::CTransform::Identity(); - Zeus::CTransform xdc = Zeus::CTransform::Identity(); + Zeus::CTransform xac_globalScaleTransform = Zeus::CTransform::Identity(); + Zeus::CTransform xdc_globalScaleTransformInverse = Zeus::CTransform::Identity(); Zeus::CVector3f x10c_localScale = {1.f, 1.f, 1.f}; - Zeus::CTransform x118 = Zeus::CTransform::Identity(); - Zeus::CTransform x148 = Zeus::CTransform::Identity(); + Zeus::CTransform x118_localScaleTransform = Zeus::CTransform::Identity(); + Zeus::CTransform x148_localScaleTransformInverse = Zeus::CTransform::Identity(); Zeus::CTransform x178_orientation = Zeus::CTransform::Identity(); - Zeus::CTransform x1a8 = Zeus::CTransform::Identity(); + Zeus::CTransform x1a8_orientationInverse = Zeus::CTransform::Identity(); Zeus::CTransform x1d8_globalOrientation = Zeus::CTransform::Identity(); u32 x208_activeParticleCount = 0; u32 x20c_recursiveParticleCount = 0; u32 x210_curEmitterFrame = 0; int x214_PSLT = 0x7fffff; Zeus::CVector3f x218_PSIV; - bool x224_24 = false; + bool x224_24_translationDirty = false; bool x224_25_LIT_; bool x224_26_AAPH; bool x224_27_ZBUF; @@ -109,7 +118,7 @@ protected: bool x225_27_FXLL; bool x225_28_warmedUp = false; bool x225_29_modelsUseLights = false; - bool x226; + bool x226_enableOPTS; int x228_MBSP; ERglLight x22c_backupLightActive = ERglLight::None; CRandom16 x230_randState; @@ -130,7 +139,7 @@ protected: Zeus::CVector3f x2b4_aabbMax; float x2c0_maxSize = 0.f; Zeus::CAABox x2c4_systemBounds = Zeus::CAABox::skInvertedBox; - ELightType x2dc_lightType; + LightType x2dc_lightType; Zeus::CColor x2e0_LCLR = Zeus::CColor::skWhite; float x2e4_LINT = 1.f; Zeus::CVector3f x2e8_LOFF; diff --git a/Runtime/Particle/CGenDescription.hpp b/Runtime/Particle/CGenDescription.hpp index 7f3e296e9..2f73f6d5d 100644 --- a/Runtime/Particle/CGenDescription.hpp +++ b/Runtime/Particle/CGenDescription.hpp @@ -25,7 +25,7 @@ public: std::unique_ptr x10_PSWT; std::unique_ptr x14_PSTS; std::unique_ptr x18_POFS; - std::unique_ptr x1c_PMED; + std::unique_ptr x1c_SEED; std::unique_ptr x20_LENG; std::unique_ptr x24_WIDT; std::unique_ptr x28_MAXP; @@ -86,7 +86,6 @@ public: std::unique_ptr x11c_LSLA; /* 0-00 additions */ - std::unique_ptr x10_SEED; union { struct diff --git a/Runtime/Particle/CParticleDataFactory.cpp b/Runtime/Particle/CParticleDataFactory.cpp index b9260b688..283238c03 100644 --- a/Runtime/Particle/CParticleDataFactory.cpp +++ b/Runtime/Particle/CParticleDataFactory.cpp @@ -1011,8 +1011,8 @@ bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& i case SBIG('PMLC'): fillDesc->xec_PMLC = GetChildGeneratorDesc(in, resPool, tracker); break; - case SBIG('PMED'): - fillDesc->x1c_PMED.reset(GetIntElement(in)); + case SBIG('SEED'): + fillDesc->x1c_SEED.reset(GetIntElement(in)); break; case SBIG('PMOO'): fillDesc->x45_25_PMOO = GetBool(in); @@ -1077,9 +1077,6 @@ bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& i case SBIG('RSOP'): fillDesc->x30_31_RSOP = GetBool(in); break; - case SBIG('SEED'): - fillDesc->x10_SEED.reset(GetIntElement(in)); - break; case SBIG('ADV1'): fillDesc->x10c_ADV1.reset(GetRealElement(in)); break;