More particle bug fixes

This commit is contained in:
Jack Andersen 2018-05-13 13:27:47 -10:00
parent faf0ac7d27
commit 9130b9459a
10 changed files with 148 additions and 70 deletions

View File

@ -863,8 +863,9 @@ SAdvancementDeltas CAnimData::Advance(float dt, const zeus::CVector3f& scale,
if (suspendParticles)
x120_particleDB.SuspendAllActiveEffects(stateMgr);
for (CParticlePOINode& node : g_ParticlePOINodes)
for (int i=0 ; i<x214_passedParticleCount ; ++i)
{
CParticlePOINode& node = g_ParticlePOINodes[i];
if (node.GetCharacterIndex() == -1 || node.GetCharacterIndex() == x204_charIdx)
{
x120_particleDB.AddParticleEffect(node.GetString(), node.GetFlags(), node.GetParticleData(),
@ -897,8 +898,9 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus::
if ((x220_28_ || x220_27_) && x210_passedIntCount > 0)
{
for (CInt32POINode& node : g_Int32POINodes)
for (int i=0 ; i<x210_passedIntCount ; ++i)
{
CInt32POINode& node = g_Int32POINodes[i];
if (node.GetPoiType() == EPOIType::UserEvent)
{
switch (EUserEventType(node.GetValue()))

View File

@ -493,6 +493,10 @@ SAdvancementResults CFBStreamedAnimReader::VAdvanceView(const CCharAnimTime& dt)
{
xc_curTime = CCharAnimTime();
x7c_totals.SetTime(x108_bitLoader, xc_curTime);
x14_passedBoolCount = 0;
x18_passedIntCount = 0;
x1c_passedParticleCount = 0;
x20_passedSoundCount = 0;
res.x0_remTime = dt;
return res;
}

View File

@ -110,7 +110,7 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p
CParticleGenInfo& info = *it->second;
if (info.GetIsActive())
{
if (info.GetState() == EParticleGenState::NotStarted)
if (info.GetType() == EParticleGenType::Normal)
{
CSegId segId = charInfo.GetSegIdFromString(info.GetLocatorName());
if (segId == 0xff)
@ -188,16 +188,16 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p
}
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();
}
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();
}
}
@ -404,7 +404,7 @@ void CParticleDatabase::AddAuxiliaryParticleEffect(std::string_view name, int fl
newGen = std::make_unique<CParticleGenInfoGeneric>(data.GetTag(), sys, data.GetDuration(), "NOT_A_VALID_LOCATOR",
scaleVec, CParticleData::EParentedMode::Initial, flags, mgr, aid,
lightId + _getGraphicLightId(sys, *search->second),
EParticleGenState::Started);
EParticleGenType::Auxiliary);
newGen->SetGlobalTranslation(data.GetTranslation(), mgr);
newGen->SetIsGrabInitialData(false);
@ -450,7 +450,7 @@ void CParticleDatabase::AddParticleEffect(std::string_view name, int flags, cons
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);
EParticleGenType::Normal);
}
break;
}
@ -462,7 +462,7 @@ void CParticleDatabase::AddParticleEffect(std::string_view name, int flags, cons
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);
-1, EParticleGenType::Normal);
}
break;
}
@ -475,7 +475,7 @@ void CParticleDatabase::AddParticleEffect(std::string_view name, int flags, cons
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);
EParticleGenType::Normal);
}
break;
}

View File

