2002-07-17 04:07:32 +08:00
|
|
|
//C++ header - Open Scene Graph - Copyright (C) 1998-2002 Robert Osfield
|
2001-10-04 23:12:57 +08:00
|
|
|
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
|
|
|
//as published by the Free Software Foundation.
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
#ifndef OSG_BILLBOARD
|
|
|
|
#define OSG_BILLBOARD 1
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
#include <osg/Matrix>
|
2001-01-11 00:32:10 +08:00
|
|
|
#include <osg/Geode>
|
|
|
|
|
|
|
|
namespace osg {
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Billboard - a Geode which orientates its child osg::Drawable's to face
|
2001-09-29 04:10:41 +08:00
|
|
|
the eye point. Typical uses are for trees, or particle explosions.
|
2001-01-11 00:32:10 +08:00
|
|
|
*/
|
|
|
|
class SG_EXPORT Billboard : public Geode
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum Mode {
|
|
|
|
POINT_ROT_EYE,
|
2002-01-19 06:15:59 +08:00
|
|
|
POINT_ROT_WORLD,
|
|
|
|
AXIAL_ROT
|
2001-01-11 00:32:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
Billboard();
|
|
|
|
|
2002-01-29 22:04:06 +08:00
|
|
|
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
|
|
|
Billboard(const Billboard&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
Added support for shallow and deep copy of nodes, drawables and state, via a
copy constructor which takes an optional Cloner object, and the old
osg::Object::clone() has changed so that it now requires a Cloner as paramter.
This is passed on to the copy constructor to help control the shallow vs
deep copying. The old functionality of clone() which was clone of type has
been renamed to cloneType().
Updated all of the OSG to work with these new conventions, implemention all
the required copy constructors etc. A couple of areas will do shallow
copies by design, a couple of other still need to be updated to do either
shallow or deep.
Neither of the shallow or deep copy operations have been tested yet, only
the old functionality of the OSG has been checked so far, such running the
viewer on various demo datasets.
Also fixed a problem in osg::Optimize::RemoveRendundentNodesVisitor which
was not checking that Group didn't have have any attached StateSet's, Callbacks
or UserData. These checks have now been added, which fixes a bug which was
revealled by the new osgscribe demo, this related to removal of group acting
as state decorator.
method
2002-01-29 05:17:01 +08:00
|
|
|
|
2002-06-06 21:25:36 +08:00
|
|
|
META_Node(osg, Billboard);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-01-19 06:15:59 +08:00
|
|
|
/** Set the billboard rotation mode. */
|
|
|
|
void setMode(const Mode mode);
|
|
|
|
/** Get the billboard rotation mode. */
|
|
|
|
inline const Mode getMode() const { return _mode; }
|
|
|
|
|
2002-08-10 00:27:39 +08:00
|
|
|
/** Set the axis about which all the billboard's drawable rotate. Only utlized when mode==AXIAL_ROT*/
|
2002-01-19 06:15:59 +08:00
|
|
|
void setAxis(const Vec3& axis);
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Get the axis about which all the billboard's drawable rotate. */
|
2002-01-19 06:15:59 +08:00
|
|
|
inline const Vec3& getAxis() const { return _axis; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-08-10 00:27:39 +08:00
|
|
|
/** Set the normal which defines the billboard's drawable front face, when unrotated. */
|
|
|
|
void setNormal(const Vec3& normal);
|
|
|
|
/** Get the normal of billboard's drawable front face. */
|
|
|
|
inline const Vec3& getNormal() const { return _normal; }
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Set the position of specified drawable. */
|
|
|
|
inline void setPos(int i,const Vec3& pos) { _positionList[i] = pos; }
|
|
|
|
/** Get the position of specified drawable. */
|
|
|
|
inline const Vec3& getPos(int i) const { return _positionList[i]; }
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** PositionList represents a list of pivot points for each drawable.*/
|
|
|
|
typedef std::vector<Vec3> PositionList;
|
|
|
|
|
2001-09-29 04:10:41 +08:00
|
|
|
/** Get the PositionList from the billboard.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline PositionList& getPositionList() { return _positionList; }
|
2001-09-29 04:10:41 +08:00
|
|
|
|
|
|
|
/** Get a const PositionList from the billboard.*/
|
2001-09-20 05:08:56 +08:00
|
|
|
inline const PositionList& getPositionList() const { return _positionList; }
|
|
|
|
|
|
|
|
/** Add Drawable to Billboard with default position(0,0,0);
|
2001-01-11 00:32:10 +08:00
|
|
|
* If gset not NULL and is not contained in Billboard then increment its
|
|
|
|
* reference count, and dirty the bounding box to cause it to recompute on
|
|
|
|
* next getBound() and return true for success. Otherwise return false.
|
|
|
|
*/
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual const bool addDrawable( Drawable *gset );
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Add Drawable to Geode at position pos.
|
2001-01-11 00:32:10 +08:00
|
|
|
* If gset not NULL and is not contained in Billboard then increment its
|
|
|
|
* reference count, and dirty the bounding box to cause it to recompute on
|
|
|
|
* next getBound() and return true for success. Otherwise return false.
|
|
|
|
*/
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual const bool addDrawable(Drawable *gset,const Vec3& pos);
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
/** Remove Drawable and associated position from Billboard.
|
2001-01-11 00:32:10 +08:00
|
|
|
* If gset is contained in Billboard then remove it from the geoset
|
|
|
|
* list and decrement its reference count, and dirty the
|
|
|
|
* bounding box to cause it to recompute on next getBound() and
|
|
|
|
* return true for success. If gset is not found then return false
|
|
|
|
* and do not the reference count of gset is left unchanged.
|
|
|
|
*/
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual const bool removeDrawable( Drawable *gset );
|
2002-02-07 09:07:11 +08:00
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-02-07 09:07:11 +08:00
|
|
|
/** Callback attached to an Billboard which allows the users to customize the billboard orientation calculation during cull traversal.*/
|
|
|
|
struct ComputeBillboardCallback : public osg::Referenced
|
|
|
|
{
|
|
|
|
/** Get the transformation matrix which moves from local coords to world coords.*/
|
2002-05-29 07:43:22 +08:00
|
|
|
virtual const bool computeMatrix(Matrix& modelview, const Billboard* billboard, const Vec3& eye_local, const Vec3& pos_local) const = 0;
|
2002-02-07 09:07:11 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/** Set the ComputeBillboardCallback which allows users to attach custom computation of the local transformation as
|
|
|
|
* seen by cull traversers and alike.*/
|
|
|
|
void setComputeBillboardCallback(ComputeBillboardCallback* ctc) { _computeBillboardCallback=ctc; }
|
|
|
|
|
|
|
|
/** Get the non const ComputeBillboardCallback.*/
|
|
|
|
ComputeBillboardCallback* getComputeBillboardCallback() { return _computeBillboardCallback.get(); }
|
|
|
|
|
|
|
|
/** Get the const ComputeBillboardCallback.*/
|
|
|
|
const ComputeBillboardCallback* getComputeBillboardCallback() const { return _computeBillboardCallback.get(); }
|
|
|
|
|
|
|
|
|
2002-04-17 17:48:19 +08:00
|
|
|
inline const bool getMatrix(Matrix& modelview, const Vec3& eye_local, const Vec3& pos_local) const
|
2002-02-07 09:07:11 +08:00
|
|
|
{
|
|
|
|
if (_computeBillboardCallback.valid())
|
2002-04-17 17:48:19 +08:00
|
|
|
return _computeBillboardCallback->computeMatrix(modelview,this,eye_local,pos_local);
|
2002-02-07 09:07:11 +08:00
|
|
|
else
|
2002-04-17 17:48:19 +08:00
|
|
|
return computeMatrix(modelview,eye_local,pos_local);
|
2002-02-07 09:07:11 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-05-29 07:43:22 +08:00
|
|
|
virtual const bool computeMatrix(Matrix& modelview, const Vec3& eye_local, const Vec3& pos_local) const;
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
protected:
|
|
|
|
|
|
|
|
virtual ~Billboard();
|
|
|
|
|
2001-09-20 05:08:56 +08:00
|
|
|
virtual const bool computeBound() const;
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-01-19 06:15:59 +08:00
|
|
|
enum AxisAligned
|
|
|
|
{
|
|
|
|
AXIAL_ROT_X_AXIS=AXIAL_ROT+1,
|
|
|
|
AXIAL_ROT_Y_AXIS,
|
2002-08-10 00:27:39 +08:00
|
|
|
AXIAL_ROT_Z_AXIS,
|
|
|
|
CACHE_DIRTY
|
2002-01-19 06:15:59 +08:00
|
|
|
};
|
|
|
|
|
2001-01-11 00:32:10 +08:00
|
|
|
|
2002-02-07 09:07:11 +08:00
|
|
|
Mode _mode;
|
|
|
|
Vec3 _axis;
|
2002-08-10 00:27:39 +08:00
|
|
|
Vec3 _normal;
|
2002-02-07 09:07:11 +08:00
|
|
|
PositionList _positionList;
|
|
|
|
ref_ptr<ComputeBillboardCallback> _computeBillboardCallback;
|
2002-01-19 06:15:59 +08:00
|
|
|
|
|
|
|
// used internally as cache of which what _axis is aligned to help
|
|
|
|
// deicde which method of rotation to use.
|
2002-08-10 00:27:39 +08:00
|
|
|
int _cachedMode;
|
|
|
|
Vec3 _side;
|
|
|
|
void updateCache();
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2002-02-03 20:33:41 +08:00
|
|
|
}
|
2001-01-11 00:32:10 +08:00
|
|
|
|
|
|
|
#endif
|