From ffdea0c2b94630e1b0e35b21568ebe4ca0774497 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 11 Feb 2016 12:38:25 -1000 Subject: [PATCH] Additional particle imps --- Runtime/CToken.hpp | 1 + Runtime/Particle/CElementGen.cpp | 320 +++++++++++++++--- Runtime/Particle/CElementGen.hpp | 60 ++-- Runtime/Particle/CGenDescription.hpp | 2 +- Runtime/Particle/CParticleDataFactory.cpp | 2 +- Runtime/Particle/CParticleElectric.hpp | 3 + Runtime/Particle/CParticleSwoosh.hpp | 4 + Runtime/Particle/CSpawnSystemKeyframeData.cpp | 15 +- Runtime/Particle/CSpawnSystemKeyframeData.hpp | 6 +- libSpecter | 2 +- 10 files changed, 334 insertions(+), 81 deletions(-) diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index 2044a3a92..ddf06c4ad 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -234,6 +234,7 @@ public: : CToken(GetIObjObjectFor(std::unique_ptr(obj))) {} TToken& operator=(T* obj) {*this = CToken(GetIObjObjectFor(obj)); return this;} T* GetObj() {return static_cast*>(CToken::GetObj())->GetObj();} + T* operator->() {return GetObj();} }; template diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index c4157d81a..747db371b 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -2,6 +2,8 @@ #include "CGenDescription.hpp" #include "CLight.hpp" #include "CParticleGlobals.hpp" +#include "CParticleSwoosh.hpp" +#include "CParticleElectric.hpp" namespace Retro { @@ -83,13 +85,13 @@ CElementGen::CElementGen(const TToken& gen, CIntElement* ndsyElem = x1c_genDesc.GetObj()->xb4_NDSY.get(); if (ndsyElem) ndsyElem->GetValue(0, ndsyVal); - x248_children.reserve(ndsyVal + x248_children.size()); + x248_finishPartChildren.reserve(ndsyVal + x248_finishPartChildren.size()); for (int i=0 ; ixa4_IDTS.m_gen.GetObj(); if (x226 && chDesc->x45_31_OPTS) break; - x248_children.emplace_back(new CElementGen(x1c_genDesc.GetObj()->xa4_IDTS.m_gen, + x248_finishPartChildren.emplace_back(new CElementGen(x1c_genDesc.GetObj()->xa4_IDTS.m_gen, EModelOrientationType::Normal, x226 ? EOptionalSystemFlags::Two : EOptionalSystemFlags::One)); } @@ -265,12 +267,7 @@ bool CElementGen::InternalUpdate(double dt) int genCount = floorf(x6c_generatorRemainder); x6c_generatorRemainder = x6c_generatorRemainder - genCount; - if (x50_curFrame < x214_PSLT) - { - if (!x68_particleEmission) - genCount = 0; - } - else + if (!x68_particleEmission || x50_curFrame >= x214_PSLT) genCount = 0; CIntElement* maxpElem = x1c_genDesc.GetObj()->x28_MAXP.get(); @@ -362,17 +359,17 @@ void CElementGen::UpdateExistingParticles() int particleFrame = x50_curFrame - particle.x28_startFrame; CParticleGlobals::UpdateParticleLifetimeTweenValues(particleFrame); - bool err; + bool err = false; CModVectorElement* vel1 = x1c_genDesc.GetObj()->x7c_VEL1.get(); if (vel1) { if (x224_30_VMD1) { Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c); + Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); err = vel1->GetValue(particleFrame, xfVel, xfPos); - particle.x1c_vel = x178 * xfVel; - particle.x4_pos = x178 * xfPos + x7c; + particle.x1c_vel = x178_orientation * xfVel; + particle.x4_pos = x178_orientation * xfPos + x7c_translation; } else { @@ -386,10 +383,10 @@ void CElementGen::UpdateExistingParticles() if (x224_31_VMD2) { Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c); + Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); err |= vel2->GetValue(particleFrame, xfVel, xfPos); - particle.x1c_vel = x178 * xfVel; - particle.x4_pos = x178 * xfPos + x7c; + particle.x1c_vel = x178_orientation * xfVel; + particle.x4_pos = x178_orientation * xfPos + x7c_translation; } else { @@ -403,10 +400,10 @@ void CElementGen::UpdateExistingParticles() if (x225_24_VMD3) { Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c); + Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); err |= vel3->GetValue(particleFrame, xfVel, xfPos); - particle.x1c_vel = x178 * xfVel; - particle.x4_pos = x178 * xfPos + x7c; + particle.x1c_vel = x178_orientation * xfVel; + particle.x4_pos = x178_orientation * xfPos + x7c_translation; } else { @@ -420,10 +417,10 @@ void CElementGen::UpdateExistingParticles() if (x225_25_VMD4) { Zeus::CVector3f xfVel = x1a8 * particle.x1c_vel; - Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c); + Zeus::CVector3f xfPos = x1a8 * (particle.x4_pos - x7c_translation); err |= vel4->GetValue(particleFrame, xfVel, xfPos); - particle.x1c_vel = x178 * xfVel; - particle.x4_pos = x178 * xfPos + x7c; + particle.x1c_vel = x178_orientation * xfVel; + particle.x4_pos = x178_orientation * xfPos + x7c_translation; } else { @@ -483,7 +480,7 @@ void CElementGen::CreateNewParticles(int count) x2c_particleLists.push_back(staticIdx); ++x208_activeParticleCount; if (x28_orientType == EModelOrientationType::One) - x3c_parentMatrices[x2c_particleLists.size()-1] = x178.buildMatrix3f(); + x3c_parentMatrices[x2c_particleLists.size()-1] = x178_orientation.buildMatrix3f(); CElementGen::CParticle& particle = g_StaticParticleList[staticIdx]; particle.x28_startFrame = x50_curFrame; @@ -504,14 +501,14 @@ void CElementGen::CreateNewParticles(int count) if (emtr) { emtr->GetValue(x210_curEmitterFrame, particle.x4_pos, particle.x1c_vel); - Zeus::CVector3f compXf1 = (xdc * x148) * x7c; - Zeus::CVector3f compXf2 = x178 * particle.x4_pos; + Zeus::CVector3f compXf1 = (xdc * x148) * x7c_translation; + Zeus::CVector3f compXf2 = x178_orientation * particle.x4_pos; particle.x4_pos = compXf1 + compXf2 + x94_POFS; - particle.x1c_vel = x178 * particle.x1c_vel; + particle.x1c_vel = x178_orientation * particle.x1c_vel; } else { - Zeus::CVector3f compXf1 = (xdc * x148) * x7c; + Zeus::CVector3f compXf1 = (xdc * x148) * x7c_translation; particle.x4_pos = compXf1 + x94_POFS; particle.x1c_vel.zeroOut(); } @@ -561,26 +558,26 @@ void CElementGen::UpdatePSTranslationAndOrientation() CModVectorElement* psvm = x1c_genDesc.GetObj()->x4_PSVM.get(); if (psvm) { - Zeus::CVector3f vel = x7c; + Zeus::CVector3f vel = x7c_translation; psvm->GetValue(x50_curFrame, x218_PSIV, vel); - if (vel != x7c) + if (vel != x7c_translation) { x224_24 = true; - x7c = vel; + x7c_translation = vel; } } - Zeus::CVector3f v = x178 * x218_PSIV; + Zeus::CVector3f v = x178_orientation * x218_PSIV; if (v != Zeus::CVector3f::skZero) x224_24 = true; - x7c += v; + x7c_translation += v; CVectorElement* psov = x1c_genDesc.GetObj()->x8_PSOV.get(); if (psov) { Zeus::CVector3f angles; psov->GetValue(x50_curFrame, angles); - Zeus::CTransform xf(x178); + Zeus::CTransform xf(x178_orientation); xf.rotateLocalX(angles[0] * M_PI / 180.f); xf.rotateLocalY(angles[1] * M_PI / 180.f); xf.rotateLocalZ(angles[2] * M_PI / 180.f); @@ -602,14 +599,24 @@ void CElementGen::UpdatePSTranslationAndOrientation() CElementGen* CElementGen::ConstructChildParticleSystem(const TToken& desc) { - + CElementGen* ret = new CElementGen(desc, EModelOrientationType::Normal, + x226 ? EOptionalSystemFlags::Two : EOptionalSystemFlags::One); + ret->SetGlobalTranslation(x88_globalTranslation); + ret->SetGlobalOrientation(x1d8_globalOrientation); + ret->SetGlobalScale(xa0_globalScale); + ret->SetLocalScale(x10c_localScale); + ret->SetTranslation(x7c_translation); + ret->SetOrientation(x178_orientation); + ret->SetParticleEmission(x68_particleEmission); + ret->SetModulationColor(x30c_moduColor); + return ret; } void CElementGen::UpdateChildParticleSystems(double dt) { CGlobalRandom gr(x230_randState); SChildGeneratorDesc& icts = x1c_genDesc.GetObj()->x8c_ICTS; - if (icts.m_found && x64 != x50_curFrame && x244_CSSD == x50_curFrame) + if (icts.m_found && x64_prevFrame != x50_curFrame && x244_CSSD == x50_curFrame) { int ncsyVal = 1; CIntElement* ncsy = x1c_genDesc.GetObj()->x9c_NCSY.get(); @@ -619,17 +626,17 @@ void CElementGen::UpdateChildParticleSystems(double dt) CGenDescription* ictsDesc = icts.m_gen.GetObj(); if (!(x226 && ictsDesc->x45_31_OPTS)) { - x234_children.reserve(ncsyVal + x234_children.size()); + x234_activePartChildren.reserve(ncsyVal + x234_activePartChildren.size()); for (int i=0 ; ixb8_IITS; - if (iits.m_found && x64 != x50_curFrame && x50_curFrame < x214_PSLT && + if (iits.m_found && x64_prevFrame != x50_curFrame && x50_curFrame < x214_PSLT && x68_particleEmission == 1 && x50_curFrame >= x258_SISY && ((x50_curFrame - x258_SISY) % x25c_PISY) == 0) { @@ -637,23 +644,256 @@ void CElementGen::UpdateChildParticleSystems(double dt) if (!(x226 && iitsDesc->x45_31_OPTS)) { CElementGen* chGen = ConstructChildParticleSystem(iits.m_gen); - x234_children.emplace_back(chGen); + x234_activePartChildren.emplace_back(chGen); } } CSpawnSystemKeyframeData* kssm = x1c_genDesc.GetObj()->xd0_KSSM.get(); - if (kssm && x64 != x50_curFrame && x50_curFrame < x214_PSLT) + if (kssm && x64_prevFrame != x50_curFrame && x50_curFrame < x214_PSLT) { + std::vector& systems = + kssm->GetSpawnedSystemsAtFrame(x50_curFrame); + x234_activePartChildren.reserve(x234_activePartChildren.size() + systems.size()); + for (CSpawnSystemKeyframeData::CSpawnSystemKeyframeInfo& system : systems) + { + TLockedToken& token = system.GetToken(); + if (!(x226 && token.GetObj()->x45_31_OPTS)) + { + CElementGen* chGen = ConstructChildParticleSystem(token); + x234_activePartChildren.emplace_back(chGen); + } + } } + SSwooshGeneratorDesc& sswh = x1c_genDesc.GetObj()->xd4_SSWH; + if (sswh.m_found && x64_prevFrame != x50_curFrame && x50_curFrame == x270_SSSD) + { + CParticleSwoosh* sswhGen = new CParticleSwoosh(sswh.m_swoosh, 0); + sswhGen->SetGlobalTranslation(x88_globalTranslation); + sswhGen->SetGlobalScale(xa0_globalScale); + sswhGen->SetTranslation(x7c_translation); + sswhGen->SetOrientation(x178_orientation); + sswhGen->SetParticleEmission(x68_particleEmission); + x260_swhcChildren.emplace_back(sswhGen); + } + + SElectricGeneratorDesc& selc = x1c_genDesc.GetObj()->xec_SELC; + if (selc.m_found && x64_prevFrame != x50_curFrame && x50_curFrame == x290_SESD) + { + CParticleElectric* selcGen = new CParticleElectric(selc.m_electric); + selcGen->SetGlobalTranslation(x88_globalTranslation); + selcGen->SetGlobalScale(xa0_globalScale); + selcGen->SetTranslation(x7c_translation); + selcGen->SetOrientation(x178_orientation); + selcGen->SetParticleEmission(x68_particleEmission); + x280_elscChildren.emplace_back(selcGen); + } + + for (auto p = x234_activePartChildren.begin() ; p != x234_activePartChildren.end() ;) + { + std::unique_ptr& ch = *p; + + if ((x50_curFrame == x4c || x224_24) && x64_prevFrame != x50_curFrame) + { + ch->SetTranslation(x7c_translation); + ch->SetOrientation(x178_orientation); + } + + ch->Update(dt); + if (ch->IsSystemDeletable()) + { + p = x234_activePartChildren.erase(p); + continue; + } + + ++p; + } + + for (auto p = x248_finishPartChildren.begin() ; p != x248_finishPartChildren.end() ;) + { + std::unique_ptr& ch = *p; + + if (x214_PSLT <= x50_curFrame) + { + if (x214_PSLT == x50_curFrame && x64_prevFrame != x50_curFrame) + { + ch->SetTranslation(x7c_translation); + ch->SetOrientation(x178_orientation); + } + ch->Update(dt); + } + + if (ch->IsSystemDeletable()) + { + p = x248_finishPartChildren.erase(p); + continue; + } + + ++p; + } + + for (auto p = x260_swhcChildren.begin() ; p != x260_swhcChildren.end() ;) + { + std::unique_ptr& ch = *p; + + if ((x50_curFrame == x270_SSSD || x224_24) && x64_prevFrame != x50_curFrame) + { + Zeus::CVector3f trans = x7c_translation + x274_SSPO; + ch->SetTranslation(trans); + ch->SetOrientation(x178_orientation); + } + + ch->Update(dt); + if (ch->IsSystemDeletable()) + { + p = x260_swhcChildren.erase(p); + continue; + } + + ++p; + } + + for (auto p = x280_elscChildren.begin() ; p != x280_elscChildren.end() ;) + { + std::unique_ptr& ch = *p; + + if ((x50_curFrame == x290_SESD || x224_24) && x64_prevFrame != x50_curFrame) + { + Zeus::CVector3f trans = x7c_translation + x294_SEPO; + ch->SetTranslation(trans); + ch->SetOrientation(x178_orientation); + } + + ch->Update(dt); + if (ch->IsSystemDeletable()) + { + p = x280_elscChildren.erase(p); + continue; + } + + ++p; + } + + x64_prevFrame = x50_curFrame; } void CElementGen::UpdateLightParameters() { + CColorElement* lclr = x1c_genDesc.GetObj()->x104_LCLR.get(); + if (lclr) + lclr->GetValue(x50_curFrame, x2e0_LCLR); + + CRealElement* lint = x1c_genDesc.GetObj()->x108_LINT.get(); + if (lint) + lint->GetValue(x50_curFrame, x2e4_LINT); + + switch (x2dc_lightType) + { + default: + case ELightType::LocalAmbient: + case ELightType::Directional: + case ELightType::Spot: + { + CVectorElement* loff = x1c_genDesc.GetObj()->x10c_LOFF.get(); + if (loff) + loff->GetValue(x50_curFrame, x2e8_LOFF); + + CRealElement* lfor = x1c_genDesc.GetObj()->x118_LFOR.get(); + if (lfor) + lfor->GetValue(x50_curFrame, x304_LFOR); + + if (x2dc_lightType == ELightType::Spot) + { + CRealElement* lsla = x1c_genDesc.GetObj()->x11c_LSLA.get(); + if (lsla) + lsla->GetValue(x50_curFrame, x308_LSLA); + } + } + case ELightType::Custom: + { + if (x2dc_lightType != ELightType::Directional) + { + CVectorElement* ldir = x1c_genDesc.GetObj()->x110_LDIR.get(); + if (ldir) + ldir->GetValue(x50_curFrame, x2f4_LDIR); + } + } + } +} + +u32 CElementGen::GetParticleCountAllInternal() const +{ + u32 ret = x208_activeParticleCount; + + for (const std::unique_ptr& ch : x234_activePartChildren) + ret += ch->GetParticleCountAll(); + + for (const std::unique_ptr& ch : x248_finishPartChildren) + ret += ch->GetParticleCountAll(); + + return ret; } void CElementGen::BuildParticleSystemBounds() { + Zeus::CAABox aabb; + bool accumulated = false; + + for (std::unique_ptr& ch : x234_activePartChildren) + { + std::pair chBounds = ch->GetBounds(); + if (chBounds.second) + { + accumulated = true; + aabb.accumulateBounds(chBounds.first); + } + } + + for (std::unique_ptr& ch : x248_finishPartChildren) + { + std::pair chBounds = ch->GetBounds(); + if (chBounds.second) + { + accumulated = true; + aabb.accumulateBounds(chBounds.first); + } + } + + for (std::unique_ptr& ch : x260_swhcChildren) + { + std::pair chBounds = ch->GetBounds(); + if (chBounds.second) + { + accumulated = true; + aabb.accumulateBounds(chBounds.first); + } + } + + for (std::unique_ptr& ch : x280_elscChildren) + { + std::pair chBounds = ch->GetBounds(); + if (chBounds.second) + { + accumulated = true; + aabb.accumulateBounds(chBounds.first); + } + } + + x20c_recursiveParticleCount = GetParticleCountAllInternal(); + if (GetParticleCount()) + { + Zeus::CVector3f scale = xa0_globalScale * x2c0_maxSize; + Zeus::CTransform xf = (xac * x1d8_globalOrientation) * x118; + 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; + x2c4_systemBounds = Zeus::CAABox(min, max); + } + else + x2c4_systemBounds = Zeus::CAABox::skInvertedBox; + + if (accumulated) + x2c4_systemBounds.accumulateBounds(aabb); } void CElementGen::Render() @@ -712,7 +952,7 @@ bool CElementGen::IsSystemDeletable() const { } -Zeus::CAABox CElementGen::GetBounds() const +std::pair CElementGen::GetBounds() const { } diff --git a/Runtime/Particle/CElementGen.hpp b/Runtime/Particle/CElementGen.hpp index 6d9fdcc03..e86539024 100644 --- a/Runtime/Particle/CElementGen.hpp +++ b/Runtime/Particle/CElementGen.hpp @@ -1,7 +1,7 @@ #ifndef __RETRO_CELEMENTGEN_HPP__ #define __RETRO_CELEMENTGEN_HPP__ -#include "../RetroTypes.hpp" +#include "RetroTypes.hpp" #include "CTransform.hpp" #include "CVector3f.hpp" #include "CColor.hpp" @@ -15,6 +15,8 @@ namespace Retro class CWarp; class CLight; class CGenDescription; +class CParticleSwoosh; +class CParticleElectric; class CElementGen { @@ -67,30 +69,26 @@ private: u32 x50_curFrame = 0; double x58_curSeconds = 0.f; float x60; - u32 x64 = -1; + u32 x64_prevFrame = -1; bool x68_particleEmission = true; float x6c_generatorRemainder = 0.f; int x70_MAXP = 0; u16 x74 = 99; float x78_generatorRate = 1.f; - Zeus::CVector3f x7c; + Zeus::CVector3f x7c_translation; Zeus::CVector3f x88_globalTranslation; Zeus::CVector3f x94_POFS; - float xa0 = 1.f; - float xa4 = 1.f; - float xa8 = 1.f; + Zeus::CVector3f xa0_globalScale = {1.f, 1.f, 1.f}; Zeus::CTransform xac = Zeus::CTransform::Identity(); Zeus::CTransform xdc = Zeus::CTransform::Identity(); - float x10c = 1.f; - float x110 = 1.f; - float x114 = 1.f; + Zeus::CVector3f x10c_localScale = {1.f, 1.f, 1.f}; Zeus::CTransform x118 = Zeus::CTransform::Identity(); Zeus::CTransform x148 = Zeus::CTransform::Identity(); - Zeus::CTransform x178 = Zeus::CTransform::Identity(); + Zeus::CTransform x178_orientation = Zeus::CTransform::Identity(); Zeus::CTransform x1a8 = Zeus::CTransform::Identity(); Zeus::CTransform x1d8_globalOrientation = Zeus::CTransform::Identity(); u32 x208_activeParticleCount = 0; - u32 x20c = 0; + u32 x20c_recursiveParticleCount = 0; u32 x210_curEmitterFrame = 0; int x214_PSLT = 0x7fffff; Zeus::CVector3f x218_PSIV; @@ -112,19 +110,15 @@ private: int x228_MBSP; bool x22c = false; CRandom16 x230_randState; - std::vector> x234_children; + std::vector> x234_activePartChildren; int x244_CSSD = 0; - std::vector> x248_children; + std::vector> x248_finishPartChildren; int x258_SISY = 16; int x25c_PISY = 16; - u32 x264 = 0; - u32 x268 = 0; - u32 x26c = 0; + std::vector> x260_swhcChildren; int x270_SSSD = 0; Zeus::CVector3f x274_SSPO; - u32 x284 = 0; - u32 x288 = 0; - u32 x28c = 0; + std::vector> x280_elscChildren; int x290_SESD = 0; Zeus::CVector3f x294_SEPO; float x2a0 = 0.f; @@ -132,20 +126,16 @@ private: Zeus::CVector3f x2a8_aabbMin; Zeus::CVector3f x2b4_aabbMax; float x2c0_maxSize = 0.f; - Zeus::CAABox x2c4 = Zeus::CAABox::skInvertedBox; + Zeus::CAABox x2c4_systemBounds = Zeus::CAABox::skInvertedBox; ELightType x2dc_lightType; - Zeus::CColor x2e0 = Zeus::CColor::skWhite; - float x2e4 = 1.f; - float x2e8 = 0.f; - float x2ec = 0.f; - float x2f0 = 0.f; - float x2f4 = 1.f; - float x2f8 = 0.f; - float x2fc = 0.f; + Zeus::CColor x2e0_LCLR = Zeus::CColor::skWhite; + float x2e4_LINT = 1.f; + Zeus::CVector3f x2e8_LOFF; + Zeus::CVector3f x2f4_LDIR = {1.f, 0.f, 0.f}; EFalloffType x300_falloffType = EFalloffType::Linear; - float x304 = 1.f; - float x308 = 45.f; - u32 x30c = -1; + float x304_LFOR = 1.f; + float x308_LSLA = 45.f; + Zeus::CColor x30c_moduColor = {1.f, 1.f, 1.f, 1.f}; void AccumulateBounds(Zeus::CVector3f& pos, float size); @@ -167,10 +157,10 @@ public: else x78_generatorRate = 0.0f; - for (std::unique_ptr& child : x234_children) + for (std::unique_ptr& child : x234_activePartChildren) child->SetGeneratorRateScalar(x78_generatorRate); - for (std::unique_ptr& child : x248_children) + for (std::unique_ptr& child : x248_finishPartChildren) child->SetGeneratorRateScalar(x78_generatorRate); } @@ -187,6 +177,8 @@ public: CElementGen* ConstructChildParticleSystem(const TToken&); void UpdateLightParameters(); void BuildParticleSystemBounds(); + u32 GetParticleCountAllInternal() const; + u32 GetParticleCountAll() const {return x20c_recursiveParticleCount;} virtual void Update(double); bool InternalUpdate(double); @@ -204,7 +196,7 @@ public: virtual const Zeus::CVector3f& GetGlobalScale() const; virtual const Zeus::CColor& GetModulationColor() const; virtual bool IsSystemDeletable() const; - virtual Zeus::CAABox GetBounds() const; + virtual std::pair GetBounds() const; virtual u32 GetParticleCount() const; virtual bool SystemHasLight() const; virtual CLight GetLight() const; diff --git a/Runtime/Particle/CGenDescription.hpp b/Runtime/Particle/CGenDescription.hpp index 5091b836d..c5c7049cd 100644 --- a/Runtime/Particle/CGenDescription.hpp +++ b/Runtime/Particle/CGenDescription.hpp @@ -72,6 +72,7 @@ public: SSwooshGeneratorDesc xd4_SSWH; std::unique_ptr xe4_SSSD; std::unique_ptr xe8_SSPO; + SElectricGeneratorDesc xec_SELC; std::unique_ptr xf8_SESD; std::unique_ptr xfc_SEPO; SChildGeneratorDesc xec_PMLC; @@ -86,7 +87,6 @@ public: /* 0-00 additions */ std::unique_ptr x10_SEED; - SElectricGeneratorDesc xd8_SELC; union { struct diff --git a/Runtime/Particle/CParticleDataFactory.cpp b/Runtime/Particle/CParticleDataFactory.cpp index ad88b0c5b..3b9586c17 100644 --- a/Runtime/Particle/CParticleDataFactory.cpp +++ b/Runtime/Particle/CParticleDataFactory.cpp @@ -1044,7 +1044,7 @@ bool CParticleDataFactory::CreateGPSM(CGenDescription* fillDesc, CInputStream& i fillDesc->x128_ADV8.reset(GetRealElement(in)); break; case SBIG('SELC'): - fillDesc->xd8_SELC = GetElectricGeneratorDesc(in, resPool); + fillDesc->xec_SELC = GetElectricGeneratorDesc(in, resPool); break; default: { diff --git a/Runtime/Particle/CParticleElectric.hpp b/Runtime/Particle/CParticleElectric.hpp index 232a0e2b3..5db78e0b5 100644 --- a/Runtime/Particle/CParticleElectric.hpp +++ b/Runtime/Particle/CParticleElectric.hpp @@ -5,9 +5,12 @@ namespace Retro { +class CElectricDescription; class CParticleElectric : public CElementGen { +public: + CParticleElectric(const TToken& desc); }; } diff --git a/Runtime/Particle/CParticleSwoosh.hpp b/Runtime/Particle/CParticleSwoosh.hpp index b915411a5..d4a993808 100644 --- a/Runtime/Particle/CParticleSwoosh.hpp +++ b/Runtime/Particle/CParticleSwoosh.hpp @@ -2,12 +2,16 @@ #define __RETRO_CPARTICLESWOOSH_HPP__ #include "CElementGen.hpp" +#include "CToken.hpp" namespace Retro { +class CSwooshDescription; class CParticleSwoosh : public CElementGen { +public: + CParticleSwoosh(const TToken& desc, int); }; } diff --git a/Runtime/Particle/CSpawnSystemKeyframeData.cpp b/Runtime/Particle/CSpawnSystemKeyframeData.cpp index c0f03d10a..f75ceb818 100644 --- a/Runtime/Particle/CSpawnSystemKeyframeData.cpp +++ b/Runtime/Particle/CSpawnSystemKeyframeData.cpp @@ -8,7 +8,7 @@ CSpawnSystemKeyframeData::CSpawnSystemKeyframeData(CInputStream& in) { x0 = in.readUint32Big(); x4 = in.readUint32Big(); - x8 = in.readUint32Big(); + x8_endFrame = in.readUint32Big(); xc = in.readUint32Big(); u32 count = in.readUint32Big(); @@ -43,8 +43,19 @@ void CSpawnSystemKeyframeData::LoadAllSpawnedSystemTokens(CSimplePool* pool) void CSpawnSystemKeyframeData::CSpawnSystemKeyframeInfo::LoadToken(CSimplePool* pool) { x10_token = std::move(pool->GetObj({FOURCC('PART'), x0_id})); - x10_token.Lock(); x18_found = true; } +std::vector& +CSpawnSystemKeyframeData::GetSpawnedSystemsAtFrame(u32 frame) +{ + static std::vector emptyReturn; + if (frame >= x8_endFrame) + return emptyReturn; + for (auto& spawn : x10_spawns) + if (spawn.first == frame) + return spawn.second; + return emptyReturn; +} + } diff --git a/Runtime/Particle/CSpawnSystemKeyframeData.hpp b/Runtime/Particle/CSpawnSystemKeyframeData.hpp index 1b5d1e606..8b68c1f42 100644 --- a/Runtime/Particle/CSpawnSystemKeyframeData.hpp +++ b/Runtime/Particle/CSpawnSystemKeyframeData.hpp @@ -19,21 +19,23 @@ public: u32 x4; u32 x8; u32 xc; - TToken x10_token; + TLockedToken x10_token; bool x18_found = false; void LoadToken(CSimplePool* pool); public: CSpawnSystemKeyframeInfo(CInputStream& in); + TLockedToken& GetToken() {return x10_token;} }; private: u32 x0; u32 x4; - u32 x8; + u32 x8_endFrame; u32 xc; std::vector>> x10_spawns; public: CSpawnSystemKeyframeData(CInputStream& in); void LoadAllSpawnedSystemTokens(CSimplePool* pool); + std::vector& GetSpawnedSystemsAtFrame(u32 frame); }; } diff --git a/libSpecter b/libSpecter index e92c9c4d7..831be4689 160000 --- a/libSpecter +++ b/libSpecter @@ -1 +1 @@ -Subproject commit e92c9c4d734d41c2d6be474c20f5dde37c297440 +Subproject commit 831be46890a3c97b7dde4fa777ddba7a0826c98b