mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Particles: Add option to remove particles on collision
Adds the particle option `collision_removal = bool` Some particles are hard to use right now since they either go through solid blocks (without collision detection), and with collision detection enabled they (e.g. raindrops) would just stop dead on the floor and sit there until they expire, or worse, scrape along a wall or ceiling. We can solve the problem by adding a boolean flag that tells the particle to be removed if it ever collides with something. This will make it easier to add rain that doesn't fall through your roof or stick on the top of it. Or clouds and smoke that don't go through trees. Particles that collide with this flag are marked expired unconditionally, causing them to be treated like normal expired particles and cleaned up normally. Documentation is adjusted accordingly. An added bonus of this patch is that particles can potentially collide many times with nodes, and this reduces the amount of collisions to 1 (max), which may end up reducing particle load on the client.
This commit is contained in:
parent
62d15ac7c1
commit
d499ec4838
9 changed files with 84 additions and 32 deletions
|
@ -54,6 +54,7 @@ Particle::Particle(
|
|||
float expirationtime,
|
||||
float size,
|
||||
bool collisiondetection,
|
||||
bool collision_removal,
|
||||
bool vertical,
|
||||
video::ITexture *texture,
|
||||
v2f texpos,
|
||||
|
@ -85,6 +86,7 @@ Particle::Particle(
|
|||
m_player = player;
|
||||
m_size = size;
|
||||
m_collisiondetection = collisiondetection;
|
||||
m_collision_removal = collision_removal;
|
||||
m_vertical = vertical;
|
||||
|
||||
// Irrlicht stuff
|
||||
|
@ -126,20 +128,21 @@ void Particle::render()
|
|||
void Particle::step(float dtime)
|
||||
{
|
||||
m_time += dtime;
|
||||
if (m_collisiondetection)
|
||||
{
|
||||
if (m_collisiondetection) {
|
||||
aabb3f box = m_collisionbox;
|
||||
v3f p_pos = m_pos*BS;
|
||||
v3f p_velocity = m_velocity*BS;
|
||||
collisionMoveSimple(m_env, m_gamedef,
|
||||
BS*0.5, box,
|
||||
0, dtime,
|
||||
&p_pos, &p_velocity, m_acceleration * BS);
|
||||
m_pos = p_pos/BS;
|
||||
m_velocity = p_velocity/BS;
|
||||
}
|
||||
else
|
||||
{
|
||||
v3f p_pos = m_pos * BS;
|
||||
v3f p_velocity = m_velocity * BS;
|
||||
collisionMoveResult r = collisionMoveSimple(m_env,
|
||||
m_gamedef, BS * 0.5, box, 0, dtime, &p_pos,
|
||||
&p_velocity, m_acceleration * BS);
|
||||
if (m_collision_removal && r.collides) {
|
||||
// force expiration of the particle
|
||||
m_expiration = -1.0;
|
||||
} else {
|
||||
m_pos = p_pos / BS;
|
||||
m_velocity = p_velocity / BS;
|
||||
}
|
||||
} else {
|
||||
m_velocity += m_acceleration * dtime;
|
||||
m_pos += m_velocity * dtime;
|
||||
}
|
||||
|
@ -210,8 +213,8 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
|
|||
u16 amount, float time,
|
||||
v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc,
|
||||
float minexptime, float maxexptime, float minsize, float maxsize,
|
||||
bool collisiondetection, bool vertical, video::ITexture *texture, u32 id,
|
||||
ParticleManager *p_manager) :
|
||||
bool collisiondetection, bool collision_removal, bool vertical,
|
||||
video::ITexture *texture, u32 id, ParticleManager *p_manager) :
|
||||
m_particlemanager(p_manager)
|
||||
{
|
||||
m_gamedef = gamedef;
|
||||
|
@ -230,6 +233,7 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
|
|||
m_minsize = minsize;
|
||||
m_maxsize = maxsize;
|
||||
m_collisiondetection = collisiondetection;
|
||||
m_collision_removal = collision_removal;
|
||||
m_vertical = vertical;
|
||||
m_texture = texture;
|
||||
m_time = 0;
|
||||
|
@ -277,6 +281,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||
exptime,
|
||||
size,
|
||||
m_collisiondetection,
|
||||
m_collision_removal,
|
||||
m_vertical,
|
||||
m_texture,
|
||||
v2f(0.0, 0.0),
|
||||
|
@ -317,6 +322,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||
exptime,
|
||||
size,
|
||||
m_collisiondetection,
|
||||
m_collision_removal,
|
||||
m_vertical,
|
||||
m_texture,
|
||||
v2f(0.0, 0.0),
|
||||
|
@ -446,6 +452,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
|
|||
event->add_particlespawner.minsize,
|
||||
event->add_particlespawner.maxsize,
|
||||
event->add_particlespawner.collisiondetection,
|
||||
event->add_particlespawner.collision_removal,
|
||||
event->add_particlespawner.vertical,
|
||||
texture,
|
||||
event->add_particlespawner.id,
|
||||
|
@ -480,6 +487,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, IGameDef *gamedef,
|
|||
event->spawn_particle.expirationtime,
|
||||
event->spawn_particle.size,
|
||||
event->spawn_particle.collisiondetection,
|
||||
event->spawn_particle.collision_removal,
|
||||
event->spawn_particle.vertical,
|
||||
texture,
|
||||
v2f(0.0, 0.0),
|
||||
|
@ -555,6 +563,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, scene::ISceneManager* s
|
|||
visual_size,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
texture,
|
||||
texpos,
|
||||
texsize);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue