diff options
Diffstat (limited to 'src/client/particles.cpp')
-rw-r--r-- | src/client/particles.cpp | 95 |
1 files changed, 51 insertions, 44 deletions
diff --git a/src/client/particles.cpp b/src/client/particles.cpp index ebd52f0f0..a0e4e54eb 100644 --- a/src/client/particles.cpp +++ b/src/client/particles.cpp @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <cmath> #include "client.h" #include "collision.h" +#include "client/content_cao.h" #include "client/clientevent.h" #include "client/renderingengine.h" #include "util/numeric.h" @@ -38,9 +39,10 @@ with this program; if not, write to the Free Software Foundation, Inc., v3f random_v3f(v3f min, v3f max) { - return v3f( rand()/(float)RAND_MAX*(max.X-min.X)+min.X, - rand()/(float)RAND_MAX*(max.Y-min.Y)+min.Y, - rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); + return v3f( + rand() / (float)RAND_MAX * (max.X - min.X) + min.X, + rand() / (float)RAND_MAX * (max.Y - min.Y) + min.Y, + rand() / (float)RAND_MAX * (max.Z - min.Z) + min.Z); } Particle::Particle( @@ -99,8 +101,13 @@ Particle::Particle( m_glow = glow; // Irrlicht stuff - m_collisionbox = aabb3f - (-size/2,-size/2,-size/2,size/2,size/2,size/2); + m_collisionbox = aabb3f( + -size / 2, + -size / 2, + -size / 2, + size / 2, + size / 2, + size / 2); this->setAutomaticCulling(scene::EAC_OFF); // Init lighting @@ -120,7 +127,7 @@ void Particle::OnRegisterSceneNode() void Particle::render() { - video::IVideoDriver* driver = SceneManager->getVideoDriver(); + video::IVideoDriver *driver = SceneManager->getVideoDriver(); driver->setMaterial(m_material); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); @@ -181,7 +188,7 @@ void Particle::updateLight() floor(m_pos.Y+0.5), floor(m_pos.Z+0.5) ); - MapNode n = m_env->getClientMap().getNodeNoEx(p, &pos_ok); + MapNode n = m_env->getClientMap().getNode(p, &pos_ok); if (pos_ok) light = n.getLightBlend(m_env->getDayNightRatio(), m_gamedef->ndef()); else @@ -291,24 +298,29 @@ ParticleSpawner::ParticleSpawner( m_animation = anim; m_glow = glow; - for (u16 i = 0; i<=m_amount; i++) + for (u16 i = 0; i <= m_amount; i++) { - float spawntime = (float)rand()/(float)RAND_MAX*m_spawntime; + float spawntime = (float)rand() / (float)RAND_MAX * m_spawntime; m_spawntimes.push_back(spawntime); } } void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, - bool is_attached, const v3f &attached_pos, float attached_yaw) + const core::matrix4 *attached_absolute_pos_rot_matrix) { v3f ppos = m_player->getPosition() / BS; v3f pos = random_v3f(m_minpos, m_maxpos); // Need to apply this first or the following check // will be wrong for attached spawners - if (is_attached) { - pos.rotateXZBy(attached_yaw); - pos += attached_pos; + if (attached_absolute_pos_rot_matrix) { + pos *= BS; + attached_absolute_pos_rot_matrix->transformVect(pos); + pos /= BS; + v3s16 camera_offset = m_particlemanager->m_env->getCameraOffset(); + pos.X += camera_offset.X; + pos.Y += camera_offset.Y; + pos.Z += camera_offset.Z; } if (pos.getDistanceFrom(ppos) > radius) @@ -317,18 +329,19 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, v3f vel = random_v3f(m_minvel, m_maxvel); v3f acc = random_v3f(m_minacc, m_maxacc); - if (is_attached) { - // Apply attachment yaw - vel.rotateXZBy(attached_yaw); - acc.rotateXZBy(attached_yaw); + if (attached_absolute_pos_rot_matrix) { + // Apply attachment rotation + attached_absolute_pos_rot_matrix->rotateVect(vel); + attached_absolute_pos_rot_matrix->rotateVect(acc); } float exptime = rand() / (float)RAND_MAX - * (m_maxexptime - m_minexptime) - + m_minexptime; + * (m_maxexptime - m_minexptime) + + m_minexptime; + float size = rand() / (float)RAND_MAX - * (m_maxsize - m_minsize) - + m_minsize; + * (m_maxsize - m_minsize) + + m_minsize; m_particlemanager->addParticle(new Particle( m_gamedef, @@ -351,7 +364,7 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, )); } -void ParticleSpawner::step(float dtime, ClientEnvironment* env) +void ParticleSpawner::step(float dtime, ClientEnvironment *env) { m_time += dtime; @@ -359,14 +372,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE; bool unloaded = false; - bool is_attached = false; - v3f attached_pos = v3f(0,0,0); - float attached_yaw = 0; - if (m_attached_id != 0) { - if (ClientActiveObject *attached = env->getActiveObject(m_attached_id)) { - attached_pos = attached->getPosition() / BS; - attached_yaw = attached->getYaw(); - is_attached = true; + const core::matrix4 *attached_absolute_pos_rot_matrix = nullptr; + if (m_attached_id) { + if (GenericCAO *attached = dynamic_cast<GenericCAO *>(env->getActiveObject(m_attached_id))) { + attached_absolute_pos_rot_matrix = &attached->getAbsolutePosRotMatrix(); } else { unloaded = true; } @@ -377,12 +386,12 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) for (std::vector<float>::iterator i = m_spawntimes.begin(); i != m_spawntimes.end();) { if ((*i) <= m_time && m_amount > 0) { - m_amount--; + --m_amount; // Pretend to, but don't actually spawn a particle if it is // attached to an unloaded object or distant from player. if (!unloaded) - spawnParticle(env, radius, is_attached, attached_pos, attached_yaw); + spawnParticle(env, radius, attached_absolute_pos_rot_matrix); i = m_spawntimes.erase(i); } else { @@ -398,13 +407,13 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env) for (int i = 0; i <= m_amount; i++) { if (rand() / (float)RAND_MAX < dtime) - spawnParticle(env, radius, is_attached, attached_pos, attached_yaw); + spawnParticle(env, radius, attached_absolute_pos_rot_matrix); } } } -ParticleManager::ParticleManager(ClientEnvironment* env) : +ParticleManager::ParticleManager(ClientEnvironment *env) : m_env(env) {} @@ -419,7 +428,7 @@ void ParticleManager::step(float dtime) stepSpawners (dtime); } -void ParticleManager::stepSpawners (float dtime) +void ParticleManager::stepSpawners(float dtime) { MutexAutoLock lock(m_spawner_list_lock); for (auto i = m_particle_spawners.begin(); i != m_particle_spawners.end();) { @@ -433,7 +442,7 @@ void ParticleManager::stepSpawners (float dtime) } } -void ParticleManager::stepParticles (float dtime) +void ParticleManager::stepParticles(float dtime) { MutexAutoLock lock(m_particle_list_lock); for (auto i = m_particles.begin(); i != m_particles.end();) { @@ -448,7 +457,7 @@ void ParticleManager::stepParticles (float dtime) } } -void ParticleManager::clearAll () +void ParticleManager::clearAll() { MutexAutoLock lock(m_spawner_list_lock); MutexAutoLock lock2(m_particle_list_lock); @@ -457,9 +466,7 @@ void ParticleManager::clearAll () m_particle_spawners.erase(i++); } - for(std::vector<Particle*>::iterator i = - m_particles.begin(); - i != m_particles.end();) + for(auto i = m_particles.begin(); i != m_particles.end();) { (*i)->remove(); delete *i; @@ -568,7 +575,7 @@ void ParticleManager::handleParticleEvent(ClientEvent *event, Client *client, // The final burst of particles when a node is finally dug, *not* particles // spawned during the digging of a node. -void ParticleManager::addDiggingParticles(IGameDef* gamedef, +void ParticleManager::addDiggingParticles(IGameDef *gamedef, LocalPlayer *player, v3s16 pos, const MapNode &n, const ContentFeatures &f) { // No particles for "airlike" nodes @@ -583,7 +590,7 @@ void ParticleManager::addDiggingParticles(IGameDef* gamedef, // During the digging of a node particles are spawned individually by this // function, called from Game::handleDigging() in game.cpp. -void ParticleManager::addNodeParticle(IGameDef* gamedef, +void ParticleManager::addNodeParticle(IGameDef *gamedef, LocalPlayer *player, v3s16 pos, const MapNode &n, const ContentFeatures &f) { // No particles for "airlike" nodes @@ -635,7 +642,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, else n.getColor(f, &color); - Particle* toadd = new Particle( + Particle *toadd = new Particle( gamedef, player, m_env, @@ -658,7 +665,7 @@ void ParticleManager::addNodeParticle(IGameDef* gamedef, addParticle(toadd); } -void ParticleManager::addParticle(Particle* toadd) +void ParticleManager::addParticle(Particle *toadd) { MutexAutoLock lock(m_particle_list_lock); m_particles.push_back(toadd); |