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

195
include/osg/BoundsChecking Normal file
View File

@@ -0,0 +1,195 @@
#ifndef OSG_BOUNDSCHECKING
#define OSG_BOUNDSCHECKING 1
#include <osg/Notify>
namespace osg {
/** if value is greater than or equal to minValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class T>
inline void clampGEQUAL(T& value,const T minValue,const char* valueName)
{
if (value<minValue)
{
notify(WARN) << "Warning: "<<valueName<<" of "<<value<<" is below permitted minimum, clampping to "<<minValue<<"."<<endl;
value = minValue;
}
}
/** if value is less than or equal to maxValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class T>
inline void clampLEQUAL(T& value,const T maxValue,const char* valueName)
{
if (value>maxValue)
{
notify(WARN) << "Warning: "<<valueName<<" of "<<value<<" is above permitted maximum, clampping to "<<maxValue<<"."<<endl;
value = maxValue;
}
}
/** if value is between or equal to minValue and maxValue do nothing - legal value,
* otherise clamp value to specified to range and return warning
* with valueName specifying which variable was clamped. Equivilant to
* calling clampGEQUAL(value,minValue,valueName); clampLEQUAL(value,maxValue,valueName); */
template <class T>
inline void clampBetweenRange(T& value,const T minValue,const T maxValue,const char* valueName)
{
if (value<minValue)
{
notify(WARN) << "Warning: "<<valueName<<" of "<<value<<" is below permitted minimum, clampping to "<<minValue<<"."<<endl;
value = minValue;
}
else
if (value>maxValue)
{
notify(WARN) << "Warning: "<<valueName<<" of "<<value<<" is above permitted maximum, clampping to "<<maxValue<<"."<<endl;
value = maxValue;
}
}
/** if array element value[i] is greater than or equal to minValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArrayElementGEQUAL(A& value,const unsigned int i,const T minValue,const char* valueName)
{
if (value[i]<minValue)
{
notify(WARN) << "Warning: "<<valueName<<"["<<i<<"] of "<<value[i]<<" is below permitted minimum, clampping to "<<minValue<<"."<<endl;
value[i] = minValue;
}
}
/** if array element value[i] is less than or equal to maxValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArrayElementLEQUAL(A& value,const unsigned int i,const T maxValue,const char* valueName)
{
if (value[i]>maxValue)
{
notify(WARN) << "Warning: "<<valueName<<"["<<i<<"] of "<<value[i]<<" is above permitted maximum, clampping to "<<maxValue<<"."<<endl;
value = maxValue;
}
}
/** if array element value[i] is between or equal to minValue and maxValue do nothing - legal value,
* otherise clamp value to specified to range and return warning
* with valueName specifying which variable was clamped. Equivilant to
* calling clampGEQUAL(value,minValue,valueName); clampLEQUAL(value,maxValue,valueName); */
template <class A, class T>
inline void clampArrayElementBetweenRange(A& value,const unsigned int i,const T minValue,const T maxValue,const char* valueName)
{
if (value[i]<minValue)
{
notify(WARN) << "Warning: "<<valueName<<"["<<i<<"] of "<<value[i]<<" is below permitted minimum, clampping to "<<minValue<<"."<<endl;
value[i] = minValue;
}
else
if (value[i]>maxValue)
{
notify(WARN) << "Warning: "<<valueName<<"["<<i<<"] of "<<value[i]<<" is above permitted maximum, clampping to "<<maxValue<<"."<<endl;
value[i] = maxValue;
}
}
/** if array elements are greater than or equal to minValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArrayElementsGEQUAL(A& value,const unsigned int first,const unsigned int last,const T minValue,const char* valueName)
{
for(unsigned int i=first;i<=last;++i)
clampArrayElementGEQUAL(value,i,minValue,valueName);
}
/** if array elements are less than or equal to maxValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArrayElementsLEQUAL(A& value,const unsigned int first,const unsigned int last,const T maxValue,const char* valueName)
{
for(unsigned int i=first;i<=last;++i)
clampArrayElementLEQUAL(value,i,maxValue,valueName);
}
/** if array elements are between or equal to minValue and maxValue do nothing - legal value,
* otherise clamp value to specified to range and return warning
* with valueName specifying which variable was clamped. Equivilant to
* calling clampGEQUAL(value,minValue,valueName); clampLEQUAL(value,maxValue,valueName); */
template <class A, class T>
inline void clampArrayElementsBetweenRange(A& value,const unsigned int first,const unsigned int last,const T minValue,const T maxValue,const char* valueName)
{
for(unsigned int i=first;i<=last;++i)
clampArrayElementBetweenRange(value,i,minValue,maxValue,valueName);
}
/** if array4 elements are greater than or equal to minValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArray3GEQUAL(A& value,const T minValue,const char* valueName)
{
clampArrayElementsGEQUAL(value,0u,2u,minValue,valueName);
}
/** if array4 elements are is less than or equal to maxValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArray3LEQUAL(A& value,const T maxValue,const char* valueName)
{
clampArrayElementsLEQUAL(value,0u,2u,maxValue,valueName);
}
/** if array4 elements are between or equal to minValue and maxValue do nothing - legal value,
* otherise clamp value to specified to range and return warning
* with valueName specifying which variable was clamped. Equivilant to
* calling clampGEQUAL(value,minValue,valueName); clampLEQUAL(value,maxValue,valueName); */
template <class A, class T>
inline void clampArray3BetweenRange(A& value,const T minValue,const T maxValue,const char* valueName)
{
clampArrayElementsBetweenRange(value,0u,2u,minValue,maxValue,valueName);
}
/** if array4 elements are greater than or equal to minValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArray4GEQUAL(A& value,const T minValue,const char* valueName)
{
clampArrayElementsGEQUAL(value,0u,3u,minValue,valueName);
}
/** if array4 elements are is less than or equal to maxValue do nothing - legal value,
* otherise clamp value to specified maximum value and return warning
* with valueName specifying which variable was clamped.*/
template <class A, class T>
inline void clampArray4LEQUAL(A& value,const unsigned int first,const unsigned int last,const T maxValue,const char* valueName)
{
clampArrayElementsLEQUAL(value,0u,3u,maxValue,valueName);
}
/** if array4 elements are between or equal to minValue and maxValue do nothing - legal value,
* otherise clamp value to specified to range and return warning
* with valueName specifying which variable was clamped. Equivilant to
* calling clampGEQUAL(value,minValue,valueName); clampLEQUAL(value,maxValue,valueName); */
template <class A, class T>
inline void clampArray4BetweenRange(A& value,const T minValue,const T maxValue,const char* valueName)
{
clampArrayElementsBetweenRange(value,0u,3u,minValue,maxValue,valueName);
}
};
#endif

72
include/osg/ClipPlane Normal file
View File

@@ -0,0 +1,72 @@
#ifndef OSG_CLIPPLANE
#define OSG_CLIPPLANE 1
#include <osg/Plane>
#include <osg/StateAttribute>
#include <osg/StateSet>
namespace osg {
/** ClipPlane state class which encapsulates OpenGL glClipPlane() functionality.*/
class SG_EXPORT ClipPlane : public StateAttribute
{
public :
ClipPlane();
/** return a shallow copy of a node, with Object* return type.*/
virtual Object* clone() const { return new ClipPlane(); }
/** return true if this and obj are of the same kind of object.*/
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const ClipPlane*>(obj)!=NULL; }
/** return the name of the node's class type.*/
virtual const char* className() const { return "ClipPlane"; }
virtual const Type getType() const { return (Type)(CLIPPLANE+_clipPlaneNum); }
virtual void setStateSetModes(StateSet& ds,const GLModeValue value) const
{
ds.setMode((GLMode)(GL_CLIP_PLANE0+_clipPlaneNum),value);
}
/** Set the clip plane, using a Vec4 to define plane. */
void setClipPlane(const Vec4& plane);
/** Set the clip plane, using a Plane to define plane. */
void setClipPlane(const Plane& plane);
/** Set the clip plane, using a double[4] to define plane. */
void setClipPlane(const double* plane);
/** Get the clip plane, values entered into a Vec4 passed to the getClipPlane. */
void getClipPlane(Vec4& plane) const;
/** Get the clip plane, values entered into a Plane passed to the getClipPlane. */
void getClipPlane(Plane& plane) const;
/** Get the clip plane, values entered into a double[4] passed to the getClipPlane. */
void getClipPlane(double* plane) const;
/** Set the clip plane number. */
void setClipPlaneNum(const unsigned int num);
/** Get the clip plane number. */
const unsigned int getClipPlaneNum() const;
/** Apply the clip plane's state to the OpenGL state machine. */
virtual void apply(State& state) const;
protected :
virtual ~ClipPlane();
double* _clipPlane;
unsigned int _clipPlaneNum;
};
};
#endif

