More clean up for synch with 0.8.42

This commit is contained in:
Don BURNS
2001-09-19 21:19:47 +00:00
parent 2462c6273c
commit 7e81f6cfa6
292 changed files with 39673 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
#ifndef OSGUTIL_CULLVIEWSTATE
#define OSGUTIL_CULLVIEWSTATE 1
#include <osg/BoundingSphere>
#include <osg/BoundingBox>
#include <osg/Matrix>
#include <osg/ClippingVolume>
#include <osgUtil/Export>
namespace osgUtil {
/** Container class for encapsulating the viewing state in local
coordinates, during the cull traversal.
*/
class OSGUTIL_EXPORT CullViewState : public osg::Referenced
{
public:
CullViewState();
osg::ref_ptr<osg::Matrix> _matrix;
osg::ref_ptr<osg::Matrix> _inverse;
osg::Vec3 _eyePoint;
osg::Vec3 _centerPoint;
osg::Vec3 _lookVector;
osg::Vec3 _upVector;
unsigned int _bbCornerFar;
unsigned int _bbCornerNear;
float _ratio2;
osg::ClippingVolume _clippingVolume;
enum
{
NO_CULLING = 0x00,
FRUSTUM_LEFT_CULLING = 0x01,
FRUSTUM_RIGHT_CULLING = 0x02,
FRUSTUM_BOTTOM_CULLING = 0x04,
FRUSTUM_TOP_CULLING = 0x08,
FRUSTUM_NEAR_CULLING = 0x10,
FRUSTUM_FAR_CULLING = 0x20,
VIEW_FRUSTUM_CULLING = 0x3F,
SMALL_FEATURE_CULLING = 0x40,
ENALBE_ALL_CULLING = 0x7F
};
typedef unsigned int CullingMode;
inline bool isCulled(const osg::BoundingSphere& sp,CullingMode& mode) const
{
if (!sp.isValid()) return true;
if (!_clippingVolume.contains(sp,mode)) return true;
if (mode&SMALL_FEATURE_CULLING)
{
osg::Vec3 delta(sp._center-_eyePoint);
if (sp.radius2()<delta.length2()*_ratio2)
{
return true;
}
}
return false;
}
inline bool isCulled(const osg::BoundingBox& bb,CullingMode mode) const
{
if (!bb.isValid()) return true;
return !_clippingVolume.contains(bb,mode);
}
protected:
~CullViewState();
};
};
#endif

378
include/osgUtil/CullVisitor Normal file
View File

