Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions Core/GameEngine/Include/GameClient/ParticleSys.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ enum ParticleSystemID CPP_11(: Int)
INVALID_PARTICLE_SYSTEM_ID = 0
};

#define MAX_VOLUME_PARTICLE_DEPTH ( 16 )
#define DEFAULT_VOLUME_PARTICLE_DEPTH ( 0 )//The Default is not to do the volume thing!
#define OPTIMUM_VOLUME_PARTICLE_DEPTH ( 6 )
constexpr const UnsignedInt INVALID_VOLUME_PARTICLE_DEPTH = 0; //The volume depth is not initialized
constexpr const UnsignedInt DEFAULT_VOLUME_PARTICLE_DEPTH = 1; //The Default is not to do the volume thing!
constexpr const UnsignedInt MIN_VOLUME_PARTICLE_DEPTH = 2;
constexpr const UnsignedInt OPTIMUM_VOLUME_PARTICLE_DEPTH = 6;
constexpr const UnsignedInt MAX_VOLUME_PARTICLE_DEPTH = 16;

// TheSuperHackers @info The X and Y angles are not necessary for particles because there are only 2 placement modes:
// Billboard (always facing camera) and Ground Aligned, which overwrite any rotations on the X and Y axis by design.
Expand Down Expand Up @@ -511,6 +513,8 @@ class ParticleSystemTemplate : public MemoryPoolObject, protected ParticleSystem
public:
ParticleSystemTemplate( const AsciiString &name );

void validate();

AsciiString getName() const { return m_name; }

// This function was made const because of update modules' module data being all const.
Expand Down Expand Up @@ -603,10 +607,11 @@ class ParticleSystem : public MemoryPoolObject,
void setInitialDelay( UnsignedInt delay ) { m_delayLeft = delay; }

AsciiString getParticleTypeName() { return m_particleTypeName; } ///< return the name of the particles
Bool isUsingDrawables() { return (m_particleType == DRAWABLE) ? true : false; }
Bool isUsingStreak() { return (m_particleType == STREAK) ? true : false; }
Bool isUsingSmudge() { return (m_particleType == SMUDGE) ? true : false; }
UnsignedInt getVolumeParticleDepth() { return ( m_particleType == VOLUME_PARTICLE ) ? OPTIMUM_VOLUME_PARTICLE_DEPTH : 0; }
Bool isUsingDrawables() { return m_particleType == DRAWABLE; }
Bool isUsingStreak() { return m_particleType == STREAK; }
Bool isUsingSmudge() { return m_particleType == SMUDGE; }
BOOL isUsingVolumeParticles() { return m_particleType == VOLUME_PARTICLE; }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only just noticed that i used BOOL instead of bool but i will fix this after the next review so the diff can be seen.

UnsignedInt getVolumeParticleDepth() { return m_volumeParticleDepth; }

Bool shouldBillboard() { return !m_isGroundAligned; }

Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Source/Common/INI/INIParticleSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ void INI::parseParticleSystemDefinition( INI* ini )

// parse the ini definition
ini->initFromINI( sysTemplate, sysTemplate->getFieldParse() );
sysTemplate->validate();
}
40 changes: 29 additions & 11 deletions Core/GameEngine/Source/GameClient/System/ParticleSys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ ParticleSystemInfo::ParticleSystemInfo()
m_windMotionEndAngleMax = TWO_PI;
m_windMotionEndAngle = m_windMotionEndAngleMin;
m_windMotionMovingToEndAngle = TRUE;
m_volumeParticleDepth = DEFAULT_VOLUME_PARTICLE_DEPTH;
m_volumeParticleDepth = INVALID_VOLUME_PARTICLE_DEPTH;

}

