mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-25 13:31:37 +00:00
Implement animated particles that aren't tied to the global animation timer
This commit is contained in:
parent
9dd6460fe6
commit
7eab519795
8 changed files with 228 additions and 116 deletions
|
@ -930,6 +930,109 @@ void FAnimDef::SetSwitchTime (uint64_t mstime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void AdvanceFrame(uint16_t &frame, uint8_t &AnimType, const FAnimDef &anim)
|
||||||
|
{
|
||||||
|
switch (AnimType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case FAnimDef::ANIM_Forward:
|
||||||
|
frame = (frame + 1) % anim.NumFrames;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FAnimDef::ANIM_Backward:
|
||||||
|
if (frame == 0)
|
||||||
|
{
|
||||||
|
frame = anim.NumFrames - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frame--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FAnimDef::ANIM_Random:
|
||||||
|
// select a random frame other than the current one
|
||||||
|
if (anim.NumFrames > 1)
|
||||||
|
{
|
||||||
|
uint16_t rndFrame = (uint16_t)pr_animatepictures(anim.NumFrames - 1);
|
||||||
|
if(rndFrame == frame) rndFrame++;
|
||||||
|
frame = rndFrame % anim.NumFrames;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FAnimDef::ANIM_OscillateUp:
|
||||||
|
frame = frame + 1;
|
||||||
|
assert(frame < anim.NumFrames);
|
||||||
|
if (frame == anim.NumFrames - 1)
|
||||||
|
{
|
||||||
|
AnimType = FAnimDef::ANIM_OscillateDown;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FAnimDef::ANIM_OscillateDown:
|
||||||
|
frame = frame - 1;
|
||||||
|
if (frame == 0)
|
||||||
|
{
|
||||||
|
AnimType = FAnimDef::ANIM_OscillateUp;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr double msPerTic = 1'000.0 / TICRATE;
|
||||||
|
|
||||||
|
bool FTextureAnimator::InitStandaloneAnimation(FStandaloneAnimation &animInfo, FTextureID tex, uint32_t curTic)
|
||||||
|
{
|
||||||
|
FAnimDef * anim;
|
||||||
|
animInfo.ok = false;
|
||||||
|
for(int i = 0; i < mAnimations.Size(); i++)
|
||||||
|
{
|
||||||
|
if(mAnimations[i].BasePic == tex)
|
||||||
|
{
|
||||||
|
animInfo.ok = true;
|
||||||
|
animInfo.AnimIndex = i;
|
||||||
|
anim = &mAnimations[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!animInfo.ok) return false;
|
||||||
|
animInfo.CurFrame = 0;
|
||||||
|
animInfo.SwitchTic = curTic;
|
||||||
|
animInfo.AnimType = (anim->AnimType == FAnimDef::ANIM_OscillateDown) ? FAnimDef::ANIM_OscillateUp : anim->AnimType;
|
||||||
|
uint32_t time = anim->Frames[0].SpeedMin;
|
||||||
|
if(anim->Frames[0].SpeedRange != 0)
|
||||||
|
{
|
||||||
|
time += pr_animatepictures(anim->Frames[0].SpeedRange);
|
||||||
|
}
|
||||||
|
animInfo.SwitchTic += time / msPerTic;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FTextureID FTextureAnimator::UpdateStandaloneAnimation(FStandaloneAnimation &animInfo, double curTic)
|
||||||
|
{
|
||||||
|
if(!animInfo.ok) return nullptr;
|
||||||
|
auto &anim = mAnimations[animInfo.AnimIndex];
|
||||||
|
if(animInfo.SwitchTic <= curTic)
|
||||||
|
{
|
||||||
|
uint16_t frame = animInfo.CurFrame;
|
||||||
|
uint16_t speedframe = anim.bDiscrete ? frame : 0;
|
||||||
|
while(animInfo.SwitchTic <= curTic)
|
||||||
|
{
|
||||||
|
AdvanceFrame(frame, animInfo.AnimType, anim);
|
||||||
|
|
||||||
|
if(anim.bDiscrete) speedframe = frame;
|
||||||
|
|
||||||
|
uint32_t time = anim.Frames[speedframe].SpeedMin;
|
||||||
|
if(anim.Frames[speedframe].SpeedRange != 0)
|
||||||
|
{
|
||||||
|
time += pr_animatepictures(anim.Frames[speedframe].SpeedRange);
|
||||||
|
}
|
||||||
|
|
||||||
|
animInfo.SwitchTic += time / msPerTic;
|
||||||
|
}
|
||||||
|
animInfo.CurFrame = frame;
|
||||||
|
}
|
||||||
|
return anim.bDiscrete ? anim.Frames[animInfo.CurFrame].FramePic : (anim.BasePic + animInfo.CurFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
@ -955,50 +1058,7 @@ void FTextureAnimator::UpdateAnimations (uint64_t mstime)
|
||||||
{ // Multiple frames may have passed since the last time calling
|
{ // Multiple frames may have passed since the last time calling
|
||||||
// R_UpdateAnimations, so be sure to loop through them all.
|
// R_UpdateAnimations, so be sure to loop through them all.
|
||||||
|
|
||||||
switch (anim->AnimType)
|
AdvanceFrame(anim->CurFrame, anim->AnimType, *anim);
|
||||||
{
|
|
||||||
default:
|
|
||||||
case FAnimDef::ANIM_Forward:
|
|
||||||
anim->CurFrame = (anim->CurFrame + 1) % anim->NumFrames;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FAnimDef::ANIM_Backward:
|
|
||||||
if (anim->CurFrame == 0)
|
|
||||||
{
|
|
||||||
anim->CurFrame = anim->NumFrames - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
anim->CurFrame -= 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FAnimDef::ANIM_Random:
|
|
||||||
// select a random frame other than the current one
|
|
||||||
if (anim->NumFrames > 1)
|
|
||||||
{
|
|
||||||
uint16_t rndFrame = (uint16_t)pr_animatepictures(anim->NumFrames - 1);
|
|
||||||
if (rndFrame >= anim->CurFrame) rndFrame++;
|
|
||||||
anim->CurFrame = rndFrame;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FAnimDef::ANIM_OscillateUp:
|
|
||||||
anim->CurFrame = anim->CurFrame + 1;
|
|
||||||
if (anim->CurFrame >= anim->NumFrames - 1)
|
|
||||||
{
|
|
||||||
anim->AnimType = FAnimDef::ANIM_OscillateDown;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FAnimDef::ANIM_OscillateDown:
|
|
||||||
anim->CurFrame = anim->CurFrame - 1;
|
|
||||||
if (anim->CurFrame == 0)
|
|
||||||
{
|
|
||||||
anim->AnimType = FAnimDef::ANIM_OscillateUp;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
anim->SetSwitchTime (mstime);
|
anim->SetSwitchTime (mstime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,17 @@
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "s_soundinternal.h"
|
#include "s_soundinternal.h"
|
||||||
|
|
||||||
|
struct FStandaloneAnimation
|
||||||
|
{
|
||||||
|
double SwitchTic;
|
||||||
|
uint32_t AnimIndex;
|
||||||
|
uint16_t CurFrame;
|
||||||
|
bool ok = false;
|
||||||
|
uint8_t AnimType;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(FStandaloneAnimation) == sizeof(uint64_t)*2);
|
||||||
|
|
||||||
struct FAnimDef
|
struct FAnimDef
|
||||||
{
|
{
|
||||||
struct FAnimFrame
|
struct FAnimFrame
|
||||||
|
@ -112,6 +123,9 @@ public:
|
||||||
FixAnimations();
|
FixAnimations();
|
||||||
InitSwitchList();
|
InitSwitchList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InitStandaloneAnimation(FStandaloneAnimation &animInfo, FTextureID tex, uint32_t curTic);
|
||||||
|
FTextureID UpdateStandaloneAnimation(FStandaloneAnimation &animInfo, double curTic);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FTextureAnimator TexAnim;
|
extern FTextureAnimator TexAnim;
|
||||||
|
|
|
@ -297,6 +297,11 @@ void P_ThinkParticles (FLevelLocals *Level)
|
||||||
i = particle->tnext;
|
i = particle->tnext;
|
||||||
if (Level->isFrozen() && !(particle->flags &SPF_NOTIMEFREEZE))
|
if (Level->isFrozen() && !(particle->flags &SPF_NOTIMEFREEZE))
|
||||||
{
|
{
|
||||||
|
if(particle->flags & SPF_STANDALONE_ANIMATIONS)
|
||||||
|
{
|
||||||
|
particle->animData.SwitchTic++;
|
||||||
|
}
|
||||||
|
|
||||||
prev = particle;
|
prev = particle;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -366,14 +371,13 @@ void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &v
|
||||||
if (particle)
|
if (particle)
|
||||||
{
|
{
|
||||||
particle->Pos = pos;
|
particle->Pos = pos;
|
||||||
particle->Vel = vel;
|
particle->Vel = FVector3(vel);
|
||||||
particle->Acc = accel;
|
particle->Acc = FVector3(accel);
|
||||||
particle->color = ParticleColor(color);
|
particle->color = ParticleColor(color);
|
||||||
particle->alpha = float(startalpha);
|
particle->alpha = float(startalpha);
|
||||||
if (fadestep < 0) particle->fadestep = FADEFROMTTL(lifetime);
|
if (fadestep < 0) particle->fadestep = FADEFROMTTL(lifetime);
|
||||||
else particle->fadestep = float(fadestep);
|
else particle->fadestep = float(fadestep);
|
||||||
particle->ttl = lifetime;
|
particle->ttl = lifetime;
|
||||||
particle->bright = !!(flags & SPF_FULLBRIGHT);
|
|
||||||
particle->size = size;
|
particle->size = size;
|
||||||
particle->sizestep = sizestep;
|
particle->sizestep = sizestep;
|
||||||
particle->texture = texture;
|
particle->texture = texture;
|
||||||
|
@ -382,6 +386,10 @@ void P_SpawnParticle(FLevelLocals *Level, const DVector3 &pos, const DVector3 &v
|
||||||
particle->RollVel = rollvel;
|
particle->RollVel = rollvel;
|
||||||
particle->RollAcc = rollacc;
|
particle->RollAcc = rollacc;
|
||||||
particle->flags = flags;
|
particle->flags = flags;
|
||||||
|
if(flags & SPF_STANDALONE_ANIMATIONS)
|
||||||
|
{
|
||||||
|
TexAnim.InitStandaloneAnimation(particle->animData, texture, Level->maptime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,10 +440,10 @@ static void MakeFountain (AActor *actor, int color1, int color2)
|
||||||
|
|
||||||
particle->Pos = actor->Vec3Angle(out, an, actor->Height + 1);
|
particle->Pos = actor->Vec3Angle(out, an, actor->Height + 1);
|
||||||
if (out < actor->radius/8)
|
if (out < actor->radius/8)
|
||||||
particle->Vel.Z += 10./3;
|
particle->Vel.Z += 10.f/3;
|
||||||
else
|
else
|
||||||
particle->Vel.Z += 3;
|
particle->Vel.Z += 3;
|
||||||
particle->Acc.Z -= 1./11;
|
particle->Acc.Z -= 1.f/11;
|
||||||
if (M_Random() < 30) {
|
if (M_Random() < 30) {
|
||||||
particle->size = 4;
|
particle->size = 4;
|
||||||
particle->color = color2;
|
particle->color = color2;
|
||||||
|
@ -474,8 +482,8 @@ void P_RunEffect (AActor *actor, int effects)
|
||||||
speed = (M_Random () - 128) * (1./200);
|
speed = (M_Random () - 128) * (1./200);
|
||||||
particle->Vel.X += speed * an.Cos();
|
particle->Vel.X += speed * an.Cos();
|
||||||
particle->Vel.Y += speed * an.Sin();
|
particle->Vel.Y += speed * an.Sin();
|
||||||
particle->Vel.Z -= 1./36;
|
particle->Vel.Z -= 1.f/36;
|
||||||
particle->Acc.Z -= 1./20;
|
particle->Acc.Z -= 1.f/20;
|
||||||
particle->color = yellow;
|
particle->color = yellow;
|
||||||
particle->size = 2;
|
particle->size = 2;
|
||||||
}
|
}
|
||||||
|
@ -492,8 +500,8 @@ void P_RunEffect (AActor *actor, int effects)
|
||||||
speed = (M_Random () - 128) * (1./200);
|
speed = (M_Random () - 128) * (1./200);
|
||||||
particle->Vel.X += speed * an.Cos();
|
particle->Vel.X += speed * an.Cos();
|
||||||
particle->Vel.Y += speed * an.Sin();
|
particle->Vel.Y += speed * an.Sin();
|
||||||
particle->Vel.Z += 1. / 80;
|
particle->Vel.Z += 1.f / 80;
|
||||||
particle->Acc.Z += 1. / 40;
|
particle->Acc.Z += 1.f / 40;
|
||||||
if (M_Random () & 7)
|
if (M_Random () & 7)
|
||||||
particle->color = grey2;
|
particle->color = grey2;
|
||||||
else
|
else
|
||||||
|
@ -635,7 +643,7 @@ void P_DrawSplash2 (FLevelLocals *Level, int count, const DVector3 &pos, DAngle
|
||||||
p->size = 4;
|
p->size = 4;
|
||||||
p->color = M_Random() & 0x80 ? color1 : color2;
|
p->color = M_Random() & 0x80 ? color1 : color2;
|
||||||
p->Vel.Z = M_Random() * zvel;
|
p->Vel.Z = M_Random() * zvel;
|
||||||
p->Acc.Z = -1 / 22.;
|
p->Acc.Z = -1 / 22.f;
|
||||||
if (kind)
|
if (kind)
|
||||||
{
|
{
|
||||||
an = angle + DAngle::fromDeg((M_Random() - 128) * (180 / 256.));
|
an = angle + DAngle::fromDeg((M_Random() - 128) * (180 / 256.));
|
||||||
|
@ -788,10 +796,13 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1,
|
||||||
p->ttl = spiralduration;
|
p->ttl = spiralduration;
|
||||||
p->fadestep = FADEFROMTTL(spiralduration);
|
p->fadestep = FADEFROMTTL(spiralduration);
|
||||||
p->size = 3;
|
p->size = 3;
|
||||||
p->bright = fullbright;
|
if(fullbright)
|
||||||
|
{
|
||||||
|
p->flags |= SPF_FULLBRIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
tempvec = DMatrix3x3(trail[segment].dir, deg) * trail[segment].extend;
|
tempvec = DMatrix3x3(trail[segment].dir, deg) * trail[segment].extend;
|
||||||
p->Vel = tempvec * drift / 16.;
|
p->Vel = FVector3(tempvec * drift / 16.);
|
||||||
p->Pos = tempvec + pos;
|
p->Pos = tempvec + pos;
|
||||||
pos += trail[segment].dir * stepsize;
|
pos += trail[segment].dir * stepsize;
|
||||||
deg += DAngle::fromDeg(r_rail_spiralsparsity * 14);
|
deg += DAngle::fromDeg(r_rail_spiralsparsity * 14);
|
||||||
|
@ -871,7 +882,10 @@ void P_DrawRailTrail(AActor *source, TArray<SPortalHit> &portalhits, int color1,
|
||||||
p->Acc.Z -= 1./4096;
|
p->Acc.Z -= 1./4096;
|
||||||
pos += trail[segment].dir * stepsize;
|
pos += trail[segment].dir * stepsize;
|
||||||
lencount -= stepsize;
|
lencount -= stepsize;
|
||||||
p->bright = fullbright;
|
if(fullbright)
|
||||||
|
{
|
||||||
|
p->flags |= SPF_FULLBRIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
if (color2 == -1)
|
if (color2 == -1)
|
||||||
{
|
{
|
||||||
|
@ -995,7 +1009,8 @@ void P_DisconnectEffect (AActor *actor)
|
||||||
void DVisualThinker::Construct()
|
void DVisualThinker::Construct()
|
||||||
{
|
{
|
||||||
PT = {};
|
PT = {};
|
||||||
PT.Pos = PT.Vel = { 0,0,0 };
|
PT.Pos = { 0,0,0 };
|
||||||
|
PT.Vel = { 0,0,0 };
|
||||||
Offset = { 0,0 };
|
Offset = { 0,0 };
|
||||||
Scale = { 1,1 };
|
Scale = { 1,1 };
|
||||||
PT.Roll = 0.0;
|
PT.Roll = 0.0;
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "renderstyle.h"
|
#include "renderstyle.h"
|
||||||
#include "dthinker.h"
|
#include "dthinker.h"
|
||||||
#include "palettecontainer.h"
|
#include "palettecontainer.h"
|
||||||
|
#include "animations.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -54,35 +55,40 @@ struct FLevelLocals;
|
||||||
|
|
||||||
enum EParticleFlags
|
enum EParticleFlags
|
||||||
{
|
{
|
||||||
SPF_FULLBRIGHT = 1,
|
SPF_FULLBRIGHT = 1 << 0,
|
||||||
SPF_RELPOS = 1 << 1,
|
SPF_RELPOS = 1 << 1,
|
||||||
SPF_RELVEL = 1 << 2,
|
SPF_RELVEL = 1 << 2,
|
||||||
SPF_RELACCEL = 1 << 3,
|
SPF_RELACCEL = 1 << 3,
|
||||||
SPF_RELANG = 1 << 4,
|
SPF_RELANG = 1 << 4,
|
||||||
SPF_NOTIMEFREEZE = 1 << 5,
|
SPF_NOTIMEFREEZE = 1 << 5,
|
||||||
SPF_ROLL = 1 << 6,
|
SPF_ROLL = 1 << 6,
|
||||||
SPF_REPLACE = 1 << 7,
|
SPF_REPLACE = 1 << 7,
|
||||||
SPF_NO_XY_BILLBOARD = 1 << 8,
|
SPF_NO_XY_BILLBOARD = 1 << 8,
|
||||||
|
SPF_STANDALONE_ANIMATIONS = 1 << 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DVisualThinker;
|
class DVisualThinker;
|
||||||
struct particle_t
|
struct particle_t
|
||||||
{
|
{
|
||||||
DVector3 Pos;
|
subsector_t* subsector; //+8 = 8
|
||||||
DVector3 Vel;
|
DVector3 Pos; //+24 = 32
|
||||||
DVector3 Acc;
|
FVector3 Vel; //+12 = 44
|
||||||
double size, sizestep;
|
FVector3 Acc; //+12 = 56
|
||||||
float fadestep, alpha;
|
float size, sizestep; //+8 = 64
|
||||||
subsector_t* subsector;
|
float fadestep, alpha; //+8 = 72
|
||||||
int32_t ttl;
|
int32_t ttl; // +4 = 76
|
||||||
int color;
|
int color; //+4 = 80
|
||||||
FTextureID texture;
|
FTextureID texture; // +4 = 84
|
||||||
ERenderStyle style;
|
ERenderStyle style; //+4 = 88
|
||||||
double Roll, RollVel, RollAcc;
|
float Roll, RollVel, RollAcc; //+12 = 100
|
||||||
uint16_t tnext, snext, tprev;
|
uint16_t tnext, snext, tprev; //+6 = 106
|
||||||
bool bright;
|
uint16_t flags; //+2 = 108
|
||||||
uint16_t flags;
|
// uint32_t padding; //+4 = 112
|
||||||
|
FStandaloneAnimation animData; //+16 = 128
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(particle_t) == 128);
|
||||||
|
|
||||||
const uint16_t NO_PARTICLE = 0xffff;
|
const uint16_t NO_PARTICLE = 0xffff;
|
||||||
|
|
||||||
void P_InitParticles(FLevelLocals *);
|
void P_InitParticles(FLevelLocals *);
|
||||||
|
@ -154,7 +160,7 @@ public:
|
||||||
DVector3 Prev;
|
DVector3 Prev;
|
||||||
DVector2 Scale,
|
DVector2 Scale,
|
||||||
Offset;
|
Offset;
|
||||||
double PrevRoll;
|
float PrevRoll;
|
||||||
int16_t LightLevel;
|
int16_t LightLevel;
|
||||||
FTranslationID Translation;
|
FTranslationID Translation;
|
||||||
sector_t *cursector;
|
sector_t *cursector;
|
||||||
|
|
|
@ -1283,13 +1283,13 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
|
||||||
index = 0;
|
index = 0;
|
||||||
actor = nullptr;
|
actor = nullptr;
|
||||||
this->particle = particle;
|
this->particle = particle;
|
||||||
fullbright = particle->bright;
|
fullbright = particle->flags & SPF_FULLBRIGHT;
|
||||||
|
|
||||||
if (di->isFullbrightScene())
|
if (di->isFullbrightScene())
|
||||||
{
|
{
|
||||||
Colormap.Clear();
|
Colormap.Clear();
|
||||||
}
|
}
|
||||||
else if (!particle->bright)
|
else if (!(particle->flags & SPF_FULLBRIGHT))
|
||||||
{
|
{
|
||||||
TArray<lightlist_t> & lightlist=sector->e->XFloor.lightlist;
|
TArray<lightlist_t> & lightlist=sector->e->XFloor.lightlist;
|
||||||
double lightbottom;
|
double lightbottom;
|
||||||
|
@ -1332,12 +1332,19 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
|
||||||
ThingColor.a = 255;
|
ThingColor.a = 255;
|
||||||
const auto& vp = di->Viewpoint;
|
const auto& vp = di->Viewpoint;
|
||||||
|
|
||||||
|
double timefrac = vp.TicFrac;
|
||||||
|
if (paused || (di->Level->isFrozen() && !(particle->flags & SPF_NOTIMEFREEZE)))
|
||||||
|
timefrac = 0.;
|
||||||
|
|
||||||
if (spr)
|
if (spr)
|
||||||
|
{
|
||||||
AdjustVisualThinker(di, spr, sector);
|
AdjustVisualThinker(di, spr, sector);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool has_texture = !particle->texture.isNull();
|
bool has_texture = particle->texture.isValid();
|
||||||
|
bool custom_animated_texture = has_texture && (particle->flags & SPF_STANDALONE_ANIMATIONS) && particle->animData.ok;
|
||||||
|
|
||||||
int particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
|
int particle_style = has_texture ? 2 : gl_particles_style; // Treat custom texture the same as smooth particles
|
||||||
|
|
||||||
// [BB] Load the texture for round or smooth particles
|
// [BB] Load the texture for round or smooth particles
|
||||||
|
@ -1350,27 +1357,36 @@ void HWSprite::ProcessParticle(HWDrawInfo *di, particle_t *particle, sector_t *s
|
||||||
}
|
}
|
||||||
else if (particle_style == 2)
|
else if (particle_style == 2)
|
||||||
{
|
{
|
||||||
lump = has_texture ? particle->texture : TexMan.glPart;
|
if(custom_animated_texture)
|
||||||
|
{
|
||||||
|
lump = TexAnim.UpdateStandaloneAnimation(particle->animData, di->Level->maptime + timefrac);
|
||||||
|
}
|
||||||
|
else if(has_texture)
|
||||||
|
{
|
||||||
|
lump = particle->texture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lump = TexMan.glPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lump.SetNull();
|
||||||
}
|
}
|
||||||
else lump.SetNull();
|
|
||||||
|
|
||||||
if (lump.isValid())
|
if (lump.isValid())
|
||||||
{
|
{
|
||||||
translation = NO_TRANSLATION;
|
translation = NO_TRANSLATION;
|
||||||
//auto tex = TexMan.GetGameTexture(lump, false);
|
|
||||||
|
|
||||||
ul = 0;
|
ul = vt = 0;
|
||||||
ur = 1;
|
ur = vb = 1;
|
||||||
vt = 0;
|
|
||||||
vb = 1;
|
texture = TexMan.GetGameTexture(lump, !custom_animated_texture);
|
||||||
texture = TexMan.GetGameTexture(lump, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double timefrac = vp.TicFrac;
|
|
||||||
if (paused || di->Level->isFrozen())
|
|
||||||
timefrac = 0.;
|
|
||||||
float xvf = (particle->Vel.X) * timefrac;
|
float xvf = (particle->Vel.X) * timefrac;
|
||||||
float yvf = (particle->Vel.Y) * timefrac;
|
float yvf = (particle->Vel.Y) * timefrac;
|
||||||
float zvf = (particle->Vel.Z) * timefrac;
|
float zvf = (particle->Vel.Z) * timefrac;
|
||||||
|
|
|
@ -223,7 +223,7 @@ namespace swrenderer
|
||||||
vis->floorclip = 0;
|
vis->floorclip = 0;
|
||||||
vis->foggy = foggy;
|
vis->foggy = foggy;
|
||||||
|
|
||||||
vis->Light.SetColormap(thread, tz, lightlevel, foggy, map, particle->bright != 0, false, false, false, true);
|
vis->Light.SetColormap(thread, tz, lightlevel, foggy, map, particle->flags & SPF_FULLBRIGHT, false, false, false, true);
|
||||||
|
|
||||||
thread->SpriteList->Push(vis);
|
thread->SpriteList->Push(vis);
|
||||||
}
|
}
|
||||||
|
|
|
@ -701,17 +701,18 @@ enum ECheckBlockFlags
|
||||||
|
|
||||||
enum EParticleFlags
|
enum EParticleFlags
|
||||||
{
|
{
|
||||||
SPF_FULLBRIGHT = 1,
|
SPF_FULLBRIGHT = 1 << 0,
|
||||||
SPF_RELPOS = 1 << 1,
|
SPF_RELPOS = 1 << 1,
|
||||||
SPF_RELVEL = 1 << 2,
|
SPF_RELVEL = 1 << 2,
|
||||||
SPF_RELACCEL = 1 << 3,
|
SPF_RELACCEL = 1 << 3,
|
||||||
SPF_RELANG = 1 << 4,
|
SPF_RELANG = 1 << 4,
|
||||||
SPF_NOTIMEFREEZE = 1 << 5,
|
SPF_NOTIMEFREEZE = 1 << 5,
|
||||||
SPF_ROLL = 1 << 6,
|
SPF_ROLL = 1 << 6,
|
||||||
SPF_REPLACE = 1 << 7,
|
SPF_REPLACE = 1 << 7,
|
||||||
SPF_NO_XY_BILLBOARD = 1 << 8,
|
SPF_NO_XY_BILLBOARD = 1 << 8,
|
||||||
|
SPF_STANDALONE_ANIMATIONS = 1 << 9,
|
||||||
|
|
||||||
SPF_RELATIVE = SPF_RELPOS|SPF_RELVEL|SPF_RELACCEL|SPF_RELANG
|
SPF_RELATIVE = SPF_RELPOS|SPF_RELVEL|SPF_RELACCEL|SPF_RELANG
|
||||||
};
|
};
|
||||||
|
|
||||||
//Flags for A_FaceMovementDirection
|
//Flags for A_FaceMovementDirection
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
Class VisualThinker : Thinker native
|
Class VisualThinker : Thinker native
|
||||||
{
|
{
|
||||||
native Vector3 Pos,
|
native Vector3 Pos,
|
||||||
Vel,
|
|
||||||
Prev;
|
Prev;
|
||||||
|
native FVector3 Vel;
|
||||||
native Vector2 Scale,
|
native Vector2 Scale,
|
||||||
Offset;
|
Offset;
|
||||||
native double Roll,
|
native float Roll,
|
||||||
PrevRoll;
|
PrevRoll,
|
||||||
native float Alpha;
|
Alpha;
|
||||||
native TextureID Texture;
|
native TextureID Texture;
|
||||||
native TranslationID Translation;
|
native TranslationID Translation;
|
||||||
native uint16 Flags;
|
native uint16 Flags;
|
||||||
|
|
Loading…
Reference in a new issue