Checked in osgParticle, writtten by Marco Jez.

This commit is contained in:
Robert Osfield
2002-06-05 12:44:55 +00:00
parent f8ffc692be
commit 9ba7505d1e
110 changed files with 10467 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
#include <osgParticle/Particle>
#include <osgParticle/LinearInterpolator>
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Matrix>
#include <osg/GL>
#include <osg/Notify>
namespace
{
const float cosPI3 = cosf(osg::PI / 3.0f);
const float sinPI3 = sinf(osg::PI / 3.0f);
const float hex_texcoord_x1 = 0.5f + 0.5f * cosPI3;
const float hex_texcoord_x2 = 0.5f - 0.5f * cosPI3;
const float hex_texcoord_y1 = 0.5f + 0.5f * sinPI3;
const float hex_texcoord_y2 = 0.5f - 0.5f * sinPI3;
}
osgParticle::Particle::Particle()
: shape_(QUAD),
sr_(0.2f, 0.2f),
ar_(1, 0),
cr_(osg::Vec4(1, 1, 1, 1), osg::Vec4(1, 1, 1, 1)),
si_(osgNew LinearInterpolator),
ai_(osgNew LinearInterpolator),
ci_(osgNew LinearInterpolator),
alive_(true),
mustdie_(false),
lifetime_(2),
radius_(0.2f),
mass_(0.1f),
massinv_(10.0f),
prev_pos_(0, 0, 0),
position_(0, 0, 0),
velocity_(0, 0, 0),
t0_(0)
{
}
bool osgParticle::Particle::update(double dt)
{
// this method should return false when the particle dies;
// so, if we were instructed to die, do it now and return.
if (mustdie_) {
alive_ = false;
return false;
}
double x = 0;
// if we don't live forever, compute our normalized age.
if (lifetime_ > 0) {
x = t0_ / lifetime_;
}
t0_ += dt;
// if our age is over the lifetime limit, then die and return.
if (x > 1) {
alive_ = false;
return false;
}
// compute the current values for size, alpha and color.
current_size_ = si_.get()->interpolate(x, sr_);
current_alpha_ = ai_.get()->interpolate(x, ar_);
current_color_ = ci_.get()->interpolate(x, cr_);
// update position
prev_pos_ = position_;
position_ += velocity_ * dt;
return true;
}
void osgParticle::Particle::render(const osg::Matrix &modelview, float scale) const
{
osg::Vec3 xpos = modelview.preMult(position_);
glColor4f( current_color_.x(),
current_color_.y(),
current_color_.z(),
current_color_.w() * current_alpha_);
float cs = current_size_ * scale;
switch (shape_)
{
case POINT:
glVertex3f(xpos.x(), xpos.y(), xpos.z());
break;
case QUAD:
glTexCoord2f(0, 0);
glVertex3f(xpos.x() - cs, xpos.y() - cs, xpos.z());
glTexCoord2f(1, 0);
glVertex3f(xpos.x() + cs, xpos.y() - cs, xpos.z());
glTexCoord2f(1, 1);
glVertex3f(xpos.x() + cs, xpos.y() + cs, xpos.z());
glTexCoord2f(0, 1);
glVertex3f(xpos.x() - cs, xpos.y() + cs, xpos.z());
break;
case QUAD_TRIANGLESTRIP:
// we must glBegin() and glEnd() here, because each particle is a single strip
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(1, 1);
glVertex3f(xpos.x() + cs, xpos.y() + cs, xpos.z());
glTexCoord2f(0, 1);
glVertex3f(xpos.x() - cs, xpos.y() + cs, xpos.z());
glTexCoord2f(1, 0);
glVertex3f(xpos.x() + cs, xpos.y() - cs, xpos.z());
glTexCoord2f(0, 0);
glVertex3f(xpos.x() - cs, xpos.y() - cs, xpos.z());
glEnd();
break;
case HEXAGON:
// we must glBegin() and glEnd() here, because each particle is a single fan
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(0.5f, 0.5f);
glVertex3f(xpos.x(), xpos.y(), xpos.z());
glTexCoord2f(hex_texcoord_x1, hex_texcoord_y1);
glVertex3f(xpos.x() + cs * cosPI3, xpos.y() + cs * sinPI3, xpos.z());
glTexCoord2f(hex_texcoord_x2, hex_texcoord_y1);
glVertex3f(xpos.x() - cs * cosPI3, xpos.y() + cs * sinPI3, xpos.z());
glTexCoord2f(0, 0.5f);
glVertex3f(xpos.x() - cs, xpos.y(), xpos.z());
glTexCoord2f(hex_texcoord_x2, hex_texcoord_y2);
glVertex3f(xpos.x() - cs * cosPI3, xpos.y() - cs * sinPI3, xpos.z());
glTexCoord2f(hex_texcoord_x1, hex_texcoord_y2);
glVertex3f(xpos.x() + cs * cosPI3, xpos.y() - cs * sinPI3, xpos.z());
glTexCoord2f(1, 0.5f);
glVertex3f(xpos.x() + cs, xpos.y(), xpos.z());
glTexCoord2f(hex_texcoord_x1, hex_texcoord_y1);
glVertex3f(xpos.x() + cs * cosPI3, xpos.y() + cs * sinPI3, xpos.z());
glEnd();
break;
default:
osg::notify(osg::WARN) << "Invalid shape for particles\n";
}
}