Moved PrecipitationDrawable into PrecipitationEffect.

This commit is contained in:
Robert Osfield
2006-04-22 06:33:01 +00:00
parent c144977b6e
commit 1cf1710f92
6 changed files with 178 additions and 250 deletions

View File

@@ -3,7 +3,6 @@ include $(TOPDIR)/Make/makedefs
CXXFILES =\
PrecipitationEffect.cpp\
PrecipitationDrawable.cpp\
osgprecipitation.cpp\
LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)

View File

@@ -1,94 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include "PrecipitationDrawable.h"
#include <osg/Notify>
#include <osg/io_utils>
using namespace osgParticle;
PrecipitationDrawable::PrecipitationDrawable()
{
setSupportsDisplayList(false);
}
PrecipitationDrawable::PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop):
Drawable(copy,copyop)
{
}
void PrecipitationDrawable::setParameters(PrecipitationParameters* parameters)
{
_parameters = parameters;
}
void PrecipitationDrawable::compileGLObjects(osg::State& state) const
{
osg::notify(osg::NOTICE)<<"PrecipitationDrawable::compileGLObjects()"<<this<<std::endl;
}
void PrecipitationDrawable::drawImplementation(osg::State& state) const
{
if (!_geometry) return;
const osg::Geometry::Extensions* extensions = osg::Geometry::getExtensions(state.getContextID(),true);
// save OpenGL matrices
glPushMatrix();
glMatrixMode( GL_TEXTURE );
glPushMatrix();
state.setActiveTextureUnit(0);
for(CellMatrixMap::const_iterator itr = _currentCellMatrixMap.begin();
itr != _currentCellMatrixMap.end();
++itr)
{
float _startTime = 0.0f;
extensions->glMultiTexCoord1f(GL_TEXTURE0+1, _startTime);
// load cells current modelview matrix
glMatrixMode( GL_MODELVIEW );
glLoadMatrix(itr->second.ptr());
CellMatrixMap::const_iterator pitr = _previousCellMatrixMap.find(itr->first);
if (pitr != _previousCellMatrixMap.end())
{
// load previous frame modelview matrix for motion blurr effect
glMatrixMode( GL_TEXTURE );
glLoadMatrix(pitr->second.ptr());
}
else
{
// use current modelview matrix as "previous" frame value, cancelling motion blurr effect
glMatrixMode( GL_TEXTURE );
glLoadMatrix(itr->second.ptr());
}
_geometry->draw(state);
}
// restore OpenGL matrices
glMatrixMode( GL_TEXTURE );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}

View File

@@ -1,112 +0,0 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2005 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGPARTICLE_PRECIPITATIODRAWABLE
#define OSGPARTICLE_PRECIPITATIODRAWABLE
#include <osg/Geometry>
#include <osgParticle/Export>
#include "PrecipitationParameters.h"
namespace osgParticle
{
class OSGPARTICLE_EXPORT PrecipitationDrawable : public osg::Drawable
{
public:
PrecipitationDrawable();
PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgParticle, PrecipitationDrawable);
virtual bool supports(const osg::PrimitiveFunctor&) const { return false; }
virtual void accept(osg::PrimitiveFunctor&) const {}
virtual bool supports(const osg::PrimitiveIndexFunctor&) const { return false; }
virtual void accept(osg::PrimitiveIndexFunctor&) const {}
void setParameters(PrecipitationParameters* parameters);
PrecipitationParameters* getParameters() { return _parameters.get(); }
const PrecipitationParameters* getParameters() const { return _parameters.get(); }
void setGeometry(osg::Geometry* geom) { _geometry = geom; }
osg::Geometry* getGeometry() { return _geometry.get(); }
const osg::Geometry* getGeometry() const { return _geometry.get(); }
virtual void compileGLObjects(osg::State& state) const;
virtual void drawImplementation(osg::State& state) const;
struct Cell
{
Cell(int in_i, int in_j, int in_k):
i(in_i), j(in_j), k(in_k) {}
inline bool operator == (const Cell& rhs) const
{
return i==rhs.i && j==rhs.j && k==rhs.k;
}
inline bool operator != (const Cell& rhs) const
{
return i!=rhs.i || j!=rhs.j || k!=rhs.k;
}
inline bool operator < (const Cell& rhs) const
{
if (i<rhs.i) return true;
if (i>rhs.i) return false;
if (j<rhs.j) return true;
if (j>rhs.j) return false;
if (k<rhs.k) return true;
if (k>rhs.k) return false;
return false;
}
int i;
int j;
int k;
};
typedef std::map< Cell, osg::Matrix > CellMatrixMap;
CellMatrixMap& getCurrentCellMatrixMap() { return _currentCellMatrixMap; }
CellMatrixMap& getPreviousCellMatrixMap() { return _previousCellMatrixMap; }
inline void newFrame()
{
_previousCellMatrixMap.swap(_currentCellMatrixMap);
_currentCellMatrixMap.clear();
}
protected:
virtual ~PrecipitationDrawable() {}
osg::ref_ptr<PrecipitationParameters> _parameters;
osg::ref_ptr<osg::Geometry> _geometry;
mutable CellMatrixMap _currentCellMatrixMap;
mutable CellMatrixMap _previousCellMatrixMap;
};
}
#endif