@@ -0,0 +1,378 @@
#ifndef OSGUTIL_NEWCULLVISITOR
#define OSGUTIL_NEWCULLVISITOR 1
#include <osg/NodeVisitor>
#include <osg/BoundingSphere>
#include <osg/BoundingBox>
#include <osg/Matrix>
#include <osg/Drawable>
#include <osg/StateSet>
#include <osg/State>
#include <osg/Camera>
#include <osg/Impostor>
#include <osg/Notify>
#include <osgUtil/RenderGraph>
#include <osgUtil/RenderStage>
#include <osgUtil/CullViewState>
#include <map>
#include <vector>
namespace osgUtil {
/**
* Basic NodeVisitor implementation for rendering a scene.
* This visitor traverses the scene graph, collecting transparent and
* opaque osg::Drawables into a depth sorted transparent bin and a state
* sorted opaque bin. The opaque bin is rendered first, and then the
* transparent bin in rendered in order from the furthest osg::Drawable
* from the eye to the one nearest the eye.
*/
class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
{
public:
CullVisitor();
virtual ~CullVisitor();
void reset();
virtual void apply(osg::Node&);
virtual void apply(osg::Geode& node);
virtual void apply(osg::Billboard& node);
virtual void apply(osg::LightSource& node);
virtual void apply(osg::Group& node);
virtual void apply(osg::Transform& node);
virtual void apply(osg::Switch& node);
virtual void apply(osg::LOD& node);
virtual void apply(osg::Impostor& node);
void setCamera(const osg::Camera& camera);
const osg::Camera* getCamera() const { return _camera.get(); }
void setLODBias(const float bias) { _LODBias = bias; }
const float getLODBias() const { return _LODBias; }
/** Switch the creation of Impostors on or off.
* Setting active to false forces the CullVisitor to use the Impostor
* LOD children for rendering. Setting active to true forces the
* CullVisitor to create the appropriate pre-rendering stages which
* render to the ImpostorSprite's texture.*/
void setImpostorsActive(const bool active) { _impostorActive = active; }
/** Get whether impostors are active or not. */
const bool getImpostorsActive() const { return _impostorActive; }
/** Set the impostor error threshold.
* Used in calculation of whether impostors remain valid.*/
void setImpostorPixelErrorThreshold(const float numPixels) { _impostorPixelErrorThreshold=numPixels; }
/** Get the impostor error threshold.*/
const float getImpostorPixelErrorThreshold() const { return _impostorPixelErrorThreshold; }
/** Set whether ImpsotorSprite's should be placed in a depth sorted bin for rendering.*/
void setDepthSortImpostorSprites(const bool doDepthSort) { _depthSortImpostorSprites = doDepthSort; }
/** Get whether ImpsotorSprite's are depth sorted bin for rendering.*/
const bool setDepthSortImpostorSprites() const { return _depthSortImpostorSprites; }
/** Set the number of frames that an ImpsotorSprite's is kept whilst not being beyond,
* before being recycled.*/
void setNumberOfFrameToKeepImpostorSprites(const int numFrames) { _numFramesToKeepImpostorSprites = numFrames; }
/** Get the number of frames that an ImpsotorSprite's is kept whilst not being beyond,
* before being recycled.*/
const int getNumberOfFrameToKeepImpostorSprites() const { return _numFramesToKeepImpostorSprites; }
enum TransparencySortMode {
LOOK_VECTOR_DISTANCE,
OBJECT_EYE_POINT_DISTANCE
};
void setTransparencySortMode(TransparencySortMode tsm) { _tsm = tsm; }
/** Sets the current CullingMode.*/
void setCullingMode(CullViewState::CullingMode mode);
/** Returns the current CullingMode.*/
CullViewState::CullingMode getCullingMode() const;
/** Set the viewport.
* Used to enable the CullVisitor can make decision
* such as based on viewport dimensions,.*/
void setViewport(int x,int y,int width,int height)
{
_view[0] = x;
_view[1] = y;
_view[2] = width;
_view[3] = height;
}
/** Get the viewport. */
void getViewport(int& x,int& y,int& width,int& height)
{
x = _view[0];
y = _view[1];
width = _view[2];
height = _view[3];
}
/** Set the frame number.*/
inline void setFrameNumber(const int fn) { _frameNumber = fn; }
/** Get the frame number.*/
inline const int getFrameNumber() const { return _frameNumber; }
void pushCullViewState(const osg::Matrix* matrix=NULL);
void popCullViewState();
/** Push state set on the current state group.
* If the state exists in a child state group of the current
* state group then move the current state group to that child.
* Otherwise, create a new state group for the state set, add
* it to the current state group then move the current state
* group pointer to the new state group.
*/
inline void pushStateSet(const osg::StateSet* ss)
{
_currentRenderGraph = _currentRenderGraph->find_or_insert(ss);
if (ss->useRenderBinDetails())
{
_currentRenderBin = _currentRenderBin->find_or_insert(ss->getBinNumber(),ss->getBinName());
}
}
/** Pop the top state set and hence associated state group.
* Move the current state group to the parent of the popped
* state group.
*/
inline void popStateSet()
{
if (_currentRenderGraph->_stateset->useRenderBinDetails())
{
_currentRenderBin = _currentRenderBin->_parent;
}
_currentRenderGraph = _currentRenderGraph->_parent;
}
void setRenderGraph(RenderGraph* rg)
{
_rootRenderGraph = rg;
_currentRenderGraph = rg;
}
RenderGraph* getRenderGraph()
{
return _rootRenderGraph.get();
}
void setRenderStage(RenderStage* rg)
{
_rootRenderStage = rg;
_currentRenderBin = rg;
}
RenderStage* getRenderStage()
{
return _rootRenderStage.get();
}
const float getCalculatedNearPlane() const { return _calculated_znear; }
const float getCalculatedFarPlane() const { return _calculated_zfar; }
protected:
/** prevent unwanted copy construction.*/
CullVisitor(const CullVisitor&):osg::NodeVisitor() {}
/** prevent unwanted copy operator.*/
CullVisitor& operator = (const CullVisitor&) { return *this; }
inline osg::Matrix* getCurrentMatrix()
{
return _cvs->_matrix.get();
}
inline osg::Matrix* getInverseCurrentMatrix()
{
return _cvs->_inverse.get();
}
inline const osg::Vec3& getEyeLocal() const
{
return _cvs->_eyePoint;
}
inline const osg::Vec3& getCenterLocal() const
{
return _cvs->_centerPoint;
}
inline const osg::Vec3& getLookVectorLocal() const
{
return _cvs->_lookVector;
}
inline bool isCulled(const osg::BoundingSphere& sp,CullViewState::CullingMode& mode) const
{
return _cvs->isCulled(sp,mode);
}
inline const bool isCulled(const osg::BoundingBox& bb,const CullViewState::CullingMode mode) const
{
return _cvs->isCulled(bb,mode);
}
void updateCalculatedNearFar(const osg::BoundingBox& bb);
void updateCalculatedNearFar(const osg::Vec3& pos);
/** Add a drawable to current render graph.*/
inline void addDrawable(osg::Drawable* drawable,osg::Matrix* matrix)
{
if (_currentRenderGraph->leaves_empty())
{
// this is first leaf to be added to RenderGraph
// and therefore should not already know to current render bin,
// so need to add it.
_currentRenderBin->addRenderGraph(_currentRenderGraph);
}
//_currentRenderGraph->addLeaf(new RenderLeaf(drawable,matrix));
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,matrix));
}
/** Add a drawable and depth to current render graph.*/
inline void addDrawableAndDepth(osg::Drawable* drawable,osg::Matrix* matrix,const float depth)
{
if (_currentRenderGraph->leaves_empty())
{
// this is first leaf to be added to RenderGraph
// and therefore should not already know to current render bin,
// so need to add it.
_currentRenderBin->addRenderGraph(_currentRenderGraph);
}
//_currentRenderGraph->addLeaf(new RenderLeaf(drawable,matrix,depth));
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,matrix,depth));
}
/** Add a light to current render graph.*/
inline void addLight(osg::Light* light,osg::Matrix* matrix)
{
_currentRenderBin->_stage->addLight(light,matrix);
}
/** create an impostor sprite by setting up a pre-rendering stage
* to generate the impostor texture. */
osg::ImpostorSprite* createImpostorSprite(osg::Impostor& node);
int _frameNumber;
typedef std::vector< osg::ref_ptr<CullViewState> > CullViewStateStack;
CullViewStateStack _viewStateStack;
osg::ref_ptr<CullViewState> _tvs;
osg::ref_ptr<CullViewState> _cvs;
osg::ref_ptr<RenderGraph> _rootRenderGraph;
RenderGraph* _currentRenderGraph;
osg::ref_ptr<RenderStage> _rootRenderStage;
RenderBin* _currentRenderBin;
std::vector<CullViewState::CullingMode> _cullingModeStack;
float _LODBias;
float _calculated_znear;
float _calculated_zfar;
osg::ref_ptr<const osg::Camera> _camera;
TransparencySortMode _tsm;
// viewport x,y,width,height respectiveyly.
int _view[4];
bool _impostorActive;
bool _depthSortImpostorSprites;
float _impostorPixelErrorThreshold;
int _numFramesToKeepImpostorSprites;
typedef std::vector< osg::ref_ptr<osg::Matrix> > MatrixList;
MatrixList _reuseMatrixList;
unsigned int _currentReuseMatrixIndex;
inline osg::Matrix* createOrReuseMatrix()
{
// skip of any already reused matrix.
while (_currentReuseMatrixIndex<_reuseMatrixList.size() &&
_reuseMatrixList[_currentReuseMatrixIndex]->referenceCount()>1)
{
osg::notify(osg::NOTICE)<<"Warning:createOrReuseMatrix() skipping multiply refrenced entry."<<endl;
++_currentReuseMatrixIndex;
}
// if still within list, element must be singularily referenced
// there return it to be reused.
if (_currentReuseMatrixIndex<_reuseMatrixList.size())
{
osg::Matrix* matrix = _reuseMatrixList[_currentReuseMatrixIndex++].get();
matrix->makeIdent();
return matrix;
}
// otherwise need to create new matrix.
osg::Matrix* matrix = new osg::Matrix();
_reuseMatrixList.push_back(matrix);
++_currentReuseMatrixIndex;
return matrix;
}
typedef std::vector< osg::ref_ptr<RenderLeaf> > RenderLeafList;
RenderLeafList _reuseRenderLeafList;
unsigned int _currentReuseRenderLeafIndex;
inline RenderLeaf* createOrReuseRenderLeaf(osg::Drawable* drawable,osg::Matrix* matrix, float depth=0.0f)
{
// skip of any already reused renderleaf.
while (_currentReuseRenderLeafIndex<_reuseRenderLeafList.size() &&
_reuseRenderLeafList[_currentReuseRenderLeafIndex]->referenceCount()>1)
{
osg::notify(osg::NOTICE)<<"Warning:createOrReuseRenderLeaf() skipping multiply refrenced entry."<<endl;
++_currentReuseRenderLeafIndex;
}
// if still within list, element must be singularily referenced
// there return it to be reused.
if (_currentReuseRenderLeafIndex<_reuseRenderLeafList.size())
{
RenderLeaf* renderleaf = _reuseRenderLeafList[_currentReuseRenderLeafIndex++].get();
renderleaf->set(drawable,matrix,depth);
return renderleaf;
}
// otherwise need to create new renderleaf.
RenderLeaf* renderleaf = new RenderLeaf(drawable,matrix,depth);
_reuseRenderLeafList.push_back(renderleaf);
++_currentReuseRenderLeafIndex;
return renderleaf;
}
osg::ref_ptr<osg::ImpostorSpriteManager> _impostorSpriteManager;
};
};
#endif