@ -12,14 +12,14 @@ namespace urde
CParticleGenInfo::CParticleGenInfo(const SObjectTag& part, int frameCount, std::string_view boneName,
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode,
int flags, EParticleGenState state)
int flags, EParticleGenType type)
: x4_part(part)
, xc_seconds(frameCount / 60.f)
, x10_boneName(boneName)
, x28_parentMode(parentMode)
, x2c_flags(flags)
, x30_particleScale(scale)
, x80_state(state)
, x80_type(type)
{
}
@ -43,7 +43,7 @@ CParticleGenInfoGeneric::CParticleGenInfoGeneric(const SObjectTag& part, const s
int frameCount, std::string_view boneName,
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode,
int flags, CStateManager& stateMgr, TAreaId areaId, int lightId,
EParticleGenState state)
EParticleGenType state)
: CParticleGenInfo(part, frameCount, boneName, scale, parentMode, flags, state), x84_system(system)
{
if (lightId == -1)

View File

@ -12,10 +12,10 @@ struct SObjectTag;
class CParticleGen;
class CStateManager;
enum class EParticleGenState
enum class EParticleGenType
{
NotStarted,
Started
Normal,
Auxiliary
};
class CParticleGenInfo
@ -32,12 +32,12 @@ class CParticleGenInfo
bool x40_grabInitialData = false;
zeus::CTransform x44_transform;
zeus::CVector3f x74_offset;
EParticleGenState x80_state;
EParticleGenType x80_type;
public:
CParticleGenInfo(const SObjectTag& part, int frameCount, std::string_view boneName,
const zeus::CVector3f& scale, CParticleData::EParentedMode parentMode,
int flags, EParticleGenState state);
int flags, EParticleGenType type);
virtual ~CParticleGenInfo() = default;
virtual void AddToRenderer() = 0;
@ -77,8 +77,7 @@ public:
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; }
EParticleGenType GetType() const { return x80_type; }
CParticleData::EParentedMode GetParentedMode() const { return x28_parentMode; }
std::string_view GetLocatorName() const { return x10_boneName; }
@ -93,7 +92,7 @@ public:
CParticleGenInfoGeneric(const SObjectTag& part, const std::weak_ptr<CParticleGen>& system,
int frames, std::string_view boneName, const zeus::CVector3f& scale,
CParticleData::EParentedMode parentMode, int flags, CStateManager& stateMgr, TAreaId,
int lightId, EParticleGenState state);
int lightId, EParticleGenType state);
void AddToRenderer();
void Render();

View File

@ -1316,15 +1316,15 @@ void CElementGen::RenderParticles()
}
}
zeus::CTransform systemViewPointMatrix(CGraphics::g_ViewMatrix);
systemViewPointMatrix.origin.zeroOut();
zeus::CTransform systemCameraMatrix = systemViewPointMatrix.inverse() * x22c_globalOrientation;
systemViewPointMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) *
systemViewPointMatrix) * x178_localScaleTransform;
zeus::CTransform systemModelMatrix(CGraphics::g_ViewMatrix);
systemModelMatrix.origin.zeroOut();
zeus::CTransform systemCameraMatrix = systemModelMatrix.inverse() * x22c_globalOrientation;
systemModelMatrix = ((zeus::CTransform::Translate(xe8_globalTranslation) * x10c_globalScaleTransform) *
systemModelMatrix) * x178_localScaleTransform;
if (x26c_29_ORNT)
CGraphics::SetModelMatrix(systemViewPointMatrix * systemCameraMatrix);
CGraphics::SetModelMatrix(systemModelMatrix * systemCameraMatrix);
else
CGraphics::SetModelMatrix(systemViewPointMatrix);
CGraphics::SetModelMatrix(systemModelMatrix);
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
@ -1475,10 +1475,10 @@ void CElementGen::RenderParticles()
{
g_instTexData.emplace_back();
SParticleInstanceTex& inst = g_instTexData.back();
inst.pos[0] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z + size, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z + size, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z - size, 1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z - size, 1.f};
inst.pos[0] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z + size, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z + size, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f};
inst.color = particle.x34_color;
inst.uvs[0] = {uvs.xMax, uvs.yMax};
inst.uvs[1] = {uvs.xMin, uvs.yMax};
@ -1490,10 +1490,10 @@ void CElementGen::RenderParticles()
{
g_instNoTexData.emplace_back();
SParticleInstanceNoTex& inst = g_instNoTexData.back();
inst.pos[0] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z + size, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z + size, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, 0.f, viewPoint.z - size, 1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, 0.f, viewPoint.z - size, 1.f};
inst.pos[0] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z + size, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z + size, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f};
inst.color = particle.x34_color;
break;
}
@ -1513,11 +1513,11 @@ void CElementGen::RenderParticles()
{
g_instTexData.emplace_back();
SParticleInstanceTex& inst = g_instTexData.back();
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, 0.f, viewPoint.z + sinT + cosT, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT),
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, viewPoint.y, viewPoint.z + cosT - sinT, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, viewPoint.y, viewPoint.z + sinT + cosT, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), viewPoint.y, viewPoint.z + (-cosT - sinT),
1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT),
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), viewPoint.y, viewPoint.z - (cosT - sinT),
1.f};
inst.color = particle.x34_color;
inst.uvs[0] = {uvs.xMax, uvs.yMax};
@ -1530,11 +1530,11 @@ void CElementGen::RenderParticles()
{
g_instNoTexData.emplace_back();
SParticleInstanceNoTex& inst = g_instNoTexData.back();
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, 0.f, viewPoint.z + cosT - sinT, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, 0.f, viewPoint.z + sinT + cosT, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), 0.f, viewPoint.z + (-cosT - sinT),
inst.pos[0] = zeus::CVector4f{viewPoint.x + sinT + cosT, viewPoint.y, viewPoint.z + cosT - sinT, 1.f};
inst.pos[1] = zeus::CVector4f{viewPoint.x + sinT - cosT, viewPoint.y, viewPoint.z + sinT + cosT, 1.f};
inst.pos[2] = zeus::CVector4f{viewPoint.x + (cosT - sinT), viewPoint.y, viewPoint.z + (-cosT - sinT),
1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), 0.f, viewPoint.z - (cosT - sinT),
inst.pos[3] = zeus::CVector4f{viewPoint.x - (sinT + cosT), viewPoint.y, viewPoint.z - (cosT - sinT),
1.f};
inst.color = particle.x34_color;
break;

