From 766fb7b46edab47f96b8b940e390daf5319261b7 Mon Sep 17 00:00:00 2001 From: Paramat Date: Sat, 8 Sep 2018 00:38:35 +0100 Subject: [PATCH] Particles: Make collision with objects optional (#7682) Also set it to false for node dig particles, as they are often created and high in number. Improve particle documentation. --- doc/lua_api.txt | 34 +++++++++++++++++------- src/client/clientevent.h | 2 ++ src/network/clientpackethandler.cpp | 23 +++++++++++------ src/network/networkprotocol.h | 12 ++++++--- src/particles.cpp | 40 +++++++++++++++++++++-------- src/particles.h | 4 +++ src/script/lua_api/l_particles.cpp | 31 ++++++++++++---------- src/server.cpp | 25 ++++++++++-------- src/server.h | 8 +++--- 9 files changed, 120 insertions(+), 59 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 80d14bff5..8ae4ddb03 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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 @@ -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}, @@ -6666,14 +6675,21 @@ 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, @@ -6681,15 +6697,15 @@ Used by `minetest.add_particlespawner`. -- 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. diff --git a/src/client/clientevent.h b/src/client/clientevent.h index f0f1dc9e0..4976eb174 100644 --- a/src/client/clientevent.h +++ b/src/client/clientevent.h @@ -82,6 +82,7 @@ struct ClientEvent f32 size; bool collisiondetection; bool collision_removal; + bool object_collision; bool vertical; std::string *texture; struct TileAnimationParams animation; @@ -103,6 +104,7 @@ struct ClientEvent f32 maxsize; bool collisiondetection; bool collision_removal; + bool object_collision; u16 attached_id; bool vertical; std::string *texture; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index f8be61317..cbd0d6a57 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -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(); @@ -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; @@ -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; @@ -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(); @@ -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); diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 113b11177..4e896602b 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -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, @@ -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 diff --git a/src/particles.cpp b/src/particles.cpp index e98068f53..923c3ad01 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -54,6 +54,7 @@ Particle::Particle( float size, bool collisiondetection, bool collision_removal, + bool object_collision, bool vertical, video::ITexture *texture, v2f texpos, @@ -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; @@ -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; @@ -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; @@ -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; @@ -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), @@ -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, @@ -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), @@ -637,6 +656,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, true, false, false, + false, texture, texpos, texsize, diff --git a/src/particles.h b/src/particles.h index 9ea56385c..3392e7e95 100644 --- a/src/particles.h +++ b/src/particles.h @@ -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, @@ -104,6 +105,7 @@ private: 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; @@ -126,6 +128,7 @@ public: float minsize, float maxsize, bool collisiondetection, bool collision_removal, + bool object_collision, u16 attached_id, bool vertical, video::ITexture *texture, @@ -165,6 +168,7 @@ private: std::vector m_spawntimes; bool m_collisiondetection; bool m_collision_removal; + bool m_object_collision; bool m_vertical; u16 m_attached_id; struct TileAnimationParams m_animation; diff --git a/src/script/lua_api/l_particles.cpp b/src/script/lua_api/l_particles.cpp index 15bcbf3b5..7783e5910 100644 --- a/src/script/lua_api/l_particles.cpp +++ b/src/script/lua_api/l_particles.cpp @@ -26,13 +26,14 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "particles.h" // add_particle({pos=, velocity=, acceleration=, expirationtime=, -// size=, collisiondetection=, collision_removal=, vertical=, -// texture=, player=}) +// size=, collisiondetection=, collision_removal=, object_collision=, +// vertical=, texture=, player=}) // pos/velocity/acceleration = {x=num, y=num, z=num} // expirationtime = num (seconds) // size = num // collisiondetection = bool // collision_removal = bool +// object_collision = bool // vertical = bool // texture = e.g."default_wood.png" // animation = TileAnimation definition @@ -43,19 +44,14 @@ int ModApiParticles::l_add_particle(lua_State *L) // Get parameters v3f pos, vel, acc; - pos = vel = acc = v3f(0, 0, 0); - float expirationtime, size; expirationtime = size = 1; - - bool collisiondetection, vertical, collision_removal; - collisiondetection = vertical = collision_removal = false; + bool collisiondetection, vertical, collision_removal, object_collision; + collisiondetection = vertical = collision_removal = object_collision = false; struct TileAnimationParams animation; animation.type = TAT_NONE; - std::string texture; std::string playername; - u8 glow = 0; if (lua_gettop(L) > 1) // deprecated @@ -107,6 +103,8 @@ int ModApiParticles::l_add_particle(lua_State *L) "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, "collision_removal", collision_removal); + object_collision = getboolfield_default(L, 1, + "object_collision", object_collision); vertical = getboolfield_default(L, 1, "vertical", vertical); lua_getfield(L, 1, "animation"); @@ -119,7 +117,8 @@ int ModApiParticles::l_add_particle(lua_State *L) glow = getintfield_default(L, 1, "glow", 0); } getServer(L)->spawnParticle(playername, pos, vel, acc, expirationtime, size, - collisiondetection, collision_removal, vertical, texture, animation, glow); + collisiondetection, collision_removal, object_collision, vertical, + texture, animation, glow); return 1; } @@ -131,6 +130,7 @@ int ModApiParticles::l_add_particle(lua_State *L) // minsize=, maxsize=, // collisiondetection=, // collision_removal=, +// object_collision=, // vertical=, // texture=, // player=}) @@ -139,6 +139,7 @@ int ModApiParticles::l_add_particle(lua_State *L) // minsize/maxsize = num // collisiondetection = bool // collision_removal = bool +// object_collision = bool // vertical = bool // texture = e.g."default_wood.png" // animation = TileAnimation definition @@ -150,11 +151,10 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) // Get parameters u16 amount = 1; v3f minpos, maxpos, minvel, maxvel, minacc, maxacc; - minpos= maxpos= minvel= maxvel= minacc= maxacc= v3f(0, 0, 0); float time, minexptime, maxexptime, minsize, maxsize; - time= minexptime= maxexptime= minsize= maxsize= 1; - bool collisiondetection, vertical, collision_removal; - collisiondetection = vertical = collision_removal = false; + time = minexptime = maxexptime = minsize = maxsize = 1; + bool collisiondetection, vertical, collision_removal, object_collision; + collisiondetection = vertical = collision_removal = object_collision = false; struct TileAnimationParams animation; animation.type = TAT_NONE; ServerActiveObject *attached = NULL; @@ -219,6 +219,8 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) "collisiondetection", collisiondetection); collision_removal = getboolfield_default(L, 1, "collision_removal", collision_removal); + object_collision = getboolfield_default(L, 1, + "object_collision", object_collision); lua_getfield(L, 1, "animation"); animation = read_animation_definition(L, -1); @@ -245,6 +247,7 @@ int ModApiParticles::l_add_particlespawner(lua_State *L) minsize, maxsize, collisiondetection, collision_removal, + object_collision, attached, vertical, texture, playername, diff --git a/src/server.cpp b/src/server.cpp index 37aad4bce..41248c869 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1578,7 +1578,7 @@ void Server::SendShowFormspecMessage(session_t peer_id, const std::string &forms void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, - bool collision_removal, + bool collision_removal, bool object_collision, bool vertical, const std::string &texture, const struct TileAnimationParams &animation, u8 glow) { @@ -1603,8 +1603,8 @@ void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version, SendSpawnParticle(client_id, player->protocol_version, pos, velocity, acceleration, - expirationtime, size, collisiondetection, - collision_removal, vertical, texture, animation, glow); + expirationtime, size, collisiondetection, collision_removal, + object_collision, vertical, texture, animation, glow); } return; } @@ -1621,6 +1621,7 @@ void Server::SendSpawnParticle(session_t peer_id, u16 protocol_version, animation.serialize(os, protocol_version); pkt.putRawString(os.str()); pkt << glow; + pkt << object_collision; Send(&pkt); } @@ -1630,7 +1631,7 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version, u16 amount, float spawntime, 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, const std::string &texture, u32 id, + bool object_collision, u16 attached_id, bool vertical, const std::string &texture, u32 id, const struct TileAnimationParams &animation, u8 glow) { if (peer_id == PEER_ID_INEXISTENT) { @@ -1644,7 +1645,8 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version, amount, spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, minexptime, maxexptime, minsize, maxsize, collisiondetection, collision_removal, - attached_id, vertical, texture, id, animation, glow); + object_collision, attached_id, vertical, texture, id, + animation, glow); } return; } @@ -1665,6 +1667,7 @@ void Server::SendAddParticleSpawner(session_t peer_id, u16 protocol_version, animation.serialize(os, protocol_version); pkt.putRawString(os.str()); pkt << glow; + pkt << object_collision; Send(&pkt); } @@ -3165,7 +3168,7 @@ void Server::notifyPlayers(const std::wstring &msg) void Server::spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool - collisiondetection, bool collision_removal, + collisiondetection, bool collision_removal, bool object_collision, bool vertical, const std::string &texture, const struct TileAnimationParams &animation, u8 glow) { @@ -3184,14 +3187,14 @@ void Server::spawnParticle(const std::string &playername, v3f pos, } SendSpawnParticle(peer_id, proto_ver, pos, velocity, acceleration, - expirationtime, size, collisiondetection, - collision_removal, vertical, texture, animation, glow); + expirationtime, size, collisiondetection, collision_removal, + object_collision, vertical, texture, animation, glow); } u32 Server::addParticleSpawner(u16 amount, float spawntime, 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 collisiondetection, bool collision_removal, bool object_collision, ServerActiveObject *attached, bool vertical, const std::string &texture, const std::string &playername, const struct TileAnimationParams &animation, u8 glow) @@ -3220,8 +3223,8 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime, SendAddParticleSpawner(peer_id, proto_ver, amount, spawntime, minpos, maxpos, minvel, maxvel, minacc, maxacc, - minexptime, maxexptime, minsize, maxsize, - collisiondetection, collision_removal, attached_id, vertical, + minexptime, maxexptime, minsize, maxsize, collisiondetection, + collision_removal, object_collision, attached_id, vertical, texture, id, animation, glow); return id; diff --git a/src/server.h b/src/server.h index 751eaa5f2..c2adbbc07 100644 --- a/src/server.h +++ b/src/server.h @@ -229,7 +229,7 @@ public: void spawnParticle(const std::string &playername, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, - bool collisiondetection, bool collision_removal, + bool collisiondetection, bool collision_removal, bool object_collision, bool vertical, const std::string &texture, const struct TileAnimationParams &animation, u8 glow); @@ -239,7 +239,7 @@ public: v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool collision_removal, + bool collisiondetection, bool collision_removal, bool object_collision, ServerActiveObject *attached, bool vertical, const std::string &texture, const std::string &playername, const struct TileAnimationParams &animation, @@ -444,7 +444,7 @@ private: v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, bool collision_removal, + bool collisiondetection, bool collision_removal, bool object_collision, u16 attached_id, bool vertical, const std::string &texture, u32 id, const struct TileAnimationParams &animation, u8 glow); @@ -455,7 +455,7 @@ private: void SendSpawnParticle(session_t peer_id, u16 protocol_version, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, - bool collisiondetection, bool collision_removal, + bool collisiondetection, bool collision_removal, bool object_collision, bool vertical, const std::string &texture, const struct TileAnimationParams &animation, u8 glow);