2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 02:27:43 +00:00

CParticleDatabase implementations

This commit is contained in:
Jack Andersen
2017-06-02 20:03:07 -10:00
parent 4c41132168
commit db8a7d3433
30 changed files with 825 additions and 140 deletions

View File

@@ -554,9 +554,9 @@ void CAnimData::SetAnimation(const CAnimPlaybackParms& parms, bool noTrans)
x220_29_animationJustStarted = true;
}
SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& b1, CRandom16& random, bool advTree)
SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& suspendParticles, CRandom16& random, bool advTree)
{
b1 = false;
suspendParticles = false;
zeus::CVector3f offsetPre, offsetPost;
zeus::CQuaternion quatPre, quatPost;
@@ -572,14 +572,14 @@ SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& b1, CRandom16& random, b
if (!x220_24_animating)
{
b1 = true;
suspendParticles = true;
return {};
}
if (x220_29_animationJustStarted)
{
x220_29_animationJustStarted = false;
b1 = true;
suspendParticles = true;
}
if (advTree && x1f8_animRoot)
@@ -629,25 +629,27 @@ SAdvancementDeltas CAnimData::DoAdvance(float dt, bool& b1, CRandom16& random, b
SAdvancementDeltas CAnimData::Advance(float dt, const zeus::CVector3f& scale,
CStateManager& stateMgr, TAreaId aid, bool advTree)
{
bool b2;
return DoAdvance(dt, b2, *stateMgr.GetActiveRandom(), advTree);
if (b2)
bool suspendParticles;
SAdvancementDeltas deltas = DoAdvance(dt, suspendParticles, *stateMgr.GetActiveRandom(), advTree);
if (suspendParticles)
x120_particleDB.SuspendAllActiveEffects(stateMgr);
for (CParticlePOINode& node : g_ParticlePOINodes)
{
if (node.GetCharacterIndex() == -1 || node.GetCharacterIndex() == x204_charIdx)
{
x120_particleDB.StartEffect(node.GetString(), node.GetFlags(), node.GetParticleData(),
scale, stateMgr, aid, x21c_);
x120_particleDB.AddParticleEffect(node.GetString(), node.GetFlags(), node.GetParticleData(),
scale, stateMgr, aid, false, x21c_particleLightIdx);
}
}
return deltas;
}
SAdvancementDeltas CAnimData::AdvanceIgnoreParticles(float dt, CRandom16& random, bool advTree)
{
bool b2;
return DoAdvance(dt, b2, random, advTree);
bool suspendParticles;
return DoAdvance(dt, suspendParticles, random, advTree);
}
void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::CQuaternion& quat)
@@ -819,4 +821,12 @@ void CAnimData::SubstituteModelData(const TCachedToken<CSkinnedModel>& model)
x108_aabb = xd8_modelData->GetModel()->GetAABB();
}
void CAnimData::SetParticleCEXTValue(const std::string& name, int idx, float value)
{
auto search = std::find_if(xc_charInfo.x98_effects.begin(), xc_charInfo.x98_effects.end(),
[&name](const auto& v) { return v.first == name; });
if (search != xc_charInfo.x98_effects.end() && search->second.size())
x120_particleDB.SetCEXTValue(search->second.front().GetComponentName(), idx, value);
}
}

View File

@@ -84,6 +84,8 @@ struct SAdvancementResults;
class CAnimData
{
friend class CModelData;
friend class CActor;
TLockedToken<CCharacterFactory> x0_charFactory;
CCharacterInfo xc_charInfo;
TLockedToken<CCharLayoutInfo> xcc_layoutData;
@@ -109,7 +111,7 @@ class CAnimData
u32 x210_passedIntCount = 0;
u32 x214_passedParticleCount = 0;
u32 x218_passedSoundCount = 0;
u32 x21c_ = 0;
u32 x21c_particleLightIdx = 0;
union
{
@@ -201,7 +203,7 @@ public:
std::vector<CToken>& tokensOut, bool preLock);
void GetAnimationPrimitives(const CAnimPlaybackParms& parms, std::set<CPrimitive>& primsOut) const;
void SetAnimation(const CAnimPlaybackParms& parms, bool);
SAdvancementDeltas DoAdvance(float, bool&, CRandom16&, bool advTree);
SAdvancementDeltas DoAdvance(float, bool& suspendParticles, CRandom16&, bool advTree);
SAdvancementDeltas Advance(float, const zeus::CVector3f&, CStateManager& stateMgr, TAreaId aid, bool advTree);
SAdvancementDeltas AdvanceIgnoreParticles(float, CRandom16&, bool advTree);
void AdvanceAnim(CCharAnimTime& time, zeus::CVector3f&, zeus::CQuaternion&);
@@ -225,6 +227,15 @@ public:
static void InitializeCache();
const CHierarchyPoseBuilder& GetPoseBuilder() const { return x2fc_poseBuilder; }
const CParticleDatabase& GetParticleDB() const { return x120_particleDB; }
CParticleDatabase& GetParticleDB() { return x120_particleDB; }
void SetParticleCEXTValue(const std::string& name, int idx, float value);
u32 GetPassedBoolPOICount() const { return x20c_passedBoolCount; }
u32 GetPassedIntPOICount() const { return x210_passedIntCount; }
u32 GetPassedParticlePOICount() const { return x214_passedParticleCount; }
u32 GetPassedSoundPOICount() const { return x218_passedSoundCount; }
u32 GetCharacterIndex() const { return x204_charIdx; }
};
}

