Fix rotation of attached particlespawner

Co-authored-by: ANAND <ClobberXD@gmail.com>
This commit is contained in:
Pedro Gimeno 2019-08-09 14:21:17 +05:30 committed by SmallJoker
parent 049256573b
commit 9543b84970
5 changed files with 44 additions and 41 deletions

View File

@ -48,8 +48,7 @@ public:
virtual bool getCollisionBox(aabb3f *toset) const { return false; } virtual bool getCollisionBox(aabb3f *toset) const { return false; }
virtual bool getSelectionBox(aabb3f *toset) const { return false; } virtual bool getSelectionBox(aabb3f *toset) const { return false; }
virtual bool collideWithObjects() const { return false; } virtual bool collideWithObjects() const { return false; }
virtual v3f getPosition(){ return v3f(0,0,0); } virtual const v3f getPosition() const { return v3f(0.0f); }
virtual float getYaw() const { return 0; }
virtual scene::ISceneNode *getSceneNode() { return NULL; } virtual scene::ISceneNode *getSceneNode() { return NULL; }
virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() { return NULL; } virtual scene::IAnimatedMeshSceneNode *getAnimatedMeshSceneNode() { return NULL; }
virtual bool isLocalPlayer() const {return false;} virtual bool isLocalPlayer() const {return false;}

View File

