Skip to content

Commit

Permalink
switch VisualThinker subsector processing to Tick/UpdateSector
Browse files Browse the repository at this point in the history
this allows visual thinkers to be moved to a non-ticking statnum if they're static decorations
  • Loading branch information
RicardoLuis0 committed Feb 26, 2024
1 parent 7561840 commit ed68e99
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 35 deletions.
104 changes: 70 additions & 34 deletions src/playsim/p_effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,18 @@ inline particle_t *NewParticle (FLevelLocals *Level, bool replace = false)
// [RH] Particle functions
//

static uint32_t * particleBuffer1;
static uint32_t * particleBuffer2;

void P_ReInitParticles (FLevelLocals *Level, int num)
{
MaxParticles = clamp<int>(num, ABSOLUTE_MIN_PARTICLES, ABSOLUTE_MAX_PARTICLES);

if(particleBuffer1) delete[] particleBuffer1;
if(particleBuffer2) delete[] particleBuffer2;
particleBuffer1 = new uint32_t[MaxParticles];
particleBuffer2 = new uint32_t[MaxParticles];

Level->ParticleIndices.Resize(MaxParticles);
Level->Particles.Resize(MaxParticles);

Expand Down Expand Up @@ -242,28 +250,13 @@ void P_ClearParticles (FLevelLocals *Level)
// Group particles by subsectors. Because particles are always
// in motion, there is little benefit to caching this information
// from one frame to the next.
// [MC] VisualThinkers hitches a ride here

void P_FindParticleSubsectors (FLevelLocals *Level)
{
// [MC] Hitch a ride on particle subsectors since VisualThinkers are effectively using the same kind of system.
for(uint32_t i = 0; i < Level->subsectors.Size(); i++)
{
Level->subsectors[i].sprites.Clear();
Level->subsectors[i].particles.Clear();
}
// [MC] Not too happy about using an iterator for this but I can't think of another way to handle it.
// At least it's on its own statnum for maximum efficiency.
auto it = Level->GetThinkerIterator<DVisualThinker>(NAME_None, STAT_VISUALTHINKER);
DVisualThinker* sp;
while (sp = it.Next())
{
if (!sp->PT.subsector) sp->PT.subsector = Level->PointInRenderSubsector(sp->PT.Pos);

sp->PT.subsector->sprites.Push(sp);
}
// End VisualThinker hitching. Now onto the particles.

if (!r_particles)
{
return;
Expand Down Expand Up @@ -393,8 +386,6 @@ void P_UpdateReplacedParticles(FLevelLocals *Level)
P_FindParticleSubsectors(Level);
}



void P_ThinkParticles(FLevelLocals *Level)
{
uint64_t startNs = I_nsTime();
Expand Down Expand Up @@ -553,7 +544,8 @@ void P_RunEffect (AActor *actor, int effects)
double speed;

particle = JitterParticle (actor->Level, 3 + (M_Random() & 31));
if (particle) {
if (particle)
{
double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset(
backx - actor->Vel.X * pathdist,
Expand All @@ -571,7 +563,8 @@ void P_RunEffect (AActor *actor, int effects)
}
for (i = 6; i; i--) {
particle_t *particle = JitterParticle (actor->Level, 3 + (M_Random() & 31));
if (particle) {
if (particle)
{
double pathdist = M_Random() / 256.;
DVector3 pos = actor->Vec3Offset(
backx - actor->Vel.X * pathdist,
Expand Down Expand Up @@ -1124,10 +1117,43 @@ DVisualThinker::DVisualThinker()

void DVisualThinker::OnDestroy()
{
if(PT.subsector)
{
PT.subsector->sprites.Delete(PT.subsector->sprites.Find(this));
}
PT.alpha = 0.0; // stops all rendering.
Super::OnDestroy();
}

void DVisualThinker::UpdateSector(subsector_t * newSubsector)
{
assert(newSubsector);
if(PT.subsector != newSubsector)
{
if(PT.subsector) PT.subsector->sprites.Delete(PT.subsector->sprites.Find(this));
PT.subsector = newSubsector;
PT.subsector->sprites.Push(this);
cursector = newSubsector->sector;
}
}

void DVisualThinker::UpdateSector()
{
UpdateSector(Level->PointInRenderSubsector(PT.Pos));
}

static void UpdateSector(DVisualThinker * self)
{
self->UpdateSector();
}

DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSector, UpdateSector)
{
PARAM_SELF_PROLOGUE(DVisualThinker);
self->UpdateSector();
return 0;
}

DVisualThinker* DVisualThinker::NewVisualThinker(FLevelLocals* Level, PClass* type)
{
if (type == nullptr)
Expand Down Expand Up @@ -1171,6 +1197,18 @@ void DVisualThinker::UpdateSpriteInfo()
}
}

static void UpdateSpriteInfo(DVisualThinker * self)
{
self->UpdateSpriteInfo();
}

DEFINE_ACTION_FUNCTION_NATIVE(DVisualThinker, UpdateSpriteInfo, UpdateSpriteInfo)
{
PARAM_SELF_PROLOGUE(DVisualThinker);
self->UpdateSpriteInfo();
return 0;
}

// This runs just like Actor's, make sure to call Super.Tick() in ZScript.
void DVisualThinker::Tick()
{
Expand All @@ -1187,8 +1225,7 @@ void DVisualThinker::Tick()

if (isFrozen())
{ // needed here because it won't retroactively update like actors do.
PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
UpdateSector();
UpdateSpriteInfo();
return;
}
Expand All @@ -1200,27 +1237,26 @@ void DVisualThinker::Tick()
PT.Pos.Y = newxy.Y;
PT.Pos.Z += PT.Vel.Z;

PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
subsector_t * ss = Level->PointInRenderSubsector(PT.Pos);

// Handle crossing a sector portal.
if (!cursector->PortalBlocksMovement(sector_t::ceiling))
if (!ss->sector->PortalBlocksMovement(sector_t::ceiling))
{
if (PT.Pos.Z > cursector->GetPortalPlaneZ(sector_t::ceiling))
if (PT.Pos.Z > ss->sector->GetPortalPlaneZ(sector_t::ceiling))
{
PT.Pos += cursector->GetPortalDisplacement(sector_t::ceiling);
PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
PT.Pos += ss->sector->GetPortalDisplacement(sector_t::ceiling);
ss = Level->PointInRenderSubsector(PT.Pos);
}
}
else if (!cursector->PortalBlocksMovement(sector_t::floor))
else if (!ss->sector->PortalBlocksMovement(sector_t::floor))
{
if (PT.Pos.Z < cursector->GetPortalPlaneZ(sector_t::floor))
if (PT.Pos.Z < ss->sector->GetPortalPlaneZ(sector_t::floor))
{
PT.Pos += cursector->GetPortalDisplacement(sector_t::floor);
PT.subsector = Level->PointInRenderSubsector(PT.Pos);
cursector = PT.subsector->sector;
PT.Pos += ss->sector->GetPortalDisplacement(sector_t::floor);
ss = Level->PointInRenderSubsector(PT.Pos);
}
}
UpdateSector(ss);
UpdateSpriteInfo();
}

Expand Down Expand Up @@ -1366,7 +1402,7 @@ DEFINE_FIELD_NAMED(DVisualThinker, PT.Vel, Vel);
DEFINE_FIELD_NAMED(DVisualThinker, PT.Roll, Roll);
DEFINE_FIELD_NAMED(DVisualThinker, PT.alpha, Alpha);
DEFINE_FIELD_NAMED(DVisualThinker, PT.texture, Texture);
DEFINE_FIELD_NAMED(DVisualThinker, PT.flags, ParticleFlags);
DEFINE_FIELD_NAMED(DVisualThinker, PT.flags, Flags);
DEFINE_FIELD_NAMED(DVisualThinker, flags, VisualThinkerFlags);

DEFINE_FIELD(DVisualThinker, Prev);
Expand Down
2 changes: 2 additions & 0 deletions src/playsim/p_effect_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ enum EVisualThinkerFlags
class DVisualThinker : public DThinker
{
DECLARE_CLASS(DVisualThinker, DThinker);
void UpdateSector(subsector_t * newSubsector);
public:
DVector3 Prev;
DVector2 Scale,
Expand Down Expand Up @@ -55,6 +56,7 @@ class DVisualThinker : public DThinker

void Tick() override;
void UpdateSpriteInfo();
void UpdateSector();
void Serialize(FSerializer& arc) override;

float GetOffset(bool y) const;
Expand Down
7 changes: 6 additions & 1 deletion wadsrc/static/zscript/visualthinker.zs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Class VisualThinker : Thinker native
native TranslationID Translation;
native int16 LightLevel;

native uint16 ParticleFlags;
native uint16 Flags;
native int VisualThinkerFlags;

native Color scolor;
Expand All @@ -23,6 +23,9 @@ Class VisualThinker : Thinker native
native void SetRenderStyle(int mode); // see ERenderStyle
native bool IsFrozen();

native void UpdateSector(); // needs to be called if the thinker is set to a non-ticking statnum and the position is modified (or if Tick is overriden and doesn't call Super.Tick())
native void UpdateSpriteInfo(); // needs to be called every time the texture is updated if the thinker uses SPF_LOCAL_ANIM and is set to a non-ticking statnum (or if Tick is overriden and doesn't call Super.Tick())

static VisualThinker Spawn(Class<VisualThinker> type, TextureID tex, Vector3 pos, Vector3 vel, double alpha = 1.0, int flags = 0,
double roll = 0.0, Vector2 scale = (1,1), Vector2 offset = (0,0), int style = STYLE_Normal, TranslationID trans = 0)
{
Expand All @@ -41,6 +44,8 @@ Class VisualThinker : Thinker native
p.SetRenderStyle(style);
p.Translation = trans;
p.ParticleFlags = flags;
p.UpdateSector();
p.UpdateSpriteInfo();
}
return p;
}
Expand Down

0 comments on commit ed68e99

Please sign in to comment.