View File

@@ -11,6 +11,7 @@ namespace urde
class CCharacterInfo
{
friend class CAnimData;
public:
struct CParticleResData
{

View File

@@ -11,19 +11,8 @@ CEffectComponent::CEffectComponent(CInputStream& in)
x10_tag = GetSObjectTagFromStream(in);
x18_boneName = in.readString();
x28_scale = in.readFloatBig();
x2c_parentedMode = in.readUint32Big();
x2c_parentedMode = CParticleData::EParentedMode(in.readUint32Big());
x30_flags = in.readUint32Big();
}
const std::string& CEffectComponent::GetComponentName() const { return x0_name; }
const SObjectTag& CEffectComponent::GetParticleTag() const { return x10_tag; }
const std::string& CEffectComponent::GetSegmentName() const { return x18_boneName; }
float CEffectComponent::GetScale() const { return x28_scale; }
u32 CEffectComponent::GetParentedMode() const { return x2c_parentedMode; }
u32 CEffectComponent::GetFlags() const { return x30_flags; }
}

View File

@@ -3,6 +3,7 @@
#include "IOStreams.hpp"
#include "RetroTypes.hpp"
#include "CParticleData.hpp"
namespace urde
{
@@ -13,18 +14,18 @@ class CEffectComponent
SObjectTag x10_tag;
std::string x18_boneName;
float x28_scale;
u32 x2c_parentedMode;
CParticleData::EParentedMode x2c_parentedMode;
u32 x30_flags;
static SObjectTag GetSObjectTagFromStream(CInputStream& in);
public:
CEffectComponent(CInputStream& in);
const std::string& GetComponentName() const;
const SObjectTag& GetParticleTag() const;
const std::string& GetSegmentName() const;
float GetScale() const;
u32 GetParentedMode() const;
u32 GetFlags() const;
const std::string& GetComponentName() const { return x0_name; }
const SObjectTag& GetParticleTag() const { return x10_tag; }
const std::string& GetSegmentName() const { return x18_boneName; }
float GetScale() const { return x28_scale; }
CParticleData::EParentedMode GetParentedMode() const { return x2c_parentedMode; }
u32 GetFlags() const { return x30_flags; }
};
}

View File

@@ -13,6 +13,7 @@ enum class EPOIType : u16
Loop = 0,
EmptyBool = 1,
EmptyInt32 = 2,
SoundInt32 = 4,
Particle = 5,
UserEvent = 6,
RandRate = 7,

View File

@@ -25,7 +25,16 @@ private:
public:
CParticleData() = default;
CParticleData(CInputStream& in);
EParentedMode GetParentedMode() const {return x20_parentMode;}
u32 GetDuration() const { return x0_duration; }
const SObjectTag& GetTag() const { return x4_particle; }
const std::string& GetSegmentName() const { return xc_boneName; }
float GetScale() const { return x1c_scale; }
EParentedMode GetParentedMode() const { return x20_parentMode; }
};
class CAuxiliaryParticleData
{
public:
};
}

View File