@ -401,7 +401,7 @@ bool GenericCAO::getSelectionBox(aabb3f *toset) const
return true; return true;
} }
v3f GenericCAO::getPosition() const v3f GenericCAO::getPosition() const
{ {
if (getParent() != nullptr) { if (getParent() != nullptr) {
if (m_matrixnode) if (m_matrixnode)

View File

@ -154,12 +154,9 @@ public:
virtual bool getSelectionBox(aabb3f *toset) const; virtual bool getSelectionBox(aabb3f *toset) const;
v3f getPosition(); const v3f getPosition() const;
inline const v3f &getRotation() inline const v3f &getRotation() const { return m_rotation; }
{
return m_rotation;
}
const bool isImmortal(); const bool isImmortal();
@ -180,6 +177,12 @@ public:
return m_matrixnode->getRelativeTransformationMatrix(); return m_matrixnode->getRelativeTransformationMatrix();
} }
inline const core::matrix4 &getAbsolutePosRotMatrix() const
{
assert(m_matrixnode);
return m_matrixnode->getAbsoluteTransformation();
}
inline f32 getStepHeight() const inline f32 getStepHeight() const
{ {
return m_prop.stepheight; return m_prop.stepheight;

View File

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <cmath> #include <cmath>
#include "client.h" #include "client.h"
#include "collision.h" #include "collision.h"
#include "client/content_cao.h"
#include "client/clientevent.h" #include "client/clientevent.h"
#include "client/renderingengine.h" #include "client/renderingengine.h"
#include "util/numeric.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) v3f random_v3f(v3f min, v3f max)
{ {
return v3f( rand()/(float)RAND_MAX*(max.X-min.X)+min.X, return v3f(
rand()/(float)RAND_MAX*(max.Y-min.Y)+min.Y, rand() / (float)RAND_MAX * (max.X - min.X) + min.X,
rand()/(float)RAND_MAX*(max.Z-min.Z)+min.Z); rand() / (float)RAND_MAX * (max.Y - min.Y) + min.Y,
rand() / (float)RAND_MAX * (max.Z - min.Z) + min.Z);
} }
Particle::Particle( Particle::Particle(
@ -299,16 +301,21 @@ ParticleSpawner::ParticleSpawner(
} }
void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius, 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 ppos = m_player->getPosition() / BS;
v3f pos = random_v3f(m_minpos, m_maxpos); v3f pos = random_v3f(m_minpos, m_maxpos);
// Need to apply this first or the following check // Need to apply this first or the following check
// will be wrong for attached spawners // will be wrong for attached spawners
if (is_attached) { if (attached_absolute_pos_rot_matrix) {
pos.rotateXZBy(attached_yaw); pos *= BS;
pos += attached_pos; 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) if (pos.getDistanceFrom(ppos) > radius)
@ -317,18 +324,19 @@ void ParticleSpawner::spawnParticle(ClientEnvironment *env, float radius,
v3f vel = random_v3f(m_minvel, m_maxvel); v3f vel = random_v3f(m_minvel, m_maxvel);
v3f acc = random_v3f(m_minacc, m_maxacc); v3f acc = random_v3f(m_minacc, m_maxacc);
if (is_attached) { if (attached_absolute_pos_rot_matrix) {
// Apply attachment yaw // Apply attachment rotation
vel.rotateXZBy(attached_yaw); attached_absolute_pos_rot_matrix->rotateVect(vel);
acc.rotateXZBy(attached_yaw); attached_absolute_pos_rot_matrix->rotateVect(acc);
} }
float exptime = rand() / (float)RAND_MAX float exptime = rand() / (float)RAND_MAX
* (m_maxexptime - m_minexptime) * (m_maxexptime - m_minexptime)
+ m_minexptime; + m_minexptime;
float size = rand() / (float)RAND_MAX float size = rand() / (float)RAND_MAX
* (m_maxsize - m_minsize) * (m_maxsize - m_minsize)
+ m_minsize; + m_minsize;
m_particlemanager->addParticle(new Particle( m_particlemanager->addParticle(new Particle(
m_gamedef, m_gamedef,
@ -359,14 +367,10 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE; g_settings->getS16("max_block_send_distance") * MAP_BLOCKSIZE;
bool unloaded = false; bool unloaded = false;
bool is_attached = false; const core::matrix4 *attached_absolute_pos_rot_matrix = nullptr;
v3f attached_pos = v3f(0,0,0); if (m_attached_id) {
float attached_yaw = 0; if (GenericCAO *attached = dynamic_cast<GenericCAO *>(env->getActiveObject(m_attached_id))) {
if (m_attached_id != 0) { attached_absolute_pos_rot_matrix = &attached->getAbsolutePosRotMatrix();
if (ClientActiveObject *attached = env->getActiveObject(m_attached_id)) {
attached_pos = attached->getPosition() / BS;
attached_yaw = attached->getYaw();
is_attached = true;
} else { } else {
unloaded = true; unloaded = true;
} }
@ -382,7 +386,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
// 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)
spawnParticle(env, radius, is_attached, attached_pos, attached_yaw); spawnParticle(env, radius, attached_absolute_pos_rot_matrix);
i = m_spawntimes.erase(i); i = m_spawntimes.erase(i);
} else { } else {
@ -398,7 +402,7 @@ void ParticleSpawner::step(float dtime, ClientEnvironment* env)
for (int i = 0; i <= m_amount; i++) { for (int i = 0; i <= m_amount; i++) {
if (rand() / (float)RAND_MAX < dtime) if (rand() / (float)RAND_MAX < dtime)
spawnParticle(env, radius, is_attached, attached_pos, attached_yaw); spawnParticle(env, radius, attached_absolute_pos_rot_matrix);
} }
} }
} }
@ -419,7 +423,7 @@ void ParticleManager::step(float dtime)
stepSpawners (dtime); stepSpawners (dtime);
} }
void ParticleManager::stepSpawners (float dtime) void ParticleManager::stepSpawners(float dtime)
{ {
MutexAutoLock lock(m_spawner_list_lock); MutexAutoLock lock(m_spawner_list_lock);
for (auto i = m_particle_spawners.begin(); i != m_particle_spawners.end();) { for (auto i = m_particle_spawners.begin(); i != m_particle_spawners.end();) {
@ -433,7 +437,7 @@ void ParticleManager::stepSpawners (float dtime)
} }
} }
void ParticleManager::stepParticles (float dtime) void ParticleManager::stepParticles(float dtime)
{ {
MutexAutoLock lock(m_particle_list_lock); MutexAutoLock lock(m_particle_list_lock);
for (auto i = m_particles.begin(); i != m_particles.end();) { for (auto i = m_particles.begin(); i != m_particles.end();) {
@ -448,7 +452,7 @@ void ParticleManager::stepParticles (float dtime)
} }
} }
void ParticleManager::clearAll () void ParticleManager::clearAll()
{ {
MutexAutoLock lock(m_spawner_list_lock); MutexAutoLock lock(m_spawner_list_lock);
MutexAutoLock lock2(m_particle_list_lock); MutexAutoLock lock2(m_particle_list_lock);
@ -457,9 +461,7 @@ void ParticleManager::clearAll ()
m_particle_spawners.erase(i++); m_particle_spawners.erase(i++);
} }
for(std::vector<Particle*>::iterator i = for(auto i = m_particles.begin(); i != m_particles.end();)
m_particles.begin();
i != m_particles.end();)
{ {
(*i)->remove(); (*i)->remove();
delete *i; delete *i;

View File

@ -144,8 +144,7 @@ public:
private: private:
void spawnParticle(ClientEnvironment *env, float radius, void spawnParticle(ClientEnvironment *env, float radius,
bool is_attached, const v3f &attached_pos, const core::matrix4 *attached_absolute_pos_rot_matrix);
float attached_yaw);
ParticleManager *m_particlemanager; ParticleManager *m_particlemanager;
float m_time; float m_time;