177
include/osg/ClippingVolume Normal file
View File

@@ -0,0 +1,177 @@
#ifndef OSG_CLIPPINGVOLUME
#define OSG_CLIPPINGVOLUME 1
#include <osg/Plane>
#include <vector>
namespace osg {
/** A ClippingVolume class for represecting convex clipping volumes made up.*/
class SG_EXPORT ClippingVolume
{
public:
typedef std::vector<osg::Plane> PlaneList;
inline ClippingVolume() {setupMask();}
inline ClippingVolume(const ClippingVolume& cv) : _localMask(cv._localMask), _planeList(cv._planeList) {}
inline ClippingVolume(const PlaneList& pl) : _planeList(pl) {setupMask();}
inline ~ClippingVolume() {}
inline void clear() { _planeList.clear(); setupMask(); }
inline ClippingVolume& operator = (const ClippingVolume& cv)
{
if (&cv==this) return *this;
_localMask = cv._localMask;
_planeList = cv._planeList;
return *this;
}
inline void set(const ClippingVolume& cs) { _planeList = cs._planeList; setupMask(); }
inline void set(const PlaneList& pl) { _planeList = pl; setupMask(); }
inline void add(const osg::Plane& pl) { _planeList.push_back(pl); setupMask(); }
inline PlaneList& getPlaneList() { return _planeList; }
inline const PlaneList& getPlaneList() const { return _planeList; }
inline void setupMask()
{
_localMask = 0;
for(unsigned int i=0;i<_planeList.size();++i)
{
_localMask = (_localMask<<1) | 1;
}
}
/** Check whether a vertex is contained with clipping set.*/
inline const bool contains(const osg::Vec3& v) const
{
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->distance(v)<0.0f) return false;
}
return true;
}
/** Check whether any part of a bounding sphere is contained within clipping set.
Using a mask to determine which planes should be used for the check, and
modifying the mask to turn off planes which wouldn't contribute to clipping
of any internal objects. This feature is used in osgUtil::CullVisitor
to prevent redundent plane checking.*/
inline const bool contains(const osg::BoundingSphere& bs,unsigned int& mask) const
{
if (!(mask & _localMask)) return true;
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (mask&selector_mask)
{
int res=itr->intersect(bs);
if (res<0) return false; // outside clipping set.
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
/** Check whether any part of a bounding sphere is contained within clipping set.*/
inline const bool contains(const osg::BoundingSphere& bs) const
{
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->intersect(bs)<0) return false; // outside clipping set.
}
return true;
}
/** Check whether any part of a bounding box is contained within clipping set.
Using a mask to determine which planes should be used for the check, and
modifying the mask to turn off planes which wouldn't contribute to clipping
of any internal objects. This feature is used in osgUtil::CullVisitor
to prevent redundent plane checking.*/
inline const bool contains(const osg::BoundingBox& bb,unsigned int& mask) const
{
if (!(mask & _localMask)) return true;
unsigned int selector_mask = 0x1;
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (mask&selector_mask)
{
int res=itr->intersect(bb);
if (res<0) return false; // outside clipping set.
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
}
selector_mask <<= 1;
}
return true;
}
/** Check whether any part of a bounding box is contained within clipping set.*/
inline const bool contains(const osg::BoundingBox& bb) const
{
for(PlaneList::const_iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
if (itr->intersect(bb)<0) return false; // outside clipping set.
}
return true;
}
/** Transform the clipping set by matrix. Note, this operations carries out
* the calculation of the inverse of the matrix since to transforms
* planes must be multiplied my the inverse transposed. This
* make this operation expensive. If the inverse has been already
* calculated elsewhere then use transformProvidingInverse() instead.
* See http://www.worldserver.com/turk/computergraphics/NormalTransformations.pdf*/
inline void transform(const osg::Matrix& matrix)
{
osg::Matrix inverse;
inverse.invert(matrix);
transformProvidingInverse(inverse);
}
/** Transform the clipping set by provide a pre inverted matrix.
* see transform for details. */
inline void transformProvidingInverse(const osg::Matrix& matrix)
{
for(PlaneList::iterator itr=_planeList.begin();
itr!=_planeList.end();
++itr)
{
itr->transformProvidingInverse(matrix);
}
}
protected:
unsigned int _localMask;
PlaneList _planeList;
};
}; // end of namespace
#endif

56
include/osg/ColorMask Normal file
View File

@@ -0,0 +1,56 @@
#ifndef OSG_COLORMASK
#define OSG_COLORMASK 1
#include <osg/StateAttribute>
#include <osg/StateSet>
#include <osg/Types>
namespace osg {
/** Encapsulte OpenGL glColorMaskFunc/Op/Mask functions.
*/
class SG_EXPORT ColorMask : public StateAttribute
{
public :
ColorMask();
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const ColorMask*>(obj)!=0L; }
virtual Object* clone() const { return new ColorMask(); }
virtual const char* className() const { return "ColorMask"; }
virtual const Type getType() const { return COLORMASK; }
inline void setMask(bool red,bool green,bool blue,bool alpha)
{
_red = red;
_green = green;
_blue = blue;
_alpha = alpha;
}
inline const bool getRedMask() const { return _red; }
inline const bool getGreenMask() const { return _green; }
inline const bool getBlueMask() const { return _blue; }
inline const bool getAlphaMask() const { return _alpha; }
virtual void apply(State& state) const;
protected:
virtual ~ColorMask();
bool _red;
bool _green;
bool _blue;
bool _alpha;
};
};
#endif

75
include/osg/Depth Normal file
View File

@@ -0,0 +1,75 @@
#ifndef OSG_DEPTH
#define OSG_DEPTH 1
#include <osg/StateAttribute>
#include <osg/StateSet>
#include <osg/Types>
namespace osg {
/** Encapsulte OpenGL glDepthFunc/Mask/Range functions.
*/
class SG_EXPORT Depth : public StateAttribute
{
public :
Depth();
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Depth*>(obj)!=0L; }
virtual Object* clone() const { return new Depth(); }
virtual const char* className() const { return "Depth"; }
virtual const Type getType() const { return DEPTH; }
virtual void setStateSetModes(StateSet& ds,const GLModeValue value) const
{
ds.setMode(GL_DEPTH_TEST,value);
}
enum Function
{
NEVER = GL_NEVER,
LESS = GL_LESS,
EQUAL = GL_EQUAL,
LEQUAL = GL_LEQUAL,
GREATER = GL_GREATER,
NOTEQUAL = GL_NOTEQUAL,
GEQUAL = GL_GEQUAL,
ALWAYS = GL_ALWAYS
};
inline void setFunction(const Function func) { _func = func; }
inline const Function getFunction() const { return _func; }
inline void setWriteMask(const bool mask) { _depthWriteMask = mask; }
inline const bool getWriteMask() const { return _depthWriteMask; }
inline void setRange(const double zNear, const double zFar)
{
_zNear = zNear;
_zFar = zFar;
}
inline const double getZNear() const { return _zNear; }
inline const double getZFar() const { return _zFar; }
virtual void apply(State& state) const;
protected:
virtual ~Depth();
Function _func;
bool _depthWriteMask;
double _zNear;
double _zFar;
};
};
#endif