Expand Down Expand Up @@ -1095,7 +1095,7 @@ ParticleSystem::ParticleSystem( const ParticleSystemTemplate *sysTemplate,


///@todo: further formalize this parameter with an UnsignedInt field in the editor
m_volumeParticleDepth = DEFAULT_VOLUME_PARTICLE_DEPTH;
m_volumeParticleDepth = sysTemplate->m_volumeParticleDepth;


m_driftVelocity = sysTemplate->m_driftVelocity;
Expand Down Expand Up @@ -1190,15 +1190,6 @@ ParticleSystem::ParticleSystem( const ParticleSystemTemplate *sysTemplate,
m_particleType = sysTemplate->m_particleType;
m_particleTypeName = sysTemplate->m_particleTypeName;

#if PRESERVE_RETAIL_PARTICLES
// TheSuperHackers @info Hack to allow isUsingSmudge() functionality with retail smudge particles
// The retail data template for smudge particles is not correctly configured with the smudge particle type
if (m_particleType != ParticleType::SMUDGE && m_particleTypeName.startsWithNoCase("SMUDGE."))
{
m_particleType = ParticleType::SMUDGE;
}
#endif

m_isStopped = false;

// set up slave particle system, if any
Expand Down Expand Up @@ -2698,6 +2689,9 @@ const FieldParse ParticleSystemTemplate::m_fieldParseTable[] =
{ "SizeRate", INI::parseGameClientRandomVariable, nullptr, offsetof( ParticleSystemTemplate, m_sizeRate ) },
{ "SizeRateDamping", INI::parseGameClientRandomVariable, nullptr, offsetof( ParticleSystemTemplate, m_sizeRateDamping ) },

// TheSuperHackers @feature Volume particle depth is now exposed for configuration
{ "VolParticleDepth", INI::parseUnsignedInt, nullptr, offsetof(ParticleSystemTemplate, m_volumeParticleDepth) },

{ "Alpha1", ParticleSystemTemplate::parseRandomKeyframe, nullptr, offsetof( ParticleSystemTemplate, m_alphaKey[0] ) },
{ "Alpha2", ParticleSystemTemplate::parseRandomKeyframe, nullptr, offsetof( ParticleSystemTemplate, m_alphaKey[1] ) },
{ "Alpha3", ParticleSystemTemplate::parseRandomKeyframe, nullptr, offsetof( ParticleSystemTemplate, m_alphaKey[2] ) },
Expand Down Expand Up @@ -2866,6 +2860,30 @@ ParticleSystemTemplate::~ParticleSystemTemplate()

}

// ------------------------------------------------------------------------------------------------
void ParticleSystemTemplate::validate()
{
// TheSuperHackers @info Initialise all volume particles that lack ini configuration to the optimum depth of 6
// In retail, volume particle depth was not configurable through ini and was hard coded to a particle depth of 6
if (m_particleType == ParticleSystemInfo::VOLUME_PARTICLE && m_volumeParticleDepth == INVALID_VOLUME_PARTICLE_DEPTH)
{
m_volumeParticleDepth = OPTIMUM_VOLUME_PARTICLE_DEPTH;
}
else
{
m_volumeParticleDepth = DEFAULT_VOLUME_PARTICLE_DEPTH;
}

#if PRESERVE_RETAIL_PARTICLES
// TheSuperHackers @info Hack to allow isUsingSmudge() functionality with retail smudge particles
// The retail data template for smudge particles is not correctly configured with the smudge particle type
if (m_particleType != ParticleSystemInfo::SMUDGE && m_particleTypeName.startsWithNoCase("SMUDGE."))
{
m_particleType = ParticleSystemInfo::SMUDGE;
}
#endif
}

// ------------------------------------------------------------------------------------------------
/** If returns non-null, it is a slave system for use ... the create slaves parameter
* tells *this* slave system whether or not it should create any slaves itself
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,10 @@ void W3DParticleSystemManager::doParticles(RenderInfoClass &rinfo)
m_pointGroup->Set_Point_Frame( 0 );

//RENDER IT!
if( sys->getVolumeParticleDepth() > 1 )
const UnsignedInt volumeParticleDepth = sys->getVolumeParticleDepth();
if( sys->isUsingVolumeParticles() && volumeParticleDepth > DEFAULT_VOLUME_PARTICLE_DEPTH )

@Mauller Mauller Aug 24, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might clean this up in the particle batching PR, it becomes more significant for ignoring misconfigured volume particles as it skips all of their setup.

{
m_pointGroup->RenderVolumeParticle( rinfo, sys->getVolumeParticleDepth() );
m_pointGroup->RenderVolumeParticle( rinfo, volumeParticleDepth);
}
else
m_pointGroup->Render( rinfo );
Expand Down
3 changes: 2 additions & 1 deletion Core/Libraries/Source/WWVegas/WW3D2/pointgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1644,11 +1644,12 @@ void PointGroupClass::_Shutdown()
* 12/03/2002 Mark Lorenzen Created. *
* *
*========================================================================*/
#define DEFAULT_VOLUME_PARTICLE_DEPTH ( 1 )
#define MAX_VOLUME_PARTICLE_DEPTH ( 16 )
void PointGroupClass::RenderVolumeParticle(RenderInfoClass &rinfo, unsigned int depth )
{

if ( depth <= 1 ) //oops,wrong number
if ( depth <= DEFAULT_VOLUME_PARTICLE_DEPTH) //oops,wrong number
{
Render( rinfo );
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9725,6 +9725,7 @@ static const std::string F_SIZE = "Size";
static const std::string F_STARTSIZERATE ="StartSizeRate";
static const std::string F_SIZERATE = "SizeRate";
static const std::string F_SIZERATEDAMP = "SizeRateDamping";
static const std::string F_VOLPARTICLEDEPTH = "VolParticleDepth";

static const std::string F_ALPHA1 = "Alpha1";
static const std::string F_ALPHA2 = "Alpha2";
Expand Down Expand Up @@ -9887,6 +9888,9 @@ void _writeSingleParticleSystem( File *out, ParticleSystemTemplate *templ )
sprintf(buff2, FORMAT_STRING, templ->m_sizeRateDamping.getMaximumValue());
thisEntry.append(SEP_HEAD).append(F_SIZERATEDAMP).append(EQ_WITH_SPACES).append(buff1).append(SEP_SPACE).append(buff2).append(SEP_EOL);

sprintf(buff1, "%d", templ->m_volumeParticleDepth);
thisEntry.append(SEP_HEAD).append(F_VOLPARTICLEDEPTH).append(EQ_WITH_SPACES).append(buff1).append(SEP_EOL);

sprintf(buff1, FORMAT_STRING, templ->m_alphaKey[0].var.getMinimumValue());
sprintf(buff2, FORMAT_STRING, templ->m_alphaKey[0].var.getMaximumValue());
sprintf(buff3, "%d", templ->m_alphaKey[0].frame);
Expand Down
Loading