View File

@@ -0,0 +1,46 @@
#ifndef OSGUTIL_DEPTHSORTEDBIN
#define OSGUTIL_DEPTHSORTEDBIN 1
#include <osgUtil/RenderBin>
namespace osgUtil {
class OSGUTIL_EXPORT DepthSortedBin : public RenderBin
{
public:
DepthSortedBin();
virtual osg::Object* clone() const { return new DepthSortedBin(); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const DepthSortedBin*>(obj)!=0L; }
virtual const char* className() const { return "DepthSortedBin"; }
virtual void reset();
virtual void sort_local();
virtual void draw_local(osg::State& state,RenderLeaf*& previous);
enum DrawOrder
{
FRONT_TO_BACK,
BACK_TO_FRONT
};
void setDrawOrder(const DrawOrder drawOrder) { _drawOrder = drawOrder; }
const DrawOrder getDrawOrder() const { return _drawOrder; }
protected:
virtual ~DepthSortedBin();
DrawOrder _drawOrder;
RenderLeafList _renderLeafList;
};
};
#endif

View File

@@ -0,0 +1,23 @@
#ifndef OSGUTIL_GUIEVENTHANDLER
#define OSGUTIL_GUIEVENTHANDLER 1
#include <osg/Referenced>
#include <osgUtil/Export>
#include <osgUtil/GUIEventAdapter>
#include <osgUtil/GUIActionAdapter>
namespace osgUtil{
class OSGUTIL_EXPORT GUIEventHandler : public osg::Referenced
{
public:
/** Handle events, return true if handled, false otherwise.*/
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us)=0;
};
};
#endif

View File

@@ -0,0 +1,57 @@
#ifndef OSGUTIL_INSERTIMPOSTORSVISITOR
#define OSGUTIL_INSERTIMPOSTORSVISITOR
#include <osg/NodeVisitor>
#include <osg/Impostor>
#include <osgUtil/Export>
namespace osgUtil {
/** Insert impostor nodes into scene graph.
* For example of usage see src/Demos/osgimpostor.
*/
class OSGUTIL_EXPORT InsertImpostorsVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
InsertImpostorsVisitor();
void setImpostorThresholdRatio(const float ratio) { _impostorThresholdRatio = ratio; }
const float getImpostorThresholdRatio() const { return _impostorThresholdRatio; }
void setMaximumNumberOfNestedImpostors(const unsigned int num) { _maximumNumNestedImpostors = num; }
const unsigned int getMaximumNumberOfNestedImpostors() const { return _maximumNumNestedImpostors; }
/** empty visitor, make it ready for next traversal.*/
void reset();
virtual void apply(osg::Node& node);
virtual void apply(osg::Group& node);
virtual void apply(osg::LOD& node);
virtual void apply(osg::Impostor& node);
/* insert the required impostors into the scene graph.*/
void insertImpostors();
protected:
typedef std::vector< osg::Group* > GroupList;
typedef std::vector< osg::LOD* > LODList;
GroupList _groupList;
LODList _lodList;
float _impostorThresholdRatio;
unsigned int _maximumNumNestedImpostors;
unsigned int _numNestedImpostors;
};
};
#endif

101
include/osgUtil/RenderBin Normal file
View File