174
include/osg/Drawable Normal file
View File

@@ -0,0 +1,174 @@
#ifndef OSG_DRAWABLE
#define OSG_DRAWABLE 1
#include <osg/BoundingBox>
#include <osg/StateSet>
#include <osg/State>
#include <osg/Types>
#include <vector>
#include <map>
#include <set>
namespace osg {
/** Pure virtual base class for drawable Geomtery. Contains no drawing primitives
directly, these are provided by subclasses such as GeoSet. State attributes
for a Drawable are maintained in StateSet which the Drawable maintains
a referenced counted pointer to. Both Drawable's and StateSet's can
be shared for optimal memory usage and graphics performance.
*/
class SG_EXPORT Drawable : public Object
{
public:
Drawable();
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Drawable*>(obj)!=NULL; }
virtual const char* className() const { return "Drawable"; }
/** Set the StateSet attached to the Drawable.
Previously attached StateSet are automatically unreferenced on
assignment of a new drawstate.*/
inline void setStateSet(StateSet *state) { _dstate = state; }
/** Get the attached StateSet.*/
inline StateSet* getStateSet() { return _dstate.get();}
/** Get the attached const StateSet.*/
inline const StateSet* getStateSet() const { return _dstate.get();}
/** Set the drawable to it can or cannot be used inconjunction with OpenGL
* display lists. With set to true, calls to Drawable::setUseDisplayList,
* whereas when set to false, no display lists can be created and calls
* to setUseDisplayList are ignored, and a warning is produced. The later
* is typically used to guard against the switching on of display lists
* on objects with dynamic internal data such as continuous Level of Detail
* algorithms.*/
void setSupportsDisplayList(const bool flag);
/** Get whether display lists are supportd for this drawable instance.*/
inline const bool getSupportsDisplayList() const { return _supportsDisplayList; }
/** When set to true, force the draw method to use OpenGL Display List for rendering.
If false rendering directly. If the display list has not been already
compile the next call to draw will automatically create the display list.*/
void setUseDisplayList(const bool flag);
/** Return whether OpenGL display lists are being used for rendering.*/
inline const bool getUseDisplayList() const { return _useDisplayList; }
/** Force a recompile on next draw() of any OpenGL display list associated with this geoset.*/
void dirtyDisplayList();
inline void dirtyBound() { _bbox_computed = false; }
/** get bounding box of geoset.
* Note, now made virtual to make it possible to implement user-drawn
* objects albeit so what crudely, to be improved later.
*/
inline const BoundingBox& getBound() const
{
if( !_bbox_computed)
computeBound();
return _bbox;
}
/** draw OpenGL primitives.
* If the drawable has _useDisplayList set to true then use an OpenGL display
* list, automatically compiling one if required.
* Otherwise call drawImmediateMode().
* Note, draw method should not be overriden in subclasses as it
* manages the optional display list.
*/
inline void draw(State& state)
{
if (_useDisplayList)
{
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
uint contextID = state.getContextID();
// fill in array if required.
while (_globjList.size()<=contextID) _globjList.push_back(0);
// get the globj for the current contextID.
uint& globj = _globjList[contextID];
// call the globj if already set otherwise comple and execute.
if( globj != 0 )
{
glCallList( globj );
}
else if (_useDisplayList)
{
globj = glGenLists( 1 );
glNewList( globj, GL_COMPILE_AND_EXECUTE );
drawImmediateMode(state);
glEndList();
}
}
else
{
// draw object as nature intended..
drawImmediateMode(state);
}
}
/** Immediately compile this drawable into an OpenGL Display List.
Note, operation is ignored if _useDisplayList to false.*/
void compile(State& state);
/** draw directly ignoring an OpenGL display list which could be attached.
* This is the internal draw method which does the drawing itself,
* and is the method to override when deriving from Drawable.
*/
virtual void drawImmediateMode(State& state) = 0;
/** use deleteDisplayList instead of glDeleteList to allow
* OpenGL display list to cached until they can be deleted
* by the OpenGL context in which they were created, specified
* by contextID.*/
static void deleteDisplayList(uint contextID,uint globj);
/** flush all the cached display list which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedDisplayLists(uint contextID);
protected:
Drawable(const Drawable&):Object() {}
Drawable& operator = (const Drawable&) { return *this;}
virtual ~Drawable();
/** compute the bounding box of the drawable. Method must be
implementated by subclasses.*/
virtual const bool computeBound() const = 0;
ref_ptr<StateSet> _dstate;
bool _supportsDisplayList;
bool _useDisplayList;
typedef std::vector<uint> GLObjectList;
mutable GLObjectList _globjList;
mutable BoundingBox _bbox;
mutable bool _bbox_computed;
// static cache of deleted display lists which can only
// by completely deleted once the appropriate OpenGL context
// is set.
typedef std::map<uint,std::set<uint> > DeletedDisplayListCache;
static DeletedDisplayListCache s_deletedDisplayListCache;
};
};
#endif

42
include/osg/FrontFace Normal file
View File

@@ -0,0 +1,42 @@
#ifndef OSG_FRONTFACE
#define OSG_FRONTFACE 1
#include <osg/StateAttribute>
#include <osg/GL>
namespace osg {
/** Class to specifies the orientation of front-facing polygons.
*/
class SG_EXPORT FrontFace : public StateAttribute
{
public :
FrontFace();
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const FrontFace*>(obj)!=0L; }
virtual Object* clone() const { return new FrontFace(); }
virtual const char* className() const { return "FrontFace"; }
virtual const Type getType() const { return FRONTFACE; }
enum Mode {
CLOCKWISE = GL_CW,
COUNTER_CLOCKWISE = GL_CCW
};
inline void setMode(const Mode mode) { _mode = mode; }
inline const Mode getMode() const { return _mode; }
virtual void apply(State& state) const;
protected:
virtual ~FrontFace();
Mode _mode;
};
};
#endif

21
include/osg/GLExtensions Normal file
View File

@@ -0,0 +1,21 @@
#ifndef OSG_GLEXTENSIONS
#define OSG_GLEXTENSIONS 1
#include <osg/Export>
namespace osg {
/** return true if OpenGL "extension" is supported.
* note: Must only called within a valid OpenGL context,
* undefined behaviour may occur otherwise.
*/
SG_EXPORT extern const bool isGLExtensionSupported(const char *extension);
/** return the address of the specified OpenGL function.
* return NULL if function not supported by OpenGL library.
*/
SG_EXPORT extern void* getGLExtensionFuncPtr(const char *funcName);
};
#endif

100
include/osg/Impostor Normal file
View File

