| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | */ |
|---|
| 13 | |
|---|
| 14 | #ifndef OSG_BILLBOARD |
|---|
| 15 | #define OSG_BILLBOARD 1 |
|---|
| 16 | |
|---|
| 17 | #include <osg/Matrix> |
|---|
| 18 | #include <osg/Geode> |
|---|
| 19 | |
|---|
| 20 | namespace osg { |
|---|
| 21 | |
|---|
| 22 | /** Billboard is a derived form of Geode that orients its osg::Drawable |
|---|
| 23 | * children to face the eye point. Typical uses include trees and |
|---|
| 24 | * particle explosions, |
|---|
| 25 | */ |
|---|
| 26 | class OSG_EXPORT Billboard : public Geode |
|---|
| 27 | { |
|---|
| 28 | public: |
|---|
| 29 | |
|---|
| 30 | enum Mode { |
|---|
| 31 | POINT_ROT_EYE, |
|---|
| 32 | POINT_ROT_WORLD, |
|---|
| 33 | AXIAL_ROT |
|---|
| 34 | }; |
|---|
| 35 | |
|---|
| 36 | Billboard(); |
|---|
| 37 | |
|---|
| 38 | /** Copy constructor using CopyOp to manage deep vs shallow copy. */ |
|---|
| 39 | Billboard(const Billboard&,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 40 | |
|---|
| 41 | META_Node(osg, Billboard); |
|---|
| 42 | |
|---|
| 43 | /** Set the billboard rotation mode. */ |
|---|
| 44 | void setMode(Mode mode); |
|---|
| 45 | /** Get the billboard rotation mode. */ |
|---|
| 46 | inline Mode getMode() const { return _mode; } |
|---|
| 47 | |
|---|
| 48 | /** Set the rotation axis for the billboard's child Drawables. |
|---|
| 49 | * Only utilized when mode==AXIAL_ROT. */ |
|---|
| 50 | void setAxis(const Vec3& axis); |
|---|
| 51 | /** Get the rotation axis. */ |
|---|
| 52 | inline const Vec3& getAxis() const { return _axis; } |
|---|
| 53 | |
|---|
| 54 | /** This normal defines child Drawables' front face direction when unrotated. */ |
|---|
| 55 | void setNormal(const Vec3& normal); |
|---|
| 56 | /** Get the front face direction normal. */ |
|---|
| 57 | inline const Vec3& getNormal() const { return _normal; } |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | /** Set the specified child Drawable's position. */ |
|---|
| 61 | inline void setPosition(unsigned int i,const Vec3& pos) { _positionList[i] = pos; } |
|---|
| 62 | /** Get the specified child Drawable's position. */ |
|---|
| 63 | inline const Vec3& getPosition(unsigned int i) const { return _positionList[i]; } |
|---|
| 64 | |
|---|
| 65 | /** Type definition for pivot point position list. */ |
|---|
| 66 | typedef std::vector<Vec3> PositionList; |
|---|
| 67 | |
|---|
| 68 | /** Set the list of pivot point positions. */ |
|---|
| 69 | inline void setPositionList(PositionList& pl) { _positionList=pl; } |
|---|
| 70 | |
|---|
| 71 | /** Get the list of pivot point positions. */ |
|---|
| 72 | inline PositionList& getPositionList() { return _positionList; } |
|---|
| 73 | |
|---|
| 74 | /** Get a const list of pivot point positions. */ |
|---|
| 75 | inline const PositionList& getPositionList() const { return _positionList; } |
|---|
| 76 | |
|---|
| 77 | /** Add a Drawable with a default position of Vec3(0,0,0). |
|---|
| 78 | * Call the base-class Geode::addDrawble() to add the given Drawable |
|---|
| 79 | * gset as a child. If Geode::addDrawable() returns true, add the |
|---|
| 80 | * default position to the pivot point position list and return true. |
|---|
| 81 | * Otherwise, return false. */ |
|---|
| 82 | virtual bool addDrawable( Drawable *gset ); |
|---|
| 83 | |
|---|
| 84 | /** Add a Drawable with a specified position. |
|---|
| 85 | * Call the base-class Geode::addDrawble() to add the given Drawable |
|---|
| 86 | * gset as a child. If Geode::addDrawable() returns true, add the |
|---|
| 87 | * given position pos to the pivot point position list and return true. |
|---|
| 88 | * Otherwise, return false. */ |
|---|
| 89 | virtual bool addDrawable(Drawable *gset,const Vec3& pos); |
|---|
| 90 | |
|---|
| 91 | /** Remove a Drawable and its associated position. |
|---|
| 92 | * If gset is a child, remove it, decrement its reference count, |
|---|
| 93 | * remove its pivot point position. and return true. |
|---|
| 94 | * Otherwise, return false. */ |
|---|
| 95 | virtual bool removeDrawable( Drawable *gset ); |
|---|
| 96 | |
|---|
| 97 | |
|---|
| 98 | bool computeMatrix(Matrix& modelview, const Vec3& eye_local, const Vec3& pos_local) const; |
|---|
| 99 | |
|---|
| 100 | virtual BoundingSphere computeBound() const; |
|---|
| 101 | |
|---|
| 102 | protected: |
|---|
| 103 | |
|---|
| 104 | virtual ~Billboard(); |
|---|
| 105 | |
|---|
| 106 | enum AxisAligned |
|---|
| 107 | { |
|---|
| 108 | AXIAL_ROT_X_AXIS=AXIAL_ROT+1, |
|---|
| 109 | AXIAL_ROT_Y_AXIS, |
|---|
| 110 | AXIAL_ROT_Z_AXIS, |
|---|
| 111 | POINT_ROT_WORLD_Z_AXIS, |
|---|
| 112 | CACHE_DIRTY |
|---|
| 113 | }; |
|---|
| 114 | |
|---|
| 115 | |
|---|
| 116 | Mode _mode; |
|---|
| 117 | Vec3 _axis; |
|---|
| 118 | Vec3 _normal; |
|---|
| 119 | Matrix _rotateNormalToZAxis; |
|---|
| 120 | PositionList _positionList; |
|---|
| 121 | |
|---|
| 122 | // used internally as cache of which what _axis is aligned to help |
|---|
| 123 | // decide which method of rotation to use. |
|---|
| 124 | int _cachedMode; |
|---|
| 125 | Vec3 _side; |
|---|
| 126 | void updateCache(); |
|---|
| 127 | |
|---|
| 128 | }; |
|---|
| 129 | |
|---|
| 130 | } |
|---|
| 131 | |
|---|
| 132 | #endif |
|---|