X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fparticles.cpp;h=5a3056c324dc1242815b4a9e0030a8c1479c2378;hb=18bfa1c785a123499ee12d0551a9447a4d32d93b;hp=1d814f6191513676f76af074f93d82cb947c3d2e;hpb=a0566270d9fa075afa36a7e3e68c690b1b23ba90;p=oweals%2Fminetest.git diff --git a/src/particles.cpp b/src/particles.cpp index 1d814f619..5a3056c32 100644 --- a/src/particles.cpp +++ b/src/particles.cpp @@ -57,12 +57,16 @@ Particle::Particle( float expirationtime, float size, bool collisiondetection, - AtlasPointer ap + bool vertical, + video::ITexture *texture, + v2f texpos, + v2f texsize ): scene::ISceneNode(smgr->getRootSceneNode(), smgr) { // Misc m_gamedef = gamedef; + m_env = &env; // Texture m_material.setFlag(video::EMF_LIGHTING, false); @@ -70,8 +74,9 @@ Particle::Particle( m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, true); m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - m_material.setTexture(0, ap.atlas); - m_ap = ap; + m_material.setTexture(0, texture); + m_texpos = texpos; + m_texsize = texsize; // Particle related @@ -83,6 +88,7 @@ Particle::Particle( m_player = player; m_size = size; m_collisiondetection = collisiondetection; + m_vertical = vertical; // Irrlicht stuff m_collisionbox = core::aabbox3d @@ -90,7 +96,7 @@ Particle::Particle( this->setAutomaticCulling(scene::EAC_OFF); // Init lighting - updateLight(env); + updateLight(); // Init model updateVertices(); @@ -129,7 +135,7 @@ void Particle::render() scene::EPT_TRIANGLES, video::EIT_16BIT); } -void Particle::step(float dtime, ClientEnvironment &env) +void Particle::step(float dtime) { m_time += dtime; if (m_collisiondetection) @@ -138,7 +144,7 @@ void Particle::step(float dtime, ClientEnvironment &env) v3f p_pos = m_pos*BS; v3f p_velocity = m_velocity*BS; v3f p_acceleration = m_acceleration*BS; - collisionMoveSimple(&env, m_gamedef, + collisionMoveSimple(m_env, m_gamedef, BS*0.5, box, 0, dtime, p_pos, p_velocity, p_acceleration); @@ -153,13 +159,13 @@ void Particle::step(float dtime, ClientEnvironment &env) } // Update lighting - updateLight(env); + updateLight(); // Update model updateVertices(); } -void Particle::updateLight(ClientEnvironment &env) +void Particle::updateLight() { u8 light = 0; try{ @@ -168,11 +174,11 @@ void Particle::updateLight(ClientEnvironment &env) floor(m_pos.Y+0.5), floor(m_pos.Z+0.5) ); - MapNode n = env.getClientMap().getNode(p); - light = n.getLightBlend(env.getDayNightRatio(), m_gamedef->ndef()); + MapNode n = m_env->getClientMap().getNode(p); + light = n.getLightBlend(m_env->getDayNightRatio(), m_gamedef->ndef()); } catch(InvalidPositionException &e){ - light = blend_light(env.getDayNightRatio(), LIGHT_SUN, 0); + light = blend_light(m_env->getDayNightRatio(), LIGHT_SUN, 0); } m_light = decode_light(light); } @@ -180,31 +186,41 @@ void Particle::updateLight(ClientEnvironment &env) void Particle::updateVertices() { video::SColor c(255, m_light, m_light, m_light); + f32 tx0 = m_texpos.X; + f32 tx1 = m_texpos.X + m_texsize.X; + f32 ty0 = m_texpos.Y; + f32 ty1 = m_texpos.Y + m_texsize.Y; + m_vertices[0] = video::S3DVertex(-m_size/2,-m_size/2,0, 0,0,0, - c, m_ap.x0(), m_ap.y1()); + c, tx0, ty1); m_vertices[1] = video::S3DVertex(m_size/2,-m_size/2,0, 0,0,0, - c, m_ap.x1(), m_ap.y1()); + c, tx1, ty1); m_vertices[2] = video::S3DVertex(m_size/2,m_size/2,0, 0,0,0, - c, m_ap.x1(), m_ap.y0()); + c, tx1, ty0); m_vertices[3] = video::S3DVertex(-m_size/2,m_size/2,0, 0,0,0, - c ,m_ap.x0(), m_ap.y0()); + c, tx0, ty0); + v3s16 camera_offset = m_env->getCameraOffset(); for(u16 i=0; i<4; i++) { - m_vertices[i].Pos.rotateYZBy(m_player->getPitch()); - m_vertices[i].Pos.rotateXZBy(m_player->getYaw()); + if (m_vertical) { + v3f ppos = m_player->getPosition()/BS; + m_vertices[i].Pos.rotateXZBy(atan2(ppos.Z-m_pos.Z, ppos.X-m_pos.X)/core::DEGTORAD+90); + } else { + m_vertices[i].Pos.rotateYZBy(m_player->getPitch()); + m_vertices[i].Pos.rotateXZBy(m_player->getYaw()); + } m_box.addInternalPoint(m_vertices[i].Pos); - m_vertices[i].Pos += m_pos*BS; + m_vertices[i].Pos += m_pos*BS - intToFloat(camera_offset, BS); } } - /* Helpers */ -void allparticles_step (float dtime, ClientEnvironment &env) +void allparticles_step (float dtime) { for(std::vector::iterator i = all_particles.begin(); i != all_particles.end();) @@ -213,11 +229,11 @@ void allparticles_step (float dtime, ClientEnvironment &env) { (*i)->remove(); delete *i; - all_particles.erase(i); + i = all_particles.erase(i); } else { - (*i)->step(dtime, env); + (*i)->step(dtime); i++; } } @@ -248,19 +264,19 @@ void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, { // Texture u8 texid = myrand_range(0,5); - AtlasPointer ap = tiles[texid].texture; - float size = rand()%64/512.; - float visual_size = BS*size; - float texsize = size*2; + video::ITexture *texture = tiles[texid].texture; - float x1 = ap.x1(); - float y1 = ap.y1(); + // Only use first frame of animated texture + f32 ymax = 1; + if(tiles[texid].material_flags & MATERIAL_FLAG_ANIMATION_VERTICAL_FRAMES) + ymax /= tiles[texid].animation_frame_count; - ap.size.X = (ap.x1() - ap.x0()) * texsize; - ap.size.Y = (ap.x1() - ap.x0()) * texsize; - - ap.pos.X = ap.x0() + (x1 - ap.x0()) * ((rand()%64)/64.-texsize); - ap.pos.Y = ap.y0() + (y1 - ap.y0()) * ((rand()%64)/64.-texsize); + float size = rand()%64/512.; + float visual_size = BS*size; + v2f texsize(size*2, ymax*size*2); + v2f texpos; + texpos.X = ((rand()%64)/64.-texsize.X); + texpos.Y = ymax*((rand()%64)/64.-texsize.Y); // Physics v3f velocity( (rand()%100/50.-1)/1.5, @@ -285,7 +301,10 @@ void addNodeParticle(IGameDef* gamedef, scene::ISceneManager* smgr, rand()%100/100., // expiration time visual_size, true, - ap); + false, + texture, + texpos, + texsize); } /* @@ -296,7 +315,7 @@ 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, AtlasPointer ap, u32 id) + bool collisiondetection, bool vertical, video::ITexture *texture, u32 id) { m_gamedef = gamedef; m_smgr = smgr; @@ -314,7 +333,8 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr, m_minsize = minsize; m_maxsize = maxsize; m_collisiondetection = collisiondetection; - m_ap = ap; + m_vertical = vertical; + m_texture = texture; m_time = 0; for (u16 i = 0; i<=m_amount; i++) @@ -362,8 +382,11 @@ void ParticleSpawner::step(float dtime, ClientEnvironment &env) exptime, size, m_collisiondetection, - m_ap); - m_spawntimes.erase(i); + m_vertical, + m_texture, + v2f(0.0, 0.0), + v2f(1.0, 1.0)); + i = m_spawntimes.erase(i); } else { @@ -398,7 +421,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment &env) exptime, size, m_collisiondetection, - m_ap); + m_vertical, + m_texture, + v2f(0.0, 0.0), + v2f(1.0, 1.0)); } } } @@ -448,6 +474,6 @@ void clear_particles () { (*i)->remove(); delete *i; - all_particles.erase(i); - } + i = all_particles.erase(i); + } }