@@ -0,0 +1,100 @@
#ifndef OSG_IMPOSTOR
#define OSG_IMPOSTOR 1
#include <osg/LOD>
#include <osg/ImpostorSprite>
namespace osg {
/** Impostor - is a form of Level Of Detail group node which allows both switching
* between children depending on distance from eye point and image caching.
*
* The principle behind Imposters is that they cache an image of real geometry and then the image is drawn
* in subsequent frames instead of the real geometry. Its a bit like a
* Billboard *but* is updated at runtime and w.r.t view point. By drawing
* just the texture mapped quad you can cut down scene complexity and
* improve performance.
*
* For more details have a look at:
*
* http://grail.cs.washington.edu/projects/hic/
*
* The OSG doesn't implement exactly the same technique as above, but its
* should be a good starting place. The OSG's impostors are much less
* intrusive since you don't need to restructure your whole scene to use
* them.
*
* All you need to do to use Impostors is to set up the visible
* range values for each LOD child of the Impostor, as per osg::LOD,
* and set an Impostor threshold to tell the renderer at what distance
* the Impsotor's image caching should cut in. The osg::CullVisitor
* automatically handles all the setting of pre-rendering stages to
* calculate the required ImpostorSprites (which encapsulates the image
* cache and quad), and updates them as the view point changes. If you
* use osg::SceneView/CullVisitor all the complexity of supporting
* Impostor will be nicely hidden away.
*
* TODO:
* Various improvements are planned for the Impostor-
* 1) Estimation of how many frames an ImpostorSprite will be reused, if
* it won't be used more often than a minimum threshold then do not create
* ImpostorSprite - use the real geometry.
* 2) Sharing of texture memory between ImpostorSprites.
* 3) Simple 3D geometry for ImpostorSprite's rather than Billboarding.
* 4) Shrinking of the ImpostorSprite size to more closely fit the underlying
* geometry.
*/
class SG_EXPORT Impostor : public LOD
{
public :
Impostor();
virtual Object* clone() const { return new Impostor(); }
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Impostor*>(obj)!=NULL; }
virtual const char* className() const { return "Impostor"; }
virtual void accept(NodeVisitor& nv) { nv.apply(*this); }
typedef std::vector< ref_ptr<ImpostorSprite> > ImpostorSpriteList;
/** Set the Impostor threshold distance.
* For eye points further than this threshold the Imposter is used if appropriate,
* otherwise the LOD children as chosen as per a standard LOD node.*/
inline void setImpostorThreshold(float distance) { _impostorThreshold = distance; }
/** Set the Impostor threshold distance relative to the node's bounding
* sphere's radius.*/
inline void setImpostorThresholdToBound(float ratio=1.0f) { _impostorThreshold = getBound().radius()*ratio; }
/* Get the Impostor threshold disntance.*/
inline const float getImpostorThreshold() const { return _impostorThreshold; }
/* Get the Impostor threshold disntance squared.*/
inline const float getImpostorThreshold2() const { return _impostorThreshold*_impostorThreshold; }
/** Find the ImposterSprite which fits the current eye point best.*/
ImpostorSprite* findBestImpostorSprite(const osg::Vec3& currLocalEyePoint);
/** Add an ImpostorSprite to the Impostor.*/
void addImpostorSprite(ImpostorSprite* is);
/** Get the list of ImpostorSprites attached to this Impostor.*/
inline ImpostorSpriteList& getImpostorSpriteList() { return _impostorSpriteList; }
/** Get a const list of ImpostorSprites attached to this const Impostor.*/
inline const ImpostorSpriteList& getImpostorSpriteList() const { return _impostorSpriteList; }
protected :
virtual ~Impostor() {}
virtual const bool computeBound() const;
ImpostorSpriteList _impostorSpriteList;
float _impostorThreshold;
};
};
#endif

176
include/osg/ImpostorSprite Normal file
View File

@@ -0,0 +1,176 @@
#ifndef OSG_ImpostorSprite
#define OSG_ImpostorSprite 1
#include <osg/Vec2>
#include <osg/BoundingSphere>
#include <osg/Drawable>
#include <osg/Camera>
#include <osg/ImpostorSprite>
namespace osg {
class Texture;
class Impostor;
class ImpostorSpriteManager;
/** An ImposterSprite is a textured quad which is rendered in place a
* 3D geometry. The ImposterSprite is generated by rendering the original
* 3D geometry to a texture as an image cache. The ImpostorSprite is
* automatiacally generatated by the osgUtil::CullVisitor so it not
* necessary to deal with it directly.
*/
class SG_EXPORT ImpostorSprite : public Drawable
{
public:
ImpostorSprite();
virtual Object* clone() const { return new ImpostorSprite(); }
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const ImpostorSprite*>(obj)!=NULL; }
virtual const char* className() const { return "ImpostorSprite"; }
/** Set the parent, which must be an Impostor.
* Unlike conventional Drawables, ImpostorSprite's can only ever have
* one parent.
*/
void setParent(Impostor* parent) { _parent = parent; }
/** Get the parent, which is an Impostor. */
Impostor* getParent() { return _parent; }
/** Get the const parent, which is an Impostor. */
const Impostor* getParent() const { return _parent; }
/** Set the eye point for when the ImpsotorSprite was snapped.*/
inline void setStoredLocalEyePoint(const Vec3& v) { _storedLocalEyePoint=v; }
/** Get the eye point for when the ImpsotorSprite was snapped.*/
inline const Vec3& getStoredLocalEyePoint() const { return _storedLocalEyePoint; }
/** Set the frame number for when the ImpostorSprite was last used in rendering.*/
inline void setLastFrameUsed(const int frameNumber) { _lastFrameUsed = frameNumber; }
/** Get the frame number for when the ImpostorSprite was last used in rendering.*/
inline int getLastFrameUsed() const { return _lastFrameUsed; }
/** Get the coordinates of the corners of the quad.
* Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left.
*/
inline Vec3* getCoords() { return _coords; }
/** Get the const coordinates of the corners of the quad.
*/
inline const Vec3* getCoords() const { return _coords; }
/** Get the texture coordinates of the corners of the quad.
* Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left.
*/
inline Vec2* getTexCoords() { return _texcoords; }
/** Get the const texture coordinates of the corners of the quad.*/
inline const Vec2* getTexCoords() const { return _texcoords; }
/** Get the control coordinates of the corners of the quad.
* The control coordinates are the cornders of the quad projected
* out onto the front face of bounding box which enclosed the impostor
* geometry when it was pre-rendered into the impostor sprite's texture.
* At the point of creation/or update of the impostor sprite the control
* coords will lie ontop of the coorners of the quad in screen space - with a pixel error
* or zero. Once the camera moves relative to the impostor sprite the
* control coords will nolonger lie ontop of the corners of the quad in
* screen space - a pixel error will have accumulated. This pixel error
* can then be used to dertermine whether the impostor needs to be updated.
* Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left.
*/
inline Vec3* getControlCoords() { return _controlcoords; }
/** Get the const control coordinates of the corners of the quad.*/
inline const Vec3* getControlCoords() const { return _controlcoords; }
/** calculate the pixel error value for current camera position and object position.*/
const float calcPixelError(const Camera& camera,const int* viewport,const osg::Matrix* matrix) const;
void setTexture(Texture* tex,int s,int t);
Texture* getTexture() { return _texture; }
const Texture* getTexture() const { return _texture; }
const int s() const { return _s; }
const int t() const { return _t; }
/** draw ImpostorSprite directly. */
virtual void drawImmediateMode(State& state);
protected:
ImpostorSprite(const ImpostorSprite&):Drawable() {}
ImpostorSprite& operator = (const ImpostorSprite&) { return *this;}
virtual ~ImpostorSprite();
virtual const bool computeBound() const;
Impostor* _parent;
friend ImpostorSpriteManager;
// support for a double linked list managed by the
// ImposotorSpriteManager.
ImpostorSpriteManager* _ism;
ImpostorSprite* _previous;
ImpostorSprite* _next;
int _lastFrameUsed;
Vec3 _storedLocalEyePoint;
Vec3 _coords[4];
Vec2 _texcoords[4];
Vec3 _controlcoords[4];
Texture* _texture;
int _s;
int _t;
};
/** Helper class for managing the reuse of ImpostorSprite resources.*/
class SG_EXPORT ImpostorSpriteManager : public Referenced
{
public:
ImpostorSpriteManager();
const bool empty() const { return _first==0; }
ImpostorSprite* first() { return _first; }
ImpostorSprite* last() { return _last; }
void push_back(ImpostorSprite* is);
void remove(ImpostorSprite* is);
ImpostorSprite* createOrReuseImpostorSprite(int s,int t,int frameNumber);
protected:
~ImpostorSpriteManager();
ImpostorSprite* _first;
ImpostorSprite* _last;
};
};
#endif

60
include/osg/LineSegment Normal file
View File