@@ -1,10 +1,21 @@
#include "CParticleDatabase.hpp"
#include "CSimplePool.hpp"
#include "GameGlobalObjects.hpp"
#include "Character/CCharLayoutInfo.hpp"
#include "Character/CPoseAsTransforms.hpp"
#include "Particle/CElementGen.hpp"
#include "Particle/CParticleSwoosh.hpp"
#include "Particle/CParticleElectric.hpp"
namespace urde
{
CParticleDatabase::CParticleDatabase()
{
xb4_24_active = true;
xb4_25_drawingEnds = false;
}
void CParticleDatabase::CacheParticleDesc(const CCharacterInfo::CParticleResData& desc)
{
for (ResId id : desc.x0_part)
@@ -30,31 +41,436 @@ void CParticleDatabase::CacheParticleDesc(const CCharacterInfo::CParticleResData
}
}
void CParticleDatabase::SetModulationColorAllActiveEffectsForParticleDB(const zeus::CColor& color,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map)
{
for (auto& e : map)
{
if (e.second)
e.second->SetModulationColor(color);
}
}
void CParticleDatabase::SetModulationColorAllActiveEffects(const zeus::CColor& color)
{
SetModulationColorAllActiveEffectsForParticleDB(color, x3c_rendererDrawLoop);
SetModulationColorAllActiveEffectsForParticleDB(color, x50_firstDrawLoop);
SetModulationColorAllActiveEffectsForParticleDB(color, x64_lastDrawLoop);
SetModulationColorAllActiveEffectsForParticleDB(color, x78_rendererDraw);
SetModulationColorAllActiveEffectsForParticleDB(color, x8c_firstDraw);
SetModulationColorAllActiveEffectsForParticleDB(color, xa0_lastDraw);
}
void CParticleDatabase::SuspendAllActiveEffectsForParticleDB(CStateManager& mgr,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map)
{
for (auto& e : map)
{
e.second->SetParticleEmission(false, mgr);
}
}
void CParticleDatabase::SuspendAllActiveEffects(CStateManager& stateMgr)
{
SuspendAllActiveEffectsForParticleDB(stateMgr, x3c_rendererDrawLoop);
SuspendAllActiveEffectsForParticleDB(stateMgr, x50_firstDrawLoop);
SuspendAllActiveEffectsForParticleDB(stateMgr, x64_lastDrawLoop);
}
void CParticleDatabase::StartEffect(const std::string& name, u32 flags, const CParticleData& data,
const zeus::CVector3f& scale, CStateManager& stateMgr, TAreaId aid, u32 unk1)
void CParticleDatabase::DeleteAllLightsForParticleDB(CStateManager& mgr,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map)
{
for (auto& e : map)
{
e.second->DeleteLight(mgr);
}
}
void CParticleDatabase::DeleteAllLights(CStateManager& mgr)
{
DeleteAllLightsForParticleDB(mgr, x3c_rendererDrawLoop);
DeleteAllLightsForParticleDB(mgr, x50_firstDrawLoop);
DeleteAllLightsForParticleDB(mgr, x64_lastDrawLoop);
DeleteAllLightsForParticleDB(mgr, x78_rendererDraw);
DeleteAllLightsForParticleDB(mgr, x8c_firstDraw);
DeleteAllLightsForParticleDB(mgr, xa0_lastDraw);
}
void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo,
const zeus::CTransform& xf, const zeus::CVector3f& scale, CStateManager& stateMgr,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map, bool deleteIfDone)
{
for (auto it = map.begin() ; it != map.end() ;)
{
CParticleGenInfo& info = *it->second;
if (info.GetIsActive())
{
if (info.GetState() == EParticleGenState::NotStarted)
{
CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName());
if (segId == 0xff)
{
++it;
continue;
}
if (!pose.ContainsDataFor(segId))
{
++it;
continue;
}
const zeus::CVector3f& off = pose.GetOffset(segId);
switch (info.GetParentedMode())
{
case CParticleData::EParentedMode::Initial:
{
if (info.GetIsGrabInitialData())
{
zeus::CTransform segXf(
(info.GetFlags() & 0x10) ? zeus::CMatrix3f::skIdentityMatrix3f : pose.GetTransformMinusOffset(segId),
off * scale);
zeus::CTransform compXf = xf * segXf;
info.SetCurTransform(compXf.getRotation());
info.SetCurOffset(compXf.origin);
info.SetCurrentTime(0.f);
info.SetIsGrabInitialData(false);
}
info.SetOrientation(info.GetCurTransform(), stateMgr);
info.SetTranslation(info.GetCurOffset(), stateMgr);
if (info.GetFlags() & 0x2000)
info.SetGlobalScale(info.GetCurScale() * scale);
else
info.SetGlobalScale(info.GetCurScale());
break;
}
case CParticleData::EParentedMode::ContinuousEmitter:
case CParticleData::EParentedMode::ContinuousSystem:
{
if (info.GetIsGrabInitialData())
{
info.SetCurrentTime(0.f);
info.SetIsGrabInitialData(false);
}
zeus::CTransform segXf(pose.GetTransformMinusOffset(segId), off * scale);
zeus::CTransform compXf = xf * segXf;
if (info.GetParentedMode() == CParticleData::EParentedMode::ContinuousEmitter)
{
info.SetTranslation(compXf.origin, stateMgr);
if (info.GetFlags() & 0x10)
info.SetOrientation(xf.getRotation(), stateMgr);
else
info.SetOrientation(compXf.getRotation(), stateMgr);
}
else
{
info.SetGlobalTranslation(compXf.origin, stateMgr);
if (info.GetFlags() & 0x10)
info.SetGlobalOrientation(xf.getRotation(), stateMgr);
else
info.SetGlobalOrientation(compXf.getRotation(), stateMgr);
}
if (info.GetFlags() & 0x2000)
info.SetGlobalScale(info.GetCurScale() * scale);
else
info.SetGlobalScale(info.GetCurScale());
break;
}
default: break;
}
float sec = (info.GetInactiveStartTime() == 0.f) ? 10000000.f : info.GetInactiveStartTime();
if (info.GetCurrentTime() > sec)
{
info.SetIsActive(false);
info.SetParticleEmission(false, stateMgr);
info.MarkFinishTime();
if (info.GetFlags() & 1)
info.DestroyParticles();
}
}
}
info.Update(dt, stateMgr);
if (!info.GetIsActive())
{
if (!info.HasActiveParticles() && info.GetCurrentTime() - info.GetFinishTime() > 5.f && deleteIfDone)
{
info.DeleteLight(stateMgr);
it = map.erase(it);
continue;
}
}
else if (info.IsSystemDeletable())
{
info.DeleteLight(stateMgr);
it = map.erase(it);
continue;
}
info.OffsetTime(dt);
++it;
}
}
void CParticleDatabase::Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo,
const zeus::CTransform& xf, const zeus::CVector3f& vec, CStateManager& stateMgr)
const zeus::CTransform& xf, const zeus::CVector3f& scale, CStateManager& stateMgr)
{
if (!xb4_24_active)
return;
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, x3c_rendererDrawLoop, true);
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, x50_firstDrawLoop, true);
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, x64_lastDrawLoop, true);
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, x78_rendererDraw, false);
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, x8c_firstDraw, false);
UpdateParticleGenDB(dt, pose, charInfo, xf, scale, stateMgr, xa0_lastDraw, false);
xb4_25_drawingEnds = (x50_firstDrawLoop.size() || x64_lastDrawLoop.size() || x8c_firstDraw.size() || xa0_lastDraw.size());
}
void CParticleDatabase::AddToRendererClipped(const zeus::CFrustum& frustum)
void CParticleDatabase::RenderParticleGenMap(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map)
{
for (auto& e : map)
{
e.second->Render();
}
}
void CParticleDatabase::GetActiveParticleLightIds(std::vector<TUniqueId>&)
void CParticleDatabase::RenderParticleGenMapMasked(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map,
int mask, int target)
{
for (auto& e : map)
{
if ((e.second->GetFlags() & mask) == target)
e.second->Render();
}
}
void CParticleDatabase::AddToRendererClippedParticleGenMap(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map,
const zeus::CFrustum& frustum)
{
for (auto& e : map)
{
if (frustum.aabbFrustumTest(*e.second->GetBounds()))
e.second->AddToRenderer();
}
}
void CParticleDatabase::AddToRendererClippedParticleGenMapMasked(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map,
const zeus::CFrustum& frustum, int mask, int target)
{
for (auto& e : map)
{
if ((e.second->GetFlags() & mask) == target)
if (frustum.aabbFrustumTest(*e.second->GetBounds()))
e.second->AddToRenderer();
}
}
void CParticleDatabase::RenderSystemsToBeDrawnLastMasked(int mask, int target) const
{
RenderParticleGenMapMasked(xa0_lastDraw, mask, target);
RenderParticleGenMapMasked(x64_lastDrawLoop, mask, target);
}
void CParticleDatabase::RenderSystemsToBeDrawnLast() const
{
RenderParticleGenMap(xa0_lastDraw);
RenderParticleGenMap(x64_lastDrawLoop);
}
void CParticleDatabase::RenderSystemsToBeDrawnFirstMasked(int mask, int target) const
{
RenderParticleGenMapMasked(x8c_firstDraw, mask, target);
RenderParticleGenMapMasked(x50_firstDrawLoop, mask, target);
}
void CParticleDatabase::RenderSystemsToBeDrawnFirst() const
{
RenderParticleGenMap(x8c_firstDraw);
RenderParticleGenMap(x50_firstDrawLoop);
}
void CParticleDatabase::AddToRendererClippedMasked(const zeus::CFrustum& frustum, int mask, int target) const
{
AddToRendererClippedParticleGenMapMasked(x78_rendererDraw, frustum, mask, target);
AddToRendererClippedParticleGenMapMasked(x3c_rendererDrawLoop, frustum, mask, target);
}
void CParticleDatabase::AddToRendererClipped(const zeus::CFrustum& frustum) const
{
AddToRendererClippedParticleGenMap(x78_rendererDraw, frustum);
AddToRendererClippedParticleGenMap(x3c_rendererDrawLoop, frustum);
}
CParticleGenInfo* CParticleDatabase::GetParticleEffect(const std::string& name) const
{
auto search = x3c_rendererDrawLoop.find(name);
if (search != x3c_rendererDrawLoop.end())
return search->second.get();
search = x50_firstDrawLoop.find(name);
if (search != x50_firstDrawLoop.end())
return search->second.get();
search = x64_lastDrawLoop.find(name);
if (search != x64_lastDrawLoop.end())
return search->second.get();
search = x78_rendererDraw.find(name);
if (search != x78_rendererDraw.end())
return search->second.get();
search = x8c_firstDraw.find(name);
if (search != x8c_firstDraw.end())
return search->second.get();
search = xa0_lastDraw.find(name);
if (search != xa0_lastDraw.end())
return search->second.get();
return nullptr;
}
void CParticleDatabase::SetParticleEffectState(const std::string& name, bool active, CStateManager& mgr)
{
if (CParticleGenInfo* info = GetParticleEffect(name))
{
info->SetParticleEmission(active, mgr);
info->SetIsActive(active);
if (!active && (info->GetFlags() & 1) != 0)
info->DestroyParticles();
info->SetIsGrabInitialData(true);
}
}
void CParticleDatabase::SetCEXTValue(const std::string& name, int idx, float value)
{
if (CParticleGenInfo* info = GetParticleEffect(name))
{
static_cast<CElementGen*>(static_cast<CParticleGenInfoGeneric*>(info)->
GetParticleSystem().get())->SetCEXTValue(idx, value);
}
}
template <class T, class U>
static int _getGraphicLightId(const T& system, const U& desc)
{
if (system->SystemHasLight())
return desc.GetObjectTag()->id;
return -1;
}
void CParticleDatabase::AddAuxiliaryParticleEffect(const std::string& name, int flags, const CAuxiliaryParticleData& data,
const zeus::CVector3f& scale, CStateManager& mgr, TAreaId aid, int lightIdx)
{
}
void CParticleDatabase::AddParticleEffect(const std::string& name, int flags, const CParticleData& data,
const zeus::CVector3f& scale, CStateManager& mgr, TAreaId aid,
bool oneShot, int lightId)
{
if (CParticleGenInfo* info = GetParticleEffect(name))
{
if (!info->GetIsActive())
{
info->SetParticleEmission(true, mgr);
info->SetIsActive(true);
info->SetIsGrabInitialData(true);
info->SetFlags(flags);
}
return;
}
zeus::CVector3f scaleVec;
if (flags & 0x2)
scaleVec.splat(data.GetScale());
else
scaleVec = scale * data.GetScale();
std::unique_ptr<CParticleGenInfo> newGen;
switch (data.GetTag().type)
{
case SBIG('PART'):
{
auto search = x0_particleDescs.find(data.GetTag().id);
if (search != x0_particleDescs.end())
{
auto sys = std::make_shared<CElementGen>(*search->second, CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
newGen = std::make_unique<CParticleGenInfoGeneric>(data.GetTag(), sys, data.GetDuration(), data.GetSegmentName(),
scaleVec, data.GetParentedMode(), flags, mgr, aid,
lightId + _getGraphicLightId(sys, *search->second),
EParticleGenState::NotStarted);
}
break;
}
case SBIG('SWHC'):
{
auto search = x14_swooshDescs.find(data.GetTag().id);
if (search != x14_swooshDescs.end())
{
auto sys = std::make_shared<CParticleSwoosh>(*search->second, 0);
newGen = std::make_unique<CParticleGenInfoGeneric>(data.GetTag(), sys, data.GetDuration(), data.GetSegmentName(),
scaleVec, data.GetParentedMode(), flags, mgr, aid,
-1, EParticleGenState::NotStarted);
}
break;
}
case SBIG('ELSC'):
{
auto search = x28_electricDescs.find(data.GetTag().id);
if (search != x28_electricDescs.end())
{
auto sys = std::make_shared<CParticleElectric>(*search->second);
newGen = std::make_unique<CParticleGenInfoGeneric>(data.GetTag(), sys, data.GetDuration(), data.GetSegmentName(),
scaleVec, data.GetParentedMode(), flags, mgr, aid,
lightId + _getGraphicLightId(sys, *search->second),
EParticleGenState::NotStarted);
}
break;
}
default: break;
}
if (newGen)
{
newGen->SetIsActive(true);
newGen->SetParticleEmission(true, mgr);
newGen->SetIsGrabInitialData(true);
InsertParticleGen(oneShot, flags, name, std::move(newGen));
}
}
void CParticleDatabase::InsertParticleGen(bool oneShot, int flags, const std::string& name,
std::unique_ptr<CParticleGenInfo>&& gen)
{
std::map<std::string, std::unique_ptr<CParticleGenInfo>>* useMap;
if (oneShot)
{
if (flags & 0x40)
useMap = &xa0_lastDraw;
else if (flags & 0x20)
useMap = &x8c_firstDraw;
else
useMap = &x78_rendererDraw;
}
else
{
if (flags & 0x40)
useMap = &x64_lastDrawLoop;
else if (flags & 0x20)
useMap = &x50_firstDrawLoop;
else
useMap = &x3c_rendererDrawLoop;
}
useMap->insert(std::make_pair(name, std::move(gen)));
if (flags & 0x60)
xb4_25_drawingEnds = true;
}
}