@@ -0,0 +1,101 @@
#ifndef OSGUTIL_RENDERBIN
#define OSGUTIL_RENDERBIN 1
#include <osgUtil/RenderGraph>
#include <osgUtil/Statistics>
#include <map>
#include <vector>
#include <string>
namespace osgUtil {
class RenderStage;
/**
* RenderBin base class.
*/
class OSGUTIL_EXPORT RenderBin : public osg::Object
{
public:
typedef std::vector<RenderLeaf*> RenderLeafList;
typedef std::vector<RenderGraph*> RenderGraphList;
typedef std::map< int, osg::ref_ptr<RenderBin> > RenderBinList;
// static methods.
static RenderBin* createRenderBin(const std::string& binName);
static void addRenderBinPrototype(RenderBin* proto);
static void removeRenderBinPrototype(RenderBin* proto);
RenderBin();
virtual osg::Object* clone() const { return new RenderBin(); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RenderBin*>(obj)!=0L; }
virtual const char* className() const { return "RenderBin"; }
virtual void reset();
RenderBin* find_or_insert(int binNum,const std::string& binName);
void addRenderGraph(RenderGraph* rg)
{
_renderGraphList.push_back(rg);
}
void sort();
virtual void sort_local() {}
virtual void draw(osg::State& state,RenderLeaf*& previous);
virtual void draw_local(osg::State& state,RenderLeaf*& previous);
/** extract stats for current draw list. */
void getPrims(Statistics *primStats);
public:
int _binNum;
RenderBin* _parent;
RenderStage* _stage;
RenderBinList _bins;
RenderGraphList _renderGraphList;
typedef std::map< std::string, osg::ref_ptr<RenderBin> > RenderBinPrototypeList;
static RenderBinPrototypeList s_renderBinPrototypeList;
protected:
virtual ~RenderBin();
};
/** Proxy class for automatic registration of renderbins with the RenderBin prototypelist.*/
template<class T>
class RegisterRenderBinProxy
{
public:
RegisterRenderBinProxy()
{
_rb = new T;
RenderBin::addRenderBinPrototype(_rb.get());
}
~RegisterRenderBinProxy()
{
RenderBin::removeRenderBinPrototype(_rb.get());
}
protected:
osg::ref_ptr<T> _rb;
};
};
#endif

200
include/osgUtil/RenderGraph Normal file
View File

@@ -0,0 +1,200 @@
#ifndef OSGUTIL_RENDERGRAPH
#define OSGUTIL_RENDERGRAPH 1
#include <osg/Matrix>
#include <osg/Drawable>
#include <osg/StateSet>
#include <osg/State>
#include <osg/Light>
#include <osgUtil/RenderLeaf>
#include <set>
#include <vector>
namespace osgUtil {
// beginings of a replacement for DrawBin.
class OSGUTIL_EXPORT RenderGraph : public osg::Referenced
{
public:
typedef std::map< const osg::StateSet*, osg::ref_ptr<RenderGraph> > ChildList;
typedef std::vector< osg::ref_ptr<RenderLeaf> > LeafList;
RenderGraph* _parent;
osg::ref_ptr<const osg::StateSet> _stateset;
int _depth;
ChildList _children;
LeafList _leaves;
RenderGraph():
_parent(NULL),
_stateset(NULL),
_depth(0)
{
}
RenderGraph(RenderGraph* parent,const osg::StateSet* stateset):
_parent(parent),
_stateset(stateset)
{
if (_parent) _depth = _parent->_depth + 1;
else _depth = 0;
}
~RenderGraph() {}
/** return true if all of drawables, lights and chilren are empty.*/
inline const bool empty() const
{
return _leaves.empty() && _children.empty();
}
inline const bool leaves_empty() const
{
return _leaves.empty();
}
/** reset the internal contents of a RenderGraph, including deleting all children.*/
void reset();
/** recursively clean the RenderGraph of all its drawables, lights and depths.
* Leaves children intact, and ready to be populated again.*/
void clean();
/** recursively prune the RenderGraph of empty children.*/
void prune();
inline RenderGraph* find_or_insert(const osg::StateSet* stateset)
{
// search for the appropriate state group, return it if found.
ChildList::iterator itr = _children.find(stateset);
if (itr!=_children.end()) return itr->second.get();
// create a state group and insert it into the chilren list
// then return the state group.
RenderGraph* sg = new RenderGraph(this,stateset);
_children[stateset] = sg;
return sg;
}
/** add a render leaf.*/
inline void addLeaf(RenderLeaf* leaf)
{
if (leaf)
{
_leaves.push_back(leaf);
leaf->_parent = this;
}
}
static inline void moveRenderGraph(osg::State& state,RenderGraph* sg_curr,RenderGraph* sg_new)
{
if (sg_new==sg_curr || sg_new==NULL) return;
if (sg_curr==NULL)
{
// use return path to trace back steps to sg_new.
std::vector<RenderGraph*> return_path;
// need to pop back root render graph.
do
{
return_path.push_back(sg_new);
sg_new = sg_new->_parent;
} while (sg_new);
for(std::vector<RenderGraph*>::reverse_iterator itr=return_path.rbegin();
itr!=return_path.rend();
++itr)
{
RenderGraph* rg = (*itr);
if (rg->_stateset.valid()) state.pushStateSet(rg->_stateset.get());
}
return;
}
// first handle the typical case which is two state groups
// are neighbours.
if (sg_curr->_parent==sg_new->_parent)
{
// state has changed so need to pop old state.
if (sg_curr->_stateset.valid()) state.popStateSet();
// and push new state.
if (sg_new->_stateset.valid()) state.pushStateSet(sg_new->_stateset.get());
return;
}
// need to pop back upto the same depth as the new state group.
while (sg_curr->_depth>sg_new->_depth)
{
if (sg_curr->_stateset.valid()) state.popStateSet();
sg_curr = sg_curr->_parent;
}
// use return path to trace back steps to sg_new.
std::vector<RenderGraph*> return_path;
// need to pop back upto the same depth as the curr state group.
while (sg_new->_depth>sg_curr->_depth)
{
return_path.push_back(sg_new);
sg_new = sg_new->_parent;
}
// now pop back up both parent paths until they agree.
while (sg_curr->_parent!=sg_new->_parent)
{
if (sg_curr->_stateset.valid()) state.popStateSet();
sg_curr = sg_curr->_parent;
return_path.push_back(sg_new);
sg_new = sg_new->_parent;
}
for(std::vector<RenderGraph*>::reverse_iterator itr=return_path.rbegin();
itr!=return_path.rend();
++itr)
{
RenderGraph* rg = (*itr);
if (rg->_stateset.valid()) state.pushStateSet(rg->_stateset.get());
}
}
inline static void moveToRootRenderGraph(osg::State& state,RenderGraph* sg_curr)
{
// need to pop back all statesets and matrices.
while (sg_curr)
{
if (sg_curr->_stateset.valid()) state.popStateSet();
sg_curr = sg_curr->_parent;
}
}
private:
/// disallow copy construction.
RenderGraph(const RenderGraph&):osg::Referenced() {}
/// disallow copy operator.
RenderGraph& operator = (const RenderGraph&) { return *this; }
};
};
#endif

