Merged changed to osgParticle from Marco Jez, the changes are (quoted from
email from Marco) "Most relevant news: 1) particle systems now have the "freezeOnCull" property set to false by default. Since it is an optimization, and using it may cause some unwanted behaviors if not handled properly, it makes more sense to turn it off by default. 2) new "LINE" shape mode which uses GL_LINES to draw line segments that point to the direction of motion. 3) particles can now have a rotation angle and angular velocity. 4) new AngularAccelOperator applies angular acceleration to particles. 5) particle processors such as emitters and programs can have a "start", "end" and "reset" time coordinate. For example, an emitter may be instructed to start emitting particles only after a certain time, stop after another amount of time and then start again. Update (2) is from Gideon May. Updates (3) to (5) are from Douglas A. Pouk."
This commit is contained in:
@@ -27,7 +27,7 @@ osgParticle::FluidFrictionOperator::FluidFrictionOperator(const FluidFrictionOpe
|
||||
{
|
||||
}
|
||||
|
||||
void osgParticle::FluidFrictionOperator::operate(Particle *P, double)
|
||||
void osgParticle::FluidFrictionOperator::operate(Particle *P, double dt)
|
||||
{
|
||||
float r = (ovr_rad_ > 0)? ovr_rad_ : P->getRadius();
|
||||
osg::Vec3 v = P->getVelocity();
|
||||
@@ -42,7 +42,7 @@ void osgParticle::FluidFrictionOperator::operate(Particle *P, double)
|
||||
}
|
||||
|
||||
// correct unwanted velocity increments
|
||||
osg::Vec3 dv = Fr * (P->getMassInv() * 0.01);
|
||||
osg::Vec3 dv = Fr * P->getMassInv() * dt;
|
||||
float dvl = dv.length();
|
||||
if (dvl > vm) {
|
||||
dv *= vm / dvl;
|
||||
|
||||
@@ -17,7 +17,7 @@ osgParticle::ModularEmitter::ModularEmitter(const ModularEmitter ©, const os
|
||||
{
|
||||
}
|
||||
|
||||
void osgParticle::ModularEmitter::emit(double dt)
|
||||
void osgParticle::ModularEmitter::emit(double dt)
|
||||
{
|
||||
int n = counter_->numParticlesToCreate(dt);
|
||||
for (int i=0; i<n; ++i) {
|
||||
|
||||
@@ -36,6 +36,9 @@ osgParticle::Particle::Particle()
|
||||
prev_pos_(0, 0, 0),
|
||||
position_(0, 0, 0),
|
||||
velocity_(0, 0, 0),
|
||||
prev_angle_(0, 0, 0),
|
||||
angle_(0, 0, 0),
|
||||
angular_vel_(0, 0, 0),
|
||||
t0_(0),
|
||||
current_size_(0),
|
||||
current_alpha_(0)
|
||||
@@ -75,6 +78,17 @@ bool osgParticle::Particle::update(double dt)
|
||||
prev_pos_ = position_;
|
||||
position_ += velocity_ * dt;
|
||||
|
||||
// update angle
|
||||
prev_angle_ = angle_;
|
||||
angle_ += angular_vel_ * dt;
|
||||
|
||||
if (angle_.x() > osg::PI*2) angle_.x() -= osg::PI*2;
|
||||
if (angle_.x() < -osg::PI*2) angle_.x() += osg::PI*2;
|
||||
if (angle_.y() > osg::PI*2) angle_.y() -= osg::PI*2;
|
||||
if (angle_.y() < -osg::PI*2) angle_.y() += osg::PI*2;
|
||||
if (angle_.z() > osg::PI*2) angle_.z() -= osg::PI*2;
|
||||
if (angle_.z() < -osg::PI*2) angle_.z() += osg::PI*2;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,67 +99,90 @@ void osgParticle::Particle::render(const osg::Vec3 &xpos, const osg::Vec3 &px, c
|
||||
current_color_.z(),
|
||||
current_color_.w() * current_alpha_);
|
||||
|
||||
osg::Matrix R;
|
||||
R.makeRotate(
|
||||
angle_.x(), osg::Vec3(1, 0, 0),
|
||||
angle_.y(), osg::Vec3(0, 1, 0),
|
||||
angle_.z(), osg::Vec3(0, 0, 1));
|
||||
|
||||
osg::Vec3 p1(px * current_size_ * scale);
|
||||
osg::Vec3 p2(py * current_size_ * scale);
|
||||
|
||||
switch (shape_)
|
||||
{
|
||||
case POINT:
|
||||
glVertex3f(xpos.x(), xpos.y(), xpos.z());
|
||||
glVertex3f(xpos.x(), xpos.y(), xpos.z());
|
||||
break;
|
||||
|
||||
case QUAD:
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3fv((xpos-p1-p2).ptr());
|
||||
glVertex3fv((xpos-(p1+p2)*R).ptr());
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3fv((xpos+p1-p2).ptr());
|
||||
glVertex3fv((xpos+(p1-p2)*R).ptr());
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3fv((xpos+p1+p2).ptr());
|
||||
glVertex3fv((xpos+(p1+p2)*R).ptr());
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3fv((xpos-p1+p2).ptr());
|
||||
glVertex3fv((xpos-(p1-p2)*R).ptr());
|
||||
break;
|
||||
|
||||
case QUAD_TRIANGLESTRIP:
|
||||
// we must glBegin() and glEnd() here, because each particle is a single strip
|
||||
glPushMatrix();
|
||||
glTranslatef(xpos.x(), xpos.y(), xpos.z());
|
||||
glMultMatrixf(R.ptr());
|
||||
// we must glBegin() and glEnd() here, because each particle is a single strip
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3fv((xpos+p1+p2).ptr());
|
||||
glVertex3fv((p1+p2).ptr());
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3fv((xpos-p1+p2).ptr());
|
||||
glVertex3fv((-p1+p2).ptr());
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3fv((xpos+p1-p2).ptr());
|
||||
glVertex3fv((p1-p2).ptr());
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3fv((xpos-p1-p2).ptr());
|
||||
glVertex3fv((-p1-p2).ptr());
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
break;
|
||||
|
||||
case HEXAGON:
|
||||
glPushMatrix();
|
||||
glTranslatef(xpos.x(), xpos.y(), xpos.z());
|
||||
glMultMatrixf(R.ptr());
|
||||
// we must glBegin() and glEnd() here, because each particle is a single fan
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0.5f, 0.5f);
|
||||
glVertex3fv(xpos.ptr());
|
||||
glVertex3f(0,0,0);
|
||||
glTexCoord2f(hex_texcoord_x1, hex_texcoord_y1);
|
||||
glVertex3fv((xpos+p1*cosPI3+p2*sinPI3).ptr());
|
||||
//glVertex3f(xpos.x() + cs * cosPI3, xpos.y() + cs * sinPI3, xpos.z());
|
||||
glVertex3fv((p1*cosPI3+p2*sinPI3).ptr());
|
||||
glTexCoord2f(hex_texcoord_x2, hex_texcoord_y1);
|
||||
glVertex3fv((xpos-p1*cosPI3+p2*sinPI3).ptr());
|
||||
//glVertex3f(xpos.x() - cs * cosPI3, xpos.y() + cs * sinPI3, xpos.z());
|
||||
glVertex3fv((-p1*cosPI3+p2*sinPI3).ptr());
|
||||
glTexCoord2f(0, 0.5f);
|
||||
glVertex3fv((xpos-p1).ptr());
|
||||
//glVertex3f(xpos.x() - cs, xpos.y(), xpos.z());
|
||||
glVertex3fv((-p1).ptr());
|
||||
glTexCoord2f(hex_texcoord_x2, hex_texcoord_y2);
|
||||
glVertex3fv((xpos-p1*cosPI3-p2*sinPI3).ptr());
|
||||
//glVertex3f(xpos.x() - cs * cosPI3, xpos.y() - cs * sinPI3, xpos.z());
|
||||
glVertex3fv((-p1*cosPI3-p2*sinPI3).ptr());
|
||||
glTexCoord2f(hex_texcoord_x1, hex_texcoord_y2);
|
||||
glVertex3fv((xpos+p1*cosPI3-p2*sinPI3).ptr());
|
||||
//glVertex3f(xpos.x() + cs * cosPI3, xpos.y() - cs * sinPI3, xpos.z());
|
||||
glVertex3fv((p1*cosPI3-p2*sinPI3).ptr());
|
||||
glTexCoord2f(1, 0.5f);
|
||||
glVertex3fv((xpos+p1).ptr());
|
||||
//glVertex3f(xpos.x() + cs, xpos.y(), xpos.z());
|
||||
glVertex3fv((p1).ptr());
|
||||
glTexCoord2f(hex_texcoord_x1, hex_texcoord_y1);
|
||||
glVertex3fv((xpos+p1*cosPI3+p2*sinPI3).ptr());
|
||||
//glVertex3f(xpos.x() + cs * cosPI3, xpos.y() + cs * sinPI3, xpos.z());
|
||||
glVertex3fv((p1*cosPI3+p2*sinPI3).ptr());
|
||||
glEnd();
|
||||
glPopMatrix();
|
||||
break;
|
||||
|
||||
case LINE:
|
||||
{
|
||||
// Get the normalized direction of the particle, to be used in the
|
||||
// calculation of one of the linesegment endpoints.
|
||||
float vl = velocity_.length();
|
||||
if (vl != 0) {
|
||||
osg::Vec3 v = velocity_ * current_size_ * scale / vl;
|
||||
|
||||
glTexCoord1f(0);
|
||||
glVertex3f(xpos.x(), xpos.y(), xpos.z());
|
||||
glTexCoord1f(1);
|
||||
glVertex3f(xpos.x() + v.x(), xpos.y() + v.y(), xpos.z() + v.z());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -19,7 +19,12 @@ osgParticle::ParticleProcessor::ParticleProcessor()
|
||||
ps_(0),
|
||||
need_ltw_matrix_(false),
|
||||
need_wtl_matrix_(false),
|
||||
current_nodevisitor_(0)
|
||||
current_nodevisitor_(0),
|
||||
endless_(true),
|
||||
lifeTime_(0.0),
|
||||
startTime_(0.0),
|
||||
currentTime_(0.0),
|
||||
resetTime_(0.0)
|
||||
{
|
||||
setCullingActive(false);
|
||||
}
|
||||
@@ -32,65 +37,84 @@ osgParticle::ParticleProcessor::ParticleProcessor(const ParticleProcessor ©,
|
||||
ps_(static_cast<ParticleSystem *>(copyop(copy.ps_.get()))),
|
||||
need_ltw_matrix_(copy.need_ltw_matrix_),
|
||||
need_wtl_matrix_(copy.need_wtl_matrix_),
|
||||
current_nodevisitor_(0)
|
||||
current_nodevisitor_(0),
|
||||
endless_(copy.endless_),
|
||||
lifeTime_(copy.lifeTime_),
|
||||
startTime_(copy.startTime_),
|
||||
currentTime_(copy.currentTime_),
|
||||
resetTime_(copy.resetTime_)
|
||||
{
|
||||
}
|
||||
|
||||
void osgParticle::ParticleProcessor::traverse(osg::NodeVisitor &nv)
|
||||
{
|
||||
// continue only if enabled
|
||||
if (enabled_ )
|
||||
{
|
||||
|
||||
// typecast the NodeVisitor to CullVisitor
|
||||
osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor *>(&nv);
|
||||
|
||||
// typecast the NodeVisitor to CullVisitor
|
||||
osgUtil::CullVisitor *cv = dynamic_cast<osgUtil::CullVisitor *>(&nv);
|
||||
// continue only if the visitor actually is a cull visitor
|
||||
if (cv) {
|
||||
|
||||
// continue only if the visitor actually is a cull visitor
|
||||
if (cv) {
|
||||
// continue only if the particle system is valid
|
||||
if (ps_.valid())
|
||||
{
|
||||
|
||||
// continue only if the particle system is valid
|
||||
if (ps_.valid())
|
||||
if (nv.getFrameStamp())
|
||||
{
|
||||
|
||||
if (nv.getFrameStamp())
|
||||
{
|
||||
// retrieve the current time
|
||||
double t = nv.getFrameStamp()->getReferenceTime();
|
||||
|
||||
// retrieve the current time
|
||||
double t = nv.getFrameStamp()->getReferenceTime();
|
||||
// reset this processor if we've reached the reset point
|
||||
if ((currentTime_ >= resetTime_) && (resetTime_ > 0)) {
|
||||
currentTime_ = 0;
|
||||
t0_ = -1;
|
||||
}
|
||||
|
||||
// skip if we haven't initialized t0_ yet
|
||||
if (t0_ != -1) {
|
||||
// skip if we haven't initialized t0_ yet
|
||||
if (t0_ != -1) {
|
||||
|
||||
// check whether the particle system is frozen/culled
|
||||
if (!ps_->isFrozen() && (ps_->getLastFrameNumber() >= (nv.getFrameStamp()->getFrameNumber() - 1) || !ps_->getFreezeOnCull())) {
|
||||
// check whether the processor is alive
|
||||
bool alive = false;
|
||||
if (currentTime_ >= startTime_) {
|
||||
if (endless_ || (currentTime_ < (startTime_ + lifeTime_)))
|
||||
alive = true;
|
||||
}
|
||||
|
||||
// initialize matrix flags
|
||||
need_ltw_matrix_ = true;
|
||||
need_wtl_matrix_ = true;
|
||||
current_nodevisitor_ = &nv;
|
||||
// update current time
|
||||
currentTime_ += t - t0_;
|
||||
|
||||
// do some process (unimplemented in this base class)
|
||||
process(t - t0_);
|
||||
}
|
||||
// process only if the particle system is not frozen/culled
|
||||
if (alive &&
|
||||
enabled_ &&
|
||||
!ps_->isFrozen() &&
|
||||
(ps_->getLastFrameNumber() >= (nv.getFrameStamp()->getFrameNumber() - 1) || !ps_->getFreezeOnCull())) {
|
||||
|
||||
// initialize matrix flags
|
||||
need_ltw_matrix_ = true;
|
||||
need_wtl_matrix_ = true;
|
||||
current_nodevisitor_ = &nv;
|
||||
|
||||
// do some process (unimplemented in this base class)
|
||||
process(t - t0_);
|
||||
}
|
||||
|
||||
// update t0_
|
||||
t0_ = t;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN) << "osgParticle::ParticleProcessor::traverse(NodeVisitor&) requires a valid FrameStamp to function, particles not updated.\n";
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
osg::notify(osg::WARN) << "ParticleProcessor \"" << getName() << "\": invalid particle system\n";
|
||||
// update t0_
|
||||
t0_ = t;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN) << "osgParticle::ParticleProcessor::traverse(NodeVisitor&) requires a valid FrameStamp to function, particles not updated.\n";
|
||||
}
|
||||
|
||||
} else
|
||||
{
|
||||
osg::notify(osg::WARN) << "ParticleProcessor \"" << getName() << "\": invalid particle system\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// call the inherited method
|
||||
Node::traverse(nv);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ osgParticle::ParticleSystem::ParticleSystem()
|
||||
bounds_computed_(false),
|
||||
def_ptemp_(Particle()),
|
||||
last_frame_(0),
|
||||
freeze_on_cull_(true),
|
||||
freeze_on_cull_(false),
|
||||
detail_(1),
|
||||
draw_count_(0)
|
||||
{
|
||||
|
||||
@@ -68,11 +68,11 @@ DataInputStream::DataInputStream(std::istream* istream){
|
||||
DataInputStream::~DataInputStream(){}
|
||||
|
||||
bool DataInputStream::readBool(){
|
||||
bool b;
|
||||
_istream->read((char*)&b, BOOLSIZE);
|
||||
char c;
|
||||
_istream->read(&c, CHARSIZE);
|
||||
if (_istream->rdstate() & _istream->failbit)
|
||||
throw Exception("DataInputStream::readBool(): Failed to read boolean value.");
|
||||
return b;
|
||||
return c;
|
||||
}
|
||||
|
||||
char DataInputStream::readChar(){
|
||||
|
||||
@@ -58,8 +58,10 @@ DataOutputStream::DataOutputStream(std::ostream * ostream){
|
||||
|
||||
DataOutputStream::~DataOutputStream(){}
|
||||
|
||||
void DataOutputStream::writeBool(bool b){
|
||||
_ostream->write((char*)&b, BOOLSIZE);
|
||||
void DataOutputStream::writeBool(bool b)
|
||||
{
|
||||
char c = b;
|
||||
_ostream->write(&c, CHARSIZE);
|
||||
}
|
||||
|
||||
void DataOutputStream::writeChar(char c){
|
||||
|
||||
@@ -3,6 +3,7 @@ include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
IO_AccelOperator.cpp\
|
||||
IO_AngularAccelOperator.cpp\
|
||||
IO_CenteredPlacer.cpp\
|
||||
IO_Emitter.cpp\
|
||||
IO_FluidFrictionOperator.cpp\
|
||||
|
||||
48
src/osgPlugins/osgParticle/IO_AngularAccelOperator.cpp
Normal file
48
src/osgPlugins/osgParticle/IO_AngularAccelOperator.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
#include <osgParticle/AngularAccelOperator>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/Input>
|
||||
#include <osgDB/Output>
|
||||
|
||||
#include <osg/Vec3>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
bool AngularAccelOperator_readLocalData(osg::Object &obj, osgDB::Input &fr);
|
||||
bool AngularAccelOperator_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
|
||||
|
||||
osgDB::RegisterDotOsgWrapperProxy AngularAccelOperator_Proxy
|
||||
(
|
||||
new osgParticle::AngularAccelOperator,
|
||||
"AngularAccelOperator",
|
||||
"Object Operator AngularAccelOperator",
|
||||
AngularAccelOperator_readLocalData,
|
||||
AngularAccelOperator_writeLocalData
|
||||
);
|
||||
|
||||
bool AngularAccelOperator_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
{
|
||||
osgParticle::AngularAccelOperator &aop = static_cast<osgParticle::AngularAccelOperator &>(obj);
|
||||
bool itAdvanced = false;
|
||||
|
||||
osg::Vec3 a;
|
||||
|
||||
if (fr[0].matchWord("angularAcceleration")) {
|
||||
if (fr[1].getFloat(a.x()) && fr[2].getFloat(a.y()) && fr[3].getFloat(a.z())) {
|
||||
aop.setAngularAcceleration(a);
|
||||
fr += 4;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return itAdvanced;
|
||||
}
|
||||
|
||||
bool AngularAccelOperator_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
||||
{
|
||||
const osgParticle::AngularAccelOperator &aop = static_cast<const osgParticle::AngularAccelOperator &>(obj);
|
||||
osg::Vec3 a = aop.getAngularAcceleration();
|
||||
fw.indent() << "angularAcceleration " << a.x() << " " << a.y() << " " << a.z() << std::endl;
|
||||
return true;
|
||||
}
|
||||
@@ -32,6 +32,8 @@ bool read_particle(osgDB::Input &fr, osgParticle::Particle &P)
|
||||
P.setShape(osgParticle::Particle::POINT);
|
||||
} else if (std::string(ptstr) == "QUAD_TRIANGLESTRIP") {
|
||||
P.setShape(osgParticle::Particle::QUAD_TRIANGLESTRIP);
|
||||
} else if (std::string(ptstr) == "LINE") {
|
||||
P.setShape(osgParticle::Particle::LINE);
|
||||
} else {
|
||||
osg::notify(osg::WARN) << "Particle reader warning: invalid shape: " << ptstr << std::endl;
|
||||
}
|
||||
@@ -87,6 +89,22 @@ bool read_particle(osgDB::Input &fr, osgParticle::Particle &P)
|
||||
fr += 4;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
if (fr[0].matchWord("angle")) {
|
||||
osg::Vec3 v;
|
||||
if (fr[1].getFloat(v.x()) && fr[2].getFloat(v.y()) && fr[3].getFloat(v.z())) {
|
||||
P.setAngle(v);
|
||||
fr += 4;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
if (fr[0].matchWord("angularVelocity")) {
|
||||
osg::Vec3 v;
|
||||
if (fr[1].getFloat(v.x()) && fr[2].getFloat(v.y()) && fr[3].getFloat(v.z())) {
|
||||
P.setAngularVelocity(v);
|
||||
fr += 4;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
if (fr[0].matchWord("radius")) {
|
||||
float f;
|
||||
@@ -152,8 +170,9 @@ void write_particle(const osgParticle::Particle &P, osgDB::Output &fw)
|
||||
case osgParticle::Particle::POINT: fw << "POINT" << std::endl; break;
|
||||
case osgParticle::Particle::HEXAGON: fw << "HEXAGON" << std::endl; break;
|
||||
case osgParticle::Particle::QUAD_TRIANGLESTRIP: fw << "QUAD_TRIANGLESTRIP" << std::endl; break;
|
||||
case osgParticle::Particle::QUAD:
|
||||
default: fw << "QUAD" << std::endl; break;
|
||||
case osgParticle::Particle::QUAD: fw << "QUAD" << std::endl; break;
|
||||
case osgParticle::Particle::LINE:
|
||||
default: fw << "LINE" << std::endl; break;
|
||||
}
|
||||
|
||||
fw.indent() << "lifeTime " << P.getLifeTime() << std::endl;
|
||||
@@ -177,8 +196,16 @@ void write_particle(const osgParticle::Particle &P, osgDB::Output &fw)
|
||||
fw.indent() << "velocity ";
|
||||
fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
|
||||
|
||||
fw.indent() << "mass " << P.getMass() << std::endl;
|
||||
v = P.getAngle();
|
||||
fw.indent() << "angle ";
|
||||
fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
|
||||
|
||||
v = P.getAngularVelocity();
|
||||
fw.indent() << "angularVelocity ";
|
||||
fw << v.x() << " " << v.y() << " " << v.z() << std::endl;
|
||||
|
||||
fw.indent() << "radius " << P.getRadius() << std::endl;
|
||||
fw.indent() << "mass " << P.getMass() << std::endl;
|
||||
|
||||
// interpolators
|
||||
|
||||
|
||||
@@ -63,6 +63,54 @@ bool ParticleProcessor_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("endless")) {
|
||||
if (fr[1].matchWord("TRUE")) {
|
||||
myobj.setEndless(true);
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
} else if (fr[1].matchWord("FALSE")) {
|
||||
myobj.setEndless(false);
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("lifeTime")) {
|
||||
float lt;
|
||||
if (fr[1].getFloat(lt)) {
|
||||
myobj.setLifeTime(lt);
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("startTime")) {
|
||||
float st;
|
||||
if (fr[1].getFloat(st)) {
|
||||
myobj.setStartTime(st);
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("currentTime")) {
|
||||
float ct;
|
||||
if (fr[1].getFloat(ct)) {
|
||||
myobj.setCurrentTime(ct);
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("resetTime")) {
|
||||
float ct;
|
||||
if (fr[1].getFloat(ct)) {
|
||||
myobj.setResetTime(ct);
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return itAdvanced;
|
||||
}
|
||||
|
||||
@@ -89,5 +137,16 @@ bool ParticleProcessor_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
||||
fw << "RELATIVE_TO_PARENTS" << std::endl;
|
||||
}
|
||||
|
||||
fw.indent() << "endless ";
|
||||
if (myobj.isEndless())
|
||||
fw << "TRUE" << std::endl;
|
||||
else
|
||||
fw << "FALSE" << std::endl;
|
||||
|
||||
fw.indent() << "lifeTime " << myobj.getLifeTime() << std::endl;
|
||||
fw.indent() << "startTime " << myobj.getStartTime() << std::endl;
|
||||
fw.indent() << "currentTime " << myobj.getCurrentTime() << std::endl;
|
||||
fw.indent() << "resetTime " << myobj.getResetTime() << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,17 @@ bool RadialShooter_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
}
|
||||
}
|
||||
|
||||
if (fr[0].matchWord("initialRotationalSpeedRange")) {
|
||||
osg::Vec3 r1;
|
||||
osg::Vec3 r2;
|
||||
if (fr[1].getFloat(r1.x()) && fr[2].getFloat(r1.y()) && fr[3].getFloat(r1.z()) && \
|
||||
fr[4].getFloat(r2.x()) && fr[5].getFloat(r2.y()) && fr[6].getFloat(r2.z())) {
|
||||
myobj.setInitialRotationalSpeedRange(r1,r2);
|
||||
fr += 7;
|
||||
itAdvanced = true;
|
||||
}
|
||||
}
|
||||
|
||||
return itAdvanced;
|
||||
}
|
||||
|
||||
@@ -63,6 +74,13 @@ bool RadialShooter_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
||||
fw.indent() << "phiRange " << r.minimum << " " << r.maximum << std::endl;
|
||||
r = myobj.getInitialSpeedRange();
|
||||
fw.indent() << "initialSpeedRange " << r.minimum << " " << r.maximum << std::endl;
|
||||
|
||||
osgParticle::rangev3 rv = myobj.getInitialRotationalSpeedRange();
|
||||
osg::Vec3 v1 = rv.minimum;
|
||||
osg::Vec3 v2 = rv.maximum;
|
||||
fw.indent() << "initialRotationalSpeedRange ";
|
||||
fw << v1.x() << " " << v1.y() << " " << v1.z() << " ";
|
||||
fw << v2.x() << " " << v2.y() << " " << v2.z() << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user