Added support for rapid movement of the emitter, with particle now seeding between
the position of the emitter in the previous frame and the new position in the new frame, the number of particles added also scales up to compensate for this movement.
This commit is contained in:
parent
320d0f67e4
commit
be285c62c0
@ -62,7 +62,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius)
|
|||||||
if (glider)
|
if (glider)
|
||||||
{
|
{
|
||||||
const osg::BoundingSphere& bs = glider->getBound();
|
const osg::BoundingSphere& bs = glider->getBound();
|
||||||
float size = radius/bs.radius()*0.3f;
|
float size = radius/bs.radius()*0.15f;
|
||||||
|
|
||||||
osg::MatrixTransform* positioned = new osg::MatrixTransform;
|
osg::MatrixTransform* positioned = new osg::MatrixTransform;
|
||||||
positioned->setDataVariance(osg::Object::STATIC);
|
positioned->setDataVariance(osg::Object::STATIC);
|
||||||
@ -84,7 +84,7 @@ osg::Node* createMovingModel(const osg::Vec3& center, float radius)
|
|||||||
if (cessna)
|
if (cessna)
|
||||||
{
|
{
|
||||||
const osg::BoundingSphere& bs = cessna->getBound();
|
const osg::BoundingSphere& bs = cessna->getBound();
|
||||||
float size = radius/bs.radius()*0.3f;
|
float size = radius/bs.radius()*0.15f;
|
||||||
|
|
||||||
osg::MatrixTransform* positioned = new osg::MatrixTransform;
|
osg::MatrixTransform* positioned = new osg::MatrixTransform;
|
||||||
positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
positioned->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
|
||||||
@ -220,7 +220,7 @@ void build_world(osg::Group *root)
|
|||||||
|
|
||||||
// create the moving models.
|
// create the moving models.
|
||||||
{
|
{
|
||||||
root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),100.0f));
|
root->addChild(createMovingModel(osg::Vec3(500.0f,500.0f,500.0f),300.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,12 +271,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3 position = handleMovingModels ? hit.getLocalIntersectPoint() : hit.getWorldIntersectPoint();
|
osg::Vec3 position = handleMovingModels ? hit.getLocalIntersectPoint() : hit.getWorldIntersectPoint();
|
||||||
float scale = 20.0f * ((float)rand() / (float)RAND_MAX);
|
float scale = 10.0f * ((float)rand() / (float)RAND_MAX);
|
||||||
float intensity = handleMovingModels ? 5.0f : 1.0f;
|
float intensity = 1.0f;
|
||||||
|
|
||||||
osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, scale, intensity);
|
osgParticle::ExplosionEffect* explosion = new osgParticle::ExplosionEffect(position, scale, intensity);
|
||||||
osgParticle::ExplosionDebrisEffect* explosionDebri = new osgParticle::ExplosionDebrisEffect(position, scale, intensity);
|
osgParticle::ExplosionDebrisEffect* explosionDebri = new osgParticle::ExplosionDebrisEffect(position, scale, intensity);
|
||||||
osgParticle::SmokeEffect* smoke = new osgParticle::SmokeEffect(position, scale, intensity);
|
osgParticle::ParticleEffect* smoke = new osgParticle::SmokeEffect(position, scale, intensity);
|
||||||
osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, scale, intensity);
|
osgParticle::FireEffect* fire = new osgParticle::FireEffect(position, scale, intensity);
|
||||||
|
|
||||||
explosion->setWind(wind);
|
explosion->setWind(wind);
|
||||||
|
@ -57,6 +57,13 @@ namespace osgParticle
|
|||||||
/// Set the Counter object.
|
/// Set the Counter object.
|
||||||
inline void setCounter(Counter* c);
|
inline void setCounter(Counter* c);
|
||||||
|
|
||||||
|
/// Get the ratio between number of particle to create in compenstation for movement of the emitter
|
||||||
|
inline float getNumParticlesToCreateMovementCompenstationRatio() const;
|
||||||
|
|
||||||
|
/// Set the ratio between number of particle to create in compenstation for movement of the emitter
|
||||||
|
inline void setNumParticlesToCreateMovementCompenstationRatio(float r);
|
||||||
|
|
||||||
|
|
||||||
/// Get the Placer object.
|
/// Get the Placer object.
|
||||||
inline Placer* getPlacer();
|
inline Placer* getPlacer();
|
||||||
|
|
||||||
@ -82,6 +89,8 @@ namespace osgParticle
|
|||||||
virtual void emit(double dt);
|
virtual void emit(double dt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
float _numParticleToCreateMovementCompensationRatio;
|
||||||
osg::ref_ptr<Counter> _counter;
|
osg::ref_ptr<Counter> _counter;
|
||||||
osg::ref_ptr<Placer> _placer;
|
osg::ref_ptr<Placer> _placer;
|
||||||
osg::ref_ptr<Shooter> _shooter;
|
osg::ref_ptr<Shooter> _shooter;
|
||||||
@ -104,6 +113,16 @@ namespace osgParticle
|
|||||||
_counter = c;
|
_counter = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float ModularEmitter::getNumParticlesToCreateMovementCompenstationRatio() const
|
||||||
|
{
|
||||||
|
return _numParticleToCreateMovementCompensationRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ModularEmitter::setNumParticlesToCreateMovementCompenstationRatio(float r)
|
||||||
|
{
|
||||||
|
_numParticleToCreateMovementCompensationRatio = r;
|
||||||
|
}
|
||||||
|
|
||||||
inline Placer* ModularEmitter::getPlacer()
|
inline Placer* ModularEmitter::getPlacer()
|
||||||
{
|
{
|
||||||
return _placer.get();
|
return _placer.get();
|
||||||
|
@ -64,6 +64,9 @@ namespace osgParticle {
|
|||||||
/// Place a partice. Called automatically by <CODE>ModularEmitter</CODE>, do not call this method manually.
|
/// Place a partice. Called automatically by <CODE>ModularEmitter</CODE>, do not call this method manually.
|
||||||
void place(Particle* P) const;
|
void place(Particle* P) const;
|
||||||
|
|
||||||
|
/// return the control position
|
||||||
|
inline osg::Vec3 getControlPosition() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~MultiSegmentPlacer() {}
|
virtual ~MultiSegmentPlacer() {}
|
||||||
MultiSegmentPlacer& operator=(const MultiSegmentPlacer&) { return *this; }
|
MultiSegmentPlacer& operator=(const MultiSegmentPlacer&) { return *this; }
|
||||||
@ -124,5 +127,10 @@ namespace osgParticle {
|
|||||||
recompute_length();
|
recompute_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline osg::Vec3 MultiSegmentPlacer::getControlPosition() const
|
||||||
|
{
|
||||||
|
return _vx.empty() ? osg::Vec3(0.0f,0.0f,0.0f) : _vx[0].first;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -178,6 +178,9 @@ namespace osgParticle
|
|||||||
/// Transform position and velocity vectors by a matrix.
|
/// Transform position and velocity vectors by a matrix.
|
||||||
inline void transformPositionVelocity(const osg::Matrix& xform);
|
inline void transformPositionVelocity(const osg::Matrix& xform);
|
||||||
|
|
||||||
|
/// Transform position and velocity vectors by a combination of two matrices
|
||||||
|
void Particle::transformPositionVelocity(const osg::Matrix& xform1, const osg::Matrix& xform2, float r);
|
||||||
|
|
||||||
/// Set the angle vector.
|
/// Set the angle vector.
|
||||||
inline void setAngle(const osg::Vec3& a);
|
inline void setAngle(const osg::Vec3& a);
|
||||||
|
|
||||||
@ -410,14 +413,19 @@ namespace osgParticle
|
|||||||
|
|
||||||
inline void Particle::transformPositionVelocity(const osg::Matrix& xform)
|
inline void Particle::transformPositionVelocity(const osg::Matrix& xform)
|
||||||
{
|
{
|
||||||
// this should be optimized!
|
|
||||||
|
|
||||||
osg::Vec3 p1 = _position + _velocity;
|
|
||||||
|
|
||||||
_position = xform.preMult(_position);
|
_position = xform.preMult(_position);
|
||||||
p1 = xform.preMult(p1);
|
_velocity = osg::Matrix::transform3x3(_velocity, xform);
|
||||||
|
}
|
||||||
|
|
||||||
_velocity = p1 - _position;
|
inline void Particle::transformPositionVelocity(const osg::Matrix& xform1, const osg::Matrix& xform2, float r)
|
||||||
|
{
|
||||||
|
osg::Vec3 position1 = xform1.preMult(_position);
|
||||||
|
osg::Vec3 velocity1 = osg::Matrix::transform3x3(_velocity, xform1);
|
||||||
|
osg::Vec3 position2 = xform2.preMult(_position);
|
||||||
|
osg::Vec3 velocity2 = osg::Matrix::transform3x3(_velocity, xform2);
|
||||||
|
float one_minus_r = 1.0f-r;
|
||||||
|
_position = position1*r + position2*one_minus_r;
|
||||||
|
_velocity = velocity1*r + velocity2*one_minus_r;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Particle::setAngle(const osg::Vec3& a)
|
inline void Particle::setAngle(const osg::Vec3& a)
|
||||||
|
@ -119,6 +119,13 @@ namespace osgParticle
|
|||||||
/// Get the current world-to-local transformation matrix (valid only during cull traversal).
|
/// Get the current world-to-local transformation matrix (valid only during cull traversal).
|
||||||
inline const osg::Matrix& getWorldToLocalMatrix();
|
inline const osg::Matrix& getWorldToLocalMatrix();
|
||||||
|
|
||||||
|
/// Get the previous local-to-world transformation matrix (valid only during cull traversal).
|
||||||
|
inline const osg::Matrix& getPreviousLocalToWorldMatrix();
|
||||||
|
|
||||||
|
/// Get the previous world-to-local transformation matrix (valid only during cull traversal).
|
||||||
|
inline const osg::Matrix& getPreviousWorldToLocalMatrix();
|
||||||
|
|
||||||
|
|
||||||
/// Transform a point from local to world coordinates (valid only during cull traversal).
|
/// Transform a point from local to world coordinates (valid only during cull traversal).
|
||||||
inline osg::Vec3 transformLocalToWorld(const osg::Vec3& P);
|
inline osg::Vec3 transformLocalToWorld(const osg::Vec3& P);
|
||||||
|
|
||||||
@ -144,10 +151,14 @@ namespace osgParticle
|
|||||||
bool _enabled;
|
bool _enabled;
|
||||||
double _t0;
|
double _t0;
|
||||||
osg::ref_ptr<ParticleSystem> _ps;
|
osg::ref_ptr<ParticleSystem> _ps;
|
||||||
|
bool _first_ltw_compute;
|
||||||
bool _need_ltw_matrix;
|
bool _need_ltw_matrix;
|
||||||
|
bool _first_wtl_compute;
|
||||||
bool _need_wtl_matrix;
|
bool _need_wtl_matrix;
|
||||||
osg::Matrix _ltw_matrix;
|
osg::Matrix _ltw_matrix;
|
||||||
osg::Matrix _wtl_matrix;
|
osg::Matrix _wtl_matrix;
|
||||||
|
osg::Matrix _previous_ltw_matrix;
|
||||||
|
osg::Matrix _previous_wtl_matrix;
|
||||||
osg::NodeVisitor* _current_nodevisitor;
|
osg::NodeVisitor* _current_nodevisitor;
|
||||||
|
|
||||||
bool _endless;
|
bool _endless;
|
||||||
@ -252,9 +263,13 @@ namespace osgParticle
|
|||||||
inline const osg::Matrix& ParticleProcessor::getLocalToWorldMatrix()
|
inline const osg::Matrix& ParticleProcessor::getLocalToWorldMatrix()
|
||||||
{
|
{
|
||||||
if (_need_ltw_matrix) {
|
if (_need_ltw_matrix) {
|
||||||
_ltw_matrix = osg::Matrix::identity();
|
_previous_ltw_matrix = _ltw_matrix;
|
||||||
//_current_nodevisitor->getLocalToWorldMatrix(_ltw_matrix, this);
|
|
||||||
_ltw_matrix = osg::computeLocalToWorld(_current_nodevisitor->getNodePath());
|
_ltw_matrix = osg::computeLocalToWorld(_current_nodevisitor->getNodePath());
|
||||||
|
if (_first_ltw_compute)
|
||||||
|
{
|
||||||
|
_previous_ltw_matrix = _ltw_matrix;
|
||||||
|
_first_ltw_compute = false;
|
||||||
|
}
|
||||||
_need_ltw_matrix = false;
|
_need_ltw_matrix = false;
|
||||||
}
|
}
|
||||||
return _ltw_matrix;
|
return _ltw_matrix;
|
||||||
@ -263,14 +278,30 @@ namespace osgParticle
|
|||||||
inline const osg::Matrix& ParticleProcessor::getWorldToLocalMatrix()
|
inline const osg::Matrix& ParticleProcessor::getWorldToLocalMatrix()
|
||||||
{
|
{
|
||||||
if (_need_wtl_matrix) {
|
if (_need_wtl_matrix) {
|
||||||
_wtl_matrix = osg::Matrix::identity();
|
_previous_wtl_matrix = _wtl_matrix;
|
||||||
//_current_nodevisitor->getWorldToLocalMatrix(_wtl_matrix, this);
|
|
||||||
_wtl_matrix = osg::computeWorldToLocal(_current_nodevisitor->getNodePath());
|
_wtl_matrix = osg::computeWorldToLocal(_current_nodevisitor->getNodePath());
|
||||||
|
if (_first_wtl_compute)
|
||||||
|
{
|
||||||
|
_previous_wtl_matrix = _wtl_matrix;
|
||||||
|
_first_wtl_compute = false;
|
||||||
|
}
|
||||||
_need_wtl_matrix = false;
|
_need_wtl_matrix = false;
|
||||||
}
|
}
|
||||||
return _wtl_matrix;
|
return _wtl_matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const osg::Matrix& ParticleProcessor::getPreviousLocalToWorldMatrix()
|
||||||
|
{
|
||||||
|
if (_need_ltw_matrix) getLocalToWorldMatrix();
|
||||||
|
return _previous_ltw_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const osg::Matrix& ParticleProcessor::getPreviousWorldToLocalMatrix()
|
||||||
|
{
|
||||||
|
if (_need_wtl_matrix) getWorldToLocalMatrix();
|
||||||
|
return _previous_wtl_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
inline osg::Vec3 ParticleProcessor::transformLocalToWorld(const osg::Vec3& P)
|
inline osg::Vec3 ParticleProcessor::transformLocalToWorld(const osg::Vec3& P)
|
||||||
{
|
{
|
||||||
return getLocalToWorldMatrix().preMult(P);
|
return getLocalToWorldMatrix().preMult(P);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <osg/CopyOp>
|
#include <osg/CopyOp>
|
||||||
#include <osg/Object>
|
#include <osg/Object>
|
||||||
|
#include <osg/Vec3>
|
||||||
|
|
||||||
namespace osgParticle
|
namespace osgParticle
|
||||||
{
|
{
|
||||||
@ -39,6 +40,9 @@ namespace osgParticle
|
|||||||
/// Place a particle. Must be implemented in descendant classes.
|
/// Place a particle. Must be implemented in descendant classes.
|
||||||
virtual void place(Particle* P) const = 0;
|
virtual void place(Particle* P) const = 0;
|
||||||
|
|
||||||
|
/// Return the control position of particles that placer will generate. Must be implemented in descendant classes.
|
||||||
|
virtual osg::Vec3 getControlPosition() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~Placer() {}
|
~Placer() {}
|
||||||
Placer& operator=(const Placer& ) { return *this; }
|
Placer& operator=(const Placer& ) { return *this; }
|
||||||
|
@ -41,6 +41,9 @@ namespace osgParticle
|
|||||||
*/
|
*/
|
||||||
inline void place(Particle* P) const;
|
inline void place(Particle* P) const;
|
||||||
|
|
||||||
|
/// return the control position
|
||||||
|
inline osg::Vec3 getControlPosition() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~PointPlacer() {}
|
virtual ~PointPlacer() {}
|
||||||
PointPlacer& operator=(const PointPlacer&) { return *this; }
|
PointPlacer& operator=(const PointPlacer&) { return *this; }
|
||||||
@ -64,6 +67,11 @@ namespace osgParticle
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline osg::Vec3 PointPlacer::getControlPosition() const
|
||||||
|
{
|
||||||
|
return getCenter();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +61,9 @@ namespace osgParticle
|
|||||||
/// Place a particle. Do not call it manually.
|
/// Place a particle. Do not call it manually.
|
||||||
inline void place(Particle* P) const;
|
inline void place(Particle* P) const;
|
||||||
|
|
||||||
|
/// return the control position
|
||||||
|
inline osg::Vec3 getControlPosition() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~SectorPlacer() {}
|
virtual ~SectorPlacer() {}
|
||||||
SectorPlacer& operator=(const SectorPlacer&) { return *this; }
|
SectorPlacer& operator=(const SectorPlacer&) { return *this; }
|
||||||
@ -127,6 +130,10 @@ namespace osgParticle
|
|||||||
P->setPosition(pos);
|
P->setPosition(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline osg::Vec3 SectorPlacer::getControlPosition() const
|
||||||
|
{
|
||||||
|
return getCenter();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,9 @@ namespace osgParticle {
|
|||||||
/// Place a particle. This method is called by <CODE>ModularEmitter</CODE>, do not call it manually.
|
/// Place a particle. This method is called by <CODE>ModularEmitter</CODE>, do not call it manually.
|
||||||
inline void place(Particle* P) const;
|
inline void place(Particle* P) const;
|
||||||
|
|
||||||
|
/// return the control position
|
||||||
|
inline osg::Vec3 getControlPosition() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~SegmentPlacer() {}
|
virtual ~SegmentPlacer() {}
|
||||||
SegmentPlacer& operator=(const SegmentPlacer&) { return *this; }
|
SegmentPlacer& operator=(const SegmentPlacer&) { return *this; }
|
||||||
@ -122,6 +125,12 @@ namespace osgParticle {
|
|||||||
_vertexB.set(x, y, z);
|
_vertexB.set(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline osg::Vec3 SegmentPlacer::getControlPosition() const
|
||||||
|
{
|
||||||
|
return (_vertexA+_vertexB)*0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -71,6 +71,11 @@ namespace osgParticle
|
|||||||
return minimum + (maximum - minimum) * sqrtf( static_cast<float>(rand()) / static_cast<float>(RAND_MAX) );
|
return minimum + (maximum - minimum) * sqrtf( static_cast<float>(rand()) / static_cast<float>(RAND_MAX) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ValueType mid() const
|
||||||
|
{
|
||||||
|
return (minimum+maximum)*0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Range of floats.
|
/// Range of floats.
|
||||||
|
@ -100,6 +100,7 @@ void FireEffect::setUpEmitterAndProgram()
|
|||||||
if (!_emitter)
|
if (!_emitter)
|
||||||
{
|
{
|
||||||
_emitter = new osgParticle::ModularEmitter;
|
_emitter = new osgParticle::ModularEmitter;
|
||||||
|
_emitter->setNumParticlesToCreateMovementCompenstationRatio(1.5f);
|
||||||
_emitter->setCounter(new osgParticle::RandomRateCounter);
|
_emitter->setCounter(new osgParticle::RandomRateCounter);
|
||||||
_emitter->setPlacer(new osgParticle::SectorPlacer);
|
_emitter->setPlacer(new osgParticle::SectorPlacer);
|
||||||
_emitter->setShooter(new osgParticle::RadialShooter);
|
_emitter->setShooter(new osgParticle::RadialShooter);
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
#include <osgParticle/ModularEmitter>
|
#include <osgParticle/ModularEmitter>
|
||||||
#include <osgParticle/Emitter>
|
#include <osgParticle/Emitter>
|
||||||
|
#include <osg/Notify>
|
||||||
|
|
||||||
osgParticle::ModularEmitter::ModularEmitter()
|
osgParticle::ModularEmitter::ModularEmitter()
|
||||||
: Emitter(),
|
: Emitter(),
|
||||||
|
_numParticleToCreateMovementCompensationRatio(0.0f),
|
||||||
_counter(new RandomRateCounter),
|
_counter(new RandomRateCounter),
|
||||||
_placer(new PointPlacer),
|
_placer(new PointPlacer),
|
||||||
_shooter(new RadialShooter)
|
_shooter(new RadialShooter)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
osgParticle::ModularEmitter::ModularEmitter(const ModularEmitter& copy, const osg::CopyOp& copyop)
|
osgParticle::ModularEmitter::ModularEmitter(const ModularEmitter& copy, const osg::CopyOp& copyop):
|
||||||
: Emitter(copy, copyop),
|
Emitter(copy, copyop),
|
||||||
|
_numParticleToCreateMovementCompensationRatio(copy._numParticleToCreateMovementCompensationRatio),
|
||||||
_counter(static_cast<Counter *>(copyop(copy._counter.get()))),
|
_counter(static_cast<Counter *>(copyop(copy._counter.get()))),
|
||||||
_placer(static_cast<Placer *>(copyop(copy._placer.get()))),
|
_placer(static_cast<Placer *>(copyop(copy._placer.get()))),
|
||||||
_shooter(static_cast<Shooter *>(copyop(copy._shooter.get())))
|
_shooter(static_cast<Shooter *>(copyop(copy._shooter.get())))
|
||||||
@ -19,14 +22,61 @@ osgParticle::ModularEmitter::ModularEmitter(const ModularEmitter& copy, const os
|
|||||||
|
|
||||||
void osgParticle::ModularEmitter::emit(double dt)
|
void osgParticle::ModularEmitter::emit(double dt)
|
||||||
{
|
{
|
||||||
int n = _counter->numParticlesToCreate(dt);
|
if (getReferenceFrame() == RELATIVE_RF)
|
||||||
for (int i=0; i<n; ++i) {
|
{
|
||||||
Particle* P = getParticleSystem()->createParticle(getUseDefaultTemplate()? 0: &getParticleTemplate());
|
const osg::Matrix& ltw = getLocalToWorldMatrix();
|
||||||
if (P) {
|
const osg::Matrix& previous_ltw = getPreviousLocalToWorldMatrix();
|
||||||
_placer->place(P);
|
|
||||||
_shooter->shoot(P);
|
int n = _counter->numParticlesToCreate(dt);
|
||||||
if (getReferenceFrame() == RELATIVE_RF) {
|
|
||||||
P->transformPositionVelocity(getLocalToWorldMatrix());
|
if (_numParticleToCreateMovementCompensationRatio>0.0f)
|
||||||
|
{
|
||||||
|
// compute the distance moved between frames
|
||||||
|
const osg::Vec3 controlPosition = _placer->getControlPosition();
|
||||||
|
osg::Vec3 previousPosition = controlPosition * previous_ltw;
|
||||||
|
osg::Vec3 currentPosition = controlPosition * ltw;
|
||||||
|
float distance = (currentPosition-previousPosition).length();
|
||||||
|
|
||||||
|
float size = getUseDefaultTemplate() ?
|
||||||
|
getParticleSystem()->getDefaultParticleTemplate().getSizeRange().minimum :
|
||||||
|
getParticleTemplate().getSizeRange().minimum;
|
||||||
|
|
||||||
|
float num_extra_samples = _numParticleToCreateMovementCompensationRatio*distance/size;
|
||||||
|
float rounded_down = floor(num_extra_samples);
|
||||||
|
float remainder = num_extra_samples-rounded_down;
|
||||||
|
|
||||||
|
n = osg::maximum(n, int(rounded_down) + (((float) rand() < remainder * (float)RAND_MAX) ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<n; ++i)
|
||||||
|
{
|
||||||
|
Particle* P = getParticleSystem()->createParticle(getUseDefaultTemplate()? 0: &getParticleTemplate());
|
||||||
|
if (P)
|
||||||
|
{
|
||||||
|
_placer->place(P);
|
||||||
|
_shooter->shoot(P);
|
||||||
|
|
||||||
|
// now need to transform the position and velocity because we having a moving model.
|
||||||
|
float r = ((float)rand()/(float)RAND_MAX);
|
||||||
|
P->transformPositionVelocity(ltw, previous_ltw, r);
|
||||||
|
//P->transformPositionVelocity(ltw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
osg::notify(osg::NOTICE)<<"run out of particle"<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int n = _counter->numParticlesToCreate(dt);
|
||||||
|
for (int i=0; i<n; ++i)
|
||||||
|
{
|
||||||
|
Particle* P = getParticleSystem()->createParticle(getUseDefaultTemplate()? 0: &getParticleTemplate());
|
||||||
|
if (P)
|
||||||
|
{
|
||||||
|
_placer->place(P);
|
||||||
|
_shooter->shoot(P);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ osgParticle::ParticleProcessor::ParticleProcessor()
|
|||||||
_enabled(true),
|
_enabled(true),
|
||||||
_t0(-1),
|
_t0(-1),
|
||||||
_ps(0),
|
_ps(0),
|
||||||
|
_first_ltw_compute(true),
|
||||||
_need_ltw_matrix(false),
|
_need_ltw_matrix(false),
|
||||||
|
_first_wtl_compute(true),
|
||||||
_need_wtl_matrix(false),
|
_need_wtl_matrix(false),
|
||||||
_current_nodevisitor(0),
|
_current_nodevisitor(0),
|
||||||
_endless(true),
|
_endless(true),
|
||||||
@ -35,7 +37,9 @@ osgParticle::ParticleProcessor::ParticleProcessor(const ParticleProcessor& copy,
|
|||||||
_enabled(copy._enabled),
|
_enabled(copy._enabled),
|
||||||
_t0(copy._t0),
|
_t0(copy._t0),
|
||||||
_ps(static_cast<ParticleSystem* >(copyop(copy._ps.get()))),
|
_ps(static_cast<ParticleSystem* >(copyop(copy._ps.get()))),
|
||||||
|
_first_ltw_compute(copy._first_ltw_compute),
|
||||||
_need_ltw_matrix(copy._need_ltw_matrix),
|
_need_ltw_matrix(copy._need_ltw_matrix),
|
||||||
|
_first_wtl_compute(copy._first_wtl_compute),
|
||||||
_need_wtl_matrix(copy._need_wtl_matrix),
|
_need_wtl_matrix(copy._need_wtl_matrix),
|
||||||
_current_nodevisitor(0),
|
_current_nodevisitor(0),
|
||||||
_endless(copy._endless),
|
_endless(copy._endless),
|
||||||
|
@ -50,7 +50,7 @@ void SmokeEffect::setDefaults()
|
|||||||
|
|
||||||
// set up unit particle.
|
// set up unit particle.
|
||||||
_defaultParticleTemplate.setLifeTime(5.0*_scale);
|
_defaultParticleTemplate.setLifeTime(5.0*_scale);
|
||||||
_defaultParticleTemplate.setSizeRange(osgParticle::rangef(0.75f, 3.0f));
|
_defaultParticleTemplate.setSizeRange(osgParticle::rangef(0.75f, 2.0f));
|
||||||
_defaultParticleTemplate.setAlphaRange(osgParticle::rangef(0.1f, 1.0f));
|
_defaultParticleTemplate.setAlphaRange(osgParticle::rangef(0.1f, 1.0f));
|
||||||
_defaultParticleTemplate.setColorRange(osgParticle::rangev4(
|
_defaultParticleTemplate.setColorRange(osgParticle::rangev4(
|
||||||
osg::Vec4(1, 1.0f, 1.0f, 1.0f),
|
osg::Vec4(1, 1.0f, 1.0f, 1.0f),
|
||||||
@ -96,6 +96,7 @@ void SmokeEffect::setUpEmitterAndProgram()
|
|||||||
if (!_emitter)
|
if (!_emitter)
|
||||||
{
|
{
|
||||||
_emitter = new osgParticle::ModularEmitter;
|
_emitter = new osgParticle::ModularEmitter;
|
||||||
|
_emitter->setNumParticlesToCreateMovementCompenstationRatio(1.5f);
|
||||||
_emitter->setCounter(new osgParticle::RandomRateCounter);
|
_emitter->setCounter(new osgParticle::RandomRateCounter);
|
||||||
_emitter->setPlacer(new osgParticle::SectorPlacer);
|
_emitter->setPlacer(new osgParticle::SectorPlacer);
|
||||||
_emitter->setShooter(new osgParticle::RadialShooter);
|
_emitter->setShooter(new osgParticle::RadialShooter);
|
||||||
|
Loading…
Reference in New Issue
Block a user