@@ -0,0 +1,60 @@
#ifndef OSG_LINESEGMENT
#define OSG_LINESEGMENT 1
#include <osg/Matrix>
#include <osg/BoundingBox>
#include <osg/BoundingSphere>
namespace osg {
/** LineSegmentment class for representing a line segment.*/
class SG_EXPORT LineSegment : public Referenced
{
public:
LineSegment() {};
LineSegment(const LineSegment& seg) : Referenced(),_s(seg._s),_e(seg._e) {}
LineSegment(const Vec3& s,const Vec3& e) : _s(s),_e(e) {}
virtual ~LineSegment() {}
LineSegment& operator = (const LineSegment& seg) { _s = seg._s; _e = seg._e; return *this; }
inline void set(const Vec3& s,const Vec3& e) { _s=s; _e=e; }
inline Vec3& start() { return _s; }
inline const Vec3& start() const { return _s; }
inline Vec3& end() { return _e; }
inline const Vec3& end() const { return _e; }
/** return true if segment intersects BoundingBox.*/
const bool intersect(const BoundingBox& bb) const;
/** return true if segment intersects BoundingSphere and return the intersection ratio's.*/
const bool intersect(const BoundingBox& bb,float& r1,float& r2) const;
/** return true if segment intersects BoundingSphere.*/
const bool intersect(const BoundingSphere& bs) const;
/** return true if segment intersects BoundingSphere and return the intersection ratio's.*/
const bool intersect(const BoundingSphere& bs,float& r1,float& r2) const;
/** return true if segment intersects triangle and set ratio long segment. */
const bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r);
/** post multiply a segment by matrix.*/
inline void mult(const LineSegment& seg,const Matrix& m) { _s = seg._s*m; _e = seg._e*m; }
/** pre multiply a segment by matrix.*/
inline void mult(const Matrix& m,const LineSegment& seg) { _s = m*seg._s; _e = m*seg._e; }
protected:
static const bool intersectAndClip(Vec3& s,Vec3& e,const BoundingBox& bb);
Vec3 _s;
Vec3 _e;
};
};
#endif

37
include/osg/MemoryAdapter Normal file
View File

@@ -0,0 +1,37 @@
#ifndef OSG_MEMORYADAPTER
#define OSG_MEMORYADAPTER 1
#include <osg/Referenced>
namespace osg {
/** Class for adapting the memory management of external data.
* Typically used to specify the memory management of user data
* which can be attached to osg::Node.
*/
class SG_EXPORT MemoryAdapter : public Referenced
{
public:
MemoryAdapter() {}
/** Increment the reference count of the userData.*/
virtual void ref_data(void* /*userData*/) = 0;
/** Decrement the reference count of the userData.
Is usually implemented such that if reference count
is decremented to zero the userData should be
deleted. However, this is entirely up to the
discression of the user who is extending this base class.*/
virtual void unref_data(void* /*userData*/) = 0;
/** not current used, but will be used in future.*/
virtual void* clone_data(void* /*userData*/) { return 0L; }
protected:
virtual ~MemoryAdapter() {}
};
};
#endif

165
include/osg/Plane Normal file
View File

@@ -0,0 +1,165 @@
#ifndef OSG_PLANE
#define OSG_PLANE 1
#include <osg/Vec3>
#include <osg/Vec4>
#include <osg/Matrix>
#include <osg/BoundingSphere>
#include <osg/BoundingBox>
namespace osg {
/** A plane class. It can be used to represent an infinite plane.*/
class SG_EXPORT Plane
{
public:
inline Plane():_fv(0.0f,0.0f,0.0f,0.0f) { _lowerBBCorner = 0; _upperBBCorner = 0; }
inline Plane(const Plane& pl):_fv(pl._fv) { calculateUpperLowerBBCorners(); }
inline Plane(const float a,const float b,const float c,const float d):_fv(a,b,c,d) { calculateUpperLowerBBCorners(); }
inline Plane(const Vec4& vec):_fv(vec) { calculateUpperLowerBBCorners(); }
inline Plane(const Vec3& norm,const float d):_fv(norm[0],norm[1],norm[2],d) { calculateUpperLowerBBCorners(); }
inline Plane(const Vec3& v1, const Vec3& v2, const Vec3& v3) { set(v1,v2,v3); calculateUpperLowerBBCorners(); }
inline Plane& operator = (const Plane& pl)
{
if (&pl==this) return *this;
_fv = pl._fv;
_lowerBBCorner = pl._lowerBBCorner;
_upperBBCorner = pl._upperBBCorner;
return *this;
}
inline void set(const Plane& pl) { _fv = pl._fv; calculateUpperLowerBBCorners(); }
inline void set(const float a,const float b,const float c,const float d) { _fv.set(a,b,c,d); calculateUpperLowerBBCorners(); }
inline void set(const Vec4& vec) { _fv = vec; calculateUpperLowerBBCorners(); }
inline void set(const Vec3& norm,const float d) { _fv.set(norm[0],norm[1],norm[2],d); calculateUpperLowerBBCorners(); }
inline void set(const Vec3& v1, const Vec3& v2, const Vec3& v3)
{
osg::Vec3 norm = (v2-v1)^(v3-v2);
float length = norm.length();
if (length>1e-6) norm/= length;
else norm.set(0.0f,0.0f,0.0f);
_fv.set(norm[0],norm[1],norm[2],-(v1*norm));
calculateUpperLowerBBCorners();
}
inline void makeUnitLength()
{
float length = sqrtf(_fv[0]*_fv[0] + _fv[1]*_fv[1]+ _fv[2]*_fv[2]);
_fv /= length;
}
/** calculate the upper and lower bounding box corners to be used
* in the intersect(BoundingBox&) method for speeding calculations.*/
inline void calculateUpperLowerBBCorners()
{
_upperBBCorner = (_fv.x()>=0.0f?1:0) |
(_fv.y()>=0.0f?2:0) |
(_fv.z()>=0.0f?4:0);
_lowerBBCorner = (~_upperBBCorner)&7;
}
inline const bool valid() const { return _fv[0]==0.0f && _fv[1]==0.0f && _fv[2]==0.0f; }
inline Vec4& asVec4() { return _fv; }
inline const Vec4& asVec4() const { return _fv; }
inline float& operator [] (const int i) { return _fv[i]; }
inline float operator [] (const int i) const { return _fv[i]; }
/** calculate the distance between a point and the plane.*/
inline const float distance(const osg::Vec3& v) const
{
return _fv[0]*v.x()+
_fv[1]*v.y()+
_fv[2]*v.z()+
_fv[3];
}
/** interesection test between plane and bounding sphere.
return 1 if the bs is completely above plane,
return 0 if the bs intersects the plane,
return -1 if the bs is completely below the plane.*/
inline const int intersect(const BoundingSphere& bs) const
{
float d = distance(bs.center());
if (d>bs.radius()) return 1;
else if (d<-bs.radius()) return -1;
else return 0;
}
/** interesection test between plane and bounding sphere.
return 1 if the bs is completely above plane,
return 0 if the bs intersects the plane,
return -1 if the bs is completely below the plane.*/
inline const int intersect(const BoundingBox& bb) const
{
// if lowest point above plane than all above.
if (distance(bb.corner(_lowerBBCorner))>0.0f) return 1;
// if highest point is below plane then all below.
if (distance(bb.corner(_upperBBCorner))<0.0f) return -1;
// d_lower<=0.0f && d_upper>=0.0f
// therefore must be crossing plane.
return 0;
}
/** Transform the plane by matrix. Note, this operations carries out
* the calculation of the inverse of the matrix since to transforms
* planes must be multiplied my the inverse transposed. This
* make this operation expensive. If the inverse has been already
* calculated elsewhere then use transformProvidingInverse() instead.
* See http://www.worldserver.com/turk/computergraphics/NormalTransformations.pdf*/
inline void transform(const osg::Matrix& matrix)
{
osg::Matrix inverse;
inverse.invert(matrix);
transformProvidingInverse(inverse);
}
/** Transform the plane by provide a pre inverted matrix.
* see transform for details. */
inline void transformProvidingInverse(const osg::Matrix& matrix)
{
// note pre multiplications, which effectively transposes matrix.
_fv = matrix * _fv;
makeUnitLength();
calculateUpperLowerBBCorners();
}
friend inline ostream& operator << (ostream& output, const Plane& pl);
protected:
Vec4 _fv;
// variables cached to optimize calcs against bounding boxes.
unsigned int _upperBBCorner;
unsigned int _lowerBBCorner;
};
inline ostream& operator << (ostream& output, const Plane& pl)
{
output << pl._fv[0] << " "
<< pl._fv[1] << " "
<< pl._fv[2] << " "
<< pl._fv[3];
return output; // to enable cascading
}
}; // end of namespace
#endif