View File

@@ -178,8 +178,6 @@ void PrecipitationEffect::traverse(osg::NodeVisitor& nv)
precipitationDrawableSet._pointPrecipitationDrawable = new PrecipitationDrawable;
precipitationDrawableSet._pointPrecipitationDrawable->setGeometry(_pointGeometry.get());
precipitationDrawableSet._pointPrecipitationDrawable->setStateSet(_pointStateSet.get());
precipitationDrawableSet.setParameters(_parameters.get());
}
cull(precipitationDrawableSet, cv);
@@ -220,15 +218,6 @@ void PrecipitationEffect::setParameters(PrecipitationParameters* parameters)
if (_parameters==parameters) return;
_parameters = parameters;
// inform the PrecipitationDrawable about the change.
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
for(ViewDrawableMap::iterator itr=_viewDrawableMap.begin();
itr!=_viewDrawableMap.end();
++itr)
{
(itr->second).setParameters(parameters);
}
}
void PrecipitationEffect::update()
@@ -272,7 +261,7 @@ void PrecipitationEffect::update()
float cellVolume = length_u*length_v*length_w;
// time taken to get from start to the end of cycle
float period = fabsf(_parameters->cellSizeZ / _parameters->particleVelocity.z());
_period = fabsf(_parameters->cellSizeZ / _parameters->particleVelocity.z());
_du.set(length_u, 0.0f, 0.0f);
_dv.set(0.0f, length_v, 0.0f);
@@ -318,8 +307,6 @@ void PrecipitationEffect::update()
precipitationDrawableSet._pointPrecipitationDrawable->setGeometry(_pointGeometry.get());
precipitationDrawableSet._pointPrecipitationDrawable->setStateSet(_pointStateSet.get());
precipitationDrawableSet.setParameters(_parameters.get());
}
}
@@ -329,11 +316,9 @@ void PrecipitationEffect::update()
const osg::BoundingBox& bb = _parameters->boundingBox;
osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/period);
//osg::Uniform* startTime = new osg::Uniform("startTime",0.0f);
osg::Uniform* inversePeriodUniform = new osg::Uniform("inversePeriod",1.0f/_period);
_precipitationStateSet->addUniform(inversePeriodUniform); // float
//stateset->addUniform(startTime); // float
_precipitationStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
_precipitationStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
@@ -694,8 +679,6 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit
float eye_i = eye_kPlane*_inverse_du;
float eye_j = eye_kPlane*_inverse_dv;
float _startTime = 0.0f;
osg::Polytope frustum;
frustum.setToUnitFrustum(false,false);
frustum.transformProvidingInverse(cv->getProjectionMatrix());
@@ -718,13 +701,19 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit
unsigned int numTested=0;
unsigned int numInFrustum=0;
float iCyle = 0.43;
float jCyle = 0.64;
for(int i = i_min; i<=i_max; ++i)
{
for(int j = j_min; j<=j_max; ++j)
{
for(int k = k_min; k<=k_max; ++k)
{
if (build(eyeLocal, i,j,k, pds, frustum, cv)) ++numInFrustum;
float startTime = (float)(i)*iCyle + (float)(j)*jCyle;
startTime = (startTime-floor(startTime))*_period;
if (build(eyeLocal, i,j,k, startTime, pds, frustum, cv)) ++numInFrustum;
++numTested;
}
}
@@ -732,11 +721,11 @@ void PrecipitationEffect::cull(PrecipitationDrawableSet& pds, osgUtil::CullVisit
osg::Timer_t endTick = osg::Timer::instance()->tick();
// osg::notify(osg::NOTICE)<<"time for cull "<<osg::Timer::instance()->delta_m(startTick,endTick)<<"ms numTested="<<numTested<<" numInFrustum"<<numInFrustum<<std::endl;
// osg::notify(osg::NOTICE)<<" quads "<<pds._quadPrecipitationDrawable->getCurrentCellMatrixMap().size()<<" lines "<<pds._linePrecipitationDrawable->getCurrentCellMatrixMap().size()<<" points "<<pds._pointPrecipitationDrawable->getCurrentCellMatrixMap().size()<<std::endl;
// osg::notify(osg::NOTICE)<<"time for cull "<<osg::Timer::instance()->delta_m(startTick,endTick)<<"ms numTested="<<numTested<<" numInFrustum"<<numInFrustum<<std::endl;
// osg::notify(osg::NOTICE)<<" quads "<<pds._quadPrecipitationDrawable->getCurrentCellMatrixMap().size()<<" lines "<<pds._linePrecipitationDrawable->getCurrentCellMatrixMap().size()<<" points "<<pds._pointPrecipitationDrawable->getCurrentCellMatrixMap().size()<<std::endl;
}
bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const
bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, float startTime, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const
{
osg::Vec3 position = _origin + osg::Vec3(float(i)*_du.x(), float(j)*_dv.y(), float(k+1)*_dw.z());
osg::Vec3 scale(_du.x(), _dv.y(), -_dw.z());
@@ -752,17 +741,23 @@ bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, P
osg::Matrix* mymodelview = 0;
if (distance < _parameters->nearTransition)
{
mymodelview = &(pds._quadPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]);
PrecipitationDrawable::MatrixStartTimePair& mstp = pds._quadPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)];
mymodelview = &mstp.first;
mstp.second = startTime;
}
else if (distance <= _parameters->farTransition)
{
if (_parameters->useFarLineSegments)
{
mymodelview = &(pds._linePrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]);
PrecipitationDrawable::MatrixStartTimePair& mstp = pds._linePrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)];
mymodelview = &mstp.first;
mstp.second = startTime;
}
else
{
mymodelview = &(pds._pointPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)]);
PrecipitationDrawable::MatrixStartTimePair& mstp = pds._pointPrecipitationDrawable->getCurrentCellMatrixMap()[PrecipitationDrawable::Cell(i,k,j)];
mymodelview = &mstp.first;
mstp.second = startTime;
}
}
else
@@ -776,3 +771,72 @@ bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, P
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Precipitation Drawable
//
////////////////////////////////////////////////////////////////////////////////////////////////////
PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable()
{
setSupportsDisplayList(false);
}
PrecipitationEffect::PrecipitationDrawable::PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop):
Drawable(copy,copyop)
{
}
void PrecipitationEffect::PrecipitationDrawable::drawImplementation(osg::State& state) const
{
if (!_geometry) return;
const osg::Geometry::Extensions* extensions = osg::Geometry::getExtensions(state.getContextID(),true);
// save OpenGL matrices
glPushMatrix();
glMatrixMode( GL_TEXTURE );
glPushMatrix();
state.setActiveTextureUnit(0);
for(CellMatrixMap::const_iterator itr = _currentCellMatrixMap.begin();
itr != _currentCellMatrixMap.end();
++itr)
{
extensions->glMultiTexCoord1f(GL_TEXTURE0+1, itr->second.second);
// load cells current modelview matrix
glMatrixMode( GL_MODELVIEW );
glLoadMatrix(itr->second.first.ptr());
CellMatrixMap::const_iterator pitr = _previousCellMatrixMap.find(itr->first);
if (pitr != _previousCellMatrixMap.end())
{
// load previous frame modelview matrix for motion blurr effect
glMatrixMode( GL_TEXTURE );
glLoadMatrix(pitr->second.first.ptr());
}
else
{
// use current modelview matrix as "previous" frame value, cancelling motion blurr effect
glMatrixMode( GL_TEXTURE );
glLoadMatrix(itr->second.first.ptr());
}
_geometry->draw(state);
}
// restore OpenGL matrices
glMatrixMode( GL_TEXTURE );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
}

