Particles: Make collision with objects optional (#7682)
authorParamat <paramat@users.noreply.github.com>
Fri, 7 Sep 2018 23:38:35 +0000 (00:38 +0100)
committerGitHub <noreply@github.com>
Fri, 7 Sep 2018 23:38:35 +0000 (00:38 +0100)
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
src/client/clientevent.h
src/network/clientpackethandler.cpp
src/network/networkprotocol.h
src/particles.cpp
src/particles.h
src/script/lua_api/l_particles.cpp
src/server.cpp
src/server.h

index 80d14bff5a718640560456a4c24749986f4ff769..8ae4ddb03f3a1378b0e2d821223355df12e2fa61 100644 (file)
@@ -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.
index f0f1dc9e0b7fd61f8ee7a2190d2449106a58bc6f..4976eb1745d5d3b3ebaca7ee2a7161552e33c827 100644 (file)
@@ -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;
index f8be613177fb398c1ba954b68fdfee926eec7db8..cbd0d6a5736333ff423231225ccae6b00b4ba8b6 100644 (file)
@@ -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);
index 113b11177252a0025fbb388c6a2248be6ff713a7..4e896602bf69e7c45d9b912db4bad90553cef9fb 100644 (file)
@@ -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
index e98068f5355dad1387c526b0b92b8c0ee3a82dde..923c3ad010840d4dc0f3f41c598ef724f7e43df4 100644 (file)
@@ -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,
index 9ea56385c61189836c3c402af8df0d1de43368b9..3392e7e950ae9a860d2b39420f817840c713236f 100644 (file)
@@ -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<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;
index 15bcbf3b5c50974f0caaa64cdbe023097df46995..7783e5910adc38fef504ee4061b616b1932282b3 100644 (file)
@@ -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,
index 37aad4bceccfa6ae48d87037a259dce801b58c0d..41248c869914a1fea5db51701d364e5a23817da9 100644 (file)
@@ -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;
index 751eaa5f2dce4f901b5831cb6be2c410208ce351..c2adbbc07fd265983877ee6069abc6e8e1c7b5a8 100644 (file)
@@ -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);