View File

@@ -0,0 +1,77 @@
#ifndef OSGUTIL_RENDERLEAF
#define OSGUTIL_RENDERLEAF 1
#include <osg/ref_ptr>
#include <osg/Matrix>
#include <osg/Drawable>
#include <osg/State>
#include <osgUtil/Export>
namespace osgUtil {
// forward declare RenderGraph
class RenderGraph;
/** container class for all data required for rendering of drawables.
*/
class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
{
public:
inline RenderLeaf(osg::Drawable* drawable,osg::Matrix* matrix, float depth=0.0f):
_parent(NULL),
_drawable(drawable),
_matrix(matrix),
_depth(depth) {}
inline void set(osg::Drawable* drawable,osg::Matrix* matrix, float depth=0.0f)
{
_parent = NULL;
_drawable = drawable;
_matrix = matrix;
_depth = depth;
}
inline void reset()
{
_parent = NULL;
_drawable = NULL;
_matrix = NULL;
_depth = 0.0f;
}
virtual void render(osg::State& state,RenderLeaf* previous);
/// allow RenderGraph to change the RenderLeaf's _parent.
friend RenderGraph;
public:
RenderGraph* _parent;
osg::Drawable* _drawable;
osg::ref_ptr<osg::Matrix> _matrix;
float _depth;
private:
/// disallow creation of blank RenderLeaf as this isn't useful.
RenderLeaf():
_parent(NULL),
_drawable(NULL),
_matrix(NULL),
_depth(0.0f) {}
/// disallow copy construction.
RenderLeaf(const RenderLeaf&):osg::Referenced() {}
/// disallow copy operator.
RenderLeaf& operator = (const RenderLeaf&) { return *this; }
};
};
#endif

154
include/osgUtil/RenderStage Normal file
View File

@@ -0,0 +1,154 @@
#ifndef OSGUTIL_RENDERSTAGE
#define OSGUTIL_RENDERSTAGE 1
#include <osg/Camera>
#include <osgUtil/RenderBin>
#include <osgUtil/RenderStageLighting>
namespace osgUtil {
/**
* RenderState base class. Used for encapsulate a complete stage in
* rendering - setting up of viewport, the projection and model
* matrices and rendering the RenderBin's enclosed with this RenderStage.
* RenderStage also has a dependancy list of other RenderStages, each
* of which must be called before the rendering of this stage. These
* 'pre' rendering stages are used for advanced rendering techniques
* like multistage pixel shading or impostors.
*/
class OSGUTIL_EXPORT RenderStage : public RenderBin
{
public:
RenderStage();
virtual osg::Object* clone() const { return new RenderStage(); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RenderStage*>(obj)!=0L; }
virtual const char* className() const { return "RenderStage"; }
virtual void reset();
/** Set the viewport of the scene view. */
void setViewport(int x,int y,int width,int height)
{
_view[0] = x;
_view[1] = y;
_view[2] = width;
_view[3] = height;
}
/** Get the viewport of the scene view. */
void getViewport(int& x,int& y,int& width,int& height) const
{
x = _view[0];
y = _view[1];
width = _view[2];
height = _view[3];
}
/** Set the clear mask used in glClear(..).
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
void setClearMask(const GLbitfield mask) { _clearMask = mask; }
/** Get the clear mask.*/
const GLbitfield getClearMask() const { return _clearMask; }
/** Set the clear color used in glClearColor(..).
* glClearColor is only called if mask & GL_COLOR_BUFFER_BIT is true*/
void setClearColor(const osg::Vec4& color) { _clearColor=color; }
/** Get the clear color.*/
const osg::Vec4& getClearColor() const { return _clearColor; }
/** Set the clear accum used in glClearAccum(..).
* glClearAcumm is only called if mask & GL_ACCUM_BUFFER_BIT is true*/
void setClearAccum(const osg::Vec4& color) { _clearAccum=color; }
/** Get the clear accum.*/
const osg::Vec4& getClearAccum() const { return _clearAccum; }
/** Set the clear depth used in glClearDepth(..). Defaults to 1.0
* glClearDepth is only called if mask & GL_DEPTH_BUFFER_BIT is true*/
void setClearDepth(const double depth) { _clearDepth=depth; }
/** Get the clear depth.*/
const double getClearDepth() const { return _clearDepth; }
/** Set the clear stencil value used in glClearStencil(). Defaults to 1.0
* glClearStencil is only called if mask & GL_STENCIL_BUFFER_BIT is true*/
void setClearStencil(const int stencil) { _clearStencil=stencil; }
/** Get the clear color.*/
const int getClearStencil() const { return _clearStencil; }
void setCamera(osg::Camera* camera) { _camera = camera; }
osg::Camera* getCamera() { return _camera.get(); }
const osg::Camera* getCamera() const { return _camera.get(); }
void setRenderStageLighting(RenderStageLighting* rsl) { _renderStageLighting = rsl; }
RenderStageLighting* getRenderStageLighting() const
{
if (!_renderStageLighting.valid()) _renderStageLighting = new RenderStageLighting;
return _renderStageLighting.get();
}
void setLightingMode(RenderStageLighting::Mode mode) { getRenderStageLighting()->setLightingMode(mode); }
RenderStageLighting::Mode getLightingMode() const { return getRenderStageLighting()->getLightingMode(); }
void setLight(osg::Light* light) { getRenderStageLighting()->setLight(light); }
osg::Light* getLight() { return getRenderStageLighting()->getLight(); }
const osg::Light* getLight() const { return getRenderStageLighting()->getLight(); }
virtual void addLight(osg::Light* light,osg::Matrix* matrix)
{
getRenderStageLighting()->addLight(light,matrix);
}
virtual void draw(osg::State& state,RenderLeaf*& previous);
void addToDependencyList(RenderStage* rs);
/** extract stats for current draw list. */
void getPrims(Statistics *primStats);
public:
typedef std::vector< osg::ref_ptr<RenderStage> > DependencyList;
bool _stageDrawnThisFrame;
DependencyList _dependencyList;
osg::ref_ptr<osg::Camera> _camera;
// viewport x,y,width,height.
GLint _view[4];
GLbitfield _clearMask;
osg::Vec4 _clearColor;
osg::Vec4 _clearAccum;
double _clearDepth;
int _clearStencil;
mutable osg::ref_ptr<RenderStageLighting> _renderStageLighting;
protected:
virtual ~RenderStage();
};
};
#endif

