forked from Mirrorlandia_minetest/minetest
ParticleSpawner::step cleanup and rotation fix (#6486)
* Particles: Move spawner code to a separate fucntion
This commit is contained in:
parent
6b0fb94d60
commit
200e9cc4a2
@ -290,6 +290,59 @@ ParticleSpawner::ParticleSpawner(IGameDef* gamedef, scene::ISceneManager *smgr,
|
|||||||
|
|
||||||
ParticleSpawner::~ParticleSpawner() {}
|
ParticleSpawner::~ParticleSpawner() {}
|
||||||
|
|
||||||
|
void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius,
|
||||||
|
bool is_attached, const v3f &attached_pos, float attached_yaw)
|
||||||
|
{
|
||||||
|
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 (pos.getDistanceFrom(ppos) > radius)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
float exptime = rand() / (float)RAND_MAX
|
||||||
|
* (m_maxexptime - m_minexptime)
|
||||||
|
+ m_minexptime;
|
||||||
|
float size = rand() / (float)RAND_MAX
|
||||||
|
* (m_maxsize - m_minsize)
|
||||||
|
+ m_minsize;
|
||||||
|
|
||||||
|
m_particlemanager->addParticle(new Particle(
|
||||||
|
m_gamedef,
|
||||||
|
m_smgr,
|
||||||
|
m_player,
|
||||||
|
env,
|
||||||
|
pos,
|
||||||
|
vel,
|
||||||
|
acc,
|
||||||
|
exptime,
|
||||||
|
size,
|
||||||
|
m_collisiondetection,
|
||||||
|
m_collision_removal,
|
||||||
|
m_vertical,
|
||||||
|
m_texture,
|
||||||
|
v2f(0.0, 0.0),
|
||||||
|
v2f(1.0, 1.0),
|
||||||
|
m_animation,
|
||||||
|
m_glow
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
||||||
{
|
{
|
||||||
m_time += dtime;
|
m_time += dtime;
|
||||||
@ -311,130 +364,33 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_spawntime != 0) // Spawner exists for a predefined timespan
|
if (m_spawntime != 0) {
|
||||||
{
|
// Spawner exists for a predefined timespan
|
||||||
for(std::vector<float>::iterator i = m_spawntimes.begin();
|
for (std::vector<float>::iterator i = m_spawntimes.begin();
|
||||||
i != m_spawntimes.end();)
|
i != m_spawntimes.end();) {
|
||||||
{
|
if ((*i) <= m_time && m_amount > 0) {
|
||||||
if ((*i) <= m_time && m_amount > 0)
|
|
||||||
{
|
|
||||||
m_amount--;
|
m_amount--;
|
||||||
|
|
||||||
// Pretend to, but don't actually spawn a particle if it is
|
// Pretend to, but don't actually spawn a particle if it is
|
||||||
// attached to an unloaded object or distant from player.
|
// attached to an unloaded object or distant from player.
|
||||||
if (!unloaded) {
|
if (!unloaded)
|
||||||
v3f ppos = m_player->getPosition() / BS;
|
spawnParticle(env, radius, is_attached, attached_pos, attached_yaw);
|
||||||
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 += attached_pos;
|
|
||||||
|
|
||||||
if (pos.getDistanceFrom(ppos) <= radius) {
|
|
||||||
v3f vel = random_v3f(m_minvel, m_maxvel);
|
|
||||||
v3f acc = random_v3f(m_minacc, m_maxacc);
|
|
||||||
|
|
||||||
if (is_attached) {
|
|
||||||
// Apply attachment yaw and position
|
|
||||||
pos.rotateXZBy(attached_yaw);
|
|
||||||
vel.rotateXZBy(attached_yaw);
|
|
||||||
acc.rotateXZBy(attached_yaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
float exptime = rand()/(float)RAND_MAX
|
|
||||||
*(m_maxexptime-m_minexptime)
|
|
||||||
+m_minexptime;
|
|
||||||
float size = rand()/(float)RAND_MAX
|
|
||||||
*(m_maxsize-m_minsize)
|
|
||||||
+m_minsize;
|
|
||||||
|
|
||||||
Particle* toadd = new Particle(
|
|
||||||
m_gamedef,
|
|
||||||
m_smgr,
|
|
||||||
m_player,
|
|
||||||
env,
|
|
||||||
pos,
|
|
||||||
vel,
|
|
||||||
acc,
|
|
||||||
exptime,
|
|
||||||
size,
|
|
||||||
m_collisiondetection,
|
|
||||||
m_collision_removal,
|
|
||||||
m_vertical,
|
|
||||||
m_texture,
|
|
||||||
v2f(0.0, 0.0),
|
|
||||||
v2f(1.0, 1.0),
|
|
||||||
m_animation,
|
|
||||||
m_glow);
|
|
||||||
m_particlemanager->addParticle(toadd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i = m_spawntimes.erase(i);
|
i = m_spawntimes.erase(i);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else // Spawner exists for an infinity timespan, spawn on a per-second base
|
// Spawner exists for an infinity timespan, spawn on a per-second base
|
||||||
{
|
|
||||||
// Skip this step if attached to an unloaded object
|
// Skip this step if attached to an unloaded object
|
||||||
if (unloaded)
|
if (unloaded)
|
||||||
return;
|
return;
|
||||||
for (int i = 0; i <= m_amount; i++)
|
|
||||||
{
|
|
||||||
if (rand()/(float)RAND_MAX < dtime)
|
|
||||||
{
|
|
||||||
// Do not spawn particle if distant from player
|
|
||||||
v3f ppos = m_player->getPosition() / BS;
|
|
||||||
v3f pos = random_v3f(m_minpos, m_maxpos);
|
|
||||||
|
|
||||||
// Need to apply this first or the following check
|
for (int i = 0; i <= m_amount; i++) {
|
||||||
// will be wrong for attached spawners
|
if (rand() / (float)RAND_MAX < dtime)
|
||||||
if (is_attached)
|
spawnParticle(env, radius, is_attached, attached_pos, attached_yaw);
|
||||||
pos += attached_pos;
|
|
||||||
|
|
||||||
if (pos.getDistanceFrom(ppos) <= radius) {
|
|
||||||
v3f vel = random_v3f(m_minvel, m_maxvel);
|
|
||||||
v3f acc = random_v3f(m_minacc, m_maxacc);
|
|
||||||
|
|
||||||
if (is_attached) {
|
|
||||||
// Apply attachment yaw and position
|
|
||||||
pos.rotateXZBy(attached_yaw);
|
|
||||||
vel.rotateXZBy(attached_yaw);
|
|
||||||
acc.rotateXZBy(attached_yaw);
|
|
||||||
}
|
|
||||||
|
|
||||||
float exptime = rand()/(float)RAND_MAX
|
|
||||||
*(m_maxexptime-m_minexptime)
|
|
||||||
+m_minexptime;
|
|
||||||
float size = rand()/(float)RAND_MAX
|
|
||||||
*(m_maxsize-m_minsize)
|
|
||||||
+m_minsize;
|
|
||||||
|
|
||||||
Particle* toadd = new Particle(
|
|
||||||
m_gamedef,
|
|
||||||
m_smgr,
|
|
||||||
m_player,
|
|
||||||
env,
|
|
||||||
pos,
|
|
||||||
vel,
|
|
||||||
acc,
|
|
||||||
exptime,
|
|
||||||
size,
|
|
||||||
m_collisiondetection,
|
|
||||||
m_collision_removal,
|
|
||||||
m_vertical,
|
|
||||||
m_texture,
|
|
||||||
v2f(0.0, 0.0),
|
|
||||||
v2f(1.0, 1.0),
|
|
||||||
m_animation,
|
|
||||||
m_glow);
|
|
||||||
m_particlemanager->addParticle(toadd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ private:
|
|||||||
|
|
||||||
class ParticleSpawner
|
class ParticleSpawner
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ParticleSpawner(IGameDef* gamedef,
|
ParticleSpawner(IGameDef* gamedef,
|
||||||
scene::ISceneManager *smgr,
|
scene::ISceneManager *smgr,
|
||||||
LocalPlayer *player,
|
LocalPlayer *player,
|
||||||
@ -144,8 +144,12 @@ class ParticleSpawner
|
|||||||
bool get_expired ()
|
bool get_expired ()
|
||||||
{ return (m_amount <= 0) && m_spawntime != 0; }
|
{ return (m_amount <= 0) && m_spawntime != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParticleManager* m_particlemanager;
|
void spawnParticle(ClientEnvironment *env, float radius,
|
||||||
|
bool is_attached, const v3f &attached_pos,
|
||||||
|
float attached_yaw);
|
||||||
|
|
||||||
|
ParticleManager *m_particlemanager;
|
||||||
float m_time;
|
float m_time;
|
||||||
IGameDef *m_gamedef;
|
IGameDef *m_gamedef;
|
||||||
scene::ISceneManager *m_smgr;
|
scene::ISceneManager *m_smgr;
|
||||||
|
Loading…
Reference in New Issue
Block a user