54
include/osg/PolygonMode Normal file
View File

@@ -0,0 +1,54 @@
#ifndef OSG_POLYGONMODE
#define OSG_POLYGONMODE 1
#include <osg/StateAttribute>
#include <osg/GL>
namespace osg {
/** Class to for setting OpenGL's polygon culling mode.
*/
class SG_EXPORT PolygonMode : public StateAttribute
{
public :
PolygonMode();
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const PolygonMode*>(obj)!=0L; }
virtual Object* clone() const { return new PolygonMode(); }
virtual const char* className() const { return "PolygonMode"; }
virtual const Type getType() const { return POLYGONMODE; }
enum Face {
FRONT,
BACK,
FRONT_AND_BACK
};
enum Mode {
POINT = GL_POINT,
LINE = GL_LINE,
FILL = GL_FILL
};
void setMode(const Face face,const Mode mode);
const Mode getMode(const Face face) const;
inline const bool getFrontAndBack() const { return _frontAndBack; }
virtual void apply(State& state) const;
protected:
virtual ~PolygonMode();
bool _frontAndBack;
Mode _modeFront;
Mode _modeBack;
};
};
#endif

132
include/osg/StateAttribute Normal file
View File

@@ -0,0 +1,132 @@
#ifndef OSG_STATEATTRIBUTE
#define OSG_STATEATTRIBUTE 1
#include <osg/Object>
#include <osg/GL>
namespace osg {
// forward declare State & StateSet
class State;
class StateSet;
/** Base class for state attribues.
*/
class SG_EXPORT StateAttribute : public Object
{
public :
/** GLMode is the value used in glEnable/glDisable(mode) */
typedef GLenum GLMode;
/** GLModeValue is used to specified whether an mode is enabled (ON) or disabled (OFF).
* GLMoveValue is also used to speficy the override behavior of modes from parent to children.
* See enum Value description for more details.*/
typedef unsigned int GLModeValue;
/** Override is used to specified the override behavior of StateAttributes
* from from parent to children.
* See enum Value description for more details.*/
typedef unsigned int OverrideValue;
/** list values which can be used in to set either GLModeValues
* or OverrideValues. When using in conjection with GLModeValues
* all Values have meaning. When using in conjection with
* StateAttribute OverrideValue only OFF,OVERRIDE and INHERIT
* are meaningful. However, they are useful when using GLModeValue
* and OverrideValue in conjunction with each other as when using
* StateSet::setAttributeAndModes(..).*/
enum Values
{
/** means that associated GLMode and Override is disabled.*/
OFF = 0x0,
/** means that associated GLMode is enabled and Override is disabled.*/
ON = 0x1,
/** Overriding of GLMode's or StateAttributes is enabled.*/
OVERRIDE = 0x2,
/** means that associated GLMode is disabled and Override is enabled.*/
OVERRIDE_OFF = 0x2,
/** means that associated GLMode and Override is enabled.*/
OVERRIDE_ON = 0x3,
/** means that GLMode or StateAttribute should in inherited from above.*/
INHERIT = 0x4
};
/** Values of StateAttribute::Type used to aid identification
* of diffenent StateAttribute subclasses. Each subclass defines
* it own value in the virtual Type getType() method. When
* extending the osg's StateAttribute's simply define your
* own Type value which is unique, using the StateAttribute::Type
* enum as a guide of what values to use. If your new subclass
* needs to override a standard StateAttriubte then simple use
* that types value. */
enum Type
{
ALPHAFUNC =1,
ANTIALIAS =2,
COLORTABLE =3,
CULLFACE =4,
FOG =5,
FRONTFACE =6,
LIGHTING =7,
MATERIAL =8,
POINT =9,
POLYGONMODE =10,
POLYGONOFFSET =11,
TEXENV =12,
TEXGEN =13,
TEXMAT =14,
TEXTURE =15,
TEXTURE_0 =TEXTURE+0,
TEXTURE_1 =TEXTURE+1,
TEXTURE_2 =TEXTURE+2,
TEXTURE_3 =TEXTURE+3,
TRANSPARENCY =19,
STENCIL =20,
COLORMASK =21,
CLIPPLANE =23,
CLIPPLANE_0 =CLIPPLANE+0,
CLIPPLANE_1 =CLIPPLANE+1,
CLIPPLANE_2 =CLIPPLANE+2,
CLIPPLANE_3 =CLIPPLANE+3,
CLIPPLANE_4 =CLIPPLANE+4,
CLIPPLANE_5 =CLIPPLANE+5,
DEPTH =29
};
StateAttribute() {}
/** return a shallow copy of a node, with Object* return type.*/
virtual Object* clone() const = 0;
/** return true if this and obj are of the same kind of object.*/
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const StateAttribute*>(obj)!=NULL; }
/** return the name of the attribute's class type.*/
virtual const char* className() const { return "StateAttribute"; }
/** return the Type idenitifer of the attribute's class type.*/
virtual const Type getType() const = 0;
virtual void setStateSetModes(StateSet&,const GLModeValue) const
{
// default to no GLMode's assocated with use of the StateAttribute.
}
/** apply the OpenGL state attributes.
* The global state for the current OpenGL context is passed
* in to allow the StateAttribute to obtain details on the
* the current context and state.
*/
virtual void apply(State&) const = 0 ;
/** default to nothing to compile - all state is applied immediately. */
virtual void compile(State&) const {};
protected:
virtual ~StateAttribute() {}
};
};
#endif

171
include/osg/StateSet Normal file
View File