View File

@@ -18,12 +18,13 @@
#include <osg/BoundingBox>
#include <osg/ClearNode>
#include <osg/Fog>
#include <osg/Geometry>
#include <osgUtil/CullVisitor>
#include <osgParticle/Export>
#include "PrecipitationDrawable.h"
#include "PrecipitationParameters.h"
namespace osgParticle
{
@@ -63,22 +64,91 @@ namespace osgParticle
void setUpGeometries(unsigned int numParticles);
class OSGPARTICLE_EXPORT PrecipitationDrawable : public osg::Drawable
{
public:
PrecipitationDrawable();
PrecipitationDrawable(const PrecipitationDrawable& copy, const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgParticle, PrecipitationDrawable);
virtual bool supports(const osg::PrimitiveFunctor&) const { return false; }
virtual void accept(osg::PrimitiveFunctor&) const {}
virtual bool supports(const osg::PrimitiveIndexFunctor&) const { return false; }
virtual void accept(osg::PrimitiveIndexFunctor&) const {}
void setGeometry(osg::Geometry* geom) { _geometry = geom; }
osg::Geometry* getGeometry() { return _geometry.get(); }
const osg::Geometry* getGeometry() const { return _geometry.get(); }
virtual void drawImplementation(osg::State& state) const;
struct Cell
{
Cell(int in_i, int in_j, int in_k):
i(in_i), j(in_j), k(in_k) {}
inline bool operator == (const Cell& rhs) const
{
return i==rhs.i && j==rhs.j && k==rhs.k;
}
inline bool operator != (const Cell& rhs) const
{
return i!=rhs.i || j!=rhs.j || k!=rhs.k;
}
inline bool operator < (const Cell& rhs) const
{
if (i<rhs.i) return true;
if (i>rhs.i) return false;
if (j<rhs.j) return true;
if (j>rhs.j) return false;
if (k<rhs.k) return true;
if (k>rhs.k) return false;
return false;
}
int i;
int j;
int k;
};
typedef std::pair<osg::Matrix, float> MatrixStartTimePair;
typedef std::map< Cell, MatrixStartTimePair > CellMatrixMap;
CellMatrixMap& getCurrentCellMatrixMap() { return _currentCellMatrixMap; }
CellMatrixMap& getPreviousCellMatrixMap() { return _previousCellMatrixMap; }
inline void newFrame()
{
_previousCellMatrixMap.swap(_currentCellMatrixMap);
_currentCellMatrixMap.clear();
}
protected:
virtual ~PrecipitationDrawable() {}
osg::ref_ptr<osg::Geometry> _geometry;
mutable CellMatrixMap _currentCellMatrixMap;
mutable CellMatrixMap _previousCellMatrixMap;
};
struct PrecipitationDrawableSet
{
void setParameters(PrecipitationParameters* parameters)
{
if (_quadPrecipitationDrawable.valid()) _quadPrecipitationDrawable->setParameters(parameters);
if (_linePrecipitationDrawable.valid()) _linePrecipitationDrawable->setParameters(parameters);
if (_pointPrecipitationDrawable.valid()) _pointPrecipitationDrawable->setParameters(parameters);
}
osg::ref_ptr<PrecipitationDrawable> _quadPrecipitationDrawable;
osg::ref_ptr<PrecipitationDrawable> _linePrecipitationDrawable;
osg::ref_ptr<PrecipitationDrawable> _pointPrecipitationDrawable;
};
void cull(PrecipitationDrawableSet& pds, osgUtil::CullVisitor* cv) const;
bool build(const osg::Vec3 eyeLocal, int i, int j, int k, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const;
bool build(const osg::Vec3 eyeLocal, int i, int j, int k, float startTime, PrecipitationDrawableSet& pds, osg::Polytope& frustum, osgUtil::CullVisitor* cv) const;
osg::ref_ptr<PrecipitationParameters> _parameters;
@@ -105,13 +175,14 @@ namespace osgParticle
osg::ref_ptr<osg::StateSet> _pointStateSet;
osg::Vec3 _origin;
osg::Vec3 _du;
osg::Vec3 _dv;
osg::Vec3 _dw;
osg::Vec3 _inverse_du;
osg::Vec3 _inverse_dv;
osg::Vec3 _inverse_dw;
float _period;
osg::Vec3 _origin;
osg::Vec3 _du;
osg::Vec3 _dv;
osg::Vec3 _dw;
osg::Vec3 _inverse_du;
osg::Vec3 _inverse_dv;
osg::Vec3 _inverse_dw;
};

View File

@@ -61,7 +61,7 @@ namespace osgParticle
void snow(float intensity)
{
particleVelocity = osg::Vec3(0.0,0.0,-1.0) + osg::Vec3(0.0,0.0,-0.5)*intensity;
particleVelocity = osg::Vec3(0.0,0.0,-0.75) + osg::Vec3(0.0,0.0,-0.25)*intensity;
particleSize = 0.02 + 0.03*intensity;
particleColour = osg::Vec4(0.85f, 0.85f, 0.85f, 1.0f) - osg::Vec4(0.1f, 0.1f, 0.1f, 1.0f)* intensity;
particleDensity = intensity * 8.2f;