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:
Robert Osfield
2003-09-02 20:39:41 +00:00
parent 763ee70f2f
commit 4761442005
19 changed files with 607 additions and 84 deletions

View File

@@ -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: