mirror of https://github.com/AxioDL/metaforce.git
CParticleDatabase implementations
This commit is contained in:
parent
4c41132168
commit
db8a7d3433
|
@ -44,8 +44,8 @@ public:
|
|||
u16 x24_sfxId;
|
||||
float x26_maxVol;
|
||||
float x27_minVol;
|
||||
u8 x28_;
|
||||
u8 x29_;
|
||||
bool x28_important; // Can't be allocated over, regardless of priority
|
||||
u8 x29_prio;
|
||||
};
|
||||
CAudioSys(boo::IAudioVoiceEngine* voiceEngine,
|
||||
amuse::IBackendVoiceAllocator& backend, u8,u8,u8,u8,u32)
|
||||
|
|
|
@ -413,11 +413,11 @@ CSfxHandle CSfxManager::AddEmitter(u16 id, const zeus::CVector3f& pos, const zeu
|
|||
parmData.xc_dir = dir;
|
||||
parmData.x18_maxDist = 150.f;
|
||||
parmData.x1c_distComp = 0.1f;
|
||||
parmData.x20_flags = 1;
|
||||
parmData.x20_flags = 1; // Continuous parameter update
|
||||
parmData.x24_sfxId = id;
|
||||
parmData.x26_maxVol = std::max(vol, 0.165f);
|
||||
parmData.x28_ = 0;
|
||||
parmData.x29_ = 0x7f;
|
||||
parmData.x28_important = false;
|
||||
parmData.x29_prio = 0x7f;
|
||||
return AddEmitter(parmData, useAcoustics, prio, looped, areaId);
|
||||
}
|
||||
|
||||
|
@ -429,7 +429,7 @@ CSfxHandle CSfxManager::AddEmitter(const CAudioSys::C3DEmitterParmData& parmData
|
|||
|
||||
CAudioSys::C3DEmitterParmData data = parmData;
|
||||
if (looped)
|
||||
data.x20_flags |= 0x6;
|
||||
data.x20_flags |= 0x6; // Pausable/restartable when inaudible
|
||||
m_doUpdate = true;
|
||||
CSfxHandle wrapper = std::make_shared<CSfxEmitterWrapper>(looped, prio, data, useAcoustics, areaId);
|
||||
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace urde
|
|||
|
||||
class CCharacterInfo
|
||||
{
|
||||
friend class CAnimData;
|
||||
public:
|
||||
struct CParticleResData
|
||||
{
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ enum class EPOIType : u16
|
|||
Loop = 0,
|
||||
EmptyBool = 1,
|
||||
EmptyInt32 = 2,
|
||||
SoundInt32 = 4,
|
||||
Particle = 5,
|
||||
UserEvent = 6,
|
||||
RandRate = 7,
|
||||
|
|
|
@ -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:
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ class CLight
|
|||
float x34_angleL;
|
||||
float x38_angleQ;
|
||||
u32 x3c_priority = 0;
|
||||
u32 x40_loadedIdx = 0;
|
||||
u32 x40_lightId = 0; // Serves as unique key
|
||||
float x44_cachedRadius;
|
||||
float x48_cachedIntensity;
|
||||
bool x4c_24_intensityDirty : 1;
|
||||
|
|
|
@ -33,13 +33,8 @@ void CColoredQuadFilter::draw(const zeus::CColor& color, const zeus::CRectangle&
|
|||
m_uniform.m_color = color;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind);
|
||||
CGraphics::g_BooMainCommandQueue->draw(0, 4);
|
||||
}
|
||||
|
||||
void CColoredQuadFilter::DrawFilter(EFilterShape shape, const zeus::CColor& color, float t)
|
||||
{
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
}
|
||||
|
||||
void CWideScreenFilter::draw(const zeus::CColor& color, float t)
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
CColoredQuadFilter(EFilterType type, const TLockedToken<CTexture>&)
|
||||
: CColoredQuadFilter(type) {}
|
||||
void draw(const zeus::CColor& color, const zeus::CRectangle& rect=DefaultRect);
|
||||
void DrawFilter(EFilterShape shape, const zeus::CColor& color, float t);
|
||||
void DrawFilter(EFilterShape shape, const zeus::CColor& color, float t) { draw(color); }
|
||||
|
||||
using _CLS = CColoredQuadFilter;
|
||||
#include "TMultiBlendShaderDecl.hpp"
|
||||
|
|
|
@ -14,7 +14,7 @@ CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, boo::ITexture* tex)
|
|||
{
|
||||
m_token = CGraphics::g_BooFactory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4);
|
||||
m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 16);
|
||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
||||
m_dataBind = TMultiBlendShader<CTexturedQuadFilter>::BuildShaderDataBinding(ctx, type, *this);
|
||||
return true;
|
||||
|
@ -46,8 +46,8 @@ void CTexturedQuadFilter::draw(const zeus::CColor& color, float uvScale, const z
|
|||
m_uniform.m_color = color;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind);
|
||||
CGraphics::g_BooMainCommandQueue->draw(0, 4);
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
}
|
||||
|
||||
void CTexturedQuadFilter::drawCropped(const zeus::CColor& color, float uvScale)
|
||||
|
@ -69,8 +69,8 @@ void CTexturedQuadFilter::drawCropped(const zeus::CColor& color, float uvScale)
|
|||
m_uniform.m_color = color;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind);
|
||||
CGraphics::g_BooMainCommandQueue->draw(0, 4);
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
}
|
||||
|
||||
void CTexturedQuadFilter::drawVerts(const zeus::CColor& color, const Vert verts[4], float lod)
|
||||
|
@ -82,13 +82,58 @@ void CTexturedQuadFilter::drawVerts(const zeus::CColor& color, const Vert verts[
|
|||
m_uniform.m_lod = lod;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind);
|
||||
CGraphics::g_BooMainCommandQueue->draw(0, 4);
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
}
|
||||
|
||||
void CTexturedQuadFilter::DrawFilter(EFilterShape shape, const zeus::CColor& color, float t)
|
||||
{
|
||||
m_uniform.m_matrix = zeus::CMatrix4f::skIdentityMatrix4f;
|
||||
m_uniform.m_lod = 0.f;
|
||||
m_uniform.m_color = color;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
|
||||
if (shape == EFilterShape::FullscreenQuarters)
|
||||
{
|
||||
Vert QuadVerts[] =
|
||||
{
|
||||
{{-1.f, -1.f, 0.f}, {0.f, 0.f}},
|
||||
{{-1.f, 0.f, 0.f}, {0.f, t}},
|
||||
{{ 0.f, -1.f, 0.f}, {t, 0.f}},
|
||||
{{ 0.f, 0.f, 0.f}, {t, t}},
|
||||
{{-1.f, 1.f, 0.f}, {0.f, 0.f}},
|
||||
{{-1.f, 0.f, 0.f}, {0.f, t}},
|
||||
{{ 0.f, 1.f, 0.f}, {t, 0.f}},
|
||||
{{ 0.f, 0.f, 0.f}, {t, t}},
|
||||
{{ 1.f, -1.f, 0.f}, {0.f, 0.f}},
|
||||
{{ 1.f, 0.f, 0.f}, {0.f, t}},
|
||||
{{ 0.f, -1.f, 0.f}, {t, 0.f}},
|
||||
{{ 0.f, 0.f, 0.f}, {t, t}},
|
||||
{{ 1.f, 1.f, 0.f}, {0.f, 0.f}},
|
||||
{{ 1.f, 0.f, 0.f}, {0.f, t}},
|
||||
{{ 0.f, 1.f, 0.f}, {t, 0.f}},
|
||||
{{ 0.f, 0.f, 0.f}, {t, t}},
|
||||
};
|
||||
m_vbo->load(QuadVerts, sizeof(Vert) * 16);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
CGraphics::DrawArray(4, 4);
|
||||
CGraphics::DrawArray(8, 4);
|
||||
CGraphics::DrawArray(12, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vert FullscreenVerts[] =
|
||||
{
|
||||
{{-1.f, -1.f, 0.f}, {0.f, 0.f}},
|
||||
{{-1.f, 1.f, 0.f}, {0.f, t}},
|
||||
{{ 1.f, -1.f, 0.f}, {t, 0.f}},
|
||||
{{ 1.f, 1.f, 0.f}, {t, t}},
|
||||
};
|
||||
m_vbo->load(FullscreenVerts, sizeof(Vert) * 4);
|
||||
CGraphics::DrawArray(0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
const zeus::CRectangle CTexturedQuadFilter::DefaultRect = {0.f, 0.f, 1.f, 1.f};
|
||||
|
|
|
@ -105,12 +105,12 @@ void CGuiFrame::DisableLights() const
|
|||
|
||||
void CGuiFrame::RemoveLight(CGuiLight* light)
|
||||
{
|
||||
m_indexedLights[light->GetLoadedIdx()] = nullptr;
|
||||
m_indexedLights[light->GetLightId()] = nullptr;
|
||||
}
|
||||
|
||||
void CGuiFrame::AddLight(CGuiLight* light)
|
||||
{
|
||||
m_indexedLights[light->GetLoadedIdx()] = light;
|
||||
m_indexedLights[light->GetLightId()] = light;
|
||||
}
|
||||
|
||||
void CGuiFrame::RegisterLight(std::shared_ptr<CGuiLight>&& light)
|
||||
|
|
|
@ -14,7 +14,7 @@ CGuiLight::CGuiLight(const CGuiWidgetParms& parms, const CLight& light)
|
|||
xcc_angleC(light.x30_angleC),
|
||||
xd0_angleL(light.x34_angleL),
|
||||
xd4_angleQ(light.x38_angleQ),
|
||||
xd8_loadedIdx(light.x40_loadedIdx)
|
||||
xd8_lightId(light.x40_lightId)
|
||||
{}
|
||||
|
||||
CGuiLight::~CGuiLight()
|
||||
|
@ -65,7 +65,7 @@ std::shared_ptr<CGuiWidget> CGuiLight::Create(CGuiFrame* frame, CInputStream& in
|
|||
float angC = in.readFloatBig();
|
||||
float angL = in.readFloatBig();
|
||||
float angQ = in.readFloatBig();
|
||||
u32 loadedIdx = in.readUint32Big();
|
||||
u32 lightId = in.readUint32Big();
|
||||
|
||||
std::shared_ptr<CGuiLight> ret = {};
|
||||
switch (tp)
|
||||
|
@ -77,7 +77,7 @@ std::shared_ptr<CGuiWidget> CGuiLight::Create(CGuiFrame* frame, CInputStream& in
|
|||
parms.x10_color, cutoff);
|
||||
lt.SetAttenuation(distC, distL, distQ);
|
||||
lt.SetAngleAttenuation(angC, angL, angQ);
|
||||
lt.x40_loadedIdx = loadedIdx;
|
||||
lt.x40_lightId = lightId;
|
||||
ret = std::make_shared<CGuiLight>(parms, lt);
|
||||
break;
|
||||
}
|
||||
|
@ -85,14 +85,14 @@ std::shared_ptr<CGuiWidget> CGuiLight::Create(CGuiFrame* frame, CInputStream& in
|
|||
{
|
||||
CLight lt = CLight::BuildPoint(zeus::CVector3f::skZero, parms.x10_color);
|
||||
lt.SetAttenuation(distC, distL, distQ);
|
||||
lt.x40_loadedIdx = loadedIdx;
|
||||
lt.x40_lightId = lightId;
|
||||
ret = std::make_shared<CGuiLight>(parms, lt);
|
||||
break;
|
||||
}
|
||||
case ELightType::Directional:
|
||||
{
|
||||
CLight lt = CLight::BuildDirectional(zeus::CVector3f::skZero, parms.x10_color);
|
||||
lt.x40_loadedIdx = loadedIdx;
|
||||
lt.x40_lightId = lightId;
|
||||
ret = std::make_shared<CGuiLight>(parms, lt);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ class CGuiLight : public CGuiWidget
|
|||
float xcc_angleC;
|
||||
float xd0_angleL;
|
||||
float xd4_angleQ;
|
||||
u32 xd8_loadedIdx;
|
||||
u32 xd8_lightId;
|
||||
zeus::CColor xdc_ambColor = zeus::CColor::skBlack;
|
||||
public:
|
||||
~CGuiLight();
|
||||
|
@ -27,7 +27,7 @@ public:
|
|||
|
||||
CLight BuildLight() const;
|
||||
void SetIsVisible(bool vis);
|
||||
u32 GetLoadedIdx() const {return xd8_loadedIdx;}
|
||||
u32 GetLightId() const {return xd8_lightId;}
|
||||
const zeus::CColor& GetAmbientLightColor() const {return xdc_ambColor;}
|
||||
void SetSpotCutoff(float v) {xbc_spotCutoff = v;}
|
||||
void SetDistC(float v) {xc0_distC = v;}
|
||||
|
@ -36,7 +36,7 @@ public:
|
|||
void SetAngleC(float v) {xcc_angleC = v;}
|
||||
void SetAngleL(float v) {xd0_angleL = v;}
|
||||
void SetAngleQ(float v) {xd4_angleQ = v;}
|
||||
void SetLoadedIdx(u32 idx) {xd8_loadedIdx = idx;}
|
||||
void SetLightId(u32 idx) {xd8_lightId = idx;}
|
||||
void SetAmbientLightColor(const zeus::CColor& color) {xdc_ambColor = color;}
|
||||
|
||||
static std::shared_ptr<CGuiWidget> Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp);
|
||||
|
|
|
@ -334,7 +334,7 @@ void CSamusHud::InitializeDamageLight()
|
|||
x3d4_damageLight->SetAngleC(g_tweakGui->GetDamageLightAngleC());
|
||||
x3d4_damageLight->SetAngleL(g_tweakGui->GetDamageLightAngleL());
|
||||
x3d4_damageLight->SetAngleQ(g_tweakGui->GetDamageLightAngleQ());
|
||||
x3d4_damageLight->SetLoadedIdx(4);
|
||||
x3d4_damageLight->SetLightId(4);
|
||||
|
||||
x3d4_damageLight->SetLocalTransform(zeus::CTransform::Identity());
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ void MP1::CActorContraption::ResetFlameThrowers(CStateManager& mgr)
|
|||
}
|
||||
}
|
||||
|
||||
void MP1::CActorContraption::DoUserAnimEvent(CStateManager& mgr, CInt32POINode& node, EUserEventType evType)
|
||||
void MP1::CActorContraption::DoUserAnimEvent(CStateManager& mgr, CInt32POINode& node, EUserEventType evType, float dt)
|
||||
{
|
||||
if (evType == EUserEventType::DamageOff)
|
||||
{
|
||||
|
@ -76,7 +76,7 @@ void MP1::CActorContraption::DoUserAnimEvent(CStateManager& mgr, CInt32POINode&
|
|||
fl->Fire(GetTransform(), mgr, false);
|
||||
}
|
||||
else
|
||||
CActor::DoUserAnimEvent(mgr, node, evType);
|
||||
CActor::DoUserAnimEvent(mgr, node, evType, dt);
|
||||
}
|
||||
|
||||
CFlameThrower* MP1::CActorContraption::CreateFlameThrower(const std::string& name, CStateManager& mgr)
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
void Accept(IVisitor &visitor);
|
||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &);
|
||||
void Think(float, CStateManager &);
|
||||
void DoUserAnimEvent(CStateManager &, CInt32POINode &, EUserEventType);
|
||||
void DoUserAnimEvent(CStateManager &, CInt32POINode &, EUserEventType, float dt);
|
||||
CFlameThrower* CreateFlameThrower(const std::string&, CStateManager&);
|
||||
void ResetFlameThrowers(CStateManager& mgr);
|
||||
};
|
||||
|
|
|
@ -90,6 +90,7 @@ private:
|
|||
float x6c_generatorRemainder = 0.f;
|
||||
int x90_MAXP = 0;
|
||||
u16 x94_randomSeed = 99;
|
||||
float x9c_cextValues[16] = {};
|
||||
float x78_generatorRate = 1.f;
|
||||
zeus::CVector3f x7c_translation;
|
||||
zeus::CVector3f x88_globalTranslation;
|
||||
|
@ -221,6 +222,8 @@ public:
|
|||
u32 GetParticleCountAll() const {return x20c_recursiveParticleCount;}
|
||||
void EndLifetime();
|
||||
void ForceParticleCreation(int amount);
|
||||
float GetCEXTValue(int i) const { return x9c_cextValues[i]; }
|
||||
void SetCEXTValue(int i, float v) { x9c_cextValues[i] = v; }
|
||||
|
||||
bool InternalUpdate(double);
|
||||
void RenderModels();
|
||||
|
|
|
@ -339,7 +339,7 @@ bool CRECEXT::GetValue(int frame, float& valOut) const
|
|||
int a;
|
||||
x4_a->GetValue(frame, a);
|
||||
int cv = std::max(0, a);
|
||||
/* TODO: Figure out how value table is generated/stored in 0-00 */
|
||||
valOut = CParticleGlobals::g_currentParticleSystem->x4_system->GetCEXTValue(cv & 0xf);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "TCastTo.hpp"
|
||||
#include "Character/IAnimReader.hpp"
|
||||
#include "Character/CActorLights.hpp"
|
||||
#include "Camera/CGameCamera.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -28,6 +29,7 @@ CActor::CActor(TUniqueId uid, bool active, const std::string& name, const CEntit
|
|||
{
|
||||
if (mData.x10_animData || mData.x1c_normalModel)
|
||||
x64_modelData = std::make_unique<CModelData>(std::move(mData));
|
||||
xd8_nonLoopingSfxHandles.resize(2);
|
||||
}
|
||||
|
||||
void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||
|
@ -123,11 +125,11 @@ zeus::CVector3f CActor::GetScanObjectIndicatorPosition(const CStateManager&) con
|
|||
|
||||
void CActor::RemoveEmitter()
|
||||
{
|
||||
if (x8c_sfxHandle)
|
||||
if (x8c_loopingSfxHandle)
|
||||
{
|
||||
CSfxManager::RemoveEmitter(*x8c_sfxHandle.get());
|
||||
CSfxManager::RemoveEmitter(x8c_loopingSfxHandle);
|
||||
x88_sfxId = -1;
|
||||
x8c_sfxHandle.reset();
|
||||
x8c_loopingSfxHandle.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +163,7 @@ void CActor::OnScanStateChanged(EScanState state, CStateManager& mgr)
|
|||
|
||||
zeus::CAABox CActor::GetSortingBounds(const CStateManager&) const { return x9c_aabox; }
|
||||
|
||||
void CActor::DoUserAnimEvent(CStateManager&, CInt32POINode&, EUserEventType) {}
|
||||
void CActor::DoUserAnimEvent(CStateManager&, CInt32POINode&, EUserEventType, float dt) {}
|
||||
|
||||
void CActor::RemoveMaterial(EMaterialTypes t1, EMaterialTypes t2, EMaterialTypes t3, EMaterialTypes t4,
|
||||
CStateManager& mgr)
|
||||
|
@ -265,16 +267,14 @@ void CActor::SetInFluid(bool in, TUniqueId uid)
|
|||
|
||||
bool CActor::HasModelData() const { return bool(x64_modelData); }
|
||||
|
||||
const CSfxHandle* CActor::GetSfxHandle() const { return x8c_sfxHandle.get(); }
|
||||
|
||||
void CActor::SetSfxPitchBend(s32 val)
|
||||
void CActor::SetSoundEventPitchBend(s32 val)
|
||||
{
|
||||
xe6_30_enablePitchBend = true;
|
||||
xc0_ = val;
|
||||
if (x8c_sfxHandle == 0)
|
||||
xc0_pitchBend = val / 8192.f;
|
||||
if (!x8c_loopingSfxHandle)
|
||||
return;
|
||||
|
||||
CSfxManager::PitchBend(*x8c_sfxHandle.get(), val);
|
||||
CSfxManager::PitchBend(x8c_loopingSfxHandle, val);
|
||||
}
|
||||
|
||||
void CActor::SetRotation(const zeus::CQuaternion &q)
|
||||
|
@ -318,9 +318,154 @@ void CActor::EnsureRendered(const CStateManager& stateMgr, const zeus::CVector3f
|
|||
stateMgr.AddDrawableActor(*this, pos, aabb);
|
||||
}
|
||||
|
||||
SAdvancementDeltas CActor::UpdateAnimation(float, CStateManager&, bool)
|
||||
void CActor::UpdateSfxEmitters()
|
||||
{
|
||||
return {};
|
||||
for (CSfxHandle& sfx : xd8_nonLoopingSfxHandles)
|
||||
CSfxManager::UpdateEmitter(sfx, x34_transform.origin, zeus::CVector3f::skZero, xd4_maxVol);
|
||||
}
|
||||
|
||||
void CActor::ProcessSoundEvent(u32 sfxId, float weight, u32 flags, float falloff, float maxDist,
|
||||
float minVol, float maxVol, const zeus::CVector3f& toListener,
|
||||
const zeus::CVector3f& position, TAreaId aid, CStateManager& mgr,
|
||||
bool translateId)
|
||||
{
|
||||
if (toListener.magSquared() >= maxDist * maxDist)
|
||||
return;
|
||||
u16 id = translateId ? CSfxManager::TranslateSFXID(sfxId) : sfxId;
|
||||
|
||||
u32 musyxFlags = 0x1; // Continuous parameter update
|
||||
if (flags & 0x8)
|
||||
musyxFlags |= 0x8; // Doppler FX
|
||||
|
||||
CAudioSys::C3DEmitterParmData parms;
|
||||
parms.x0_pos = position;
|
||||
parms.xc_dir = zeus::CVector3f::skZero;
|
||||
parms.x18_maxDist = maxDist;
|
||||
parms.x1c_distComp = falloff;
|
||||
parms.x20_flags = musyxFlags;
|
||||
parms.x24_sfxId = id;
|
||||
parms.x26_maxVol = maxVol;
|
||||
parms.x27_minVol = minVol;
|
||||
parms.x28_important = false;
|
||||
parms.x29_prio = 0x7f;
|
||||
|
||||
bool useAcoustics = (flags & 0x80) == 0;
|
||||
bool looping = (sfxId & 0x80000000) != 0;
|
||||
bool nonEmitter = (sfxId & 0x40000000) != 0;
|
||||
bool continuousUpdate = (sfxId & 0x20000000) != 0;
|
||||
|
||||
if (mgr.GetActiveRandom()->Float() > weight)
|
||||
return;
|
||||
|
||||
if (looping)
|
||||
{
|
||||
u16 curId = x88_sfxId;
|
||||
if (!x8c_loopingSfxHandle)
|
||||
{
|
||||
CSfxHandle handle;
|
||||
if (nonEmitter)
|
||||
handle = CSfxManager::SfxStart(id, 1.f, 0.f, true, 0x7f, true, aid);
|
||||
else
|
||||
handle = CSfxManager::AddEmitter(parms, useAcoustics, 0x7f, true, aid);
|
||||
if (handle)
|
||||
{
|
||||
x88_sfxId = id;
|
||||
x8c_loopingSfxHandle = handle;
|
||||
if (xe6_30_enablePitchBend)
|
||||
CSfxManager::PitchBend(handle, xc0_pitchBend);
|
||||
}
|
||||
}
|
||||
else if (curId == id)
|
||||
{
|
||||
CSfxManager::UpdateEmitter(x8c_loopingSfxHandle, position, zeus::CVector3f::skZero, maxVol);
|
||||
}
|
||||
else if (flags & 0x4)
|
||||
{
|
||||
CSfxManager::RemoveEmitter(x8c_loopingSfxHandle);
|
||||
CSfxHandle handle = CSfxManager::AddEmitter(parms, useAcoustics, 0x7f, true, aid);
|
||||
if (handle)
|
||||
{
|
||||
x88_sfxId = id;
|
||||
x8c_loopingSfxHandle = handle;
|
||||
if (xe6_30_enablePitchBend)
|
||||
CSfxManager::PitchBend(handle, xc0_pitchBend);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CSfxHandle handle;
|
||||
if (nonEmitter)
|
||||
handle = CSfxManager::SfxStart(id, 1.f, 0.f, useAcoustics, 0x7f, false, aid);
|
||||
else
|
||||
handle = CSfxManager::AddEmitter(parms, useAcoustics, 0x7f, false, aid);
|
||||
|
||||
if (continuousUpdate)
|
||||
{
|
||||
xd8_nonLoopingSfxHandles[xe4_24_nextNonLoopingSfxHandle] = handle;
|
||||
xe4_24_nextNonLoopingSfxHandle = (xe4_24_nextNonLoopingSfxHandle + 1) % xd8_nonLoopingSfxHandles.size();
|
||||
}
|
||||
|
||||
if (xe6_30_enablePitchBend)
|
||||
CSfxManager::PitchBend(handle, xc0_pitchBend);
|
||||
}
|
||||
}
|
||||
|
||||
SAdvancementDeltas CActor::UpdateAnimation(float dt, CStateManager& mgr, bool advTree)
|
||||
{
|
||||
SAdvancementDeltas deltas = x64_modelData->AdvanceAnimation(dt, mgr, GetAreaId(), advTree);
|
||||
x64_modelData->AdvanceParticles(x34_transform, dt, mgr);
|
||||
UpdateSfxEmitters();
|
||||
if (x64_modelData && x64_modelData->HasAnimData())
|
||||
{
|
||||
zeus::CVector3f toCamera =
|
||||
mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation() - x34_transform.origin;
|
||||
|
||||
for (int i=0 ; i<x64_modelData->GetAnimationData()->GetPassedSoundPOICount() ; ++i)
|
||||
{
|
||||
CSoundPOINode& poi = CAnimData::g_SoundPOINodes[i];
|
||||
if (poi.GetPoiType() != EPOIType::Sound)
|
||||
continue;
|
||||
if (xe5_26_muted)
|
||||
continue;
|
||||
if (poi.GetCharacterIndex() != -1 &&
|
||||
x64_modelData->GetAnimationData()->GetCharacterIndex() != poi.GetCharacterIndex())
|
||||
continue;
|
||||
ProcessSoundEvent(poi.GetSfxId(), poi.GetWeight(), poi.GetFlags(), poi.GetFalloff(),
|
||||
poi.GetMaxDist(), 0.16f, xd4_maxVol, toCamera, x34_transform.origin, x4_areaId,
|
||||
mgr, true);
|
||||
}
|
||||
|
||||
for (int i=0 ; i<x64_modelData->GetAnimationData()->GetPassedIntPOICount() ; ++i)
|
||||
{
|
||||
CInt32POINode& poi = CAnimData::g_Int32POINodes[i];
|
||||
if (poi.GetPoiType() == EPOIType::SoundInt32)
|
||||
{
|
||||
if (xe5_26_muted)
|
||||
continue;
|
||||
if (poi.GetCharacterIndex() != -1 &&
|
||||
x64_modelData->GetAnimationData()->GetCharacterIndex() != poi.GetCharacterIndex())
|
||||
continue;
|
||||
ProcessSoundEvent(poi.GetValue(), poi.GetWeight(), poi.GetFlags(), 0.1f,
|
||||
150.f, 0.16f, xd4_maxVol, toCamera, x34_transform.origin, x4_areaId,
|
||||
mgr, true);
|
||||
}
|
||||
else if (poi.GetPoiType() == EPOIType::UserEvent)
|
||||
{
|
||||
DoUserAnimEvent(mgr, poi, EUserEventType(poi.GetValue()), dt);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0 ; i<x64_modelData->GetAnimationData()->GetPassedParticlePOICount() ; ++i)
|
||||
{
|
||||
CParticlePOINode& poi = CAnimData::g_ParticlePOINodes[i];
|
||||
if (poi.GetCharacterIndex() != -1 &&
|
||||
x64_modelData->GetAnimationData()->GetCharacterIndex() != poi.GetCharacterIndex())
|
||||
continue;
|
||||
x64_modelData->AnimationData()->GetParticleDB().SetParticleEffectState(poi.GetString(), true, mgr);
|
||||
}
|
||||
}
|
||||
return deltas;
|
||||
}
|
||||
|
||||
void CActor::SetActorLights(std::unique_ptr<CActorLights> lights)
|
||||
|
|
|
@ -33,25 +33,26 @@ protected:
|
|||
CMaterialList x68_material;
|
||||
CMaterialFilter x70_materialFilter;
|
||||
s16 x88_sfxId = -1;
|
||||
std::unique_ptr<CSfxHandle> x8c_sfxHandle;
|
||||
CSfxHandle x8c_loopingSfxHandle;
|
||||
std::unique_ptr<CActorLights> x90_actorLights;
|
||||
std::unique_ptr<CSimpleShadow> x94_simpleShadow;
|
||||
std::unique_ptr<TToken<CScannableObjectInfo>> x98_scanObjectInfo;
|
||||
zeus::CAABox x9c_aabox;
|
||||
CModelFlags xb4_drawFlags;
|
||||
float xbc_time = 0.f;
|
||||
s32 xc0_ = 0;
|
||||
float xc0_pitchBend = 0.f;
|
||||
TUniqueId xc4_fluidId = kInvalidUniqueId;
|
||||
TUniqueId xc6_nextDrawNode = kInvalidUniqueId;
|
||||
u32 xc8_drawnToken = -1;
|
||||
u32 xcc_addedToken = -1;
|
||||
float xd0_;
|
||||
u8 xd4_ = 0x7F;
|
||||
u32 xd8_ = 2;
|
||||
float xd4_maxVol = 1.f;
|
||||
rstl::reserved_vector<CSfxHandle, 2> xd8_nonLoopingSfxHandles;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u8 xe4_24_nextNonLoopingSfxHandle : 3;
|
||||
bool xe4_27_ : 1;
|
||||
bool xe4_28_ : 1;
|
||||
bool xe4_29_ : 1;
|
||||
|
@ -72,6 +73,7 @@ protected:
|
|||
u32 dummy = 0;
|
||||
};
|
||||
void _CreateShadow();
|
||||
void UpdateSfxEmitters();
|
||||
|
||||
public:
|
||||
enum class EFluidState
|
||||
|
@ -117,7 +119,7 @@ public:
|
|||
virtual void FluidFXThink(EFluidState, CScriptWater&, CStateManager&);
|
||||
virtual void OnScanStateChanged(EScanState, CStateManager&);
|
||||
virtual zeus::CAABox GetSortingBounds(const CStateManager&) const;
|
||||
virtual void DoUserAnimEvent(CStateManager&, CInt32POINode&, EUserEventType);
|
||||
virtual void DoUserAnimEvent(CStateManager&, CInt32POINode&, EUserEventType, float dt);
|
||||
|
||||
void RemoveEmitter();
|
||||
const zeus::CTransform& GetTransform() const { return x34_transform; }
|
||||
|
@ -145,8 +147,8 @@ public:
|
|||
const CMaterialList& GetMaterialList() const { return x68_material; }
|
||||
void SetInFluid(bool in, TUniqueId uid);
|
||||
bool HasModelData() const;
|
||||
const CSfxHandle* GetSfxHandle() const;
|
||||
void SetSfxPitchBend(s32);
|
||||
const CSfxHandle& GetSfxHandle() const { return x8c_loopingSfxHandle; }
|
||||
void SetSoundEventPitchBend(s32);
|
||||
void SetRotation(const zeus::CQuaternion& q);
|
||||
void SetTranslation(const zeus::CVector3f& tr);
|
||||
void SetTransform(const zeus::CTransform& tr);
|
||||
|
@ -157,6 +159,10 @@ public:
|
|||
CModelData* ModelData() { return x64_modelData.get(); }
|
||||
void EnsureRendered(const CStateManager&);
|
||||
void EnsureRendered(const CStateManager&, const zeus::CVector3f&, const zeus::CAABox&) const;
|
||||
void ProcessSoundEvent(u32 sfxId, float weight, u32 flags, float falloff, float maxDist,
|
||||
float minVol, float maxVol, const zeus::CVector3f& toListener,
|
||||
const zeus::CVector3f& position, TAreaId aid, CStateManager& mgr,
|
||||
bool translateId);
|
||||
SAdvancementDeltas UpdateAnimation(float, CStateManager&, bool);
|
||||
void SetActorLights(std::unique_ptr<CActorLights>);
|
||||
bool CanDrawStatic() const;
|
||||
|
|
|
@ -35,7 +35,7 @@ void CGameLight::Think(float dt, CStateManager& mgr)
|
|||
void CGameLight::SetLightPriorityAndId()
|
||||
{
|
||||
xec_light.x3c_priority = x140_priority;
|
||||
xec_light.x40_loadedIdx = x13c_loadedIdx;
|
||||
xec_light.x40_lightId = x13c_loadedIdx;
|
||||
}
|
||||
|
||||
void CGameLight::SetLight(const CLight& light)
|
||||
|
|
Loading…
Reference in New Issue