From 89d9ca11c9c88a4c411f431927d4c96d381db329 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 5 Mar 2004 15:44:15 +0000 Subject: [PATCH] From Marco Jez, on behalf of Farshid Lashkari. Details from Marco's email: "I've just received an addition to osgParticle from Farshid Lashkari. It enhances the generation of texture coordinates on particles so that animated textures can be used, with the current frame of animation being computed from each particle's current age. Clients just have to call Particle::setTextureTile() and specify the number of horizontal and vertical tiles that make the animation up in the texture image." --- include/osgParticle/Particle | 24 +++++++++++++++++ src/osgParticle/Particle.cpp | 50 ++++++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/include/osgParticle/Particle b/include/osgParticle/Particle index d9fc3b604..2ca8a9003 100644 --- a/include/osgParticle/Particle +++ b/include/osgParticle/Particle @@ -212,6 +212,9 @@ namespace osgParticle /// Get the current (interpolated) polygon size. Valid only after the first call to update(). inline float getCurrentSize() const; + + // Specify how the particle texture is tiled + inline void setTextureTile(int sTile, int tTile, int numTiles = 0); private: Shape shape_; @@ -244,6 +247,13 @@ namespace osgParticle float current_size_; float current_alpha_; osg::Vec4 current_color_; + + float s_tile_; + float t_tile_; + int num_tile_; + int cur_tile_; + float s_coord_; + float t_coord_; }; // INLINE FUNCTIONS @@ -487,6 +497,20 @@ namespace osgParticle { return current_size_; } + + inline void Particle::setTextureTile(int sTile, int tTile, int numTiles) + { + s_tile_ = 1.0f / static_cast(sTile); + t_tile_ = 1.0f / static_cast(tTile); + if (numTiles <= 0) + { + num_tile_ = sTile * tTile; + } + else + { + num_tile_ = numTiles; + } + } } diff --git a/src/osgParticle/Particle.cpp b/src/osgParticle/Particle.cpp index 07e8de7ad..06307aa88 100644 --- a/src/osgParticle/Particle.cpp +++ b/src/osgParticle/Particle.cpp @@ -41,7 +41,13 @@ osgParticle::Particle::Particle() angular_vel_(0, 0, 0), t0_(0), current_size_(0), - current_alpha_(0) + current_alpha_(0), + s_tile_(1.0f), + t_tile_(1.0f), + num_tile_(1), + cur_tile_(-1), + s_coord_(0.0f), + t_coord_(0.0f) { } @@ -69,6 +75,16 @@ bool osgParticle::Particle::update(double dt) return false; } + //Compute the current texture tile based on our normalized age + int currentTile = static_cast(x * num_tile_); + + //If the current texture tile is different from previous, then compute new texture coords + if(currentTile != cur_tile_) { + cur_tile_ = currentTile; + s_coord_ = s_tile_ * fmod(cur_tile_ , 1.0 / s_tile_); + t_coord_ = 1.0 - t_tile_ * (static_cast(cur_tile_ * t_tile_) + 1); + } + // compute the current values for size, alpha and color. current_size_ = si_.get()->interpolate(x, sr_); current_alpha_ = ai_.get()->interpolate(x, ar_); @@ -115,13 +131,13 @@ void osgParticle::Particle::render(const osg::Vec3 &xpos, const osg::Vec3 &px, c break; case QUAD: - glTexCoord2f(0, 0); + glTexCoord2f(s_coord_, t_coord_); glVertex3fv((xpos-(p1+p2)*R).ptr()); - glTexCoord2f(1, 0); + glTexCoord2f(s_coord_+s_tile_, t_coord_); glVertex3fv((xpos+(p1-p2)*R).ptr()); - glTexCoord2f(1, 1); + glTexCoord2f(s_coord_+s_tile_, t_coord_+t_tile_); glVertex3fv((xpos+(p1+p2)*R).ptr()); - glTexCoord2f(0, 1); + glTexCoord2f(s_coord_, t_coord_+t_tile_); glVertex3fv((xpos-(p1-p2)*R).ptr()); break; @@ -131,13 +147,13 @@ void osgParticle::Particle::render(const osg::Vec3 &xpos, const osg::Vec3 &px, c glMultMatrix(R.ptr()); // we must glBegin() and glEnd() here, because each particle is a single strip glBegin(GL_TRIANGLE_STRIP); - glTexCoord2f(1, 1); + glTexCoord2f(s_coord_+s_tile_, t_coord_+t_tile_); glVertex3fv((p1+p2).ptr()); - glTexCoord2f(0, 1); + glTexCoord2f(s_coord_, t_coord_+t_tile_); glVertex3fv((-p1+p2).ptr()); - glTexCoord2f(1, 0); + glTexCoord2f(s_coord_+s_tile_, t_coord_); glVertex3fv((p1-p2).ptr()); - glTexCoord2f(0, 0); + glTexCoord2f(s_coord_, t_coord_); glVertex3fv((-p1-p2).ptr()); glEnd(); glPopMatrix(); @@ -149,21 +165,21 @@ void osgParticle::Particle::render(const osg::Vec3 &xpos, const osg::Vec3 &px, c glMultMatrix(R.ptr()); // we must glBegin() and glEnd() here, because each particle is a single fan glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(0.5f, 0.5f); + glTexCoord2f(s_coord_ + s_tile_ * 0.5f, t_coord_ + t_tile_ * 0.5f); glVertex3f(0,0,0); - glTexCoord2f(hex_texcoord_x1, hex_texcoord_y1); + glTexCoord2f(s_coord_ + s_tile_ * hex_texcoord_x1, t_coord_ + t_tile_ * hex_texcoord_y1); glVertex3fv((p1*cosPI3+p2*sinPI3).ptr()); - glTexCoord2f(hex_texcoord_x2, hex_texcoord_y1); + glTexCoord2f(s_coord_ + s_tile_ * hex_texcoord_x2, t_coord_ + t_tile_ * hex_texcoord_y1); glVertex3fv((-p1*cosPI3+p2*sinPI3).ptr()); - glTexCoord2f(0, 0.5f); + glTexCoord2f(s_coord_, t_coord_ + t_tile_ * 0.5f); glVertex3fv((-p1).ptr()); - glTexCoord2f(hex_texcoord_x2, hex_texcoord_y2); + glTexCoord2f(s_coord_ + s_tile_ * hex_texcoord_x2, t_coord_ + t_tile_ * hex_texcoord_y2); glVertex3fv((-p1*cosPI3-p2*sinPI3).ptr()); - glTexCoord2f(hex_texcoord_x1, hex_texcoord_y2); + glTexCoord2f(s_coord_ + s_tile_ * hex_texcoord_x1, t_coord_ + t_tile_ * hex_texcoord_y2); glVertex3fv((p1*cosPI3-p2*sinPI3).ptr()); - glTexCoord2f(1, 0.5f); + glTexCoord2f(s_coord_ + s_tile_, t_coord_ + t_tile_ * 0.5f); glVertex3fv((p1).ptr()); - glTexCoord2f(hex_texcoord_x1, hex_texcoord_y1); + glTexCoord2f(s_coord_ + s_tile_ * hex_texcoord_x1, t_coord_ + t_tile_ * hex_texcoord_y1); glVertex3fv((p1*cosPI3+p2*sinPI3).ptr()); glEnd(); glPopMatrix();