View File

@@ -0,0 +1,67 @@
#ifndef OSGUTIL_RENDERSTAGELIGHTING
#define OSGUTIL_RENDERSTAGELIGHTING 1
#include <osg/Object>
#include <osg/Light>
#include <osg/State>
#include <osgUtil/RenderLeaf>
#include <osgUtil/RenderGraph>
namespace osgUtil {
/**
* RenderBin base class.
*/
class OSGUTIL_EXPORT RenderStageLighting : public osg::Object
{
public:
RenderStageLighting();
virtual osg::Object* clone() const { return new RenderStageLighting(); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RenderStageLighting*>(obj)!=0L; }
virtual const char* className() const { return "RenderStageLighting"; }
virtual void reset();
enum Mode {
HEADLIGHT, // default
SKY_LIGHT,
NO_SCENEVIEW_LIGHT
};
void setLightingMode(Mode mode) { _lightingMode=mode; }
Mode getLightingMode() const { return _lightingMode; }
void setLight(osg::Light* light) { _light = light; }
osg::Light* getLight() { return _light.get(); }
const osg::Light* getLight() const { return _light.get(); }
typedef std::pair< osg::Light*, osg::ref_ptr<osg::Matrix> > LightMatrixPair;
typedef std::vector< LightMatrixPair > LightList;
virtual void addLight(osg::Light* light,osg::Matrix* matrix)
{
_lightList.push_back(LightMatrixPair(light,matrix));
}
virtual void draw(osg::State& state,RenderLeaf*& previous);
public:
Mode _lightingMode;
osg::ref_ptr<osg::Light> _light;
LightList _lightList;
protected:
virtual ~RenderStageLighting();
};
};
#endif

View File

@@ -0,0 +1,44 @@
#ifndef OSGUTIL_RENDERTOTEXTURESTAGE
#define OSGUTIL_RENDERTOTEXTURESTAGE 1
#include <osg/Texture>
#include <osgUtil/RenderStage>
namespace osgUtil {
/**
* RenderBin base class.
*/
class OSGUTIL_EXPORT RenderToTextureStage : public RenderStage
{
public:
RenderToTextureStage();
virtual osg::Object* clone() const { return new RenderToTextureStage(); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const RenderToTextureStage*>(obj)!=0L; }
virtual const char* className() const { return "RenderToTextureStage"; }
virtual void reset();
void setTexture(osg::Texture* texture) { _texture = texture; }
osg::Texture* getTexture() { return _texture.get(); }
virtual void draw(osg::State& state,RenderLeaf*& previous);
public:
protected:
virtual ~RenderToTextureStage();
osg::ref_ptr<osg::Texture> _texture;
};
};
#endif

View File

@@ -0,0 +1,62 @@
#ifndef OSGUTIL_SceneViewManipulator
#define OSGUTIL_SceneViewManipulator 1
#include <osgUtil/Export>
#include <osgUtil/SceneView>
#include <osgUtil/CameraManipulator>
#include <osgUtil/StateSetManipulator>
#include <osgUtil/GUIEventAdapter>
#include <osgUtil/GUIActionAdapter>
namespace osgUtil{
class OSGUTIL_EXPORT SceneViewManipulator : public GUIEventHandler
{
public:
SceneViewManipulator();
virtual ~SceneViewManipulator();
/** attach a scene view to the manipulator. */
virtual void setSceneView(SceneView*);
/** get the attached a scene view.*/
virtual SceneView * getSceneView();
/** get the attached a const scene view.*/
virtual const SceneView * getSceneView() const;
/** Set the camera manipulator on the object.*/
virtual void setCameraManipulator(CameraManipulator *cm) {_cm=cm;}
/** Get the camera manipulator on the object */
virtual CameraManipulator *getCameraManipulator() {return _cm.get();}
/** Get the const camera manipulator on the object */
virtual const CameraManipulator *getCameraManipulator() const {return _cm.get();}
/** Set the geostate manipulator on the object.*/
virtual void setStateSetManipulator(StateSetManipulator *cm) {_gm=cm;}
/** Get the geostate manipulator on the object */
virtual StateSetManipulator *getStateSetManipulator() { return _gm.get();}
/** Get the geostate manipulator on the object */
virtual const StateSetManipulator *getStateSetManipulator() const {return _gm.get();}
/** Handle events, return true if handled, false otherwise.*/
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
protected:
// Reference pointer to our scene view
osg::ref_ptr<SceneView> _sv;
osg::ref_ptr<CameraManipulator> _cm;
osg::ref_ptr<StateSetManipulator> _gm;
};
}
#endif

View File

@@ -0,0 +1,35 @@
#ifndef OSGUTIL_SMOOTHINGVISITOR
#define OSGUTIL_SMOOTHINGVISITOR 1
#include <osg/NodeVisitor>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osgUtil/Export>
namespace osgUtil {
/** A smoothing visitor for calculating smoothed normals for
* osg::GeoSet's which contains surface primitives.
*/
class OSGUTIL_EXPORT SmoothingVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
SmoothingVisitor()
{
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
}
/// smooth geoset by creating per vertex normals.
static void smooth(osg::GeoSet& geoset);
/// apply smoothing method to all geode geosets.
virtual void apply(osg::Geode& geode);
};
};
#endif

View File

