diff --git a/src/osgParticle/Particle.cpp b/src/osgParticle/Particle.cpp index 288062cfc..683bda217 100644 --- a/src/osgParticle/Particle.cpp +++ b/src/osgParticle/Particle.cpp @@ -130,12 +130,6 @@ 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); @@ -147,19 +141,18 @@ void osgParticle::Particle::render(const osg::Vec3& xpos, const osg::Vec3& px, c case QUAD: glTexCoord2f(_s_coord, _t_coord); - glVertex3fv((xpos-(p1+p2)*R).ptr()); + glVertex3fv((xpos-(p1+p2)).ptr()); glTexCoord2f(_s_coord+_s_tile, _t_coord); - glVertex3fv((xpos+(p1-p2)*R).ptr()); + glVertex3fv((xpos+(p1-p2)).ptr()); glTexCoord2f(_s_coord+_s_tile, _t_coord+_t_tile); - glVertex3fv((xpos+(p1+p2)*R).ptr()); + glVertex3fv((xpos+(p1+p2)).ptr()); glTexCoord2f(_s_coord, _t_coord+_t_tile); - glVertex3fv((xpos-(p1-p2)*R).ptr()); + glVertex3fv((xpos-(p1-p2)).ptr()); break; case QUAD_TRIANGLESTRIP: glPushMatrix(); glTranslatef(xpos.x(), xpos.y(), xpos.z()); - glMultMatrix(R.ptr()); // we must glBegin() and glEnd() here, because each particle is a single strip glBegin(GL_TRIANGLE_STRIP); glTexCoord2f(_s_coord+_s_tile, _t_coord+_t_tile); @@ -170,14 +163,12 @@ void osgParticle::Particle::render(const osg::Vec3& xpos, const osg::Vec3& px, c glVertex3fv((p1-p2).ptr()); glTexCoord2f(_s_coord, _t_coord); glVertex3fv((-p1-p2).ptr()); - glEnd(); glPopMatrix(); break; case HEXAGON: glPushMatrix(); glTranslatef(xpos.x(), xpos.y(), xpos.z()); - glMultMatrix(R.ptr()); // we must glBegin() and glEnd() here, because each particle is a single fan glBegin(GL_TRIANGLE_FAN); glTexCoord2f(_s_coord + _s_tile * 0.5f, _t_coord + _t_tile * 0.5f); @@ -197,7 +188,6 @@ void osgParticle::Particle::render(const osg::Vec3& xpos, const osg::Vec3& px, c glTexCoord2f(_s_coord + _s_tile * hex_texcoord_x1, _t_coord + _t_tile * hex_texcoord_y1); glVertex3fv((p1*cosPI3+p2*sinPI3).ptr()); glEnd(); - glPopMatrix(); break; case LINE: diff --git a/src/osgParticle/ParticleSystem.cpp b/src/osgParticle/ParticleSystem.cpp index 80b5b4b9c..6266376dd 100644 --- a/src/osgParticle/ParticleSystem.cpp +++ b/src/osgParticle/ParticleSystem.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -180,23 +181,36 @@ void osgParticle::ParticleSystem::single_pass_render(osg::State& /*state*/, con osg::Vec3 xAxis = _align_X_axis; osg::Vec3 yAxis = _align_Y_axis; + osg::Vec3 scaled_aligned_xAxis = _align_X_axis; + osg::Vec3 scaled_aligned_yAxis = _align_Y_axis; + + float xScale = 1.0f; + float yScale = 1.0f; + if (_alignment==BILLBOARD) { - xAxis = osg::Matrix::transform3x3(modelview,xAxis); - yAxis = osg::Matrix::transform3x3(modelview,yAxis); - float scaleX = xAxis.length(); - float scaleY = yAxis.length(); + xAxis = osg::Matrix::transform3x3(modelview,_align_X_axis); + yAxis = osg::Matrix::transform3x3(modelview,_align_Y_axis); + + float lengthX2 = xAxis.length2(); + float lengthY2 = yAxis.length2(); if (_particleScaleReferenceFrame==LOCAL_COORDINATES) { - xAxis /= scaleX; - yAxis /= scaleY; + xScale = 1.0f/sqrtf(lengthX2); + yScale = 1.0f/sqrtf(lengthY2); } else { - xAxis /= (scaleX*scaleX); - yAxis /= (scaleY*scaleY); + xScale = 1.0f/lengthX2; + yScale = 1.0f/lengthY2; } + + scaled_aligned_xAxis *= xScale; + scaled_aligned_xAxis *= yScale; + + xAxis *= xScale; + yAxis *= yScale; } for(unsigned int i=0; i<_particles.size(); i+=_detail) @@ -212,7 +226,38 @@ void osgParticle::ParticleSystem::single_pass_render(osg::State& /*state*/, con } ++_draw_count; - currentParticle->render(currentParticle->getPosition(), xAxis, yAxis, scale); + const osg::Vec3& angle = currentParticle->getAngle(); + bool requiresRotation = (angle.x()!=0.0f || angle.y()!=0.0f || angle.z()!=0.0f); + if (requiresRotation) + { + 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)); + + if (_alignment==BILLBOARD) + { + xAxis = osg::Matrix::transform3x3(R,scaled_aligned_xAxis); + xAxis = osg::Matrix::transform3x3(modelview,xAxis); + + yAxis = osg::Matrix::transform3x3(R,scaled_aligned_yAxis); + yAxis = osg::Matrix::transform3x3(modelview,yAxis); + + currentParticle->render(currentParticle->getPosition(), xAxis, yAxis, scale); + } + else + { + xAxis = osg::Matrix::transform3x3(R, scaled_aligned_xAxis); + yAxis = osg::Matrix::transform3x3(R, scaled_aligned_yAxis); + + currentParticle->render(currentParticle->getPosition(), xAxis, yAxis, scale); + } + } + else + { + currentParticle->render(currentParticle->getPosition(), xAxis, yAxis, scale); + } } }