//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield //Distributed under the terms of the GNU Library General Public License (LGPL) //as published by the Free Software Foundation. #ifndef OSG_BILLBOARD #define OSG_BILLBOARD 1 #include #include namespace osg { /** Billboard - a Geode which orientates its child osg::Drawable's to face the eye point. Typical uses are for trees, or particle explosions. */ class SG_EXPORT Billboard : public Geode { public: enum Mode { POINT_ROT_EYE, POINT_ROT_WORLD, AXIAL_ROT }; Billboard(); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ Billboard(const Billboard&,const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_Node(Billboard); /** Set the billboard rotation mode. */ void setMode(const Mode mode); /** Get the billboard rotation mode. */ inline const Mode getMode() const { return _mode; } /** Set the axis about which all the billboard's drawable rotate. */ void setAxis(const Vec3& axis); /** Get the axis about which all the billboard's drawable rotate. */ inline const Vec3& getAxis() const { return _axis; } /** 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]; } /** PositionList represents a list of pivot points for each drawable.*/ typedef std::vector PositionList; /** Get the PositionList from the billboard.*/ inline PositionList& getPositionList() { return _positionList; } /** Get a const PositionList from the billboard.*/ inline const PositionList& getPositionList() const { return _positionList; } /** Add Drawable to Billboard with default position(0,0,0); * 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. */ virtual const bool addDrawable( Drawable *gset ); /** Add Drawable to Geode at position pos. * 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. */ virtual const bool addDrawable(Drawable *gset,const Vec3& pos); /** Remove Drawable and associated position from Billboard. * 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. */ virtual const bool removeDrawable( Drawable *gset ); /** 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.*/ virtual const bool computeMatrix(Matrix& modelview, const Billboard* billboard, const Vec3& eye_local, const Vec3& pos_local) const = 0; }; /** 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(); } inline const bool getMatrix(Matrix& modelview, const Vec3& eye_local, const Vec3& pos_local) const { if (_computeBillboardCallback.valid()) return _computeBillboardCallback->computeMatrix(modelview,this,eye_local,pos_local); else return computeMatrix(modelview,eye_local,pos_local); } virtual const bool computeMatrix(Matrix& modelview, const Vec3& eye_local, const Vec3& pos_local) const; protected: virtual ~Billboard(); virtual const bool computeBound() const; enum AxisAligned { AXIAL_ROT_X_AXIS=AXIAL_ROT+1, AXIAL_ROT_Y_AXIS, AXIAL_ROT_Z_AXIS }; Mode _mode; Vec3 _axis; PositionList _positionList; ref_ptr _computeBillboardCallback; // used internally as cache of which what _axis is aligned to help // deicde which method of rotation to use. int _cachedMode; void setCachedMode(); }; } #endif