@@ -0,0 +1,44 @@
#ifndef OSGUTIL_GEOSTATE_MANIPULATOR
#define OSGUTIL_GEOSTATE_MANIPULATOR 1
#include <osg/StateSet>
#include <osgUtil/Export>
#include <osgUtil/GUIEventAdapter>
#include <osgUtil/GUIActionAdapter>
#include <osgUtil/GUIEventHandler>
namespace osgUtil{
class OSGUTIL_EXPORT StateSetManipulator : public GUIEventHandler
{
public:
StateSetManipulator();
virtual ~StateSetManipulator();
/** attach a geostate to the manipulator to be used for specifying view.*/
virtual void setStateSet(osg::StateSet*);
/** get the attached a geostate.*/
virtual osg::StateSet * getStateSet();
/** get the attached a geostate.*/
virtual const osg::StateSet * getStateSet() const;
/** Handle events, return true if handled, false otherwise.*/
virtual bool handle(const GUIEventAdapter& ea,GUIActionAdapter& us);
protected:
// Reference pointer to a geostate
osg::ref_ptr<osg::StateSet> _drawState;
bool _backface;
bool _lighting;
bool _texture;
};
}
#endif

141
include/osgUtil/Statistics Normal file
View File

@@ -0,0 +1,141 @@
#ifndef OSGUTIL_STATISTICS
#define OSGUTIL_STATISTICS 1
#include <osg/GeoSet>
namespace osgUtil {
/**
* Statistics base class. Used to extract primitive information from
* the renderBin(s).
*/
class OSGUTIL_EXPORT Statistics : public osg::Object
{
public:
Statistics() {
numOpaque=0, nummat=0;
nprims=0, nlights=0; nbins=0;
reset();
};
~Statistics() {}; // no dynamic allocations, so no need to free
void reset() {
for (int i=0; i<20; i++) primverts[i]=numprimtypes[i]=primlens[i]=primtypes[i]=0;
}
virtual osg::Object* clone() const { return new Statistics(); }
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const Statistics*>(obj)!=0L; }
virtual const char* className() const { return "Statistics"; }
void addstat(osg::GeoSet *gs) { // analyse the drawable GeoSet
const int np=gs->getNumPrims(); // number of primitives in this geoset
nprims += np;
const int type=gs->getPrimType();
switch (type) {
case osg::GeoSet::POINTS:
case osg::GeoSet::LINES:
case osg::GeoSet::LINE_STRIP:
case osg::GeoSet::FLAT_LINE_STRIP:
case osg::GeoSet::LINE_LOOP:
case osg::GeoSet::TRIANGLE_STRIP:
case osg::GeoSet::FLAT_TRIANGLE_STRIP:
case osg::GeoSet::TRIANGLE_FAN:
case osg::GeoSet::FLAT_TRIANGLE_FAN:
case osg::GeoSet::QUAD_STRIP:
case osg::GeoSet::POLYGON:
primtypes[type]++;
primtypes[0]++;
break;
case osg::GeoSet::TRIANGLES: // should not have any lengths for tris & quads
primtypes[type]++;
primtypes[0]++;
primlens[0]+=np;
primlens[type]+=np;
numprimtypes[type]+=np;
primverts[type]+=3*np;
primverts[0]+=3*np;
break;
case osg::GeoSet::QUADS:
primtypes[type]++;
primtypes[0]++;
primlens[0]+=np*2;
primlens[type]+=np*2; // quad is equiv to 2 triangles
numprimtypes[type]+=np;
primverts[type]+=4*np;
primverts[0]+=4*np;
break;
case osg::GeoSet::NO_TYPE:
default:
break;
}
// now count the lengths, ie efficiency of triangulation
const int *lens=gs->getPrimLengths(); // primitive lengths
for (int i=0; i<np && lens; i++) {
switch (type) {
case osg::GeoSet::POINTS:
case osg::GeoSet::LINES:
case osg::GeoSet::LINE_STRIP:
case osg::GeoSet::FLAT_LINE_STRIP:
case osg::GeoSet::LINE_LOOP:
case osg::GeoSet::TRIANGLES: // should not have any lengths for tris & quads
case osg::GeoSet::QUADS:
case osg::GeoSet::QUAD_STRIP:
case osg::GeoSet::POLYGON:
primlens[0]+=lens[i];
primlens[type]+=lens[i];
break;
case osg::GeoSet::TRIANGLE_STRIP:
case osg::GeoSet::FLAT_TRIANGLE_STRIP:
case osg::GeoSet::TRIANGLE_FAN:
case osg::GeoSet::FLAT_TRIANGLE_FAN:
primlens[0]+=lens[i]-2;
primlens[type]+=lens[i]-2; // tri strips & fans create lens[i]-2 triangles
break;
case osg::GeoSet::NO_TYPE:
default:
break;
}
switch (type) {
case osg::GeoSet::POINTS:
case osg::GeoSet::LINES:
case osg::GeoSet::LINE_STRIP:
case osg::GeoSet::FLAT_LINE_STRIP:
case osg::GeoSet::LINE_LOOP:
case osg::GeoSet::TRIANGLES:
case osg::GeoSet::QUADS:
case osg::GeoSet::TRIANGLE_STRIP:
case osg::GeoSet::FLAT_TRIANGLE_STRIP:
case osg::GeoSet::TRIANGLE_FAN:
case osg::GeoSet::FLAT_TRIANGLE_FAN:
case osg::GeoSet::QUAD_STRIP:
case osg::GeoSet::POLYGON:
numprimtypes[0]++;
numprimtypes[type]++;
primverts[type]+=lens[i];
primverts[0]+=lens[i];
break;
case osg::GeoSet::NO_TYPE:
default:
break;
}
}
}
public:
int numOpaque, nummat, nbins;
int nprims, nlights;
int numprimtypes[20]; // histogram of number of each type of prim
int primtypes[20]; // histogram of number of each type of prim
int primlens[20]; // histogram of lengths of each type of prim
int primverts[20]; // histogram of number of vertices to be transformed
protected:
};
};
#endif

112
include/osgUtil/Tesselator Normal file
View File

