You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
9.3 KiB
241 lines
9.3 KiB
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|
* |
|
* This library is open source and may be redistributed and/or modified under |
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|
* (at your option) any later version. The full license is in LICENSE file |
|
* included with this distribution, and on the openscenegraph.org website. |
|
* |
|
* This library is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* OpenSceneGraph Public License for more details. |
|
*/ |
|
|
|
#ifndef OSG_ImpostorSprite |
|
#define OSG_ImpostorSprite 1 |
|
|
|
#include <osg/Vec2> |
|
#include <osg/BoundingSphere> |
|
#include <osg/Drawable> |
|
#include <osg/AlphaFunc> |
|
#include <osg/TexEnv> |
|
#include <osg/Texture2D> |
|
#include <osg/Camera> |
|
|
|
#include <osgSim/Export> |
|
|
|
namespace osgSim { |
|
|
|
class Impostor; |
|
class ImpostorSpriteManager; |
|
|
|
/** An ImposterSprite is a textured quad which is rendered in place of |
|
* 3D geometry. The ImposterSprite is generated by rendering the original |
|
* 3D geometry to a texture as an image cache. The ImpostorSprite is |
|
* automatically generated by the osgUtil::CullVisitor so it not |
|
* necessary to deal with it directly. |
|
*/ |
|
class OSGSIM_EXPORT ImpostorSprite : public osg::Drawable |
|
{ |
|
public: |
|
|
|
ImpostorSprite(); |
|
|
|
/** Clone an object of the same type as an ImpostorSprite. */ |
|
virtual osg::Object* cloneType() const { return new ImpostorSprite(); } |
|
|
|
/** Clone on ImpostorSprite just returns a clone of type, |
|
* since it is not appropriate to share data of an ImpostorSprite. |
|
*/ |
|
virtual osg::Object* clone(const osg::CopyOp&) const { return new ImpostorSprite(); } |
|
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const ImpostorSprite*>(obj)!=NULL; } |
|
virtual const char* libraryName() const { return "osgSim"; } |
|
virtual const char* className() const { return "ImpostorSprite"; } |
|
|
|
/** Set the parent, which must be an Impostor. |
|
* Unlike conventional Drawables, ImpostorSprites 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 ImpostorSprite was snapped. */ |
|
inline void setStoredLocalEyePoint(const osg::Vec3& v) { _storedLocalEyePoint=v; } |
|
|
|
/** Get the eye point for when the ImpostorSprite was snapped. */ |
|
inline const osg::Vec3& getStoredLocalEyePoint() const { return _storedLocalEyePoint; } |
|
|
|
/** Set the frame number for when the ImpostorSprite was last used in rendering. */ |
|
inline void setLastFrameUsed(unsigned int frameNumber) { _lastFrameUsed = frameNumber; } |
|
|
|
/** Get the frame number for when the ImpostorSprite was last used in rendering. */ |
|
inline unsigned 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 osg::Vec3* getCoords() { return _coords; } |
|
|
|
/** Get the const coordinates of the corners of the quad. */ |
|
inline const osg::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 osg::Vec2* getTexCoords() { return _texcoords; } |
|
|
|
/** Get the const texture coordinates of the corners of the quad. */ |
|
inline const osg::Vec2* getTexCoords() const { return _texcoords; } |
|
|
|
/** Get the control coordinates of the corners of the quad. |
|
* The control coordinates are the corners 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 on top of the corners of the quad in screen space - with a pixel error |
|
* of zero. Once the camera moves relative to the impostor sprite the |
|
* control coords will no longer lie on top of the corners of the quad in |
|
* screen space - a pixel error will have accumulated. This pixel error |
|
* can then be used to determine whether the impostor needs to be updated. |
|
* Stored in the order, [0] - top_left, [1] - bottom_left, [2] - bottom_right, [3] - top_left. |
|
*/ |
|
inline osg::Vec3* getControlCoords() { return _controlcoords; } |
|
|
|
/** Get the const control coordinates of the corners of the quad. */ |
|
inline const osg::Vec3* getControlCoords() const { return _controlcoords; } |
|
|
|
|
|
/** Calculate the pixel error value for passing in the ModelViewProjectionWindow transform, |
|
* which transform local coords into screen space. |
|
*/ |
|
float calcPixelError(const osg::Matrix& MVPW) const; |
|
|
|
void setTexture(osg::Texture2D* tex,int s,int t); |
|
osg::Texture2D* getTexture() { return _texture; } |
|
const osg::Texture2D* getTexture() const { return _texture; } |
|
|
|
int s() const { return _s; } |
|
int t() const { return _t; } |
|
|
|
/** Draw ImpostorSprite directly. */ |
|
virtual void drawImplementation(osg::RenderInfo& renderInfo) const; |
|
|
|
/** Return true, osg::ImpostorSprite does support accept(Drawable::AttributeFunctor&). */ |
|
virtual bool supports(const Drawable::AttributeFunctor&) const { return true; } |
|
|
|
/** Accept an Drawable::AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. */ |
|
virtual void accept(Drawable::AttributeFunctor& af); |
|
|
|
/** Return true, osg::ImpostorSprite does support accept(Drawable::ConstAttributeFunctor&). */ |
|
virtual bool supports(const Drawable::ConstAttributeFunctor&) const { return true; } |
|
|
|
/** Accept a Drawable::ConstAttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. */ |
|
virtual void accept(Drawable::ConstAttributeFunctor& af) const; |
|
|
|
/** Return true, osg::ImpostorSprite does support accept(PrimitiveFunctor&). */ |
|
virtual bool supports(const osg::PrimitiveFunctor&) const { return true; } |
|
|
|
/** Accept a PrimtiveFunctor and call its methods to tell it about the internal primitives that this Drawable has. */ |
|
virtual void accept(osg::PrimitiveFunctor& pf) const; |
|
|
|
// for debugging purposes. |
|
osg::Vec4 _color; |
|
|
|
virtual osg::BoundingBox computeBound() const; |
|
|
|
/** Set the camera node to use for pre rendering the impostor sprite's texture.*/ |
|
void setCamera(osg::Camera* camera) { _camera = camera; } |
|
|
|
/** Get the camera node to use for pre rendering the impostor sprite's texture.*/ |
|
osg::Camera* getCamera() { return _camera.get(); } |
|
|
|
/** Get the const camera node to use for pre rendering the impostor sprite's texture.*/ |
|
const osg::Camera* getCamera() const { return _camera.get(); } |
|
|
|
protected: |
|
|
|
ImpostorSprite(const ImpostorSprite&); |
|
ImpostorSprite& operator = (const ImpostorSprite&) { return *this;} |
|
|
|
virtual ~ImpostorSprite(); |
|
|
|
Impostor* _parent; |
|
|
|
friend class osgSim::ImpostorSpriteManager; |
|
|
|
// camera node for doing the pre rendering. |
|
osg::ref_ptr<osg::Camera> _camera; |
|
|
|
// support for a double linked list managed by the |
|
// ImposotorSpriteManager. |
|
ImpostorSpriteManager* _ism; |
|
ImpostorSprite* _previous; |
|
ImpostorSprite* _next; |
|
|
|
unsigned int _lastFrameUsed; |
|
|
|
osg::Vec3 _storedLocalEyePoint; |
|
|
|
osg::Vec3 _coords[4]; |
|
osg::Vec2 _texcoords[4]; |
|
osg::Vec3 _controlcoords[4]; |
|
|
|
osg::Texture2D* _texture; |
|
int _s; |
|
int _t; |
|
|
|
|
|
}; |
|
|
|
/** Helper class for managing the reuse of ImpostorSprite resources. */ |
|
class OSGSIM_EXPORT ImpostorSpriteManager : public osg::Referenced |
|
{ |
|
public: |
|
|
|
ImpostorSpriteManager(); |
|
|
|
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,unsigned int frameNumber); |
|
|
|
osg::StateSet* createOrReuseStateSet(); |
|
|
|
void reset(); |
|
|
|
protected: |
|
|
|
|
|
~ImpostorSpriteManager(); |
|
|
|
osg::ref_ptr<osg::TexEnv> _texenv; |
|
osg::ref_ptr<osg::AlphaFunc> _alphafunc; |
|
|
|
ImpostorSprite* _first; |
|
ImpostorSprite* _last; |
|
|
|
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList; |
|
StateSetList _stateSetList; |
|
unsigned int _reuseStateSetIndex; |
|
|
|
|
|
}; |
|
|
|
} |
|
|
|
#endif
|
|
|