@@ -0,0 +1,171 @@
#ifndef OSG_STATESET
#define OSG_STATESET 1
#include <osg/Object>
#include <osg/StateAttribute>
#include <osg/ref_ptr>
#include <map>
#include <vector>
#include <string>
namespace osg {
/**
Encapsulates OpenGL state modes and attributes.
Used to specificy textures etc of osg::Drawable's which hold references
to a single osg::StateSet. StateSet can be shared between Drawable's
and is recommend if possible as it minimize expensive state changes
in the graphics pipeline.
*/
class SG_EXPORT StateSet : public Object
{
public :
StateSet();
virtual Object* clone() const { return new StateSet(); }
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const StateSet*>(obj)!=NULL; }
virtual const char* className() const { return "StateSet"; }
/** set all the modes to on or off so that it defines a
complete state, typically used for a default global state.*/
void setGlobalDefaults();
/** set all the modes to inherit, typically used to signifiy
nodes which inherit all of their modes for the global state.*/
void setAllToInherit();
/** a container to map GLModes to their respective GLModeValues.*/
typedef std::map<StateAttribute::GLMode,StateAttribute::GLModeValue> ModeList;
/** set this StateSet to contain specified GLMode and value.*/
void setMode(const StateAttribute::GLMode mode, const StateAttribute::GLModeValue value);
/** set this StateSet to inherit specified GLMode type from parents.
* has the effect of deleting any GlMode of specified type from StateSet.*/
void setModeToInherit(const StateAttribute::GLMode mode);
/** get specified GLModeValue for specified GLMode.
* returns INHERIT if no GLModeValue is contained within StateSet.*/
const StateAttribute::GLModeValue getMode(const StateAttribute::GLMode mode) const;
/** return the list of all GLModes contained in this StateSet.*/
inline ModeList& getModeList() { return _modeList; }
/** return the const list of all GLModes contained in this const StateSet.*/
inline const ModeList& getModeList() const { return _modeList; }
/** simple pairing between an attribute and its override flag.*/
typedef std::pair<ref_ptr<StateAttribute>,StateAttribute::OverrideValue> RefAttributePair;
/** a container to map StateAttribyte::Types to their respective RefAttributePair.*/
typedef std::map<StateAttribute::Type,RefAttributePair> AttributeList;
/** set this StateSet to contain specified attribute and override flag.*/
void setAttribute(StateAttribute *attribute, const StateAttribute::OverrideValue value=StateAttribute::OFF);
/** set this StateSet to contain specified attribute and set the associated GLMode's to specifed value.*/
void setAttributeAndModes(StateAttribute *attribute, const StateAttribute::GLModeValue value=StateAttribute::ON);
/** set this StateSet to inherit specified attribute type from parents.
* has the effect of deleting any state attributes of specified type from StateSet.*/
void setAttributeToInherit(const StateAttribute::Type type);
/** get specified StateAttribute for specified type.
* returns NULL if no type is contained within StateSet.*/
const StateAttribute* getAttribute(const StateAttribute::Type type) const;
/** get specified RefAttributePair for specified type.
* returns NULL if no type is contained within StateSet.*/
const RefAttributePair* getAttributePair(const StateAttribute::Type type) const;
/** return the list of all StateAttributes contained in this StateSet.*/
inline AttributeList& getAttributeList() { return _attributeList; }
/** return the const list of all StateAttributes contained in this const StateSet.*/
inline const AttributeList& getAttributeList() const { return _attributeList; }
/** tempory type def to support tempory method getModeVector.*/
typedef std::vector<std::pair<StateAttribute::GLMode,StateAttribute::GLModeValue> > ModeVector;
/** get method which copies this StateSet's osg::GLModeValues's into
* a std::vector. method is overlaps on the propper get method -
* getModeList and only exists to get round a crash under Windows.
* Will be removed once problem is fixed.*/
const ModeVector getModeVector() const;
/** tempory type def to support tempory method getAttributeVector.*/
typedef std::vector<const StateAttribute*> AttributeVector;
/** get method which copies this StateSet's osg::StateAttribute's into
* a std::vector. method is overlaps on the propper get method -
* getAttributeList and only exists to get round a crash under Windows.
* Will be removed once problem is fixed.*/
const AttributeVector getAttributeVector() const;
enum RenderingHint
{
DEFAULT_BIN = 0,
OPAQUE_BIN = 1,
TRANSPARENT_BIN = 2
};
/** set the RenderingHint of the StateSet.
* RenderingHint is used by osgUtil::Renderer to determine which
* draw bin to drop associated osg::Drawables in. For opaque
* objects OPAQUE_BIN would typical used, which TRANSPARENT_BIN
* should be used for objects which need to be depth sorted.*/
void setRenderingHint(const int hint);
/** get the RenderingHint of the StateSet.*/
inline const int getRenderingHint() const { return _renderingHint; }
enum RenderBinMode
{
INHERIT_RENDERBIN_DETAILS,
USE_RENDERBIN_DETAILS,
OVERRIDE_RENDERBIN_DETAILS,
ENCLOSE_RENDERBIN_DETAILS
};
/** set the render bin details.*/
void setRenderBinDetails(const int binNum,const std::string& binName,const RenderBinMode mode=USE_RENDERBIN_DETAILS);
/** set the render bin details to inherit.*/
void setRendingBinToInherit();
/** get the render bin mode.*/
inline const RenderBinMode getRenderBinMode() const { return _binMode; }
/** get whether the render bin details are set and should be used.*/
inline const bool useRenderBinDetails() const { return _binMode!=INHERIT_RENDERBIN_DETAILS; }
/** get the render bin number.*/
inline const int getBinNumber() const { return _binNum; }
/** get the render bin name.*/
inline const std::string& getBinName() const { return _binName; }
/** call compile on all StateAttributes contained within this StateSet.*/
void compile(State& state) const;
protected :
virtual ~StateSet();
StateSet(const StateSet&):Object() {}
StateSet& operator = (const StateSet&) { return *this; }
ModeList _modeList;
AttributeList _attributeList;
int _renderingHint;
RenderBinMode _binMode;
int _binNum;
std::string _binName;
};
};
#endif

114
include/osg/Stencil Normal file
View File

@@ -0,0 +1,114 @@
#ifndef OSG_STENCIL
#define OSG_STENCIL 1
#include <osg/StateAttribute>
#include <osg/StateSet>
#include <osg/Types>
namespace osg {
/** Encapsulte OpenGL glStencilFunc/Op/Mask functions.
*/
class SG_EXPORT Stencil : public StateAttribute
{
public :
Stencil();
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Stencil*>(obj)!=0L; }
virtual Object* clone() const { return new Stencil(); }
virtual const char* className() const { return "Stencil"; }
virtual const Type getType() const { return STENCIL; }
virtual void setStateSetModes(StateSet& ds,const GLModeValue value) const
{
ds.setMode(GL_STENCIL_TEST,value);
}
enum Function
{
NEVER = GL_NEVER,
LESS = GL_LESS,
EQUAL = GL_EQUAL,
LEQUAL = GL_LEQUAL,
GREATER = GL_GREATER,
NOTEQUAL = GL_NOTEQUAL,
GEQUAL = GL_GEQUAL,
ALWAYS = GL_ALWAYS
};
inline void setFunction(const Function func,int ref,uint mask)
{
_func = func;
_funcRef = ref;
_funcMask = mask;
}
inline const Function getFunction() const { return _func; }
inline const int getFunctionRef() const { return _funcRef; }
inline const uint getFunctionMask() const { return _funcMask; }
enum Operation
{
KEEP = GL_KEEP,
ZERO = GL_ZERO,
REPLACE = GL_REPLACE,
INCR = GL_INCR,
DECR = GL_DECR,
INVERT = GL_INVERT
};
/** set the operations to apply when the various stencil and depth
* tests fail or pass. First paramater is to control the operation
* when the stencil test fails. The second paramter is to control the
* operatiorn when the stencil test passes, but depth test fails. The
* third parameter controls the operation when both the stencil test
* and depth pass. Ordering of parameter is the same as if using
* glStencilOp(,,).*/
inline void setOperation(const Operation sfail, const Operation zfail, const Operation zpass)
{
_sfail = sfail;
_zfail = zfail;
_zpass = zpass;
}
/** get the operation when the stencil test fails.*/
inline const Operation getStencilFailOperation() const { return _sfail; }
/** get the operation when the stencil test passes but the depth test fails*/
inline const Operation getStencilPassAndDepthFailOperation() const { return _zfail; }
/** get the operation when both the stencil test and the depth test pass*/
inline const Operation getStencilPassAndDepthPassOperation() const { return _zpass; }
inline void setWriteMask(uint mask) { _writeMask = mask; }
inline const uint getWriteMask() const { return _writeMask; }
virtual void apply(State& state) const;
protected:
virtual ~Stencil();
Function _func;
int _funcRef;
uint _funcMask;
Operation _sfail;
Operation _zfail;
Operation _zpass;
uint _writeMask;
};
};
#endif

46
include/osg/Transform Normal file
View File

