Checked in osgParticle, writtten by Marco Jez.
This commit is contained in:
99
include/osgParticle/AccelOperator
Normal file
99
include/osgParticle/AccelOperator
Normal file
@@ -0,0 +1,99 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_ACCELOPERATOR_
|
||||
#define OSGPARTICLE_ACCELOPERATOR_ 1
|
||||
|
||||
#include <osgParticle/ModularProgram>
|
||||
#include <osgParticle/Operator>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** An operator class that applies a constant acceleration to the particles.
|
||||
*/
|
||||
class AccelOperator: public Operator {
|
||||
public:
|
||||
inline AccelOperator();
|
||||
inline AccelOperator(const AccelOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(AccelOperator);
|
||||
|
||||
/// Get the acceleration vector.
|
||||
inline const osg::Vec3 &getAcceleration() const;
|
||||
|
||||
/// Set the acceleration vector.
|
||||
inline void setAcceleration(const osg::Vec3 &v);
|
||||
|
||||
/** Quickly set the acceleration vector to the gravity on earth (0, 0, -9.81).
|
||||
The acceleration will be multiplied by the <CODE>scale</CODE> parameter.
|
||||
*/
|
||||
inline void setToGravity(float scale = 1);
|
||||
|
||||
/// Apply the acceleration to a particle. Do not call this method manually.
|
||||
inline void operate(Particle *P, double dt);
|
||||
|
||||
/// Perform some initializations. Do not call this method manually.
|
||||
inline void beginOperate(Program *prg);
|
||||
|
||||
protected:
|
||||
virtual ~AccelOperator() {}
|
||||
AccelOperator &operator=(const AccelOperator &) { return *this; }
|
||||
|
||||
private:
|
||||
osg::Vec3 accel_;
|
||||
osg::Vec3 xf_accel_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline AccelOperator::AccelOperator()
|
||||
: Operator(), accel_(0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
inline AccelOperator::AccelOperator(const AccelOperator ©, const osg::CopyOp ©op)
|
||||
: Operator(copy, copyop), accel_(copy.accel_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &AccelOperator::getAcceleration() const
|
||||
{
|
||||
return accel_;
|
||||
}
|
||||
|
||||
inline void AccelOperator::setAcceleration(const osg::Vec3 &v)
|
||||
{
|
||||
accel_ = v;
|
||||
}
|
||||
|
||||
inline void AccelOperator::setToGravity(float scale)
|
||||
{
|
||||
accel_.set(0, 0, -9.80665f * scale);
|
||||
}
|
||||
|
||||
inline void AccelOperator::operate(Particle *P, double dt)
|
||||
{
|
||||
P->addVelocity(xf_accel_ * dt);
|
||||
}
|
||||
|
||||
inline void AccelOperator::beginOperate(Program *prg)
|
||||
{
|
||||
if (prg->getReferenceFrame() == ModularProgram::RELATIVE_TO_PARENTS) {
|
||||
xf_accel_ = prg->rotateLocalToWorld(accel_);
|
||||
} else {
|
||||
xf_accel_ = accel_;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
74
include/osgParticle/CenteredPlacer
Normal file
74
include/osgParticle/CenteredPlacer
Normal file
@@ -0,0 +1,74 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_CENTEREDPLACER_
|
||||
#define OSGPARTICLE_CENTEREDPLACER_ 1
|
||||
|
||||
#include <osgParticle/Placer>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** An abstract placer base class for placers which need a <I>center point</I>.
|
||||
*/
|
||||
class CenteredPlacer: public Placer {
|
||||
public:
|
||||
inline CenteredPlacer();
|
||||
inline CenteredPlacer(const CenteredPlacer ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "CenteredPlacer"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Placer *>(obj) != 0; }
|
||||
|
||||
/// Get the center point.
|
||||
inline const osg::Vec3 &getCenter() const;
|
||||
|
||||
/// Set the center point.
|
||||
inline void setCenter(const osg::Vec3 &v);
|
||||
|
||||
/// Set the center point.
|
||||
inline void setCenter(float x, float y, float z);
|
||||
|
||||
protected:
|
||||
virtual ~CenteredPlacer() {}
|
||||
|
||||
private:
|
||||
osg::Vec3 center_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline CenteredPlacer::CenteredPlacer()
|
||||
: Placer(), center_(0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
inline CenteredPlacer::CenteredPlacer(const CenteredPlacer ©, const osg::CopyOp ©op)
|
||||
: Placer(copy, copyop), center_(copy.center_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &CenteredPlacer::getCenter() const
|
||||
{
|
||||
return center_;
|
||||
}
|
||||
|
||||
inline void CenteredPlacer::setCenter(const osg::Vec3 &v)
|
||||
{
|
||||
center_ = v;
|
||||
}
|
||||
|
||||
inline void CenteredPlacer::setCenter(float x, float y, float z)
|
||||
{
|
||||
center_.set(x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
44
include/osgParticle/Counter
Normal file
44
include/osgParticle/Counter
Normal file
@@ -0,0 +1,44 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_COUNTER_
|
||||
#define OSGPARTICLE_COUNTER_ 1
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
class Counter: public osg::Object {
|
||||
public:
|
||||
inline Counter();
|
||||
inline Counter(const Counter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "Counter"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Counter *>(obj) != 0; }
|
||||
|
||||
virtual int numParticlesToCreate(double dt) const = 0;
|
||||
|
||||
protected:
|
||||
~Counter() {}
|
||||
Counter &operator=(const Counter &) { return *this; }
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline Counter::Counter()
|
||||
: osg::Object()
|
||||
{
|
||||
}
|
||||
|
||||
inline Counter::Counter(const Counter ©, const osg::CopyOp ©op)
|
||||
: osg::Object(copy, copyop)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
96
include/osgParticle/Emitter
Normal file
96
include/osgParticle/Emitter
Normal file
@@ -0,0 +1,96 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_EMITTER_
|
||||
#define OSGPARTICLE_EMITTER_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/ParticleProcessor>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/CopyOp>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** An abstract base class for particle emitters.
|
||||
Descendant classes must override the <CODE>emit()</CODE> method to generate new particles by
|
||||
calling the <CODE>ParticleSystem::createParticle()</CODE> method on the particle system associated
|
||||
to the emitter.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT Emitter: public ParticleProcessor {
|
||||
public:
|
||||
Emitter();
|
||||
Emitter(const Emitter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "Emitter"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) { return dynamic_cast<const Emitter*>(obj) != 0; }
|
||||
virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } }
|
||||
|
||||
/// Get the particle template.
|
||||
inline const Particle &getParticleTemplate() const;
|
||||
|
||||
/// Set the particle template (particle is copied).
|
||||
inline void setParticleTemplate(const Particle &p);
|
||||
|
||||
/// Return whether the particle system's default template should be used.
|
||||
inline bool getUseDefaultTemplate() const;
|
||||
|
||||
/** Set whether the default particle template should be used.
|
||||
When this flag is true, the particle template is ignored, and the
|
||||
particle system's default template is used instead.
|
||||
*/
|
||||
inline void setUseDefaultTemplate(bool v);
|
||||
|
||||
protected:
|
||||
virtual ~Emitter() {}
|
||||
Emitter &operator=(const Emitter &) { return *this; }
|
||||
|
||||
inline void process(double dt);
|
||||
|
||||
virtual void emit(double dt) = 0;
|
||||
|
||||
private:
|
||||
bool usedeftemp_;
|
||||
Particle ptemp_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline const Particle &Emitter::getParticleTemplate() const
|
||||
{
|
||||
return ptemp_;
|
||||
}
|
||||
|
||||
inline void Emitter::setParticleTemplate(const Particle &p)
|
||||
{
|
||||
ptemp_ = p;
|
||||
usedeftemp_ = false;
|
||||
}
|
||||
|
||||
inline bool Emitter::getUseDefaultTemplate() const
|
||||
{
|
||||
return usedeftemp_;
|
||||
}
|
||||
|
||||
inline void Emitter::setUseDefaultTemplate(bool v)
|
||||
{
|
||||
usedeftemp_ = v;
|
||||
}
|
||||
|
||||
inline void Emitter::process(double dt)
|
||||
{
|
||||
emit(dt);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
30
include/osgParticle/Export
Normal file
30
include/osgParticle/Export
Normal file
@@ -0,0 +1,30 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_EXPORT_
|
||||
#define OSGPARTICLE_EXPORT_ 1
|
||||
|
||||
#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW32__))
|
||||
#pragma warning( disable : 4244 )
|
||||
#pragma warning( disable : 4251 )
|
||||
#pragma warning( disable : 4275 )
|
||||
#pragma warning( disable : 4786 )
|
||||
#pragma warning( disable : 4290 )
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined( __BCPLUSPLUS__) || defined( __MWERKS__)
|
||||
# ifdef OSGPARTICLE_LIBRARY
|
||||
# define OSGPARTICLE_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define OSGPARTICLE_EXPORT __declspec(dllimport)
|
||||
# endif /* OSGPARTICLE_LIBRARY */
|
||||
#else
|
||||
# define OSGPARTICLE_EXPORT
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
132
include/osgParticle/FluidFrictionOperator
Normal file
132
include/osgParticle/FluidFrictionOperator
Normal file
@@ -0,0 +1,132 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_FLUIDFRICTIONOPERATOR_
|
||||
#define OSGPARTICLE_FLUIDFRICTIONOPERATOR_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/Operator>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Math>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
class Particle;
|
||||
|
||||
/** An operator that simulates the friction of a fluid.
|
||||
By using this operator you can let the particles move in a fluid of a given <I>density</I>
|
||||
and <I>viscosity</I>. There are two functions to quickly setup the parameters for pure water
|
||||
and air. You can decide whether to compute the forces using the particle's physical
|
||||
radius or another value, by calling the <CODE>setOverrideRadius()</CODE> method.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT FluidFrictionOperator: public Operator {
|
||||
public:
|
||||
|
||||
FluidFrictionOperator();
|
||||
FluidFrictionOperator(const FluidFrictionOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(FluidFrictionOperator);
|
||||
|
||||
/// Get the density of the fluid.
|
||||
inline float getFluidDensity() const;
|
||||
|
||||
/// Set the density of the fluid.
|
||||
inline void setFluidDensity(float d);
|
||||
|
||||
/// Get the viscosity of the fluid.
|
||||
inline float getFluidViscosity() const;
|
||||
|
||||
/// Set the viscosity of the fluid.
|
||||
inline void setFluidViscosity(float v);
|
||||
|
||||
/// Get the overriden radius value.
|
||||
inline float getOverrideRadius() const;
|
||||
|
||||
/// Set the overriden radius value (pass 0 if you want to use particle's radius).
|
||||
inline void setOverrideRadius(float r);
|
||||
|
||||
/// Set the fluid parameters as for air (20<32>C temperature).
|
||||
inline void setFluidToAir();
|
||||
|
||||
/// Set the fluid parameters as for pure water (20<32>C temperature).
|
||||
inline void setFluidToWater();
|
||||
|
||||
/// Apply the friction forces to a particle. Do not call this method manually.
|
||||
void operate(Particle *P, double dt);
|
||||
|
||||
/// Perform some initializations. Do not call this method manually.
|
||||
inline void beginOperate(Program *prg);
|
||||
|
||||
protected:
|
||||
virtual ~FluidFrictionOperator() {}
|
||||
FluidFrictionOperator &operator=(const FluidFrictionOperator &) { return *this; }
|
||||
|
||||
private:
|
||||
float A_;
|
||||
float B_;
|
||||
float density_;
|
||||
float viscosity_;
|
||||
float ovr_rad_;
|
||||
Program *current_program_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline float FluidFrictionOperator::getFluidDensity() const
|
||||
{
|
||||
return density_;
|
||||
}
|
||||
|
||||
inline float FluidFrictionOperator::getFluidViscosity() const
|
||||
{
|
||||
return viscosity_;
|
||||
}
|
||||
|
||||
inline void FluidFrictionOperator::setFluidDensity(float d)
|
||||
{
|
||||
density_ = d;
|
||||
B_ = 0.2f * osg::PI * density_;
|
||||
}
|
||||
|
||||
inline void FluidFrictionOperator::setFluidViscosity(float v)
|
||||
{
|
||||
viscosity_ = v;
|
||||
A_ = 6 * osg::PI * viscosity_;
|
||||
}
|
||||
|
||||
inline void FluidFrictionOperator::setFluidToAir()
|
||||
{
|
||||
setFluidViscosity(1.8e-5f);
|
||||
setFluidDensity(1.2929f);
|
||||
}
|
||||
|
||||
inline void FluidFrictionOperator::setFluidToWater()
|
||||
{
|
||||
setFluidViscosity(1.002e-3f);
|
||||
setFluidDensity(1.0f);
|
||||
}
|
||||
|
||||
inline float FluidFrictionOperator::getOverrideRadius() const
|
||||
{
|
||||
return ovr_rad_;
|
||||
}
|
||||
|
||||
inline void FluidFrictionOperator::setOverrideRadius(float r)
|
||||
{
|
||||
ovr_rad_ = r;
|
||||
}
|
||||
|
||||
inline void FluidFrictionOperator::beginOperate(Program *prg)
|
||||
{
|
||||
current_program_ = prg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
89
include/osgParticle/ForceOperator
Normal file
89
include/osgParticle/ForceOperator
Normal file
@@ -0,0 +1,89 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_FORCEOPERATOR_
|
||||
#define OSGPARTICLE_FORCEOPERATOR_ 1
|
||||
|
||||
#include <osgParticle/ModularProgram>
|
||||
#include <osgParticle/Operator>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** An operator that applies a constant force to the particles.
|
||||
Remember that if the mass of particles is expressed in <U>kg</U> and the lengths are
|
||||
expressed in <U>meters</U>, then the force should be expressed in <U>Newtons</U>.
|
||||
*/
|
||||
class ForceOperator: public Operator {
|
||||
public:
|
||||
inline ForceOperator();
|
||||
inline ForceOperator(const ForceOperator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(ForceOperator);
|
||||
|
||||
/// Get the force vector.
|
||||
inline const osg::Vec3 &getForce() const;
|
||||
|
||||
/// Set the force vector.
|
||||
inline void setForce(const osg::Vec3 &f);
|
||||
|
||||
/// Apply the force to a particle. Do not call this method manually.
|
||||
inline void operate(Particle *P, double dt);
|
||||
|
||||
/// Perform some initialization. Do not call this method manually.
|
||||
inline void beginOperate(Program *prg);
|
||||
|
||||
protected:
|
||||
virtual ~ForceOperator() {};
|
||||
ForceOperator &operator=(const ForceOperator &) { return *this; }
|
||||
|
||||
private:
|
||||
osg::Vec3 force_;
|
||||
osg::Vec3 xf_force_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline ForceOperator::ForceOperator()
|
||||
: Operator(), force_(0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
inline ForceOperator::ForceOperator(const ForceOperator ©, const osg::CopyOp ©op)
|
||||
: Operator(copy, copyop), force_(copy.force_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &ForceOperator::getForce() const
|
||||
{
|
||||
return force_;
|
||||
}
|
||||
|
||||
inline void ForceOperator::setForce(const osg::Vec3 &v)
|
||||
{
|
||||
force_ = v;
|
||||
}
|
||||
|
||||
inline void ForceOperator::operate(Particle *P, double dt)
|
||||
{
|
||||
P->addVelocity(xf_force_ * (P->getMassInv() * dt));
|
||||
}
|
||||
|
||||
inline void ForceOperator::beginOperate(Program *prg)
|
||||
{
|
||||
if (prg->getReferenceFrame() == ModularProgram::RELATIVE_TO_PARENTS) {
|
||||
xf_force_ = prg->rotateLocalToWorld(force_);
|
||||
} else {
|
||||
xf_force_ = force_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
77
include/osgParticle/Interpolator
Normal file
77
include/osgParticle/Interpolator
Normal file
@@ -0,0 +1,77 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_INTERPOLATOR_
|
||||
#define OSGPARTICLE_INTERPOLATOR_
|
||||
|
||||
#include <osgParticle/range>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/// An abstract base class for implementing interpolators.
|
||||
class Interpolator : public osg::Object {
|
||||
public:
|
||||
Interpolator()
|
||||
: osg::Object() {}
|
||||
|
||||
Interpolator(const Interpolator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY)
|
||||
: osg::Object(copy, copyop) {}
|
||||
|
||||
virtual const char *className() const { return "Interpolator"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Interpolator *>(obj) != 0; }
|
||||
|
||||
/// Interpolate between floats. Must be overriden in descendant classes.
|
||||
virtual float interpolate(float t, float y1, float y2) const = 0;
|
||||
|
||||
/// Interpolate between 2-dimensional vectors. Default behavior is to interpolate each component separately.
|
||||
virtual osg::Vec2 interpolate(float t, const osg::Vec2 &y1, const osg::Vec2 &y2) const
|
||||
{
|
||||
return osg::Vec2(
|
||||
interpolate(t, y1.x(), y2.x()),
|
||||
interpolate(t, y1.y(), y2.y())
|
||||
);
|
||||
}
|
||||
|
||||
/// Interpolate between 3-dimensional vectors. Default behavior is to interpolate each component separately.
|
||||
virtual osg::Vec3 interpolate(float t, const osg::Vec3 &y1, const osg::Vec3 &y2) const
|
||||
{
|
||||
return osg::Vec3(
|
||||
interpolate(t, y1.x(), y2.x()),
|
||||
interpolate(t, y1.y(), y2.y()),
|
||||
interpolate(t, y1.z(), y2.z())
|
||||
);
|
||||
}
|
||||
|
||||
/// Interpolate between 4-dimensional vectors. Default behavior is to interpolate each component separately.
|
||||
virtual osg::Vec4 interpolate(float t, const osg::Vec4 &y1, const osg::Vec4 &y2) const
|
||||
{
|
||||
return osg::Vec4(
|
||||
interpolate(t, y1.x(), y2.x()),
|
||||
interpolate(t, y1.y(), y2.y()),
|
||||
interpolate(t, y1.z(), y2.z()),
|
||||
interpolate(t, y1.w(), y2.w())
|
||||
);
|
||||
}
|
||||
|
||||
template<class T_>
|
||||
T_ interpolate(float t, const range<T_> &r) const
|
||||
{
|
||||
return interpolate(t, r.min, r.max);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~Interpolator() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
41
include/osgParticle/LinearInterpolator
Normal file
41
include/osgParticle/LinearInterpolator
Normal file
@@ -0,0 +1,41 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_LINEARINTERPOLATOR_
|
||||
#define OSGPARTICLE_LINEARINTERPOLATOR_
|
||||
|
||||
#include <osgParticle/Interpolator>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/// A linear interpolator.
|
||||
class LinearInterpolator: public Interpolator {
|
||||
public:
|
||||
LinearInterpolator()
|
||||
: Interpolator() {}
|
||||
|
||||
LinearInterpolator(const LinearInterpolator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY)
|
||||
: Interpolator(copy, copyop) {}
|
||||
|
||||
META_Object(LinearInterpolator);
|
||||
|
||||
virtual float interpolate(float t, float y1, float y2) const
|
||||
{
|
||||
return y1 + (y2 - y1) * t;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~LinearInterpolator() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
130
include/osgParticle/ModularEmitter
Normal file
130
include/osgParticle/ModularEmitter
Normal file
@@ -0,0 +1,130 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_MODULAREMITTER_
|
||||
#define OSGPARTICLE_MODULAREMITTER_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/Emitter>
|
||||
#include <osgParticle/Particle>
|
||||
#include <osgParticle/RandomRateCounter>
|
||||
#include <osgParticle/Placer>
|
||||
#include <osgParticle/PointPlacer>
|
||||
#include <osgParticle/Shooter>
|
||||
#include <osgParticle/RadialShooter>
|
||||
#include <osgParticle/ParticleSystem>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** An emitter class that holds three objects to control the creation of particles.
|
||||
These objects are a <I>counter</I>, a <I>placer</I> and a <I>shooter</I>.
|
||||
The counter controls the number of particles to be emitted at each frame;
|
||||
the placer must initialize the particle's position vector, while the shooter initializes
|
||||
its velocity vector.
|
||||
You can use the predefined counter/placer/shooter classes, or you can create your own.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT ModularEmitter: public Emitter {
|
||||
public:
|
||||
ModularEmitter();
|
||||
ModularEmitter(const ModularEmitter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Node(ModularEmitter);
|
||||
|
||||
/// Get the counter object.
|
||||
inline Counter *getCounter();
|
||||
|
||||
/// Get the const Counter object.
|
||||
inline const Counter *getCounter() const;
|
||||
|
||||
/// Set the Counter object.
|
||||
inline void setCounter(Counter *c);
|
||||
|
||||
/// Get the Placer object.
|
||||
inline Placer *getPlacer();
|
||||
|
||||
/// Get the const Placer object.
|
||||
inline const Placer *getPlacer() const;
|
||||
|
||||
/// Set the Placer object.
|
||||
inline void setPlacer(Placer *p);
|
||||
|
||||
/// Get the Shooter object.
|
||||
inline Shooter *getShooter();
|
||||
|
||||
/// Get the const Shooter object.
|
||||
inline const Shooter *getShooter() const;
|
||||
|
||||
/// Set the Shooter object.
|
||||
inline void setShooter(Shooter *s);
|
||||
|
||||
protected:
|
||||
virtual ~ModularEmitter() {}
|
||||
ModularEmitter &operator=(const ModularEmitter &) { return *this; }
|
||||
|
||||
void emit(double dt);
|
||||
|
||||
private:
|
||||
osg::ref_ptr<Counter> counter_;
|
||||
osg::ref_ptr<Placer> placer_;
|
||||
osg::ref_ptr<Shooter> shooter_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline Counter *ModularEmitter::getCounter()
|
||||
{
|
||||
return counter_.get();
|
||||
}
|
||||
|
||||
inline const Counter *ModularEmitter::getCounter() const
|
||||
{
|
||||
return counter_.get();
|
||||
}
|
||||
|
||||
inline void ModularEmitter::setCounter(Counter *c)
|
||||
{
|
||||
counter_ = c;
|
||||
}
|
||||
|
||||
inline Placer *ModularEmitter::getPlacer()
|
||||
{
|
||||
return placer_.get();
|
||||
}
|
||||
|
||||
inline const Placer *ModularEmitter::getPlacer() const
|
||||
{
|
||||
return placer_.get();
|
||||
}
|
||||
|
||||
inline void ModularEmitter::setPlacer(Placer *p)
|
||||
{
|
||||
placer_ = p;
|
||||
}
|
||||
|
||||
inline Shooter *ModularEmitter::getShooter()
|
||||
{
|
||||
return shooter_.get();
|
||||
}
|
||||
|
||||
inline const Shooter *ModularEmitter::getShooter() const
|
||||
{
|
||||
return shooter_.get();
|
||||
}
|
||||
|
||||
inline void ModularEmitter::setShooter(Shooter *s)
|
||||
{
|
||||
shooter_ = s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
90
include/osgParticle/ModularProgram
Normal file
90
include/osgParticle/ModularProgram
Normal file
@@ -0,0 +1,90 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_MODULARPROGRAM_
|
||||
#define OSGPARTICLE_MODULARPROGRAM_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/Program>
|
||||
#include <osgParticle/Operator>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** A program class for performing operations on particles using a sequence of <I>operators</I>.
|
||||
To use a <CODE>ModularProgram</CODE> you have to create some <CODE>Operator</CODE> objects and
|
||||
add them to the program.
|
||||
All operators will be applied to each particle in the same order they've been added to the program.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT ModularProgram: public Program {
|
||||
public:
|
||||
ModularProgram();
|
||||
ModularProgram(const ModularProgram ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Node(ModularProgram);
|
||||
|
||||
/// Get the number of operators.
|
||||
inline int numOperators() const;
|
||||
|
||||
/// Add an operator to the list.
|
||||
inline void addOperator(Operator *o);
|
||||
|
||||
/// Get a pointer to an operator in the list.
|
||||
inline Operator *getOperator(int i);
|
||||
|
||||
/// Get a const pointer to an operator in the list.
|
||||
inline const Operator *getOperator(int i) const;
|
||||
|
||||
/// Remove an operator from the list.
|
||||
inline void removeOperator(int i);
|
||||
|
||||
protected:
|
||||
virtual ~ModularProgram() {}
|
||||
ModularProgram &operator=(const ModularProgram &) { return *this; }
|
||||
|
||||
void execute(double dt);
|
||||
|
||||
private:
|
||||
typedef std::vector<osg::ref_ptr<Operator> > Operator_vector;
|
||||
|
||||
Operator_vector operators_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline int ModularProgram::numOperators() const
|
||||
{
|
||||
return static_cast<int>(operators_.size());
|
||||
}
|
||||
|
||||
inline void ModularProgram::addOperator(Operator *o)
|
||||
{
|
||||
operators_.push_back(o);
|
||||
}
|
||||
|
||||
inline Operator *ModularProgram::getOperator(int i)
|
||||
{
|
||||
return operators_[i].get();
|
||||
}
|
||||
|
||||
inline const Operator *ModularProgram::getOperator(int i) const
|
||||
{
|
||||
return operators_[i].get();
|
||||
}
|
||||
|
||||
inline void ModularProgram::removeOperator(int i)
|
||||
{
|
||||
operators_.erase(operators_.begin()+i);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
119
include/osgParticle/MultiSegmentPlacer
Normal file
119
include/osgParticle/MultiSegmentPlacer
Normal file
@@ -0,0 +1,119 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_MULTISEGMENTPLACER_
|
||||
#define OSGPARTICLE_MULTISEGMENTPLACER_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/Placer>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
|
||||
namespace osgParticle {
|
||||
|
||||
/** A polyline-shaped particle placer.
|
||||
This placer class sets the position of incoming particles by choosing a random point on the
|
||||
specified sequence of connected segments.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT MultiSegmentPlacer: public Placer {
|
||||
public:
|
||||
MultiSegmentPlacer();
|
||||
MultiSegmentPlacer(const MultiSegmentPlacer ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(MultiSegmentPlacer);
|
||||
|
||||
/// Get the number of vertices which define the segments.
|
||||
inline int numVertices() const;
|
||||
|
||||
/// Get a vertex.
|
||||
inline const osg::Vec3 &getVertex(int i) const;
|
||||
|
||||
/// Set a vertex.
|
||||
inline void setVertex(int i, const osg::Vec3 &v);
|
||||
|
||||
/// Set a vertex.
|
||||
inline void setVertex(int i, float x, float y, float z);
|
||||
|
||||
/// Add a vertex.
|
||||
inline void addVertex(const osg::Vec3 &v);
|
||||
|
||||
/// Add a vertex.
|
||||
inline void addVertex(float x, float y, float z);
|
||||
|
||||
/// Remove a vertex.
|
||||
inline void removeVertex(int i);
|
||||
|
||||
/// Place a partice. Called automatically by <CODE>ModularEmitter</CODE>, do not call this method manually.
|
||||
void place(Particle *P) const;
|
||||
|
||||
protected:
|
||||
virtual ~MultiSegmentPlacer() {}
|
||||
MultiSegmentPlacer &operator=(const MultiSegmentPlacer &) { return *this; }
|
||||
|
||||
private:
|
||||
typedef std::pair<osg::Vec3, float> Vertex_data;
|
||||
typedef std::vector<Vertex_data> Vertex_vector;
|
||||
|
||||
Vertex_vector vx_;
|
||||
float total_length_;
|
||||
|
||||
void recompute_length();
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
|
||||
inline int MultiSegmentPlacer::numVertices() const
|
||||
{
|
||||
return static_cast<int>(vx_.size());
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &MultiSegmentPlacer::getVertex(int i) const
|
||||
{
|
||||
return vx_[i].first;
|
||||
}
|
||||
|
||||
inline void MultiSegmentPlacer::setVertex(int i, const osg::Vec3 &v)
|
||||
{
|
||||
vx_[i].first = v;
|
||||
recompute_length();
|
||||
}
|
||||
|
||||
inline void MultiSegmentPlacer::setVertex(int i, float x, float y, float z)
|
||||
{
|
||||
vx_[i].first.set(x, y, z);
|
||||
recompute_length();
|
||||
}
|
||||
|
||||
inline void MultiSegmentPlacer::addVertex(const osg::Vec3 &v)
|
||||
{
|
||||
float l = 0;
|
||||
if (vx_.size() > 0) {
|
||||
l = (v - vx_.back().first).length();
|
||||
}
|
||||
total_length_ += l;
|
||||
vx_.push_back(std::make_pair(v, total_length_));
|
||||
}
|
||||
|
||||
inline void MultiSegmentPlacer::addVertex(float x, float y, float z)
|
||||
{
|
||||
addVertex(osg::Vec3(x, y, z));
|
||||
}
|
||||
|
||||
inline void MultiSegmentPlacer::removeVertex(int i)
|
||||
{
|
||||
vx_.erase(vx_.begin()+i);
|
||||
recompute_length();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
91
include/osgParticle/Operator
Normal file
91
include/osgParticle/Operator
Normal file
@@ -0,0 +1,91 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_OPERATOR_
|
||||
#define OSGPARTICLE_OPERATOR_ 1
|
||||
|
||||
#include <osgParticle/Program>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Matrix>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
// forward declaration to avoid including the whole header file
|
||||
class Particle;
|
||||
|
||||
/** An abstract base class used by <CODE>ModularProgram</CODE> to perform operations on particles before they are updated.
|
||||
To implement a new operator, derive from this class and override the <CODE>operate()</CODE> method.
|
||||
You should also override the <CODE>beginOperate()</CODE> method to query the calling program for the reference frame
|
||||
used, and initialize the right transformations if needed.
|
||||
*/
|
||||
class Operator: public osg::Object {
|
||||
public:
|
||||
inline Operator();
|
||||
inline Operator(const Operator ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "Operator"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Operator *>(obj) != 0; }
|
||||
|
||||
/// Get whether this operator is enabled.
|
||||
inline bool isEnabled() const;
|
||||
|
||||
/// Enable or disable this operator.
|
||||
inline void setEnabled(bool v);
|
||||
|
||||
/** Do something on a particle.
|
||||
This method is called by <CODE>ModularProgram</CODE> objects to perform some operations
|
||||
on the particles. You must override it in descendant classes. Common operations
|
||||
consist of modifying the particle's velocity vector. The <CODE>dt</CODE> parameter is
|
||||
the time elapsed from last operation.
|
||||
*/
|
||||
virtual void operate(Particle *P, double dt) = 0;
|
||||
|
||||
/** Do something before processing particles via the <CODE>operate()</CODE> method.
|
||||
Overriding this method could be necessary to query the calling <CODE>Program</CODE> object
|
||||
for the current reference frame. If the reference frame is RELATIVE_TO_PARENTS, then your
|
||||
class should prepare itself to do all operations in local coordinates.
|
||||
*/
|
||||
virtual void beginOperate(Program *) {}
|
||||
|
||||
/// Do something after all particles have been processed.
|
||||
virtual void endOperate() {}
|
||||
|
||||
protected:
|
||||
virtual ~Operator() {}
|
||||
Operator &operator=(const Operator &) { return *this; }
|
||||
|
||||
private:
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline Operator::Operator()
|
||||
: osg::Object(), enabled_(true)
|
||||
{
|
||||
}
|
||||
|
||||
inline Operator::Operator(const Operator ©, const osg::CopyOp ©op)
|
||||
: osg::Object(copy, copyop), enabled_(copy.enabled_)
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Operator::isEnabled() const
|
||||
{
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
inline void Operator::setEnabled(bool v)
|
||||
{
|
||||
enabled_ = v;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
399
include/osgParticle/Particle
Normal file
399
include/osgParticle/Particle
Normal file
@@ -0,0 +1,399 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_PARTICLE_
|
||||
#define OSGPARTICLE_PARTICLE_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/Interpolator>
|
||||
#include <osgParticle/range>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/GL>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** Implementation of a <B>particle</B>.
|
||||
Objects of this class are particles, they have some graphical properties
|
||||
and some physical properties. Particles are created by emitters and then placed
|
||||
into Particle Systems, where they live and get updated at each frame.
|
||||
Particles can either live forever (lifeTime < 0), or die after a specified
|
||||
time (lifeTime >= 0). For each property which is defined as a range of values, a
|
||||
"current" value will be evaluated at each frame by interpolating the <I>min</I>
|
||||
and <I>max</I> values so that <I>curr_value = min</I> when <I>t == 0</I>, and
|
||||
<I>curr_value = max</I> when <I>t == lifeTime</I>.
|
||||
You may customize the interpolator objects to achieve any kind of transition.
|
||||
If you want the particle to live forever, set its lifetime to any value <= 0;
|
||||
in that case, no interpolation is done to compute real-time properties, and only
|
||||
minimum values are used.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT Particle {
|
||||
public:
|
||||
|
||||
enum Shape {
|
||||
POINT, // uses GL_POINTS as primitive
|
||||
QUAD, // uses GL_QUADS as primitive
|
||||
QUAD_TRIANGLESTRIP, // uses GL_TRIANGLE_STRIP as primitive, but each particle needs a glBegin/glEnd pair
|
||||
HEXAGON // may save some filling time, but uses more triangles
|
||||
};
|
||||
|
||||
Particle();
|
||||
|
||||
/// Get the shape of the particle.
|
||||
inline Shape getShape() const;
|
||||
|
||||
/// Set the shape of the particle.
|
||||
inline void setShape(Shape s);
|
||||
|
||||
/// Get whether the particle is still alive.
|
||||
inline bool isAlive() const;
|
||||
|
||||
/// Get the life time of the particle (in seconds).
|
||||
inline double getLifeTime() const;
|
||||
|
||||
/// Get the age of the particle (in seconds).
|
||||
inline double getAge() const;
|
||||
|
||||
/// Get the minimum and maximum values for polygon size.
|
||||
inline const rangef &getSizeRange() const;
|
||||
|
||||
/// Get the minimum and maximum values for alpha.
|
||||
inline const rangef &getAlphaRange() const;
|
||||
|
||||
/// Get the minimum and maximum values for color.
|
||||
inline const rangev4 &getColorRange() const;
|
||||
|
||||
/// Get the interpolator for computing the size of polygons.
|
||||
inline const Interpolator *getSizeInterpolator() const;
|
||||
|
||||
/// Get the interpolator for computing alpha values.
|
||||
inline const Interpolator *getAlphaInterpolator() const;
|
||||
|
||||
/// Get the interpolator for computing color values.
|
||||
inline const Interpolator *getColorInterpolator() const;
|
||||
|
||||
/** Get the physical radius of the particle.
|
||||
For built-in operators to work correctly, lengths must be expressed in meters.
|
||||
*/
|
||||
inline float getRadius() const;
|
||||
|
||||
/** Get the mass of the particle.
|
||||
For built-in operators to work correctly, remember that the mass is expressed in kg.
|
||||
*/
|
||||
inline float getMass() const;
|
||||
|
||||
/// Get <CODE>1 / getMass()</CODE>.
|
||||
inline float getMassInv() const;
|
||||
|
||||
/// Get the position vector.
|
||||
inline const osg::Vec3 &getPosition() const;
|
||||
|
||||
/** Get the velocity vector.
|
||||
For built-in operators to work correctly, remember that velocity components are expressed
|
||||
in meters per second.
|
||||
*/
|
||||
inline const osg::Vec3 &getVelocity() const;
|
||||
|
||||
/// Get the previous position (the position before last update).
|
||||
inline const osg::Vec3 &getPreviousPosition() const;
|
||||
|
||||
/** Kill the particle on next update
|
||||
NOTE: after calling this function, the <CODE>isAlive()</CODE> method will still
|
||||
return true until the particle is updated again.
|
||||
*/
|
||||
inline void kill();
|
||||
|
||||
/// Set the life time of the particle.
|
||||
inline void setLifeTime(double t);
|
||||
|
||||
/// Set the minimum and maximum values for polygon size.
|
||||
inline void setSizeRange(const rangef &r);
|
||||
|
||||
/// Set the minimum and maximum values for alpha.
|
||||
inline void setAlphaRange(const rangef &r);
|
||||
|
||||
/// Set the minimum and maximum values for color.
|
||||
inline void setColorRange(const rangev4 &r);
|
||||
|
||||
/// Set the interpolator for computing size values.
|
||||
inline void setSizeInterpolator(Interpolator *ri);
|
||||
|
||||
/// Set the interpolator for computing alpha values.
|
||||
inline void setAlphaInterpolator(Interpolator *ai);
|
||||
|
||||
/// Set the interpolator for computing color values.
|
||||
inline void setColorInterpolator(Interpolator *ci);
|
||||
|
||||
/** Set the physical radius of the particle.
|
||||
For built-in operators to work correctly, lengths must be expressed in meters.
|
||||
*/
|
||||
inline void setRadius(float r);
|
||||
|
||||
/** Set the mass of the particle.
|
||||
For built-in operators to work correctly, remember that the mass is expressed in kg.
|
||||
*/
|
||||
inline void setMass(float m);
|
||||
|
||||
/// Set the position vector.
|
||||
inline void setPosition(const osg::Vec3 &p);
|
||||
|
||||
/** Set the velocity vector.
|
||||
For built-in operators to work correctly, remember that velocity components are expressed
|
||||
in meters per second.
|
||||
*/
|
||||
inline void setVelocity(const osg::Vec3 &v);
|
||||
|
||||
/// Add a vector to the velocity vector.
|
||||
inline void addVelocity(const osg::Vec3 &dv);
|
||||
|
||||
/// Transform position and velocity vectors by a matrix.
|
||||
inline void transformPositionVelocity(const osg::Matrix &xform);
|
||||
|
||||
/** Update the particle (don't call this method manually).
|
||||
This method is called automatically by <CODE>ParticleSystem::update()</CODE>; it
|
||||
updates the graphical properties of the particle for the current time,
|
||||
checks whether the particle is still alive, and then updates its position
|
||||
by computing <I>P = P + V * dt</I> (where <I>P</I> is the position and <I>V</I> is the velocity).
|
||||
*/
|
||||
bool update(double dt);
|
||||
|
||||
/// Perform some pre-rendering tasks. Called automatically by particle systems.
|
||||
inline void beginRender();
|
||||
|
||||
/// Render the particle. Called automatically by particle systems.
|
||||
void render(const osg::Matrix &modelview, float scale = 1.0f) const;
|
||||
|
||||
/// Perform some post-rendering tasks. Called automatically by particle systems.
|
||||
inline void endRender();
|
||||
|
||||
private:
|
||||
Shape shape_;
|
||||
|
||||
rangef sr_;
|
||||
rangef ar_;
|
||||
rangev4 cr_;
|
||||
|
||||
osg::ref_ptr<Interpolator> si_;
|
||||
osg::ref_ptr<Interpolator> ai_;
|
||||
osg::ref_ptr<Interpolator> ci_;
|
||||
|
||||
bool alive_;
|
||||
bool mustdie_;
|
||||
double lifetime_;
|
||||
|
||||
float radius_;
|
||||
float mass_;
|
||||
float massinv_;
|
||||
osg::Vec3 prev_pos_;
|
||||
osg::Vec3 position_;
|
||||
osg::Vec3 velocity_;
|
||||
|
||||
double t0_;
|
||||
|
||||
float current_size_;
|
||||
float current_alpha_;
|
||||
osg::Vec4 current_color_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline Particle::Shape Particle::getShape() const
|
||||
{
|
||||
return shape_;
|
||||
}
|
||||
|
||||
inline void Particle::setShape(Shape s)
|
||||
{
|
||||
shape_ = s;
|
||||
}
|
||||
|
||||
inline bool Particle::isAlive() const
|
||||
{
|
||||
return alive_;
|
||||
}
|
||||
|
||||
inline double Particle::getLifeTime() const
|
||||
{
|
||||
return lifetime_;
|
||||
}
|
||||
|
||||
inline double Particle::getAge() const
|
||||
{
|
||||
return t0_;
|
||||
}
|
||||
|
||||
inline float Particle::getRadius() const
|
||||
{
|
||||
return radius_;
|
||||
}
|
||||
|
||||
inline void Particle::setRadius(float r)
|
||||
{
|
||||
radius_ = r;
|
||||
}
|
||||
|
||||
inline const rangef &Particle::getSizeRange() const
|
||||
{
|
||||
return sr_;
|
||||
}
|
||||
|
||||
inline const rangef &Particle::getAlphaRange() const
|
||||
{
|
||||
return ar_;
|
||||
}
|
||||
|
||||
inline const rangev4 &Particle::getColorRange() const
|
||||
{
|
||||
return cr_;
|
||||
}
|
||||
|
||||
inline const Interpolator *Particle::getSizeInterpolator() const
|
||||
{
|
||||
return si_.get();
|
||||
}
|
||||
|
||||
inline const Interpolator *Particle::getAlphaInterpolator() const
|
||||
{
|
||||
return ai_.get();
|
||||
}
|
||||
|
||||
inline const Interpolator *Particle::getColorInterpolator() const
|
||||
{
|
||||
return ci_.get();
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &Particle::getPosition() const
|
||||
{
|
||||
return position_;
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &Particle::getVelocity() const
|
||||
{
|
||||
return velocity_;
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &Particle::getPreviousPosition() const
|
||||
{
|
||||
return prev_pos_;
|
||||
}
|
||||
|
||||
inline void Particle::kill()
|
||||
{
|
||||
mustdie_ = true;
|
||||
}
|
||||
|
||||
inline void Particle::setLifeTime(double t)
|
||||
{
|
||||
lifetime_ = t;
|
||||
}
|
||||
|
||||
inline void Particle::setSizeRange(const rangef &r)
|
||||
{
|
||||
sr_ = r;
|
||||
}
|
||||
|
||||
inline void Particle::setAlphaRange(const rangef &r)
|
||||
{
|
||||
ar_ = r;
|
||||
}
|
||||
|
||||
inline void Particle::setColorRange(const rangev4 &r)
|
||||
{
|
||||
cr_ = r;
|
||||
}
|
||||
|
||||
inline void Particle::setSizeInterpolator(Interpolator *ri)
|
||||
{
|
||||
si_ = ri;
|
||||
}
|
||||
|
||||
inline void Particle::setAlphaInterpolator(Interpolator *ai)
|
||||
{
|
||||
ai_ = ai;
|
||||
}
|
||||
|
||||
inline void Particle::setColorInterpolator(Interpolator *ci)
|
||||
{
|
||||
ci_ = ci;
|
||||
}
|
||||
|
||||
inline void Particle::setPosition(const osg::Vec3 &p)
|
||||
{
|
||||
position_ = p;
|
||||
}
|
||||
|
||||
inline void Particle::setVelocity(const osg::Vec3 &v)
|
||||
{
|
||||
velocity_ = v;
|
||||
}
|
||||
|
||||
inline void Particle::addVelocity(const osg::Vec3 &v)
|
||||
{
|
||||
velocity_ += v;
|
||||
}
|
||||
|
||||
inline void Particle::transformPositionVelocity(const osg::Matrix &xform)
|
||||
{
|
||||
// this should be optimized!
|
||||
|
||||
osg::Vec3 p1 = position_ + velocity_;
|
||||
|
||||
position_ = xform.preMult(position_);
|
||||
p1 = xform.preMult(p1);
|
||||
|
||||
velocity_ = p1 - position_;
|
||||
}
|
||||
|
||||
inline float Particle::getMass() const
|
||||
{
|
||||
return mass_;
|
||||
}
|
||||
|
||||
inline float Particle::getMassInv() const
|
||||
{
|
||||
return massinv_;
|
||||
}
|
||||
|
||||
inline void Particle::setMass(float m)
|
||||
{
|
||||
mass_ = m;
|
||||
massinv_ = 1 / m;
|
||||
}
|
||||
|
||||
inline void Particle::beginRender()
|
||||
{
|
||||
switch (shape_)
|
||||
{
|
||||
case POINT:
|
||||
glBegin(GL_POINTS);
|
||||
break;
|
||||
case QUAD:
|
||||
glBegin(GL_QUADS);
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
inline void Particle::endRender()
|
||||
{
|
||||
switch (shape_)
|
||||
{
|
||||
case POINT:
|
||||
case QUAD:
|
||||
glEnd();
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
195
include/osgParticle/ParticleProcessor
Normal file
195
include/osgParticle/ParticleProcessor
Normal file
@@ -0,0 +1,195 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_PARTICLEPROCESSOR_
|
||||
#define OSGPARTICLE_PARTICLEPROCESSOR_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/ParticleSystem>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Object>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Matrix>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** A common base interface for those classes which need to do something on particles. Such classes
|
||||
are, for example, <CODE>Emitter</CODE> (particle generation) and <CODE>Program</CODE> (particle animation).
|
||||
This class holds some properties, like a <I>reference frame</I> and a reference to a <CODE>ParticleSystem<CODE>;
|
||||
descendant classes should process the particles taking into account the reference frame, computing the right
|
||||
transformations when needed.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT ParticleProcessor: public osg::Node {
|
||||
public:
|
||||
|
||||
enum ReferenceFrame {
|
||||
RELATIVE_TO_PARENTS,
|
||||
RELATIVE_TO_ABSOLUTE
|
||||
};
|
||||
|
||||
ParticleProcessor();
|
||||
ParticleProcessor(const ParticleProcessor ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "ParticleProcessor"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) { return dynamic_cast<const ParticleProcessor*>(obj) != 0; }
|
||||
virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } }
|
||||
|
||||
/// Get the reference frame.
|
||||
inline ReferenceFrame getReferenceFrame() const;
|
||||
|
||||
/// Set the reference frame.
|
||||
inline void setReferenceFrame(ReferenceFrame rf);
|
||||
|
||||
/// Get whether this processor is enabled or not.
|
||||
inline bool isEnabled() const;
|
||||
|
||||
/// Set whether this processor is enabled or not.
|
||||
inline void setEnabled(bool v);
|
||||
|
||||
/// Get a pointer to the destination particle system.
|
||||
inline ParticleSystem *getParticleSystem();
|
||||
|
||||
/// Get a const pointer to the destination particle system.
|
||||
inline const ParticleSystem *getParticleSystem() const;
|
||||
|
||||
/// Set the destination particle system.
|
||||
inline void setParticleSystem(ParticleSystem *ps);
|
||||
|
||||
void traverse(osg::NodeVisitor &nv);
|
||||
|
||||
/// Get the current local-to-world transformation matrix (valid only during cull traversal).
|
||||
inline const osg::Matrix &getLocalToWorldMatrix();
|
||||
|
||||
/// Get the current world-to-local transformation matrix (valid only during cull traversal).
|
||||
inline const osg::Matrix &getWorldToLocalMatrix();
|
||||
|
||||
/// Transform a point from local to world coordinates (valid only during cull traversal).
|
||||
inline osg::Vec3 transformLocalToWorld(const osg::Vec3 &P);
|
||||
|
||||
/// Transform a vector from local to world coordinates, discarding translation (valid only during cull traversal).
|
||||
inline osg::Vec3 rotateLocalToWorld(const osg::Vec3 &P);
|
||||
|
||||
/// Transform a point from world to local coordinates (valid only during cull traversal).
|
||||
inline osg::Vec3 transformWorldToLocal(const osg::Vec3 &P);
|
||||
|
||||
/// Transform a vector from world to local coordinates, discarding translation (valid only during cull traversal).
|
||||
inline osg::Vec3 rotateWorldToLocal(const osg::Vec3 &P);
|
||||
|
||||
protected:
|
||||
virtual ~ParticleProcessor() {}
|
||||
ParticleProcessor &operator=(const ParticleProcessor &) { return *this; }
|
||||
|
||||
inline const bool computeBound() const;
|
||||
|
||||
virtual void process(double dt) = 0;
|
||||
|
||||
private:
|
||||
ReferenceFrame rf_;
|
||||
bool enabled_;
|
||||
double t0_;
|
||||
osg::ref_ptr<ParticleSystem> ps_;
|
||||
bool need_ltw_matrix_;
|
||||
bool need_wtl_matrix_;
|
||||
osg::Matrix ltw_matrix_;
|
||||
osg::Matrix wtl_matrix_;
|
||||
osg::NodeVisitor *current_nodevisitor_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline ParticleProcessor::ReferenceFrame ParticleProcessor::getReferenceFrame() const
|
||||
{
|
||||
return rf_;
|
||||
}
|
||||
|
||||
inline void ParticleProcessor::setReferenceFrame(ReferenceFrame rf)
|
||||
{
|
||||
rf_ = rf;
|
||||
}
|
||||
|
||||
inline bool ParticleProcessor::isEnabled() const
|
||||
{
|
||||
return enabled_;
|
||||
}
|
||||
|
||||
inline void ParticleProcessor::setEnabled(bool v)
|
||||
{
|
||||
enabled_ = v;
|
||||
if (enabled_) t0_ = -1;
|
||||
}
|
||||
|
||||
inline ParticleSystem *ParticleProcessor::getParticleSystem()
|
||||
{
|
||||
return ps_.get();
|
||||
}
|
||||
|
||||
inline const ParticleSystem *ParticleProcessor::getParticleSystem() const
|
||||
{
|
||||
return ps_.get();
|
||||
}
|
||||
|
||||
inline void ParticleProcessor::setParticleSystem(ParticleSystem *ps)
|
||||
{
|
||||
ps_ = ps;
|
||||
}
|
||||
|
||||
inline const bool ParticleProcessor::computeBound() const
|
||||
{
|
||||
_bsphere.init();
|
||||
_bsphere_computed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline const osg::Matrix &ParticleProcessor::getLocalToWorldMatrix()
|
||||
{
|
||||
if (need_ltw_matrix_) {
|
||||
ltw_matrix_ = osg::Matrix::identity();
|
||||
current_nodevisitor_->getLocalToWorldMatrix(ltw_matrix_, this);
|
||||
need_ltw_matrix_ = false;
|
||||
}
|
||||
return ltw_matrix_;
|
||||
}
|
||||
|
||||
inline const osg::Matrix &ParticleProcessor::getWorldToLocalMatrix()
|
||||
{
|
||||
if (need_wtl_matrix_) {
|
||||
wtl_matrix_ = osg::Matrix::identity();
|
||||
current_nodevisitor_->getWorldToLocalMatrix(wtl_matrix_, this);
|
||||
need_wtl_matrix_ = false;
|
||||
}
|
||||
return wtl_matrix_;
|
||||
}
|
||||
|
||||
inline osg::Vec3 ParticleProcessor::transformLocalToWorld(const osg::Vec3 &P)
|
||||
{
|
||||
return getLocalToWorldMatrix().preMult(P);
|
||||
}
|
||||
|
||||
inline osg::Vec3 ParticleProcessor::transformWorldToLocal(const osg::Vec3 &P)
|
||||
{
|
||||
return getWorldToLocalMatrix().preMult(P);
|
||||
}
|
||||
|
||||
inline osg::Vec3 ParticleProcessor::rotateLocalToWorld(const osg::Vec3 &P)
|
||||
{
|
||||
return getLocalToWorldMatrix().preMult(P) -
|
||||
getLocalToWorldMatrix().preMult(osg::Vec3(0, 0, 0));
|
||||
}
|
||||
|
||||
inline osg::Vec3 ParticleProcessor::rotateWorldToLocal(const osg::Vec3 &P)
|
||||
{
|
||||
return getWorldToLocalMatrix().preMult(P) -
|
||||
getWorldToLocalMatrix().preMult(osg::Vec3(0, 0, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
318
include/osgParticle/ParticleSystem
Normal file
318
include/osgParticle/ParticleSystem
Normal file
@@ -0,0 +1,318 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_PARTICLESYSTEM_
|
||||
#define OSGPARTICLE_PARTICLESYSTEM_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osg/Drawable>
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/State>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Statistics>
|
||||
#include <osg/BoundingBox>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** The heart of this class library; its purpose is to hold a set of particles and manage particle creation, update, rendering and destruction.
|
||||
You can add this drawable to any <CODE>Geode</CODE> as you usually do with other
|
||||
<CODE>Drawable</CODE> classes. Each instance of <CODE>ParticleSystem</CODE> is a separate set of
|
||||
particles; it provides the interface for creating particles and iterating
|
||||
through them (see the <CODE>Emitter</CODE> and <CODE>Program</CODE> classes).
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT ParticleSystem: public osg::Drawable {
|
||||
public:
|
||||
|
||||
ParticleSystem();
|
||||
ParticleSystem(const ParticleSystem ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(ParticleSystem);
|
||||
|
||||
/// Get the default bounding box
|
||||
inline const osg::BoundingBox &getDefaultBoundingBox() const;
|
||||
|
||||
/** Set the default bounding box.
|
||||
The default bounding box is used when a real bounding box cannot be computed, for example
|
||||
because no particles has been updated yet.
|
||||
*/
|
||||
inline void setDefaultBoundingBox(const osg::BoundingBox &bbox);
|
||||
|
||||
/// Get the double pass rendering flag.
|
||||
inline bool getDoublePassRendering() const;
|
||||
|
||||
/** Set the double pass rendering flag.
|
||||
Double pass rendering avoids overdraw problems between particle systems
|
||||
and other opaque objects. If you can render all the particle systems <U>after</U>
|
||||
the opaque objects, then double pass is not necessary and can be turned off (best choice).
|
||||
If you set the default attributes with <CODE>setDefaultAttributes</CODE>, then the particle
|
||||
system will fall into a transparent bin.
|
||||
*/
|
||||
inline void setDoublePassRendering(bool v);
|
||||
|
||||
/// Return true if the particle system is frozen.
|
||||
inline bool isFrozen() const;
|
||||
|
||||
/** Set or reset the <I>frozen</I> state.
|
||||
When the particle system is frozen, emitters and programs won't do anything on it.
|
||||
*/
|
||||
inline void setFrozen(bool v);
|
||||
|
||||
/// Get the number of allocated particles (alive + dead).
|
||||
inline int numParticles() const;
|
||||
|
||||
/// Get the number of dead particles.
|
||||
inline int numDeadParticles() const;
|
||||
|
||||
/// Get a pointer to the i-th particle.
|
||||
inline Particle *getParticle(int i);
|
||||
|
||||
/// Get a const pointer to the i-th particle.
|
||||
inline const Particle *getParticle(int i) const;
|
||||
|
||||
/// Create a new particle from the specified template (or the default one if <CODE>ptemplate</CODE> is null).
|
||||
inline virtual Particle *createParticle(const Particle *ptemplate);
|
||||
|
||||
/// Destroy the i-th particle.
|
||||
inline virtual void destroyParticle(int i);
|
||||
|
||||
/// Get the last frame number.
|
||||
inline int getLastFrameNumber() const;
|
||||
|
||||
/// Get a reference to the default particle template.
|
||||
inline const Particle &getDefaultParticleTemplate() const;
|
||||
|
||||
/// Set the default particle template (particle is copied).
|
||||
inline void setDefaultParticleTemplate(const Particle &p);
|
||||
|
||||
/// Get whether the particle system can freeze when culled
|
||||
inline bool getFreezeOnCull() const;
|
||||
|
||||
/// Set whether the particle system can freeze when culled (default is true)
|
||||
inline void setFreezeOnCull(bool v);
|
||||
|
||||
/** A useful method to set the most common <CODE>StateAttribute</CODE>'s in one call.
|
||||
If <CODE>texturefile</CODE> is empty, then texturing is turned off.
|
||||
*/
|
||||
void setDefaultAttributes(const std::string &texturefile = "", bool emissive_particles = true, bool lighting = false);
|
||||
|
||||
/// (<B>EXPERIMENTAL</B>) Get the level of detail.
|
||||
inline int getLevelOfDetail() const;
|
||||
|
||||
/** (<B>EXPERIMENTAL</B>) Set the level of detail. The total number of particles is divided by the detail value to
|
||||
get the actual number of particles to be drawn. This value must be greater than zero.
|
||||
*/
|
||||
inline void setLevelOfDetail(int v);
|
||||
|
||||
/// Update the particles. Don't call this directly, use a <CODE>ParticleSystemUpdater</CODE> instead.
|
||||
virtual void update(double dt);
|
||||
|
||||
inline virtual bool getStats(osg::Statistics &stats);
|
||||
|
||||
protected:
|
||||
virtual ~ParticleSystem();
|
||||
|
||||
ParticleSystem &operator=(const ParticleSystem &) { return *this; }
|
||||
|
||||
inline virtual const bool computeBound() const;
|
||||
virtual void drawImmediateMode(osg::State &state);
|
||||
inline void update_bounds(const osg::Vec3 &p);
|
||||
void single_pass_render(const osg::Matrix &modelview);
|
||||
|
||||
private:
|
||||
typedef std::vector<Particle> Particle_vector;
|
||||
typedef std::stack<Particle*> Death_stack;
|
||||
|
||||
Particle_vector particles_;
|
||||
Death_stack deadparts_;
|
||||
|
||||
osg::BoundingBox def_bbox_;
|
||||
|
||||
bool doublepass_;
|
||||
bool frozen_;
|
||||
int display_list_id_;
|
||||
|
||||
osg::Vec3 bmin_;
|
||||
osg::Vec3 bmax_;
|
||||
|
||||
bool reset_bounds_flag_;
|
||||
bool bounds_computed_;
|
||||
|
||||
Particle def_ptemp_;
|
||||
int last_frame_;
|
||||
bool freeze_on_cull_;
|
||||
|
||||
int detail_;
|
||||
int draw_count_;
|
||||
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline bool ParticleSystem::isFrozen() const
|
||||
{
|
||||
return frozen_;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::setFrozen(bool v)
|
||||
{
|
||||
frozen_ = v;
|
||||
}
|
||||
|
||||
inline const osg::BoundingBox &ParticleSystem::getDefaultBoundingBox() const
|
||||
{
|
||||
return def_bbox_;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::setDefaultBoundingBox(const osg::BoundingBox &bbox)
|
||||
{
|
||||
def_bbox_ = bbox;
|
||||
}
|
||||
|
||||
inline bool ParticleSystem::getDoublePassRendering() const
|
||||
{
|
||||
return doublepass_;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::setDoublePassRendering(bool v)
|
||||
{
|
||||
doublepass_ = v;
|
||||
}
|
||||
|
||||
inline int ParticleSystem::numParticles() const
|
||||
{
|
||||
return static_cast<int>(particles_.size());
|
||||
}
|
||||
|
||||
inline int ParticleSystem::numDeadParticles() const
|
||||
{
|
||||
return static_cast<int>(deadparts_.size());
|
||||
}
|
||||
|
||||
inline Particle *ParticleSystem::getParticle(int i)
|
||||
{
|
||||
return &particles_[i];
|
||||
}
|
||||
|
||||
inline const Particle *ParticleSystem::getParticle(int i) const
|
||||
{
|
||||
return &particles_[i];
|
||||
}
|
||||
|
||||
inline void ParticleSystem::destroyParticle(int i)
|
||||
{
|
||||
particles_[i].kill();
|
||||
}
|
||||
|
||||
inline int ParticleSystem::getLastFrameNumber() const
|
||||
{
|
||||
return last_frame_;
|
||||
}
|
||||
|
||||
inline const bool ParticleSystem::computeBound() const
|
||||
{
|
||||
if (!bounds_computed_) {
|
||||
_bbox = def_bbox_;
|
||||
} else {
|
||||
_bbox._min = bmin_;
|
||||
_bbox._max = bmax_;
|
||||
}
|
||||
_bbox_computed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool ParticleSystem::getStats(osg::Statistics &stats)
|
||||
{
|
||||
stats.addNumPrims(draw_count_);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::update_bounds(const osg::Vec3 &p)
|
||||
{
|
||||
if (reset_bounds_flag_) {
|
||||
reset_bounds_flag_ = false;
|
||||
bmin_ = p;
|
||||
bmax_ = p;
|
||||
} else {
|
||||
if (p.x() < bmin_.x()) bmin_.x() = p.x();
|
||||
if (p.y() < bmin_.y()) bmin_.y() = p.y();
|
||||
if (p.z() < bmin_.z()) bmin_.z() = p.z();
|
||||
if (p.x() > bmax_.x()) bmax_.x() = p.x();
|
||||
if (p.y() > bmax_.y()) bmax_.y() = p.y();
|
||||
if (p.z() > bmax_.z()) bmax_.z() = p.z();
|
||||
|
||||
if (!bounds_computed_)
|
||||
bounds_computed_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline const Particle &ParticleSystem::getDefaultParticleTemplate() const
|
||||
{
|
||||
return def_ptemp_;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::setDefaultParticleTemplate(const Particle &p)
|
||||
{
|
||||
def_ptemp_ = p;
|
||||
}
|
||||
|
||||
inline bool ParticleSystem::getFreezeOnCull() const
|
||||
{
|
||||
return freeze_on_cull_;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::setFreezeOnCull(bool v)
|
||||
{
|
||||
freeze_on_cull_ = v;
|
||||
}
|
||||
|
||||
inline int ParticleSystem::getLevelOfDetail() const
|
||||
{
|
||||
return detail_;
|
||||
}
|
||||
|
||||
inline void ParticleSystem::setLevelOfDetail(int v)
|
||||
{
|
||||
if (v < 1) v = 1;
|
||||
detail_ = v;
|
||||
}
|
||||
|
||||
// I'm not sure this function should be inlined...
|
||||
|
||||
inline Particle *ParticleSystem::createParticle(const Particle *ptemplate)
|
||||
{
|
||||
// is there any dead particle?
|
||||
if (!deadparts_.empty()) {
|
||||
|
||||
// retrieve a pointer to the last dead particle
|
||||
Particle *P = deadparts_.top();
|
||||
|
||||
// create a new (alive) particle in the same place
|
||||
*P = Particle(ptemplate? *ptemplate: def_ptemp_);
|
||||
|
||||
// remove the pointer from the death stack
|
||||
deadparts_.pop();
|
||||
return P;
|
||||
|
||||
} else {
|
||||
|
||||
// add a new particle to the vector
|
||||
particles_.push_back(Particle(ptemplate? *ptemplate: def_ptemp_));
|
||||
return &particles_.back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
128
include/osgParticle/ParticleSystemUpdater
Normal file
128
include/osgParticle/ParticleSystemUpdater
Normal file
@@ -0,0 +1,128 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_PARTICLESYSTEMUPDATER_
|
||||
#define OSGPARTICLE_PARTICLESYSTEMUPDATER_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/ParticleSystem>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** A useful node class for updating particle systems automatically.
|
||||
When a <CODE>ParticleSystemUpdater</CODE> is traversed by a cull visitor, it calls the
|
||||
<CODE>update()</CODE> method on the specified particle systems. You should place this updater
|
||||
<U>AFTER</U> other nodes like emitters and programs.
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT ParticleSystemUpdater: public osg::Node {
|
||||
public:
|
||||
ParticleSystemUpdater();
|
||||
ParticleSystemUpdater(const ParticleSystemUpdater ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Node(ParticleSystemUpdater);
|
||||
|
||||
/// Return the number of particle systems on the list.
|
||||
inline int numParticleSystems() const;
|
||||
|
||||
/// Add a particle system to the list.
|
||||
inline void addParticleSystem(ParticleSystem *ps);
|
||||
|
||||
/// Get a const particle system from the list.
|
||||
inline const ParticleSystem *getParticleSystem(int i) const;
|
||||
|
||||
/// Get a particle system from the list.
|
||||
inline ParticleSystem *getParticleSystem(int i);
|
||||
|
||||
/// Find a particle system.
|
||||
inline int findParticleSystem(ParticleSystem *ps) const;
|
||||
|
||||
/// Remove a particle system from the list (by index).
|
||||
inline void removeParticleSystem(int i);
|
||||
|
||||
/// Remove a particle system from the list (by pointer).
|
||||
inline bool removeParticleSystem(ParticleSystem *ps);
|
||||
|
||||
virtual void traverse(osg::NodeVisitor &nv);
|
||||
|
||||
protected:
|
||||
virtual ~ParticleSystemUpdater() {}
|
||||
ParticleSystemUpdater &operator=(const ParticleSystemUpdater &) { return *this; }
|
||||
|
||||
inline virtual const bool computeBound() const;
|
||||
|
||||
private:
|
||||
typedef std::vector<osg::ref_ptr<ParticleSystem> > ParticleSystem_Vector;
|
||||
|
||||
ParticleSystem_Vector psv_;
|
||||
double t0_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline const bool ParticleSystemUpdater::computeBound() const
|
||||
{
|
||||
_bsphere.init();
|
||||
_bsphere_computed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int ParticleSystemUpdater::numParticleSystems() const
|
||||
{
|
||||
return static_cast<int>(psv_.size());
|
||||
}
|
||||
|
||||
inline void ParticleSystemUpdater::addParticleSystem(ParticleSystem *ps)
|
||||
{
|
||||
psv_.push_back(ps);
|
||||
}
|
||||
|
||||
inline const ParticleSystem *ParticleSystemUpdater::getParticleSystem(int i) const
|
||||
{
|
||||
return psv_[i].get();
|
||||
}
|
||||
|
||||
inline ParticleSystem *ParticleSystemUpdater::getParticleSystem(int i)
|
||||
{
|
||||
return psv_[i].get();
|
||||
}
|
||||
|
||||
inline void ParticleSystemUpdater::removeParticleSystem(int i)
|
||||
{
|
||||
psv_.erase(psv_.begin()+i);
|
||||
}
|
||||
|
||||
inline int ParticleSystemUpdater::findParticleSystem(ParticleSystem *ps) const
|
||||
{
|
||||
ParticleSystem_Vector::const_iterator i;
|
||||
int j = 0;
|
||||
for (i=psv_.begin(); i!=psv_.end(); ++i, ++j) {
|
||||
if (i->get() == ps) return j;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline bool ParticleSystemUpdater::removeParticleSystem(ParticleSystem *ps)
|
||||
{
|
||||
int i = findParticleSystem(ps);
|
||||
if (i == -1) return false;
|
||||
removeParticleSystem(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
51
include/osgParticle/Placer
Normal file
51
include/osgParticle/Placer
Normal file
@@ -0,0 +1,51 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_PLACER_
|
||||
#define OSGPARTICLE_PLACER_ 1
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
class Particle;
|
||||
|
||||
/** An abstract base class for implementing <I>particle placers</I>. A placer is an object which take
|
||||
a particle as input, and places it somewhere by setting its position vector. Placer objects are
|
||||
used by the <CODE>ModularEmitter</CODE> class as part of the particle emission process.
|
||||
*/
|
||||
class Placer: public osg::Object {
|
||||
public:
|
||||
inline Placer();
|
||||
inline Placer(const Placer ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "Placer"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Placer *>(obj) != 0; }
|
||||
|
||||
/// Place a particle. Must be implemented in descendant classes.
|
||||
virtual void place(Particle *P) const = 0;
|
||||
|
||||
protected:
|
||||
~Placer() {}
|
||||
Placer &operator=(const Placer &) { return *this; }
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline Placer::Placer()
|
||||
: osg::Object()
|
||||
{
|
||||
}
|
||||
|
||||
inline Placer::Placer(const Placer ©, const osg::CopyOp ©op)
|
||||
: osg::Object(copy, copyop)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
61
include/osgParticle/PointPlacer
Normal file
61
include/osgParticle/PointPlacer
Normal file
@@ -0,0 +1,61 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_POINTPLACER_
|
||||
#define OSGPARTICLE_POINTPLACER_ 1
|
||||
|
||||
#include <osgParticle/CenteredPlacer>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** A point-shaped particle placer.
|
||||
This placer class uses the center point defined in its base class <CODE>CenteredPlacer</CODE>
|
||||
to place there all incoming particles.
|
||||
*/
|
||||
class PointPlacer: public CenteredPlacer {
|
||||
public:
|
||||
inline PointPlacer();
|
||||
inline PointPlacer(const PointPlacer ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(PointPlacer);
|
||||
|
||||
/** Place a particle.
|
||||
This method is called automatically by <CODE>ModularEmitter</CODE> and should not be called
|
||||
manually.
|
||||
*/
|
||||
inline void place(Particle *P) const;
|
||||
|
||||
protected:
|
||||
virtual ~PointPlacer() {}
|
||||
PointPlacer &operator=(const PointPlacer &) { return *this; }
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline PointPlacer::PointPlacer()
|
||||
: CenteredPlacer()
|
||||
{
|
||||
}
|
||||
|
||||
inline PointPlacer::PointPlacer(const PointPlacer ©, const osg::CopyOp ©op)
|
||||
: CenteredPlacer(copy, copyop)
|
||||
{
|
||||
}
|
||||
|
||||
inline void PointPlacer::place(Particle *P) const
|
||||
{
|
||||
P->setPosition(getCenter());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
57
include/osgParticle/Program
Normal file
57
include/osgParticle/Program
Normal file
@@ -0,0 +1,57 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_PROGRAM_
|
||||
#define OSGPARTICLE_PROGRAM_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
#include <osgParticle/ParticleProcessor>
|
||||
|
||||
#include <osg/Object>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
#include <osg/CopyOp>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** An abstract <CODE>ParticleProcessor</CODE> descendant for modifying particles "on the fly"
|
||||
during the cull traversal.
|
||||
Descendants of this class must implement the <CODE>execute()</CODE> method, which should iterate
|
||||
through all particles in the linked particle system and modify them somehow
|
||||
(usually updating their velocity vector).
|
||||
*/
|
||||
class OSGPARTICLE_EXPORT Program: public ParticleProcessor {
|
||||
public:
|
||||
Program();
|
||||
Program(const Program ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "Program"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) { return dynamic_cast<const Program*>(obj) != 0; }
|
||||
virtual void accept(osg::NodeVisitor& nv) { if (nv.validNodeMask(*this)) { nv.pushOntoNodePath(this); nv.apply(*this); nv.popFromNodePath(); } }
|
||||
|
||||
protected:
|
||||
virtual ~Program() {}
|
||||
Program &operator=(const Program &) { return *this; }
|
||||
|
||||
/// Implementation of <CODE>ParticleProcessor::process()</CODE>. Do not call this method by yourself.
|
||||
inline void process(double dt);
|
||||
|
||||
/// Execute the program on the particle system. Must be overriden in descendant classes.
|
||||
virtual void execute(double dt) = 0;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline void Program::process(double dt)
|
||||
{
|
||||
execute(dt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
156
include/osgParticle/RadialShooter
Normal file
156
include/osgParticle/RadialShooter
Normal file
@@ -0,0 +1,156 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_RADIALSHOOTER_
|
||||
#define OSGPARTICLE_RADIALSHOOTER_ 1
|
||||
|
||||
#include <osgParticle/Shooter>
|
||||
#include <osgParticle/Particle>
|
||||
#include <osgParticle/range>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Math>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** A shooter class that shoots particles radially.
|
||||
This shooter computes the velocity vector of incoming particles by choosing a
|
||||
random direction and a random speed. Both direction and speed are chosen within
|
||||
specified ranges. The direction is defined by two angles: <B>theta</B>, which
|
||||
is the angle between the velocity vector and the Z axis, and <B>phi</B>, which is
|
||||
the angle between the X axis and the velocity vector projected onto the X-Y plane.
|
||||
*/
|
||||
class RadialShooter: public Shooter {
|
||||
public:
|
||||
inline RadialShooter();
|
||||
inline RadialShooter(const RadialShooter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(RadialShooter);
|
||||
|
||||
/// Get the range of possible values for <B>theta</B> angle.
|
||||
inline const rangef &getThetaRange() const;
|
||||
|
||||
/// Set the range of possible values for <B>theta</B> angle.
|
||||
inline void setThetaRange(const rangef &r);
|
||||
|
||||
/// Set the range of possible values for <B>theta</B> angle.
|
||||
inline void setThetaRange(float r1, float r2);
|
||||
|
||||
/// Get the range of possible values for <B>phi</B> angle.
|
||||
inline const rangef &getPhiRange() const;
|
||||
|
||||
/// Set the range of possible values for <B>phi</B> angle.
|
||||
inline void setPhiRange(const rangef &r);
|
||||
|
||||
/// Set the range of possible values for <B>phi</B> angle.
|
||||
inline void setPhiRange(float r1, float r2);
|
||||
|
||||
/// Get the range of possible values for initial speed of particles.
|
||||
inline const rangef &getInitialSpeedRange() const;
|
||||
|
||||
/// Set the range of possible values for initial speed of particles.
|
||||
inline void setInitialSpeedRange(const rangef &r);
|
||||
|
||||
/// Set the range of possible values for initial speed of particles.
|
||||
inline void setInitialSpeedRange(float r1, float r2);
|
||||
|
||||
/// Shoot a particle. Do not call this method manually.
|
||||
inline void shoot(Particle *P) const;
|
||||
|
||||
protected:
|
||||
virtual ~RadialShooter() {}
|
||||
RadialShooter &operator=(const RadialShooter &) { return *this; }
|
||||
|
||||
private:
|
||||
rangef theta_range_;
|
||||
rangef phi_range_;
|
||||
rangef speed_range_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline RadialShooter::RadialShooter()
|
||||
: Shooter(),
|
||||
theta_range_(0, 0.5f*osg::PI_4),
|
||||
phi_range_(0, 2*osg::PI),
|
||||
speed_range_(10, 10)
|
||||
{
|
||||
}
|
||||
|
||||
inline RadialShooter::RadialShooter(const RadialShooter ©, const osg::CopyOp ©op)
|
||||
: Shooter(copy, copyop),
|
||||
theta_range_(copy.theta_range_),
|
||||
phi_range_(copy.phi_range_),
|
||||
speed_range_(copy.speed_range_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const rangef &RadialShooter::getThetaRange() const
|
||||
{
|
||||
return theta_range_;
|
||||
}
|
||||
|
||||
inline const rangef &RadialShooter::getPhiRange() const
|
||||
{
|
||||
return phi_range_;
|
||||
}
|
||||
|
||||
inline const rangef &RadialShooter::getInitialSpeedRange() const
|
||||
{
|
||||
return speed_range_;
|
||||
}
|
||||
|
||||
inline void RadialShooter::setThetaRange(const rangef &r)
|
||||
{
|
||||
theta_range_ = r;
|
||||
}
|
||||
|
||||
inline void RadialShooter::setThetaRange(float r1, float r2)
|
||||
{
|
||||
theta_range_.min = r1;
|
||||
theta_range_.max = r2;
|
||||
}
|
||||
|
||||
inline void RadialShooter::setPhiRange(const rangef &r)
|
||||
{
|
||||
phi_range_ = r;
|
||||
}
|
||||
|
||||
inline void RadialShooter::setPhiRange(float r1, float r2)
|
||||
{
|
||||
phi_range_.min = r1;
|
||||
phi_range_.max = r2;
|
||||
}
|
||||
|
||||
inline void RadialShooter::setInitialSpeedRange(const rangef &r)
|
||||
{
|
||||
speed_range_ = r;
|
||||
}
|
||||
|
||||
inline void RadialShooter::setInitialSpeedRange(float r1, float r2)
|
||||
{
|
||||
speed_range_.min = r1;
|
||||
speed_range_.max = r2;
|
||||
}
|
||||
|
||||
inline void RadialShooter::shoot(Particle *P) const
|
||||
{
|
||||
float theta = theta_range_.get_random();
|
||||
float phi = phi_range_.get_random();
|
||||
float speed = speed_range_.get_random();
|
||||
|
||||
P->setVelocity(osg::Vec3(
|
||||
speed * sinf(theta) * cosf(phi),
|
||||
speed * sinf(theta) * sinf(phi),
|
||||
speed * cosf(theta)
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
57
include/osgParticle/RandomRateCounter
Normal file
57
include/osgParticle/RandomRateCounter
Normal file
@@ -0,0 +1,57 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_RANDOMRATECOUNTER_
|
||||
#define OSGPARTICLE_RANDOMRATECOUNTER_ 1
|
||||
|
||||
#include <osgParticle/VariableRateCounter>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
class RandomRateCounter: public VariableRateCounter {
|
||||
public:
|
||||
inline RandomRateCounter();
|
||||
inline RandomRateCounter(const RandomRateCounter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(RandomRateCounter);
|
||||
|
||||
/// Return the number of particles to be created in this frame
|
||||
inline int numParticlesToCreate(double dt) const;
|
||||
|
||||
protected:
|
||||
virtual ~RandomRateCounter() {}
|
||||
|
||||
private:
|
||||
mutable float np_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline RandomRateCounter::RandomRateCounter()
|
||||
: VariableRateCounter(), np_(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline RandomRateCounter::RandomRateCounter(const RandomRateCounter ©, const osg::CopyOp ©op)
|
||||
: VariableRateCounter(copy, copyop), np_(copy.np_)
|
||||
{
|
||||
}
|
||||
|
||||
inline int RandomRateCounter::numParticlesToCreate(double dt) const
|
||||
{
|
||||
np_ += dt * getRateRange().get_random();
|
||||
int n = static_cast<int>(np_);
|
||||
np_ -= n;
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
124
include/osgParticle/SectorPlacer
Normal file
124
include/osgParticle/SectorPlacer
Normal file
@@ -0,0 +1,124 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_SECTORPLACER_
|
||||
#define OSGPARTICLE_SECTORPLACER_ 1
|
||||
|
||||
#include <osgParticle/CenteredPlacer>
|
||||
#include <osgParticle/Particle>
|
||||
#include <osgParticle/range>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Math>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/** A sector-shaped particle placer.
|
||||
This placer sets the initial position of incoming particle by choosing a random position
|
||||
within a circular sector; this sector is defined by three parameters: a <I>center point</I>,
|
||||
which is inherited directly from <CODE>osgParticle::CenteredPlacer</CODE>, a range of values
|
||||
for <I>radius</I>, and a range of values for the <I>central angle</I> (sometimes called <B>phi</B>).
|
||||
*/
|
||||
class SectorPlacer: public CenteredPlacer {
|
||||
public:
|
||||
inline SectorPlacer();
|
||||
inline SectorPlacer(const SectorPlacer ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
/// Get the range of possible values for radius.
|
||||
inline const rangef &getRadiusRange() const;
|
||||
|
||||
/// Set the range of possible values for radius.
|
||||
inline void setRadiusRange(const rangef &r);
|
||||
|
||||
/// Set the range of possible values for radius.
|
||||
inline void setRadiusRange(float r1, float r2);
|
||||
|
||||
/// Get the range of possible values for the central angle.
|
||||
inline const rangef &getPhiRange() const;
|
||||
|
||||
/// Set the range of possible values for the central angle.
|
||||
inline void setPhiRange(const rangef &r);
|
||||
|
||||
/// Set the range of possible values for the central angle.
|
||||
inline void setPhiRange(float r1, float r2);
|
||||
|
||||
META_Object(SectorPlacer);
|
||||
|
||||
/// Place a particle. Do not call it manually.
|
||||
inline void place(Particle *P) const;
|
||||
|
||||
protected:
|
||||
virtual ~SectorPlacer() {}
|
||||
SectorPlacer &operator=(const SectorPlacer &) { return *this; }
|
||||
|
||||
private:
|
||||
rangef rad_range_;
|
||||
rangef phi_range_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline SectorPlacer::SectorPlacer()
|
||||
: CenteredPlacer(), rad_range_(0, 1), phi_range_(0, osg::PI*2)
|
||||
{
|
||||
}
|
||||
|
||||
inline SectorPlacer::SectorPlacer(const SectorPlacer ©, const osg::CopyOp ©op)
|
||||
: CenteredPlacer(copy, copyop), rad_range_(copy.rad_range_), phi_range_(copy.phi_range_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const rangef &SectorPlacer::getRadiusRange() const
|
||||
{
|
||||
return rad_range_;
|
||||
}
|
||||
|
||||
inline const rangef &SectorPlacer::getPhiRange() const
|
||||
{
|
||||
return phi_range_;
|
||||
}
|
||||
|
||||
inline void SectorPlacer::setRadiusRange(const rangef &r)
|
||||
{
|
||||
rad_range_ = r;
|
||||
}
|
||||
|
||||
inline void SectorPlacer::setRadiusRange(float r1, float r2)
|
||||
{
|
||||
rad_range_.min = r1;
|
||||
rad_range_.max = r2;
|
||||
}
|
||||
|
||||
inline void SectorPlacer::setPhiRange(const rangef &r)
|
||||
{
|
||||
phi_range_ = r;
|
||||
}
|
||||
|
||||
inline void SectorPlacer::setPhiRange(float r1, float r2)
|
||||
{
|
||||
phi_range_.min = r1;
|
||||
phi_range_.max = r2;
|
||||
}
|
||||
|
||||
inline void SectorPlacer::place(Particle *P) const
|
||||
{
|
||||
float rad = rad_range_.get_random();
|
||||
float phi = phi_range_.get_random();
|
||||
|
||||
osg::Vec3 pos(
|
||||
getCenter().x() + rad * cosf(phi),
|
||||
getCenter().y() + rad * sinf(phi),
|
||||
getCenter().z());
|
||||
|
||||
P->setPosition(pos);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
118
include/osgParticle/SegmentPlacer
Normal file
118
include/osgParticle/SegmentPlacer
Normal file
@@ -0,0 +1,118 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_SEGMENTPLACER_
|
||||
#define OSGPARTICLE_SEGMENTPLACER_ 1
|
||||
|
||||
#include <osgParticle/Placer>
|
||||
#include <osgParticle/Particle>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
#include <osg/Vec3>
|
||||
|
||||
namespace osgParticle {
|
||||
|
||||
/** A segment-shaped particle placer.
|
||||
To use this placer you have to define a segment, by setting its two vertices (<B>A</B> and <B>B</B>);
|
||||
when an emitter requests a <CODE>SegmentPlacer</CODE> to place a particle, the position is chosen randomly
|
||||
within that segment.
|
||||
*/
|
||||
class SegmentPlacer: public Placer {
|
||||
public:
|
||||
inline SegmentPlacer();
|
||||
inline SegmentPlacer(const SegmentPlacer ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
META_Object(SegmentPlacer);
|
||||
|
||||
/// get vertex <B>A</B>.
|
||||
inline const osg::Vec3 &getVertexA() const;
|
||||
|
||||
/// Set vertex <B>A</B> of the segment as a vector.
|
||||
inline void setVertexA(const osg::Vec3 &v);
|
||||
|
||||
/// Set vertex <B>A</B> of the segment as three floats.
|
||||
inline void setVertexA(float x, float y, float z);
|
||||
|
||||
/// get vertex <B>B</B>.
|
||||
inline const osg::Vec3 &getVertexB() const;
|
||||
|
||||
/// Set vertex <B>B</B> of the segment as a vector.
|
||||
inline void setVertexB(const osg::Vec3 &v);
|
||||
|
||||
/// Set vertex <B>B</B> of the segment as three floats.
|
||||
inline void setVertexB(float x, float y, float z);
|
||||
|
||||
/// Set both vertices.
|
||||
inline void setSegment(const osg::Vec3 &A, const osg::Vec3 &B);
|
||||
|
||||
/// Place a particle. This method is called by <CODE>ModularEmitter</CODE>, do not call it manually.
|
||||
inline void place(Particle *P) const;
|
||||
|
||||
protected:
|
||||
virtual ~SegmentPlacer() {}
|
||||
SegmentPlacer &operator=(const SegmentPlacer &) { return *this; }
|
||||
|
||||
private:
|
||||
osg::Vec3 A_;
|
||||
osg::Vec3 B_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline SegmentPlacer::SegmentPlacer()
|
||||
: Placer(), A_(-1, 0, 0), B_(1, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
inline SegmentPlacer::SegmentPlacer(const SegmentPlacer ©, const osg::CopyOp ©op)
|
||||
: Placer(copy, copyop), A_(copy.A_), B_(copy.B_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &SegmentPlacer::getVertexA() const
|
||||
{
|
||||
return A_;
|
||||
}
|
||||
|
||||
inline const osg::Vec3 &SegmentPlacer::getVertexB() const
|
||||
{
|
||||
return B_;
|
||||
}
|
||||
|
||||
inline void SegmentPlacer::setSegment(const osg::Vec3 &A, const osg::Vec3 &B)
|
||||
{
|
||||
A_ = A;
|
||||
B_ = B;
|
||||
}
|
||||
|
||||
inline void SegmentPlacer::place(Particle *P) const
|
||||
{
|
||||
P->setPosition(rangev3(A_, B_).get_random());
|
||||
}
|
||||
|
||||
inline void SegmentPlacer::setVertexA(const osg::Vec3 &v)
|
||||
{
|
||||
A_ = v;
|
||||
}
|
||||
|
||||
inline void SegmentPlacer::setVertexA(float x, float y, float z)
|
||||
{
|
||||
A_.set(x, y, z);
|
||||
}
|
||||
|
||||
inline void SegmentPlacer::setVertexB(const osg::Vec3 &v)
|
||||
{
|
||||
B_ = v;
|
||||
}
|
||||
|
||||
inline void SegmentPlacer::setVertexB(float x, float y, float z)
|
||||
{
|
||||
B_.set(x, y, z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
53
include/osgParticle/Shooter
Normal file
53
include/osgParticle/Shooter
Normal file
@@ -0,0 +1,53 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_SHOOTER_
|
||||
#define OSGPARTICLE_SHOOTER_ 1
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
class Particle;
|
||||
|
||||
/** An abstract base class used by ModularEmitter to "shoot" the particles after they have been placed.
|
||||
Descendants of this class must override the <CODE>shoot()</CODE> method.
|
||||
*/
|
||||
class Shooter: public osg::Object {
|
||||
public:
|
||||
inline Shooter();
|
||||
inline Shooter(const Shooter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "Shooter"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const Shooter *>(obj) != 0; }
|
||||
|
||||
/** Shoot a particle. Must be overriden by descendants.
|
||||
This method should only set the velocity vector of particle <CODE>P</CODE>, leaving other
|
||||
attributes unchanged.
|
||||
*/
|
||||
virtual void shoot(Particle *P) const = 0;
|
||||
|
||||
protected:
|
||||
virtual ~Shooter() {}
|
||||
Shooter &operator=(const Shooter &) { return *this; }
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline Shooter::Shooter()
|
||||
: osg::Object()
|
||||
{
|
||||
}
|
||||
|
||||
inline Shooter::Shooter(const Shooter ©, const osg::CopyOp ©op)
|
||||
: osg::Object(copy, copyop)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
67
include/osgParticle/VariableRateCounter
Normal file
67
include/osgParticle/VariableRateCounter
Normal file
@@ -0,0 +1,67 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_VARIABLERATECOUNTER_
|
||||
#define OSGPARTICLE_VARIABLERATECOUNTER_ 1
|
||||
|
||||
#include <osgParticle/Counter>
|
||||
#include <osgParticle/range>
|
||||
|
||||
#include <osg/CopyOp>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
class VariableRateCounter: public Counter {
|
||||
public:
|
||||
inline VariableRateCounter();
|
||||
inline VariableRateCounter(const VariableRateCounter ©, const osg::CopyOp ©op = osg::CopyOp::SHALLOW_COPY);
|
||||
|
||||
virtual const char *className() const { return "VariableRateCounter"; }
|
||||
virtual bool isSameKindAs(const osg::Object *obj) const { return dynamic_cast<const VariableRateCounter *>(obj) != 0; }
|
||||
|
||||
inline const rangef &getRateRange() const;
|
||||
inline void setRateRange(const rangef &r);
|
||||
inline void setRateRange(float minrange, float maxrange);
|
||||
|
||||
protected:
|
||||
virtual ~VariableRateCounter() {}
|
||||
|
||||
private:
|
||||
rangef rate_range_;
|
||||
};
|
||||
|
||||
// INLINE FUNCTIONS
|
||||
|
||||
inline VariableRateCounter::VariableRateCounter()
|
||||
: Counter(), rate_range_(1, 1)
|
||||
{
|
||||
}
|
||||
|
||||
inline VariableRateCounter::VariableRateCounter(const VariableRateCounter ©, const osg::CopyOp ©op)
|
||||
: Counter(copy, copyop), rate_range_(copy.rate_range_)
|
||||
{
|
||||
}
|
||||
|
||||
inline const rangef &VariableRateCounter::getRateRange() const
|
||||
{
|
||||
return rate_range_;
|
||||
}
|
||||
|
||||
inline void VariableRateCounter::setRateRange(const rangef &r)
|
||||
{
|
||||
rate_range_ = r;
|
||||
}
|
||||
|
||||
inline void VariableRateCounter::setRateRange(float minrange, float maxrange)
|
||||
{
|
||||
rate_range_.set(minrange, maxrange);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
19
include/osgParticle/Version
Normal file
19
include/osgParticle/Version
Normal file
@@ -0,0 +1,19 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_VERSION_
|
||||
#define OSGPARTICLE_VERSION_ 1
|
||||
|
||||
#include <osgParticle/Export>
|
||||
|
||||
extern "C" {
|
||||
|
||||
OSGPARTICLE_EXPORT const char* osgParticleGetVersion();
|
||||
OSGPARTICLE_EXPORT const char* osgParticleGetLibraryName();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
65
include/osgParticle/range
Normal file
65
include/osgParticle/range
Normal file
@@ -0,0 +1,65 @@
|
||||
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
//osgParticle - Copyright (C) 2002 Marco Jez
|
||||
|
||||
#ifndef OSGPARTICLE_RANGE_
|
||||
#define OSGPARTICLE_RANGE_ 1
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
|
||||
namespace osgParticle
|
||||
{
|
||||
|
||||
/**
|
||||
A simple struct template useful to store ranges of values as min/max pairs.
|
||||
This struct template helps storing min/max ranges for values of any kind; class <CODE>T_</CODE> is
|
||||
the type of values to be stored, and it must support operations <CODE>T_ + T_</CODE>, <CODE>T_ - T_</CODE>,
|
||||
and <CODE>T_ * float</CODE>, otherwise the <CODE>get_random()</CODE> method will not compile.
|
||||
This struct could be extended to customize the random number generator (now it uses only
|
||||
<CODE>std::rand()</CODE>).
|
||||
*/
|
||||
template<class T_> struct range {
|
||||
|
||||
/// Lower bound.
|
||||
T_ min;
|
||||
|
||||
/// Higher bound.
|
||||
T_ max;
|
||||
|
||||
/// Construct the object by calling default constructors for min and max.
|
||||
range() : min(T_()), max(T_()) {}
|
||||
|
||||
/// Construct and initialize min and max directly.
|
||||
range(const T_ &mn, const T_ &mx) : min(mn), max(mx) {}
|
||||
|
||||
/// Set min and max.
|
||||
void set(const T_ &mn, const T_ &mx) { min = mn; max = mx; }
|
||||
|
||||
/// Get a random value between min and max.
|
||||
T_ get_random() const
|
||||
{
|
||||
return min + (max - min) * std::rand() / RAND_MAX;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/// Range of floats.
|
||||
typedef range<float> rangef;
|
||||
|
||||
/// Range of osg::Vec2s.
|
||||
typedef range<osg::Vec2> rangev2;
|
||||
|
||||
/// Range of osg::Vec3s.
|
||||
typedef range<osg::Vec3> rangev3;
|
||||
|
||||
/// Range of osg::Vec4s.
|
||||
typedef range<osg::Vec4> rangev4;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user