View File

@ -152,7 +152,8 @@ void CAreaRenderOctTree::Node::RecursiveBuildOverlaps(u32* bmpOut,
{
if (testAABB.intersects(curAABB))
{
if (curAABB.inside(testAABB))
u32 childCount = GetChildCount(); // HACK: Always return the smallest set of intersections
if (curAABB.inside(testAABB) || childCount == 0)
{
const u32* bmp = &parent.x30_bitmaps[x0_bitmapIdx * parent.x14_bitmapWordCount];
for (u32 c=0 ; c<parent.x14_bitmapWordCount ; ++c)
@ -160,7 +161,6 @@ void CAreaRenderOctTree::Node::RecursiveBuildOverlaps(u32* bmpOut,
}
else
{
u32 childCount = GetChildCount();
for (u32 c=0 ; c<childCount ; ++c)
{
zeus::CAABox childAABB = GetNodeBounds(curAABB, c);

View File

@ -3,6 +3,9 @@
#include "World/CLightParameters.hpp"
#include "GameGlobalObjects.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "CStateManager.hpp"
#include "Character/CAssetFactory.hpp"
#include "Character/CCharacterFactory.hpp"
namespace urde
{
@ -10,12 +13,13 @@ CScriptPlayerActor::CScriptPlayerActor(TUniqueId uid, std::string_view name, con
const zeus::CTransform& xf, const CAnimRes& animRes, CModelData&& mData,
const zeus::CAABox& aabox, bool b1, const CMaterialList& list, float mass,
float zMomentum, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
const CActorParameters& aParams, bool loop, bool active, u32 w1, u32 w2)
const CActorParameters& aParams, bool loop, bool active, u32 flags,
CPlayerState::EBeamId beam)
: CScriptActor(uid, name, info, xf, std::move(mData), aabox, mass, zMomentum, list, hInfo, dVuln, aParams, loop, active,
0, 1.f, false, false, false, false)
, x2e8_(animRes)
, x304_(w2)
, x350_(w1)
, x2e8_suitRes(animRes)
, x304_beam(beam)
, x350_flags(flags)
{
x354_24_ = b1;
x354_29_ = true;
@ -30,11 +34,73 @@ CScriptPlayerActor::CScriptPlayerActor(TUniqueId uid, std::string_view name, con
x2e3_24_cameraMoveIntoAlpha = true;
}
void CScriptPlayerActor::Think(float, CStateManager&)
u32 CScriptPlayerActor::GetSuitCharIdx(const CStateManager& mgr, CPlayerState::EPlayerSuit suit) const
{
if (mgr.GetPlayerState()->IsFusionEnabled())
{
switch (suit)
{
case CPlayerState::EPlayerSuit::Power:
return 4;
case CPlayerState::EPlayerSuit::Varia:
return 7;
case CPlayerState::EPlayerSuit::Gravity:
return 6;
case CPlayerState::EPlayerSuit::Phazon:
return 8;
default:
break;
}
}
return u32(suit);
}
void CScriptPlayerActor::LoadSuit(u32 charIdx)
{
if (charIdx != x310_loadedCharIdx)
{
TToken<CCharacterFactory> fac = g_CharFactoryBuilder->GetFactory(x2e8_suitRes);
const CCharacterInfo& chInfo = fac->GetCharInfo(charIdx);
x324_suitModel = g_SimplePool->GetObj({FOURCC('CMDL'), chInfo.GetModelId()});
x354_28_ = true;
x310_loadedCharIdx = charIdx;
}
}
void CScriptPlayerActor::LoadBeam(CPlayerState::EBeamId beam)
{
}
void CScriptPlayerActor::Think(float dt, CStateManager& mgr)
{
auto& pState = *mgr.GetPlayerState();
if (x354_31_)
{
x354_25_ = true;
x354_31_ = false;
x308_suit = pState.GetCurrentSuitRaw();
LoadSuit(GetSuitCharIdx(mgr, x308_suit));
}
if (x354_30_)
{
if (!(x350_flags & 0x1))
{
u32 tmpIdx = GetSuitCharIdx(mgr, pState.GetCurrentSuitRaw());
if (tmpIdx != x310_loadedCharIdx)
{
SetModelData(std::make_unique<CModelData>(CModelData::CModelDataNull()));
LoadSuit(tmpIdx);
x354_25_ = true;
}
}
LoadBeam(x304_beam != CPlayerState::EBeamId::Invalid ? x304_beam : pState.GetCurrentBeam());
}
}
void CScriptPlayerActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
}
@ -47,7 +113,7 @@ void CScriptPlayerActor::SetActive(bool active)
void CScriptPlayerActor::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
{
if (x2e8_.GetCharacterNodeId() == 3)
if (x2e8_suitRes.GetCharacterNodeId() == 3)
g_Renderer->AllocatePhazonSuitMaskTexture();
CScriptActor::PreRender(mgr, frustum);
}

View File

@ -2,26 +2,27 @@
#define __URDE_CSCRIPTPLAYERACTOR_HPP__
#include "CScriptActor.hpp"
#include "CPlayerState.hpp"
namespace urde
{
class CScriptPlayerActor : public CScriptActor
{
CAnimRes x2e8_;
u32 x304_;
s32 x308_ = -1;
CAnimRes x2e8_suitRes;
CPlayerState::EBeamId x304_beam;
CPlayerState::EPlayerSuit x308_suit = CPlayerState::EPlayerSuit::Invalid;
s32 x30c_ = -1;
s32 x310_ = -1;
s32 x310_loadedCharIdx = -1;
u32 x314_ = 0;
u32 x318_ = 0;
u32 x31c_ = 0;
u32 x320_ = 0;
u32 x324_ = 0;
TLockedToken<CModel> x324_suitModel;
u8 x334_ = 0;
u8 x344_ = 0;
u32 x348_ = 0;
float x34c_ = 0.f;
u32 x350_;
u32 x350_flags;
union
{
struct
@ -36,13 +37,19 @@ class CScriptPlayerActor : public CScriptActor
bool x354_31_ : 1;
bool x355_24_ : 1;
};
u8 x355_dummy = 0;
u32 _dummy = 0;
};
u32 GetSuitCharIdx(const CStateManager& mgr, CPlayerState::EPlayerSuit suit) const;
void LoadSuit(u32 charIdx);
void LoadBeam(CPlayerState::EBeamId beam);
public:
CScriptPlayerActor(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, const CAnimRes&,
CModelData&&, const zeus::CAABox&, bool, const CMaterialList&, float, float,
const CHealthInfo&, const CDamageVulnerability&, const CActorParameters&, bool, bool, u32, u32);
CScriptPlayerActor(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, const CAnimRes& animRes, CModelData&& mData,
const zeus::CAABox& aabox, bool b1, const CMaterialList& list, float mass,
float zMomentum, const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
const CActorParameters& aParams, bool loop, bool active, u32 flags, CPlayerState::EBeamId beam);
void Think(float, CStateManager &);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager &);

View File

@ -1863,7 +1863,7 @@ CEntity* ScriptLoader::LoadPlayerActor(CStateManager& mgr, CInputStream& in, int
bool solid = in.readBool();
bool active = in.readBool();
u32 flags = LoadParameterFlags(in);
bool w1 = in.readUint32Big() - 1;
CPlayerState::EBeamId beam = CPlayerState::EBeamId(in.readUint32Big() - 1);
FourCC fcc = g_ResFactory->GetResourceTypeById(animParms.GetACSFile());
if (!fcc || fcc != SBIG('ANCS'))
@ -1884,7 +1884,7 @@ CEntity* ScriptLoader::LoadPlayerActor(CStateManager& mgr, CInputStream& in, int
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), aHead.x40_scale,
animParms.GetInitialAnimation(), loop),
CModelData::CModelDataNull(), aabox, true, list, mass, zMomentum, hInfo, dVuln,
actParms, loop, active, flags, w1);
actParms, loop, active, flags, beam);
}
CEntity* ScriptLoader::LoadFlaahgra(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)