Skip to content

Commit

Permalink
Particles: Make collision with objects optional (#7682)
Browse files Browse the repository at this point in the history
Also set it to false for node dig particles, as they are often created
and high in number.

Improve particle documentation.
  • Loading branch information
paramat committed Sep 7, 2018
1 parent 6ed9c6f commit 766fb7b
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 59 deletions.
34 changes: 25 additions & 9 deletions doc/lua_api.txt
Expand Up @@ -6619,14 +6619,21 @@ Used by `minetest.add_particle`.
-- Disappears after expirationtime seconds

size = 1,
-- Scales the visual size of the particle texture.

collisiondetection = false,
-- If true collides with physical objects
-- If true collides with `walkable` nodes and, depending on the
-- `object_collision` field, objects too.

collision_removal = false,
-- If true particle is removed when it collides.
-- Requires collisiondetection = true to have any effect.

object_collision = false,
-- If true particle collides with objects that are defined as
-- `physical = true,` and `collide_with_objects = true,`.
-- Requires collisiondetection = true to have any effect.

vertical = false,
-- If true faces player using y axis only

Expand All @@ -6651,10 +6658,12 @@ Used by `minetest.add_particlespawner`.

{
amount = 1,
-- Number of particles spawned over the time period `time`.

time = 1,
-- If time is 0 has infinite lifespan and spawns the amount on a
-- per-second basis.
-- Lifespan of spawner in seconds.
-- If time is 0 spawner has infinite lifespan and spawns the `amount` on
-- a per-second basis.

minpos = {x=0, y=0, z=0},
maxpos = {x=0, y=0, z=0},
Expand All @@ -6666,30 +6675,37 @@ Used by `minetest.add_particlespawner`.
maxexptime = 1,
minsize = 1,
maxsize = 1,
-- The particle's properties are random values in between the bounds
-- The particles' properties are random values between the min and max
-- values.
-- pos, velocity, acceleration, expirationtime, size

collisiondetection = false,
-- If true collides with physical objects
-- If true collide with `walkable` nodes and, depending on the
-- `object_collision` field, objects too.

collision_removal = false,
-- If true particle is removed when it collides.
-- If true particles are removed when they collide.
-- Requires collisiondetection = true to have any effect.

object_collision = false,
-- If true particles collide with objects that are defined as
-- `physical = true,` and `collide_with_objects = true,`.
-- Requires collisiondetection = true to have any effect.

attached = ObjectRef,
-- If defined, particle positions, velocities and accelerations are
-- relative to this object's position and yaw

vertical = false,
-- If true faces player using y axis only
-- If true face player using y axis only

texture = "image.png",

playername = "singleplayer",
-- Optional, if specified spawns particle only on the player's client
-- Optional, if specified spawns particles only on the player's client

animation = {Tile Animation definition},
-- Optional, specifies how to animate the particle texture
-- Optional, specifies how to animate the particles' texture

glow = 0
-- Optional, specify particle self-luminescence in darkness.
Expand Down
2 changes: 2 additions & 0 deletions src/client/clientevent.h
Expand Up @@ -82,6 +82,7 @@ struct ClientEvent
f32 size;
bool collisiondetection;
bool collision_removal;
bool object_collision;
bool vertical;
std::string *texture;
struct TileAnimationParams animation;
Expand All @@ -103,6 +104,7 @@ struct ClientEvent
f32 maxsize;
bool collisiondetection;
bool collision_removal;
bool object_collision;
u16 attached_id;
bool vertical;
std::string *texture;
Expand Down
23 changes: 15 additions & 8 deletions src/network/clientpackethandler.cpp
Expand Up @@ -889,16 +889,19 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
float size = readF1000(is);
bool collisiondetection = readU8(is);
std::string texture = deSerializeLongString(is);
bool vertical = false;
bool collision_removal = false;

bool vertical = false;
bool collision_removal = false;
TileAnimationParams animation;
animation.type = TAT_NONE;
u8 glow = 0;
animation.type = TAT_NONE;
u8 glow = 0;
bool object_collision = false;
try {
vertical = readU8(is);
collision_removal = readU8(is);
animation.deSerialize(is, m_proto_ver);
glow = readU8(is);
object_collision = readU8(is);
} catch (...) {}

ClientEvent *event = new ClientEvent();
Expand All @@ -910,6 +913,7 @@ void Client::handleCommand_SpawnParticle(NetworkPacket* pkt)
event->spawn_particle.size = size;
event->spawn_particle.collisiondetection = collisiondetection;
event->spawn_particle.collision_removal = collision_removal;
event->spawn_particle.object_collision = object_collision;
event->spawn_particle.vertical = vertical;
event->spawn_particle.texture = new std::string(texture);
event->spawn_particle.animation = animation;
Expand Down Expand Up @@ -943,12 +947,13 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)

*pkt >> server_id;

bool vertical = false;
bool vertical = false;
bool collision_removal = false;
u16 attached_id = 0;
TileAnimationParams animation;
animation.type = TAT_NONE;
u8 glow = 0;
u16 attached_id = 0;
animation.type = TAT_NONE;
u8 glow = 0;
bool object_collision = false;
try {
*pkt >> vertical;
*pkt >> collision_removal;
Expand All @@ -959,6 +964,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
std::istringstream is(datastring, std::ios_base::binary);
animation.deSerialize(is, m_proto_ver);
glow = readU8(is);
object_collision = readU8(is);
} catch (...) {}

u32 client_id = m_particle_manager.getSpawnerId();
Expand All @@ -980,6 +986,7 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt)
event->add_particlespawner.maxsize = maxsize;
event->add_particlespawner.collisiondetection = collisiondetection;
event->add_particlespawner.collision_removal = collision_removal;
event->add_particlespawner.object_collision = object_collision;
event->add_particlespawner.attached_id = attached_id;
event->add_particlespawner.vertical = vertical;
event->add_particlespawner.texture = new std::string(texture);
Expand Down
12 changes: 9 additions & 3 deletions src/network/networkprotocol.h
Expand Up @@ -477,10 +477,13 @@ enum ToClientCommand
f1000 expirationtime
f1000 size
u8 bool collisiondetection
u8 bool vertical
u32 len
u8[len] texture
u8 bool vertical
u8 collision_removal
TileAnimation animation
u8 glow
u8 object_collision
*/