@@ -0,0 +1,46 @@
#ifndef OSG_TRANSFORM
#define OSG_TRANSFORM 1
#include <osg/Group>
#include <osg/Matrix>
namespace osg {
/** Transform - is group which all children
are transformed by the the Transform's osg::Matrix. Typical uses
of the Transform is for positioning objects within a scene or
producing trakerball functionality or for animatiion.
*/
class SG_EXPORT Transform : public Group
{
public :
Transform();
Transform(const Matrix& matix);
virtual Object* clone() const { return new Transform(); }
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Transform*>(obj)!=NULL; }
virtual const char* className() const { return "Transform"; }
virtual void accept(NodeVisitor& nv) { nv.apply(*this); }
void setMatrix(const Matrix& mat );
inline Matrix& getMatrix() { return *_matrix; }
inline const Matrix& getMatrix() const { return *_matrix; }
void preMult( const Matrix& mat );
void preScale( const float sx, const float sy, const float sz );
void preTranslate( const float tx, const float ty, const float tz );
void preRotate( const float deg, const float x, const float y, const float z );
protected :
virtual ~Transform();
virtual const bool computeBound() const;
ref_ptr<Matrix> _matrix;
};
};
#endif

202
include/osg/mem_ptr Normal file
View File

@@ -0,0 +1,202 @@
#ifndef OSG_MEM_PTR
#define OSG_MEM_PTR 1
#include <osg/ref_ptr>
#include <osg/MemoryAdapter>
#include <map>
namespace osg {
/** Smart pointer for handling memory pointers via associated memory adapter.*/
template<class T>
class mem_ptr
{
public:
mem_ptr() :_ptr(0L),_ma(0L) {}
mem_ptr(T* t,MemoryAdapter* ma):_ptr(t),_ma(ma)
{
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
}
mem_ptr(const mem_ptr& rp):_ptr(rp._ptr),_ma(rp._ma)
{
if (_ptr && _ma.valid()) _ma->unref_data(_ptr);
}
~mem_ptr()
{
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
}
inline mem_ptr& operator = (const mem_ptr& rp)
{
if (_ptr==rp._ptr) return *this;
if (_ptr && _ma.valid()) _ma->unref_data(_ptr);
_ptr = rp._ptr;
_ma = rp._ma;
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
return *this;
}
inline void set(T* t,MemoryAdapter* ma)
{
if (_ptr==t)
{
if (_ma==ma) return;
if (ma)
{
ma->ref(_ptr);
if (_ma.valid()) _ma->unref_data(_ptr);
}
_ma = ma;
}
else
{
if (_ptr && _ma.valid()) _ma->unref_data(_ptr);
_ptr = t;
_ma = rp._ma;
if (_ptr && _ma.valid()) _ma->ref_data(_ptr);
}
}
inline const bool operator == (const mem_ptr& rp) const
{
return (_ptr==rp._ptr);
}
inline const bool operator == (const T* ptr) const
{
return (_ptr==ptr);
}
inline const bool operator != (const mem_ptr& rp) const
{
return (_ptr!=rp._ptr);
}
inline const bool operator != (const T* ptr) const
{
return (_ptr!=ptr);
}
inline T& operator*() { return *_ptr; }
inline const T& operator*() const { return *_ptr; }
inline T* operator->() { return _ptr; }
inline const T* operator->() const { return _ptr; }
inline const bool operator!() const { return _ptr==0L; }
inline const bool valid() const { return _ptr!=0L; }
inline T* get() { return _ptr; }
inline const T* get() const { return _ptr; }
private:
T* _ptr;
ref_ptr<MemoryAdapter> _ma;
};
// /** Exprimental memory adapter implmentation.*/
// template<class T>
// class CppMemoryAdapter : public MemoryAdapter
// {
// public:
//
// virtual void ref_data(void* userData)
// {
// ++_memoryMap[(T*)userData];
// }
//
// virtual void unref_data(void* userData)
// {
// --_memoryMap[(T*)userData];
// if (_memoryMap[(T*)userData]<=0) delete userData;
// _memoryMap.erase((T*)userData);
// }
//
// protected:
//
// static std::map<T*,int> _memoryMap;
//
// };
//
// /** Exprimental memory adapter implmentation.*/
// class NewMemoryAdapter : public MemoryAdapter
// {
// public:
//
// static MemoryAdapter* instance();
//
// virtual void ref_data(void* userData)
// {
// ++_memoryMap[userData];
// }
//
// virtual void unref_data(void* userData)
// {
// --_memoryMap[userData];
// if (_memoryMap[userData]<=0) delete userData;
// _memoryMap.erase(userData);
// }
//
// protected:
//
// NewMemoryAdapter() {}
// NewMemoryAdapter(NewMemoryAdapter&):MemoryAdapter() {}
// ~NewMemoryAdapter() {}
//
// std::map<void*,int> _memoryMap;
//
// };
//
// /** Exprimental memory adapter implmentation.*/
// template<class T>
// class newMemoryAdapter : public MemoryAdapter
// {
// public:
//
// static newMemoryAdapter<T>* instance()
// {
// static ref_ptr<newMemoryAdapter<T> > s_newMemoryAdapter = new newMemoryAdapter<T>();
// return s_newMemoryAdapter.get();
// }
//
// T* allocate(int no) { cout<<"Allocating Memory"<<endl;return new T[no]; }
//
// virtual void ref_data(void* userData)
// {
// cout<<"Incrementing Memory"<<endl;
// ++_memoryMap[(T*)userData];
// }
//
// virtual void unref_data(void* userData)
// {
// cout<<"Decrementing Memory"<<endl;
// --_memoryMap[(T*)userData];
// if (_memoryMap[(T*)userData]<=0)
// {
// cout<<"Deleting Memory"<<endl;
// delete (T*)userData;
// }
// _memoryMap.erase((T*)userData);
// }
//
// protected:
//
// newMemoryAdapter() {cout<<"*** Constructing nMA"<<endl;}
// newMemoryAdapter(newMemoryAdapter&):MemoryAdapter() {}
// ~newMemoryAdapter() {cout<<"*** Destructing nMA"<<endl;}
//
// std::map<T*,int> _memoryMap;
//
// };
};
#endif

87
include/osg/ref_ptr Normal file
View File

@@ -0,0 +1,87 @@
#ifndef OSG_REF_PTR
#define OSG_REF_PTR 1
namespace osg {
/** Smart pointer for handling referenced counted objects.*/
template<class T>
class ref_ptr
{
public:
ref_ptr() :_ptr(0L) {}
ref_ptr(T* t):_ptr(t) { if (_ptr) _ptr->ref(); }
ref_ptr(const ref_ptr& rp):_ptr(rp._ptr) { if (_ptr) _ptr->ref(); }
~ref_ptr() { if (_ptr) _ptr->unref(); }
inline ref_ptr& operator = (const ref_ptr& rp)
{
if (_ptr==rp._ptr) return *this;
if (_ptr) _ptr->unref();
_ptr = rp._ptr;
if (_ptr) _ptr->ref();
return *this;
}
inline ref_ptr& operator = (T* ptr)
{
if (_ptr==ptr) return *this;
if (_ptr) _ptr->unref();
_ptr = ptr;
if (_ptr) _ptr->ref();
return *this;
}
inline const bool operator == (const ref_ptr& rp) const
{
return (_ptr==rp._ptr);
}
inline const bool operator == (const T* ptr) const
{
return (_ptr==ptr);
}
inline const bool operator != (const ref_ptr& rp) const
{
return (_ptr!=rp._ptr);
}
inline const bool operator != (const T* ptr) const
{
return (_ptr!=ptr);
}
inline const bool operator < (const ref_ptr& rp) const
{
return (_ptr<rp._ptr);
}
inline const bool operator < (const T* ptr) const
{
return (_ptr<ptr);
}
inline T& operator*() { return *_ptr; }
inline const T& operator*() const { return *_ptr; }
inline T* operator->() { return _ptr; }
inline const T* operator->() const { return _ptr; }
inline const bool operator!() const { return _ptr==0L; }
inline const bool valid() const { return _ptr!=0L; }
inline T* get() { return _ptr; }
inline const T* get() const { return _ptr; }
private:
T* _ptr;
};
};
#endif

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