@@ -0,0 +1,112 @@
#ifndef OSGUTIL_Tesselator
#define OSGUTIL_Tesselator
#include <osg/Types>
#include <osg/Vec3>
#include <osgUtil/Export>
#include <vector>
namespace osgUtil {
/** A simple class for tesselating a single polygon boundary.
* Currently uses old style glu tesselation functions for portablity.
* It be nice to use the modern glu tesselation functions or to find
* a small set of code for doing this job better.*/
class OSGUTIL_EXPORT Tesselator
{
public:
Tesselator();
~Tesselator();
enum InputBoundaryDirection
{
CLOCK_WISE,
COUNTER_CLOCK_WISE
};
void tesselate(osg::Vec3* coords,int numIndices, int* indices,InputBoundaryDirection ibd=COUNTER_CLOCK_WISE);
void tesselate(osg::Vec3* coords,int numIndices, osg::ushort* indices,InputBoundaryDirection ibd=COUNTER_CLOCK_WISE);
void tesselate(osg::Vec3* coords,int numIndices, osg::uint* indices,InputBoundaryDirection ibd=COUNTER_CLOCK_WISE);
typedef std::vector<osg::uint> IndexVec;
const IndexVec& getResult() const { return _tesselated_indices; }
void beginPrimitive(int primitiveType);
void endPrimitive();
int _errorCode;
struct VertexIndexSet
{
VertexIndexSet(Tesselator* tess,const osg::Vec3& vec,osg::uint index)
{
set(tess,vec,index);
}
VertexIndexSet(const VertexIndexSet& vip)
{
_Tesselator = vip._Tesselator;
_vertex[0] = vip._vertex[0];
_vertex[1] = vip._vertex[1];
_vertex[2] = vip._vertex[2];
_index = vip._index;
}
VertexIndexSet& operator = (const VertexIndexSet& vip)
{
if (&vip==this) return *this;
_Tesselator = vip._Tesselator;
_vertex[0] = vip._vertex[0];
_vertex[1] = vip._vertex[1];
_vertex[2] = vip._vertex[2];
_index = vip._index;
return *this;
}
void set(Tesselator* tess,const osg::Vec3& vec,osg::uint index)
{
_Tesselator = tess;
_vertex[0] = vec[0];
_vertex[1] = vec[1];
_vertex[2] = vec[2];
_index = index;
}
void accumulate()
{
_Tesselator->_acummulated_indices.push_back(_index);
}
// note,_vertex must be first so that callbacks can use a pointer
// to it to dereference the VertexIndexSet for it.
double _vertex[3];
Tesselator* _Tesselator;
osg::uint _index;
};
protected:
friend VertexIndexSet;
typedef std::vector<VertexIndexSet> CoordVec;
void init();
void do_it();
CoordVec _coordVec;
IndexVec _tesselated_indices;
int _currentPrimtiveType;
IndexVec _acummulated_indices;
};
};
#endif

View File

@@ -0,0 +1,38 @@
#ifndef OSGUTIL_TRISTRIPVISITOR
#define OSGUTIL_TRISTRIPVISITOR 1
#include <osg/NodeVisitor>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osgUtil/Export>
namespace osgUtil {
/** A tri stripping visitor for converting GeoSet primitives into tri strips.
* The current implemention is based up NVidia's NvTriStrip.
*/
class OSGUTIL_EXPORT TriStripVisitor : public osg::NodeVisitor
{
public:
/// default to traversing all children.
TriStripVisitor()
{
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
}
/** convert mesh primitives in geoset into Tri Strips using
* NvTriStrip. Converts all primtive types except points
* and lines, linestrips which it leaves unchanged.
*/
static void stripify(osg::GeoSet& gset);
/// apply stripify method to all geode geosets.
virtual void apply(osg::Geode& geode);
};
};
#endif

View File

@@ -0,0 +1,76 @@
#ifndef OSGUTIL_VISUALSREQUIREMENTSVISITOR
#define OSGUTIL_VISUALSREQUIREMENTSVISITOR 1
#include <osg/NodeVisitor>
#include <osg/Geode>
#include <osg/GeoSet>
#include <osgUtil/Export>
namespace osgUtil {
/** A visitor for traversing a scene graph establishing the OpenGL visuals are required
* to support rendering of that scene graph. The results can then be used by
* applications to set up there windows with the corret visuals. Have a look at
* src/osgGLUT/Viewer.cpp's Viewer::open() method for an example how to use it.
*/
class OSGUTIL_EXPORT VisualsRequirementsVisitor : public osg::NodeVisitor
{
public:
/** Default to traversing all children, and reqiresDoubleBuffer,
* requiresRGB and requiresDepthBuffer to true and with
* alpha and stencil off.*/
VisualsRequirementsVisitor();
void setRequiresDoubleBuffer(const bool flag) { _requiresDoubleBuffer = flag; }
const bool requiresDoubleBuffer() const { return _requiresDoubleBuffer; }
void setRequiresRGB(const bool flag) { _requiresRBG = flag; }
const bool requiresRGB() const { return _requiresRBG; }
void setRequiresDepthBuffer(const bool flag) { _requiresDepthBuffer = flag; }
const bool requiresDepthBuffer() const { return _requiresDepthBuffer; }
void setMinumumNumAlphaBits(const unsigned int bits) { _minimumNumberAlphaBits = bits; }
const unsigned int getMinumumNumAlphaBits() const { return _minimumNumberAlphaBits; }
const bool requiresAlphaBuffer() const { return _minimumNumberAlphaBits!=0; }
void setMinumumNumStencilBits(const unsigned int bits) { _minimumNumberStencilBits = bits; }
const unsigned int getMinumumNumStencilBits() const { return _minimumNumberStencilBits; }
const bool requiresStencilBuffer() const { return _minimumNumberStencilBits!=0; }
virtual void applyStateSet(osg::StateSet& stateset);
virtual void apply(osg::Node& node);
virtual void apply(osg::Geode& geode);
virtual void apply(osg::Impostor& impostor);
protected:
bool _requiresDoubleBuffer;
bool _requiresRBG;
bool _requiresDepthBuffer;
unsigned int _minimumNumberAlphaBits;
unsigned int _minimumNumberStencilBits;
};
};
#endif