TOCLIENT_ADD_PARTICLESPAWNER = 0x47,
Expand All @@ -498,11 +501,14 @@ enum ToClientCommand
f1000 minsize
f1000 maxsize
u8 bool collisiondetection
u8 bool vertical
u32 len
u8[len] texture
u32 id
u8 bool vertical
u8 collision_removal
u32 id
TileAnimation animation
u8 glow
u8 object_collision
*/

TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48, // Obsolete
Expand Down
40 changes: 30 additions & 10 deletions src/particles.cpp
Expand Up @@ -54,6 +54,7 @@ Particle::Particle(
float size,
bool collisiondetection,
bool collision_removal,
bool object_collision,
bool vertical,
video::ITexture *texture,
v2f texpos,
Expand Down Expand Up @@ -93,6 +94,7 @@ Particle::Particle(
m_size = size;
m_collisiondetection = collisiondetection;
m_collision_removal = collision_removal;
m_object_collision = object_collision;
m_vertical = vertical;
m_glow = glow;

Expand Down Expand Up @@ -135,9 +137,9 @@ void Particle::step(float dtime)
aabb3f box = m_collisionbox;
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);
collisionMoveResult r = collisionMoveSimple(m_env, m_gamedef, BS * 0.5f,
box, 0.0f, dtime, &p_pos, &p_velocity, m_acceleration * BS, nullptr,
m_object_collision);
if (m_collision_removal && r.collides) {
// force expiration of the particle
m_expiration = -1.0;
Expand Down Expand Up @@ -243,14 +245,27 @@ void Particle::updateVertices()
ParticleSpawner
*/

ParticleSpawner::ParticleSpawner(IGameDef *gamedef, LocalPlayer *player,
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 collision_removal, u16 attached_id, bool vertical,
video::ITexture *texture, u32 id, const struct TileAnimationParams &anim,
ParticleSpawner::ParticleSpawner(
IGameDef *gamedef,
LocalPlayer *player,
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 collision_removal,
bool object_collision,
u16 attached_id,
bool vertical,
video::ITexture *texture,
u32 id,
const struct TileAnimationParams &anim,
u8 glow,
ParticleManager *p_manager) :
ParticleManager *p_manager
):
m_particlemanager(p_manager)
{
m_gamedef = gamedef;
Expand All @@ -269,6 +284,7 @@ ParticleSpawner::ParticleSpawner(IGameDef *gamedef, LocalPlayer *player,
m_maxsize = maxsize;
m_collisiondetection = collisiondetection;
m_collision_removal = collision_removal;
m_object_collision = object_collision;
m_attached_id = attached_id;
m_vertical = vertical;
m_texture = texture;
Expand Down Expand Up @@ -326,6 +342,7 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius,
size,
m_collisiondetection,
m_collision_removal,
m_object_collision,
m_vertical,
m_texture,
v2f(0.0, 0.0),
Expand Down Expand Up @@ -507,6 +524,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client,
event->add_particlespawner.maxsize,
event->add_particlespawner.collisiondetection,
event->add_particlespawner.collision_removal,
event->add_particlespawner.object_collision,
event->add_particlespawner.attached_id,
event->add_particlespawner.vertical,
texture,
Expand Down Expand Up @@ -545,6 +563,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client,
event->spawn_particle.size,
event->spawn_particle.collisiondetection,
event->spawn_particle.collision_removal,
event->spawn_particle.object_collision,
event->spawn_particle.vertical,
texture,
v2f(0.0, 0.0),
Expand Down Expand Up @@ -637,6 +656,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef,
true,
false,
false,
false,
texture,
texpos,
texsize,
Expand Down
4 changes: 4 additions & 0 deletions src/particles.h
Expand Up @@ -45,6 +45,7 @@ class Particle : public scene::ISceneNode
float size,
bool collisiondetection,
bool collision_removal,
bool object_collision,
bool vertical,
video::ITexture *texture,
v2f texpos,
Expand Down Expand Up @@ -104,6 +105,7 @@ class Particle : public scene::ISceneNode
video::SColor m_color;
bool m_collisiondetection;
bool m_collision_removal;
bool m_object_collision;
bool m_vertical;
v3s16 m_camera_offset;
struct TileAnimationParams m_animation;
Expand All @@ -126,6 +128,7 @@ class ParticleSpawner
float minsize, float maxsize,
bool collisiondetection,
bool collision_removal,
bool object_collision,
u16 attached_id,
bool vertical,
video::ITexture *texture,
Expand Down Expand Up @@ -165,6 +168,7 @@ class ParticleSpawner
std::vector<float> m_spawntimes;
bool m_collisiondetection;
bool m_collision_removal;
bool m_object_collision;
bool m_vertical;
u16 m_attached_id;
struct TileAnimationParams m_animation;
Expand Down

0 comments on commit 766fb7b

Please sign in to comment.