View File

@@ -20,26 +20,54 @@ class CParticleDatabase
std::map<ResId, std::shared_ptr<TLockedToken<CGenDescription>>> x0_particleDescs;
std::map<ResId, std::shared_ptr<TLockedToken<CSwooshDescription>>> x14_swooshDescs;
std::map<ResId, std::shared_ptr<TLockedToken<CElectricDescription>>> x28_electricDescs;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x3c_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x50_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x64_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x78_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x8c_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> xa0_;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x3c_rendererDrawLoop;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x50_firstDrawLoop;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x64_lastDrawLoop;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x78_rendererDraw;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> x8c_firstDraw;
std::map<std::string, std::unique_ptr<CParticleGenInfo>> xa0_lastDraw;
bool xb4_24_active : 1;
bool xb4_25_drawingEnds : 1;
static void SetModulationColorAllActiveEffectsForParticleDB(const zeus::CColor& color,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map);
static void SuspendAllActiveEffectsForParticleDB(CStateManager& mgr,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map);
static void DeleteAllLightsForParticleDB(CStateManager& mgr,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map);
static void RenderParticleGenMap(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map);
static void RenderParticleGenMapMasked(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map,
int mask, int target);
static void AddToRendererClippedParticleGenMap(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map,
const zeus::CFrustum& frustum);
static void AddToRendererClippedParticleGenMapMasked(const std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map,
const zeus::CFrustum& frustum, int mask, int target);
static void UpdateParticleGenDB(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo,
const zeus::CTransform& xf, const zeus::CVector3f& vec, CStateManager& stateMgr,
std::map<std::string, std::unique_ptr<CParticleGenInfo>>& map, bool deleteIfDone);
public:
CParticleDatabase();
void CacheParticleDesc(const CCharacterInfo::CParticleResData& desc);
void SetModulationColorAllActiveEffects(const zeus::CColor& color);
void SuspendAllActiveEffects(CStateManager& stateMgr);
void StartEffect(const std::string& name, u32 flags, const CParticleData& data, const zeus::CVector3f& scale,
CStateManager& stateMgr, TAreaId aid, u32 unk1);
void DeleteAllLights(CStateManager& stateMgr);
void Update(float dt, const CPoseAsTransforms& pose, const CCharLayoutInfo& charInfo, const zeus::CTransform& xf,
const zeus::CVector3f& vec, CStateManager& stateMgr);
void AddToRendererClipped(const zeus::CFrustum& frustum);
void GetActiveParticleLightIds(std::vector<TUniqueId>&);
void GetActiveParticleLightIdsFromParticleDB(
std::vector<TUniqueId>&,
const std::map<std::string, std::unique_ptr<CParticleGenInfo>, std::less<std::string>>&);
const zeus::CVector3f& scale, CStateManager& stateMgr);
void RenderSystemsToBeDrawnLastMasked(int mask, int target) const;
void RenderSystemsToBeDrawnLast() const;
void RenderSystemsToBeDrawnFirstMasked(int mask, int target) const;
void RenderSystemsToBeDrawnFirst() const;
void AddToRendererClippedMasked(const zeus::CFrustum& frustum, int mask, int target) const;
void AddToRendererClipped(const zeus::CFrustum& frustum) const;
CParticleGenInfo* GetParticleEffect(const std::string& name) const;
void SetParticleEffectState(const std::string& name, bool active, CStateManager& mgr);
void SetCEXTValue(const std::string& name, int idx, float value);
void AddAuxiliaryParticleEffect(const std::string& name, int flags, const CAuxiliaryParticleData& data,
const zeus::CVector3f& scale, CStateManager& mgr, TAreaId aid, int lightIdx);
void AddParticleEffect(const std::string& name, int flags, const CParticleData& data,
const zeus::CVector3f& scale, CStateManager& mgr, TAreaId aid, bool oneShot, int lightIdx);
void InsertParticleGen(bool oneShot, int flags, const std::string& name,
std::unique_ptr<CParticleGenInfo>&& gen);
};
}

View File

@@ -11,14 +11,15 @@ namespace urde
{
CParticleGenInfo::CParticleGenInfo(const SObjectTag& part, int frameCount, const std::string& boneName,
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode, int a, int b)
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode,
int flags, EParticleGenState state)
: x4_part(part)
, xc_seconds(frameCount / 60.f)
, x10_boneName(boneName)
, x28_parentMode(parentMode)
, x2c_a(a)
, x2c_flags(flags)
, x30_particleScale(scale)
, x80_(b)
, x80_state(state)
{
}
@@ -41,8 +42,9 @@ static TUniqueId _initializeLight(const std::weak_ptr<CParticleGen>& system, CSt
CParticleGenInfoGeneric::CParticleGenInfoGeneric(const SObjectTag& part, const std::weak_ptr<CParticleGen>& system,
int frameCount, const std::string& boneName,
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode,
int a, CStateManager& stateMgr, TAreaId areaId, int lightId, int b)
: CParticleGenInfo(part, frameCount, boneName, scale, parentMode, a, b), x84_system(system)
int flags, CStateManager& stateMgr, TAreaId areaId, int lightId,
EParticleGenState state)
: CParticleGenInfo(part, frameCount, boneName, scale, parentMode, flags, state), x84_system(system)
{
if (lightId == -1)
x88_lightId = kInvalidUniqueId;
@@ -141,7 +143,10 @@ TUniqueId CParticleGenInfoGeneric::GetLightId() const { return x88_lightId; }
void CParticleGenInfoGeneric::DeleteLight(CStateManager& mgr)
{
if (x88_lightId != kInvalidUniqueId)
mgr.DeleteObjectRequest(x88_lightId);
{
mgr.FreeScriptObject(x88_lightId);
x88_lightId = kInvalidUniqueId;
}
}
void CParticleGenInfoGeneric::SetModulationColor(const zeus::CColor& color) { x84_system->SetModulationColor(color); }

View File

@@ -12,25 +12,32 @@ struct SObjectTag;
class CParticleGen;
class CStateManager;
enum class EParticleGenState
{
NotStarted,
Started
};
class CParticleGenInfo
{
SObjectTag x4_part;
float xc_seconds;
std::string x10_boneName;
float x20_ = 0.f;
bool x24_ = false;
float x20_curTime = 0.f;
bool x24_active = false;
CParticleData::EParentedMode x28_parentMode;
int x2c_a;
s32 x2c_flags;
zeus::CVector3f x30_particleScale;
float x3c_ = 0.f;
bool x40_ = false;
float x3c_finishTime = 0.f;
bool x40_grabInitialData = false;
zeus::CTransform x44_transform;
zeus::CVector3f x74_offset;
s32 x80_;
EParticleGenState x80_state;
public:
CParticleGenInfo(const SObjectTag& part, int frameCount, const std::string& boneName, const zeus::CVector3f&,
CParticleData::EParentedMode parentMode, int a, int b);
CParticleGenInfo(const SObjectTag& part, int frameCount, const std::string& boneName,
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode,
int flags, EParticleGenState state);
virtual ~CParticleGenInfo() = default;
virtual void AddToRenderer() = 0;
@@ -48,22 +55,30 @@ public:
virtual void DestroyParticles() = 0;
virtual bool HasLight() const = 0;
virtual TUniqueId GetLightId() const = 0;
virtual void DeleteLight(CStateManager&) const = 0;
virtual void DeleteLight(CStateManager& stateMgr) = 0;
virtual void SetModulationColor(const zeus::CColor& color) = 0;
void SetFlags(s32);
s32 GetFlags() const;
void SetIsGrabInitialData(bool);
bool GetIsGrabInitialData() const;
bool GetIsActive() const;
bool SetIsActive(bool);
void OffsetTime(float);
void SetFlags(s32 f) { x2c_flags = f; }
s32 GetFlags() const { return x2c_flags; }
void SetIsGrabInitialData(bool g) { x40_grabInitialData = g; }
bool GetIsGrabInitialData() const { return x40_grabInitialData; }
bool GetIsActive() const { return x24_active; }
void SetIsActive(bool a) { x24_active = a; }
void OffsetTime(float dt) { x20_curTime += dt; }
const zeus::CVector3f& GetCurOffset() const { return x74_offset; }
void SetCurOffset(const zeus::CVector3f& offset) { x74_offset = offset; }
const zeus::CTransform& GetCurTransform() const { return x44_transform; }
void SetCurTransform(const zeus::CTransform& xf) { x44_transform = xf; }
void SetInactiveStartTime(float);
float GetInactiveStartTime() const;
float GetFinishTime() const;
float GetCurrentTime() const;
const zeus::CVector3f& GetCurScale() const { return x30_particleScale; }
void SetCurScale(const zeus::CVector3f& scale) { x30_particleScale = scale; }
void SetInactiveStartTime(float s) { xc_seconds = s; }
float GetInactiveStartTime() const { return xc_seconds; }
void MarkFinishTime() { x3c_finishTime = x20_curTime; }
float GetFinishTime() const { return x3c_finishTime; }
float GetCurrentTime() const { return x20_curTime; }
void SetCurrentTime(float t) { x20_curTime = t; }
EParticleGenState GetState() const { return x80_state; }
void SetState(EParticleGenState s) { x80_state = s; }
CParticleData::EParentedMode GetParentedMode() const { return x28_parentMode; }
const std::string& GetLocatorName() const { return x10_boneName; }
@@ -75,10 +90,10 @@ class CParticleGenInfoGeneric : public CParticleGenInfo
TUniqueId x88_lightId;
public:
CParticleGenInfoGeneric(const SObjectTag& part, const std::weak_ptr<CParticleGen>& system, int,
const std::string& boneName, const zeus::CVector3f& scale,
CParticleData::EParentedMode parentMode, int a, CStateManager& stateMgr, TAreaId,
int lightId, int b);
CParticleGenInfoGeneric(const SObjectTag& part, const std::weak_ptr<CParticleGen>& system,
int frames, const std::string& boneName, const zeus::CVector3f& scale,
CParticleData::EParentedMode parentMode, int flags, CStateManager& stateMgr, TAreaId,
int lightId, EParticleGenState state);
void AddToRenderer();
void Render();
@@ -95,8 +110,9 @@ public:
void DestroyParticles();
bool HasLight() const;
TUniqueId GetLightId() const;
void DeleteLight(CStateManager&);
void DeleteLight(CStateManager& mgr);
void SetModulationColor(const zeus::CColor& color);
const std::shared_ptr<CParticleGen> GetParticleSystem() const { return x84_system; }
};
}

View File

@@ -32,6 +32,7 @@ public:
const zeus::CTransform& GetRestToAccumTransform(const CSegId& id) const;
const zeus::CVector3f& GetOffset(const CSegId& id) const;
const zeus::CMatrix3f& GetRotation(const CSegId& id) const;
const zeus::CMatrix3f& GetTransformMinusOffset(const CSegId& id) const { return GetRotation(id); }
void Insert(const CSegId& id,
const zeus::CMatrix3f& rotation,
const zeus::CVector3f& offset,

View File

@@ -22,6 +22,9 @@ public:
static CSoundPOINode CopyNodeMinusStartTime(const CSoundPOINode& node,
const CCharAnimTime& startTime);
u32 GetSfxId() const { return x38_sfxId; }
float GetFalloff() const { return x3c_falloff; }
float GetMaxDist() const { return x40_maxDist; }
};
}