Further work on removing Camera references from NewCullVisitor and releted
classes, this work paves the way for making osg::Camera an optional extra rather than a requirement for rendering.
This commit is contained in:
parent
57248a4bf9
commit
6f65e86057
@ -102,9 +102,9 @@ class SG_EXPORT ImpostorSprite : public Drawable
|
||||
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 Viewport& viewport,const osg::Matrix* matrix) const;
|
||||
|
||||
/** calculate the pixel error value for passing in the ModelViewProjectionWindow transform,
|
||||
* which transform local coords into screen space.*/
|
||||
const float ImpostorSprite::calcPixelError(const Matrix& MVPW) const;
|
||||
|
||||
void setTexture(Texture* tex,int s,int t);
|
||||
|
||||
|
@ -88,9 +88,35 @@ class SG_EXPORT Matrix : public Object
|
||||
void makeRotate( float angle, float x, float y, float z );
|
||||
void makeRotate( const Quat& );
|
||||
void makeRotate( float, float, float ); //Euler angles
|
||||
|
||||
|
||||
/** Set to a orthographic projection. See glOrtho for further details.*/
|
||||
void makeOrtho(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar);
|
||||
|
||||
/** Set to a 2D orthographic projection. See glOrtho2D for further details.*/
|
||||
inline void makeOrtho2D(const double left, const double right,
|
||||
const double bottom, const double top)
|
||||
{
|
||||
makeOrtho(left,right,bottom,top,-1.0,1.0);
|
||||
}
|
||||
|
||||
/** Set to a perspective projection. See glFrustum for further details.*/
|
||||
void makeFrustum(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar);
|
||||
|
||||
/** Set to a symmetrical perspective projection, See gluPerspective for further details.
|
||||
* Aspect ratio is defined as width/height.*/
|
||||
void makePerspective(const double fovy,const double aspectRatio,
|
||||
const double zNear, const double zFar);
|
||||
|
||||
/** Set to the position and orientation as per a camera, using the same convention as gluLookAt. */
|
||||
void makeLookAt(const Vec3& eye,const Vec3& center,const Vec3& up);
|
||||
|
||||
|
||||
bool invert( const Matrix& );
|
||||
bool invertAffine( const Matrix& );
|
||||
|
||||
//basic utility functions to create new matrices
|
||||
inline static Matrix identity( void );
|
||||
@ -101,7 +127,30 @@ class SG_EXPORT Matrix : public Object
|
||||
inline static Matrix rotate( const Vec3&, const Vec3& );
|
||||
inline static Matrix rotate( float, float, float, float );
|
||||
inline static Matrix rotate( float angle, const Vec3& axis);
|
||||
inline static Matrix rotate( const Quat& );
|
||||
inline static Matrix rotate( const Quat&);
|
||||
|
||||
/** Create a orthographic projection. See glOrtho for further details.*/
|
||||
inline static Matrix ortho(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar);
|
||||
|
||||
/** Create a 2D orthographic projection. See glOrtho for further details.*/
|
||||
inline static Matrix ortho2D(const double left, const double right,
|
||||
const double bottom, const double top);
|
||||
|
||||
/** Create a perspective projection. See glFrustum for further details.*/
|
||||
inline static Matrix frustum(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar);
|
||||
|
||||
/** Create a symmetrical perspective projection, See gluPerspective for further details.
|
||||
* Aspect ratio is defined as width/height.*/
|
||||
inline static Matrix perspective(const double fovy,const double aspectRatio,
|
||||
const double zNear, const double zFar);
|
||||
|
||||
/** Create the position and orientation as per a camera, using the same convention as gluLookAt. */
|
||||
inline static Matrix lookAt(const Vec3& eye,const Vec3& center,const Vec3& up);
|
||||
|
||||
|
||||
inline Vec3 preMult( const Vec3& v ) const;
|
||||
inline Vec3 postMult( const Vec3& v ) const;
|
||||
@ -227,6 +276,48 @@ inline Matrix Matrix::rotate(const Vec3& from, const Vec3& to )
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Matrix Matrix::ortho(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
Matrix m;
|
||||
m.makeOrtho(left,right,bottom,top,zNear,zFar);
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Matrix Matrix::ortho2D(const double left, const double right,
|
||||
const double bottom, const double top)
|
||||
{
|
||||
Matrix m;
|
||||
m.makeOrtho2D(left,right,bottom,top);
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Matrix Matrix::frustum(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
Matrix m;
|
||||
m.makeFrustum(left,right,bottom,top,zNear,zFar);
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Matrix Matrix::perspective(const double fovy,const double aspectRatio,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
Matrix m;
|
||||
m.makePerspective(fovy,aspectRatio,zNear,zFar);
|
||||
return m;
|
||||
}
|
||||
|
||||
inline Matrix Matrix::lookAt(const Vec3& eye,const Vec3& center,const Vec3& up)
|
||||
{
|
||||
Matrix m;
|
||||
m.makeLookAt(eye,center,up);
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
inline Vec3 Matrix::postMult( const Vec3& v ) const
|
||||
{
|
||||
float d = 1.0f/(_mat[3][0]*v.x()+_mat[3][1]*v.y()+_mat[3][2]*v.z()+_mat[3][3]) ;
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <osg/Drawable>
|
||||
#include <osg/StateSet>
|
||||
#include <osg/State>
|
||||
#include <osg/Camera>
|
||||
#include <osg/Impostor>
|
||||
#include <osg/EarthSky>
|
||||
#include <osg/Notify>
|
||||
@ -60,12 +59,6 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
|
||||
virtual void apply(osg::EarthSky& node);
|
||||
virtual void apply(osg::Impostor& node);
|
||||
|
||||
|
||||
|
||||
void setCamera(const osg::Camera& camera);
|
||||
const osg::Camera* getCamera() const { return _camera.get(); }
|
||||
|
||||
|
||||
void setEarthSky(const osg::EarthSky* earthSky) { _earthSky = earthSky; }
|
||||
const osg::EarthSky* getEarthSky() const { return _earthSky.get(); }
|
||||
|
||||
@ -118,24 +111,14 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
|
||||
CullViewState::CullingMode getCullingMode() const;
|
||||
|
||||
|
||||
/** Set the viewport.
|
||||
* Used to enable the NewCullVisitor can make decision
|
||||
* such as based on viewport dimensions.*/
|
||||
void setViewport(osg::Viewport* viewport) { _viewport = viewport; }
|
||||
void pushViewport(osg::Viewport* viewport);
|
||||
void popViewport();
|
||||
|
||||
/** Get the const viewport. */
|
||||
const osg::Viewport* getViewport() const { return _viewport.get(); }
|
||||
void pushProjectionMatrix(osg::Matrix* matrix);
|
||||
void popProjectionMatrix();
|
||||
|
||||
/** Get the viewport. */
|
||||
osg::Viewport* getViewport() { return _viewport.get(); }
|
||||
|
||||
inline void pushCullViewState() { pushCullViewState_ModelView(NULL,NULL); }
|
||||
|
||||
void pushCullViewState_Projection(osg::Matrix* matrix);
|
||||
void pushCullViewState_ModelView(osg::Matrix* matrix);
|
||||
void pushCullViewState_ModelView(osg::Matrix* matrix,osg::Matrix* inverse);
|
||||
|
||||
void popCullViewState();
|
||||
void pushModelViewMatrix(osg::Matrix* matrix);
|
||||
void popModelViewMatrix();
|
||||
|
||||
/** Push state set on the current state group.
|
||||
* If the state exists in a child state group of the current
|
||||
@ -202,55 +185,56 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
|
||||
|
||||
inline osg::Matrix* getCurrentMatrix()
|
||||
{
|
||||
return _cvs->_matrix.get();
|
||||
}
|
||||
|
||||
|
||||
inline osg::Matrix* getInverseCurrentMatrix()
|
||||
{
|
||||
return _cvs->_inverse.get();
|
||||
return _modelviewStack.back().get();
|
||||
}
|
||||
|
||||
inline const osg::Vec3& getEyeLocal() const
|
||||
{
|
||||
return _cvs->_eyePoint;
|
||||
return _eyePointStack.back();
|
||||
}
|
||||
|
||||
inline const osg::Vec3 NewCullVisitor::getUpLocal() const
|
||||
{
|
||||
const osg::Matrix& matrix = *_modelviewStack.back();
|
||||
return osg::Vec3(matrix(0,1),matrix(1,1),matrix(2,1));
|
||||
}
|
||||
|
||||
inline const osg::Vec3& getUpLocal() const
|
||||
inline const osg::Vec3 NewCullVisitor::getLookVectorLocal() const
|
||||
{
|
||||
return _cvs->_upVector;
|
||||
}
|
||||
|
||||
inline const osg::Vec3& getCenterLocal() const
|
||||
{
|
||||
return _cvs->_centerPoint;
|
||||
}
|
||||
|
||||
|
||||
inline const osg::Vec3& getLookVectorLocal() const
|
||||
{
|
||||
return _cvs->_lookVector;
|
||||
const osg::Matrix& matrix = *_modelviewStack.back();
|
||||
return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
|
||||
}
|
||||
|
||||
|
||||
inline bool isCulled(const osg::BoundingSphere& sp,CullViewState::CullingMode& mode) const
|
||||
{
|
||||
return _cvs->isCulled(sp,mode);
|
||||
if (!sp.isValid()) return true;
|
||||
|
||||
if (!(_modelviewClippingVolumeStack.back().contains(sp,mode))) return true;
|
||||
|
||||
if (mode&CullViewState::SMALL_FEATURE_CULLING)
|
||||
{
|
||||
const float _ratio2 = 0.002f*0.002f;
|
||||
osg::Vec3 delta(sp._center-getEyeLocal());
|
||||
if (sp.radius2()<delta.length2()*_ratio2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline const bool isCulled(const osg::BoundingBox& bb,const CullViewState::CullingMode mode) const
|
||||
inline const bool isCulled(const osg::BoundingBox& bb,CullViewState::CullingMode mode) const
|
||||
{
|
||||
return _cvs->isCulled(bb,mode);
|
||||
if (!bb.isValid()) return true;
|
||||
|
||||
return !_modelviewClippingVolumeStack.back().contains(bb,mode);
|
||||
}
|
||||
|
||||
void updateCalculatedNearFar(const osg::BoundingBox& bb);
|
||||
|
||||
void updateCalculatedNearFar(const osg::Vec3& pos);
|
||||
|
||||
/**calculates near for "global" vertex in scene*/
|
||||
double calculateZNear(const osg::Vec3& position, const osg::Vec3& eye, const osg::Vec3& look);
|
||||
|
||||
|
||||
/** Add a drawable to current render graph.*/
|
||||
inline void addDrawable(osg::Drawable* drawable,osg::Matrix* matrix)
|
||||
{
|
||||
@ -262,7 +246,7 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
|
||||
_currentRenderBin->addRenderGraph(_currentRenderGraph);
|
||||
}
|
||||
//_currentRenderGraph->addLeaf(new RenderLeaf(drawable,matrix));
|
||||
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_cvs->_projection.get(),matrix));
|
||||
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_projectionStack.back().get(),matrix));
|
||||
}
|
||||
|
||||
/** Add a drawable and depth to current render graph.*/
|
||||
@ -276,7 +260,7 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
|
||||
_currentRenderBin->addRenderGraph(_currentRenderGraph);
|
||||
}
|
||||
//_currentRenderGraph->addLeaf(new RenderLeaf(drawable,matrix,depth));
|
||||
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_cvs->_projection.get(),matrix,depth));
|
||||
_currentRenderGraph->addLeaf(createOrReuseRenderLeaf(drawable,_projectionStack.back().get(),matrix,depth));
|
||||
}
|
||||
|
||||
/** Add a light to current render graph.*/
|
||||
@ -289,33 +273,125 @@ class OSGUTIL_EXPORT NewCullVisitor : public osg::NodeVisitor
|
||||
* to generate the impostor texture. */
|
||||
osg::ImpostorSprite* createImpostorSprite(osg::Impostor& node);
|
||||
|
||||
typedef std::vector< osg::ref_ptr<CullViewState> > CullViewStateStack;
|
||||
CullViewStateStack _viewStateStack;
|
||||
osg::ref_ptr<CullViewState> _tvs;
|
||||
osg::ref_ptr<CullViewState> _cvs;
|
||||
|
||||
osg::Viewport* getViewport()
|
||||
{
|
||||
if (!_viewportStack.empty())
|
||||
{
|
||||
return _viewportStack.back().get();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Matrix& getModelViewMatrix()
|
||||
{
|
||||
if (!_modelviewStack.empty())
|
||||
{
|
||||
return *_modelviewStack.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// default construction to identity.
|
||||
static osg::Matrix identity;
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
||||
osg::Matrix& getProjectionMatrix()
|
||||
{
|
||||
if (!_projectionStack.empty())
|
||||
{
|
||||
return *_projectionStack.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// default construction to identity.
|
||||
static osg::Matrix identity;
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
||||
const osg::Matrix getWindowMatrix()
|
||||
{
|
||||
if (!_viewportStack.empty())
|
||||
{
|
||||
osg::Viewport* viewport = _viewportStack.back().get();
|
||||
return osg::Matrix::scale(0.5f*viewport->width(),viewport->height(),0.5f)*osg::Matrix::translate(0.5f,0.5f,0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// default construction to identity.
|
||||
static osg::Matrix identity;
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
||||
const osg::Matrix& getMVPW()
|
||||
{
|
||||
if (!_MVPW_Stack.empty())
|
||||
{
|
||||
if (!_MVPW_Stack.back())
|
||||
{
|
||||
_MVPW_Stack.back() = new osg::Matrix(getModelViewMatrix()*getProjectionMatrix()*getWindowMatrix());
|
||||
}
|
||||
return *_MVPW_Stack.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
// default construction to identity.
|
||||
static osg::Matrix identity;
|
||||
return identity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pushClippingVolume();
|
||||
void popClippingVolume();
|
||||
|
||||
|
||||
typedef std::vector<osg::ClippingVolume> ClippingVolumeStack;
|
||||
typedef std::vector<osg::ref_ptr<osg::Matrix> > MatrixStack;
|
||||
|
||||
MatrixStack _projectionStack;
|
||||
MatrixStack _PW_Stack;
|
||||
ClippingVolumeStack _projectionClippingVolumeStack;
|
||||
|
||||
MatrixStack _modelviewStack;
|
||||
MatrixStack _MVPW_Stack;
|
||||
ClippingVolumeStack _modelviewClippingVolumeStack;
|
||||
|
||||
typedef std::vector<osg::ref_ptr<osg::Viewport> > ViewportStack;
|
||||
ViewportStack _viewportStack;
|
||||
|
||||
typedef std::vector<osg::Vec3> EyePointStack;
|
||||
EyePointStack _eyePointStack;
|
||||
|
||||
typedef std::vector<CullViewState::CullingMode> CullingModeStack;
|
||||
CullingModeStack _cullingModeStack;
|
||||
|
||||
unsigned int _bbCornerNear;
|
||||
unsigned int _bbCornerFar;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
osg::ref_ptr<const osg::EarthSky> _earthSky;
|
||||
|
||||
TransparencySortMode _tsm;
|
||||
|
||||
// viewport x,y,width,height respectively.
|
||||
osg::ref_ptr<osg::Viewport> _viewport;
|
||||
|
||||
bool _impostorActive;
|
||||
bool _depthSortImpostorSprites;
|
||||
float _impostorPixelErrorThreshold;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef OSGUTIL_RENDERSTAGE
|
||||
#define OSGUTIL_RENDERSTAGE 1
|
||||
|
||||
#include <osg/Camera>
|
||||
#include <osg/ColorMask>
|
||||
|
||||
#include <osgUtil/RenderBin>
|
||||
@ -92,12 +91,6 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
/** 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
|
||||
@ -125,8 +118,6 @@ class OSGUTIL_EXPORT RenderStage : public RenderBin
|
||||
bool _stageDrawnThisFrame;
|
||||
DependencyList _dependencyList;
|
||||
|
||||
osg::ref_ptr<osg::Camera> _camera;
|
||||
|
||||
// viewport x,y,width,height.
|
||||
osg::ref_ptr<osg::Viewport> _viewport;
|
||||
|
||||
|
@ -40,31 +40,16 @@ ImpostorSprite::~ImpostorSprite()
|
||||
}
|
||||
}
|
||||
|
||||
const float ImpostorSprite::calcPixelError(const Camera& camera,const Viewport& viewport,const osg::Matrix* matrix) const
|
||||
const float ImpostorSprite::calcPixelError(const Matrix& MVPW) const
|
||||
{
|
||||
// find the maximum screen space pixel error between the control coords and the quad coners.
|
||||
float max_error_sqrd = 0.0f;
|
||||
|
||||
for(int i=0;i<4;++i)
|
||||
{
|
||||
|
||||
Vec3 projected_coord;
|
||||
Vec3 projected_control;
|
||||
if (matrix)
|
||||
{
|
||||
// project the coords of the quad into screen space.
|
||||
camera.project(_coords[i]*(*matrix),viewport,projected_coord);
|
||||
|
||||
// project the controls coords into screen space.
|
||||
camera.project(_controlcoords[i]*(*matrix),viewport,projected_control);
|
||||
}
|
||||
else
|
||||
{
|
||||
// project the coords of the quad into screen space.
|
||||
camera.project(_coords[i],viewport,projected_coord);
|
||||
|
||||
// project the controls coords into screen space.
|
||||
camera.project(_controlcoords[i],viewport,projected_control);
|
||||
}
|
||||
Vec3 projected_coord = _coords[i]*MVPW;
|
||||
Vec3 projected_control = _controlcoords[i]*MVPW;
|
||||
|
||||
float dx = (projected_coord.x()-projected_control.x());
|
||||
float dy = (projected_coord.y()-projected_control.y());
|
||||
@ -77,7 +62,6 @@ const float ImpostorSprite::calcPixelError(const Camera& camera,const Viewport&
|
||||
|
||||
return sqrtf(max_error_sqrd);
|
||||
}
|
||||
|
||||
void ImpostorSprite::drawImmediateMode(State&)
|
||||
{
|
||||
// when the tex env is set to REPLACE, and the
|
||||
|
@ -227,7 +227,6 @@ void Matrix::postMult( const Matrix& other )
|
||||
}
|
||||
}
|
||||
|
||||
#undef SET_ROW
|
||||
#undef INNER_PRODUCT
|
||||
|
||||
|
||||
@ -310,24 +309,51 @@ bool Matrix::invert( const Matrix& mat )
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matrix::invertAffine( const Matrix& mat)
|
||||
void Matrix::makeOrtho(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
// | R p |' | R' -R'p |'
|
||||
// | | -> | |
|
||||
// | 0 0 0 1 | | 0 0 0 1 |
|
||||
for (unsigned int i=0; i<3; i++)
|
||||
{
|
||||
operator()(i,3) = 0;
|
||||
operator()(3,i) = -(mat(i,0)*mat(3,0) +
|
||||
mat(i,1)*mat(3,1) +
|
||||
mat(i,2)*mat(3,2));
|
||||
for (unsigned int j=0; j<3; j++)
|
||||
{
|
||||
operator()(i,j) = mat(j,i);
|
||||
}
|
||||
}
|
||||
operator()(3,3) = 1;
|
||||
|
||||
return true;
|
||||
// note transpose of Matrix wr.t OpenGL documentation, since the OSG use post multiplication rather than pre.
|
||||
double tx = -(right+left)/(right-left);
|
||||
double ty = -(top+bottom)/(top-bottom);
|
||||
double tz = -(zFar+zNear)/(zFar-zNear);
|
||||
SET_ROW(0, 2.0f/(right-left), 0.0f, 0.0f, 0.0f )
|
||||
SET_ROW(1, 0.0f, 2.0f/(top-bottom), 0.0f, 0.0f )
|
||||
SET_ROW(2, 0.0f, 0.0f, -2.0f/(zFar-zNear), 0.0f )
|
||||
SET_ROW(3, tx, ty, tz, 1.0f )
|
||||
}
|
||||
|
||||
void Matrix::makeFrustum(const double left, const double right,
|
||||
const double bottom, const double top,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
// note transpose of Matrix wr.t OpenGL documentation, since the OSG use post multiplication rather than pre.
|
||||
double A = (right+left)/(right-left);
|
||||
double B = (top+bottom)/(top-bottom);
|
||||
double C = -(zFar+zNear)/(zFar-zNear);
|
||||
double D = -2.0*zFar*zNear/(zFar-zNear);
|
||||
SET_ROW(0, 2.0f*zNear/(right-left), 0.0f, 0.0f, 0.0f )
|
||||
SET_ROW(1, 0.0f, 2.0f*zNear/(top-bottom), 0.0f, 0.0f )
|
||||
SET_ROW(2, A, B, C, -1.0f )
|
||||
SET_ROW(3, 0.0f, 0.0f, D, 0.0f )
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makePerspective(const double fovy,const double aspectRatio,
|
||||
const double zNear, const double zFar)
|
||||
{
|
||||
// calculate the appropriate left, right etc.
|
||||
double tan_fovy = tan(DegreesToRadians(fovy*0.5));
|
||||
double right = tan_fovy * aspectRatio * zNear;
|
||||
double left = -right;
|
||||
double top = tan_fovy * zNear;
|
||||
double bottom = -top;
|
||||
makeFrustum(left,right,bottom,top,zNear,zFar);
|
||||
}
|
||||
|
||||
|
||||
void Matrix::makeLookAt(const Vec3& eye,const Vec3& center,const Vec3& up)
|
||||
{
|
||||
}
|
||||
|
||||
#undef SET_ROW
|
||||
|
@ -1280,8 +1280,11 @@ void CullVisitor::apply(Impostor& node)
|
||||
if (impostorSprite)
|
||||
{
|
||||
// impostor found, now check to see if it is good enough to use
|
||||
float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
|
||||
|
||||
// RO, commenting this out since the calcPixelError's calling convention
|
||||
// has changed, this version of CullVisitor is soon to be removed
|
||||
// so this shouldn't be a problem.
|
||||
//float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
|
||||
float error = 0.0f;
|
||||
if (error>_impostorPixelErrorThreshold)
|
||||
{
|
||||
// chosen impostor sprite pixel error is too great to use
|
||||
@ -1403,9 +1406,10 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
|
||||
|
||||
osg::Camera* camera = osgNew osg::Camera(*_camera);
|
||||
rtts->setCamera(camera);
|
||||
// temporarily commeted out to keep things compiling.
|
||||
osg::Camera* camera = osgNew osg::Camera(*_camera);
|
||||
// rtts->setCamera(camera);
|
||||
std::cout<<"Warning:: in createImpostorSprite() rtts->setCamera(camera) call has been removed, this will cause problems."<<std::endl;
|
||||
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
|
@ -12,7 +12,7 @@ using namespace osgUtil;
|
||||
InsertImpostorsVisitor::InsertImpostorsVisitor()
|
||||
{
|
||||
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
|
||||
_impostorThresholdRatio = 10.0f;
|
||||
_impostorThresholdRatio = 30.0f;
|
||||
_maximumNumNestedImpostors = 3;
|
||||
_numNestedImpostors = 0;
|
||||
}
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <float.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include <osg/Timer>
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
@ -86,23 +88,14 @@ NewCullVisitor::NewCullVisitor()
|
||||
// unless there is bug somewhere...
|
||||
_cullingModeStack.push_back(CullViewState::ENABLE_ALL_CULLING);
|
||||
|
||||
_tvs = osgNew CullViewState;
|
||||
_tvs->_eyePoint.set(0.0f,0.0f,1.0f);
|
||||
_tvs->_centerPoint.set(0.0f,0.0f,0.0f);
|
||||
_tvs->_lookVector.set(0.0f,0.0f,-1.0f);
|
||||
_tvs->_upVector.set(0.0f,1.0f,0.0f);
|
||||
|
||||
_cvs = _tvs;
|
||||
|
||||
_tsm = LOOK_VECTOR_DISTANCE;
|
||||
//_tsm = LOOK_VECTOR_DISTANCE;
|
||||
_tsm = OBJECT_EYE_POINT_DISTANCE;
|
||||
|
||||
|
||||
_calculated_znear = FLT_MAX;
|
||||
_calculated_zfar = -FLT_MAX;
|
||||
|
||||
_viewport = NULL;
|
||||
|
||||
_impostorActive = true;
|
||||
_depthSortImpostorSprites = false;
|
||||
_impostorPixelErrorThreshold = 4.0f;
|
||||
@ -124,20 +117,32 @@ void NewCullVisitor::reset()
|
||||
//
|
||||
// first unref all referenced objects and then empty the containers.
|
||||
//
|
||||
_viewStateStack.clear();
|
||||
_projectionStack.clear();
|
||||
_projectionClippingVolumeStack.clear();
|
||||
|
||||
_modelviewStack.clear();
|
||||
_modelviewClippingVolumeStack.clear();
|
||||
|
||||
_viewportStack.clear();
|
||||
|
||||
_eyePointStack.clear();
|
||||
|
||||
// remove all accept the first element of the stack.
|
||||
_cullingModeStack.erase(_cullingModeStack.begin()+1,_cullingModeStack.end());
|
||||
|
||||
if (_cvs!=_tvs)
|
||||
{
|
||||
_cvs = _tvs;
|
||||
}
|
||||
|
||||
// reset the calculated near far planes.
|
||||
_calculated_znear = FLT_MAX;
|
||||
_calculated_zfar = -FLT_MAX;
|
||||
|
||||
|
||||
// remove all accept the first element of the stack.
|
||||
_cullingModeStack.erase(_cullingModeStack.begin()+1,_cullingModeStack.end());
|
||||
osg::Vec3 lookVector(0.0,0.0,-1.0);
|
||||
|
||||
_bbCornerFar = (lookVector.x()>=0?1:0) |
|
||||
(lookVector.y()>=0?2:0) |
|
||||
(lookVector.z()>=0?4:0);
|
||||
|
||||
_bbCornerNear = (~_bbCornerFar)&7;
|
||||
|
||||
// reset the resuse lists.
|
||||
_currentReuseMatrixIndex = 0;
|
||||
@ -152,188 +157,105 @@ void NewCullVisitor::reset()
|
||||
|
||||
}
|
||||
|
||||
void NewCullVisitor::setCamera(const Camera& camera)
|
||||
void NewCullVisitor::pushClippingVolume()
|
||||
{
|
||||
_camera = &camera;
|
||||
|
||||
_tvs->_clippingVolume.setToUnitFrustumWithoutNearFar();
|
||||
_tvs->_clippingVolume.transformProvidingInverse(_camera->getModelViewMatrix()*_camera->getProjectionMatrix());
|
||||
|
||||
//_tvs->_clippingVolume = camera.getClippingVolume();
|
||||
|
||||
_tvs->_eyePoint = camera.getEyePoint_Model();
|
||||
|
||||
_tvs->_centerPoint = camera.getCenterPoint_Model();
|
||||
|
||||
_tvs->_lookVector = _tvs->_centerPoint-_tvs->_eyePoint;
|
||||
_tvs->_lookVector.normalize();
|
||||
|
||||
_tvs->_upVector = camera.getUpVector_Model();
|
||||
|
||||
_tvs->_bbCornerFar = (_tvs->_lookVector.x()>=0?1:0) |
|
||||
(_tvs->_lookVector.y()>=0?2:0) |
|
||||
(_tvs->_lookVector.z()>=0?4:0);
|
||||
|
||||
_tvs->_bbCornerNear = (~_tvs->_bbCornerFar)&7;
|
||||
_modelviewClippingVolumeStack.push_back(_projectionClippingVolumeStack.back());
|
||||
if (!_modelviewStack.empty()) _modelviewClippingVolumeStack.back().transformProvidingInverse(*_modelviewStack.back());
|
||||
|
||||
_MVPW_Stack.push_back(0L);
|
||||
}
|
||||
|
||||
void NewCullVisitor::pushCullViewState_Projection(Matrix* matrix)
|
||||
void NewCullVisitor::popClippingVolume()
|
||||
{
|
||||
std::cout<<"NewCullVisitor::pushCullViewState_Projection(Matrix* matrix) not properly implemented yet..."<<std::endl;
|
||||
pushCullViewState_ModelView(NULL,NULL);
|
||||
_modelviewClippingVolumeStack.pop_back();
|
||||
_MVPW_Stack.pop_back();
|
||||
}
|
||||
|
||||
|
||||
void NewCullVisitor::pushCullViewState_ModelView(Matrix* matrix)
|
||||
void NewCullVisitor::pushViewport(osg::Viewport* viewport)
|
||||
{
|
||||
if (matrix)
|
||||
{
|
||||
osg::Matrix* inverse = osgNew osg::Matrix;
|
||||
inverse->invert(*matrix);
|
||||
pushCullViewState_ModelView(matrix,inverse);
|
||||
}
|
||||
else
|
||||
pushCullViewState_ModelView(NULL,NULL);
|
||||
_viewportStack.push_back(viewport);
|
||||
_MVPW_Stack.push_back(0L);
|
||||
}
|
||||
|
||||
void NewCullVisitor::pushCullViewState_ModelView(Matrix* matrix,osg::Matrix* inverse)
|
||||
void NewCullVisitor::popViewport()
|
||||
{
|
||||
_viewportStack.pop_back();
|
||||
_MVPW_Stack.pop_back();
|
||||
}
|
||||
|
||||
osg::ref_ptr<CullViewState> nvs = osgNew CullViewState;
|
||||
|
||||
Matrix* inverse_world = NULL;
|
||||
|
||||
if (matrix)
|
||||
{
|
||||
if (_cvs.valid() && _cvs->_matrix.valid())
|
||||
{
|
||||
matrix->postMult(*(_cvs->_matrix));
|
||||
}
|
||||
|
||||
nvs->_matrix = matrix;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_cvs.valid())
|
||||
{
|
||||
nvs->_matrix = _cvs->_matrix;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
nvs->_matrix = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (inverse)
|
||||
{
|
||||
if (_cvs.valid() && _cvs->_inverse.valid())
|
||||
{
|
||||
inverse->preMult(*(_cvs->_inverse));
|
||||
}
|
||||
|
||||
nvs->_inverse = inverse;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_cvs.valid())
|
||||
{
|
||||
nvs->_inverse = _cvs->_inverse;
|
||||
}
|
||||
else
|
||||
{
|
||||
nvs->_inverse = NULL;
|
||||
}
|
||||
}
|
||||
inverse_world = nvs->_inverse.get();
|
||||
void NewCullVisitor::pushProjectionMatrix(Matrix* matrix)
|
||||
{
|
||||
_projectionStack.push_back(matrix);
|
||||
|
||||
if (inverse_world)
|
||||
{
|
||||
nvs->_eyePoint = _tvs->_eyePoint*(*inverse_world);
|
||||
//nvs->_eyePoint = inverse_world->getTrans();
|
||||
|
||||
nvs->_centerPoint = _tvs->_centerPoint*(*inverse_world);
|
||||
|
||||
nvs->_lookVector = nvs->_centerPoint - nvs->_eyePoint;
|
||||
nvs->_lookVector.normalize();
|
||||
|
||||
Vec3 zero_transformed = Vec3(0.0f,0.0f,0.0f)*(*inverse_world);
|
||||
nvs->_upVector = (_tvs->_upVector)*(*inverse_world) - zero_transformed;
|
||||
nvs->_upVector.normalize();
|
||||
|
||||
nvs->_clippingVolume = _tvs->_clippingVolume;
|
||||
nvs->_clippingVolume.transformProvidingInverse(*(nvs->_matrix));
|
||||
|
||||
// osg::ClippingVolume cv;
|
||||
// cv.setToUnitFrustum();
|
||||
// cv.transformProvidingInverse((*(nvs->_matrix))*_camera->getProjectionMatrix());
|
||||
//
|
||||
// std::cout << "cv "<<std::endl;
|
||||
// for(ClippingVolume::PlaneList::iterator itr = cv.getPlaneList().begin();
|
||||
// itr!=cv.getPlaneList().end();
|
||||
// ++itr)
|
||||
// {
|
||||
// std::cout << " Plane "<<*itr<<std::endl;
|
||||
// }
|
||||
//
|
||||
// std::cout << "nvs->_clippingVolume "<<std::endl;
|
||||
// for(ClippingVolume::PlaneList::iterator itr = nvs->_clippingVolume.getPlaneList().begin();
|
||||
// itr!=nvs->_clippingVolume.getPlaneList().end();
|
||||
// ++itr)
|
||||
// {
|
||||
// std::cout << " Plane "<<*itr<<std::endl;
|
||||
// }
|
||||
// std::cout << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
nvs->_eyePoint = _tvs->_eyePoint;
|
||||
|
||||
nvs->_lookVector = _tvs->_lookVector;
|
||||
|
||||
nvs->_centerPoint = _tvs->_centerPoint;
|
||||
|
||||
nvs->_upVector = _tvs->_upVector;
|
||||
|
||||
nvs->_clippingVolume = _tvs->_clippingVolume;
|
||||
}
|
||||
|
||||
|
||||
nvs->_bbCornerFar = (nvs->_lookVector.x()>=0?1:0) |
|
||||
(nvs->_lookVector.y()>=0?2:0) |
|
||||
(nvs->_lookVector.z()>=0?4:0);
|
||||
|
||||
nvs->_bbCornerNear = (~nvs->_bbCornerFar)&7;
|
||||
|
||||
_cvs = nvs;
|
||||
|
||||
_viewStateStack.push_back(nvs);
|
||||
_projectionClippingVolumeStack.push_back(ClippingVolume());
|
||||
_projectionClippingVolumeStack.back().setToUnitFrustumWithoutNearFar();
|
||||
_projectionClippingVolumeStack.back().transformProvidingInverse(*matrix);
|
||||
|
||||
pushClippingVolume();
|
||||
}
|
||||
|
||||
void NewCullVisitor::popCullViewState()
|
||||
void NewCullVisitor::popProjectionMatrix()
|
||||
{
|
||||
// pop the top of the view stack and unref it.
|
||||
_viewStateStack.pop_back();
|
||||
|
||||
// to new cvs and ref it.
|
||||
if (_viewStateStack.empty())
|
||||
{
|
||||
_cvs = _tvs;
|
||||
}
|
||||
else
|
||||
{
|
||||
_cvs = _viewStateStack.back().get();
|
||||
}
|
||||
_projectionStack.pop_back();
|
||||
_projectionClippingVolumeStack.pop_back();
|
||||
|
||||
popClippingVolume();
|
||||
}
|
||||
|
||||
double NewCullVisitor::calculateZNear(const osg::Vec3& position, const osg::Vec3& eye, const osg::Vec3& look)
|
||||
void NewCullVisitor::pushModelViewMatrix(Matrix* matrix)
|
||||
{
|
||||
//note: the candidate points are always in "global" coordinates
|
||||
return (position - eye)*look;
|
||||
_modelviewStack.push_back(matrix);
|
||||
|
||||
pushClippingVolume();
|
||||
|
||||
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
|
||||
const float x_0 = (*matrix)(0,0);
|
||||
const float x_1 = (*matrix)(1,0);
|
||||
const float x_2 = (*matrix)(2,0);
|
||||
const float x_scale = (*matrix)(3,0) / -(x_0*x_0+x_1*x_1+x_2*x_2);
|
||||
|
||||
const float y_0 = (*matrix)(0,1);
|
||||
const float y_1 = (*matrix)(1,1);
|
||||
const float y_2 = (*matrix)(2,1);
|
||||
const float y_scale = (*matrix)(3,1) / -(y_0*y_0+y_1*y_1+y_2*y_2);
|
||||
|
||||
const float z_0 = (*matrix)(0,2);
|
||||
const float z_1 = (*matrix)(1,2);
|
||||
const float z_2 = (*matrix)(2,2);
|
||||
const float z_scale = (*matrix)(3,2) / -(z_0*z_0+z_1*z_1+z_2*z_2);
|
||||
|
||||
_eyePointStack.push_back(osg::Vec3(x_0*x_scale + y_0*y_scale + z_0*z_scale,
|
||||
x_1*x_scale + y_1*y_scale + z_1*z_scale,
|
||||
x_2*x_scale + y_2*y_scale + z_2*z_scale));
|
||||
|
||||
|
||||
osg::Vec3 lookVector = getLookVectorLocal();
|
||||
|
||||
_bbCornerFar = (lookVector.x()>=0?1:0) |
|
||||
(lookVector.y()>=0?2:0) |
|
||||
(lookVector.z()>=0?4:0);
|
||||
|
||||
_bbCornerNear = (~_bbCornerFar)&7;
|
||||
|
||||
}
|
||||
|
||||
void NewCullVisitor::popModelViewMatrix()
|
||||
{
|
||||
_modelviewStack.pop_back();
|
||||
_eyePointStack.pop_back();
|
||||
popClippingVolume();
|
||||
|
||||
|
||||
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
|
||||
if (!_modelviewStack.empty())
|
||||
{
|
||||
lookVector = getLookVectorLocal();
|
||||
}
|
||||
_bbCornerFar = (lookVector.x()>=0?1:0) |
|
||||
(lookVector.y()>=0?2:0) |
|
||||
(lookVector.z()>=0?4:0);
|
||||
|
||||
_bbCornerNear = (~_bbCornerFar)&7;
|
||||
}
|
||||
|
||||
inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
|
||||
@ -352,18 +274,18 @@ void NewCullVisitor::updateCalculatedNearFar(const osg::BoundingBox& bb)
|
||||
}
|
||||
|
||||
float d_near,d_far;
|
||||
if (_cvs->_matrix.valid())
|
||||
if (!_modelviewStack.empty())
|
||||
{
|
||||
|
||||
const osg::Matrix& matrix = *(_cvs->_matrix);
|
||||
d_near = distance(bb.corner(_cvs->_bbCornerNear),matrix);
|
||||
d_far = distance(bb.corner(_cvs->_bbCornerFar),matrix);
|
||||
const osg::Matrix& matrix = *(_modelviewStack.back());
|
||||
d_near = distance(bb.corner(_bbCornerNear),matrix);
|
||||
d_far = distance(bb.corner(_bbCornerFar),matrix);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
d_near = -(bb.corner(_cvs->_bbCornerNear)).z();
|
||||
d_far = -(bb.corner(_cvs->_bbCornerFar)).z();
|
||||
d_near = -(bb.corner(_bbCornerNear)).z();
|
||||
d_far = -(bb.corner(_bbCornerFar)).z();
|
||||
}
|
||||
|
||||
if (d_near<=d_far)
|
||||
@ -388,9 +310,9 @@ void NewCullVisitor::updateCalculatedNearFar(const osg::BoundingBox& bb)
|
||||
void NewCullVisitor::updateCalculatedNearFar(const osg::Vec3& pos)
|
||||
{
|
||||
float d;
|
||||
if (_cvs->_matrix.valid())
|
||||
if (!_modelviewStack.empty())
|
||||
{
|
||||
const osg::Matrix& matrix = *(_cvs->_matrix);
|
||||
const osg::Matrix& matrix = *(_modelviewStack.back());
|
||||
d = distance(pos,matrix);
|
||||
}
|
||||
else
|
||||
@ -487,14 +409,13 @@ void NewCullVisitor::apply(Geode& node)
|
||||
{
|
||||
center = drawable->getBound().center();
|
||||
}
|
||||
Vec3 delta_center = center-_tvs->_eyePoint;
|
||||
|
||||
float depth;
|
||||
switch(_tsm)
|
||||
{
|
||||
case(LOOK_VECTOR_DISTANCE):depth = _tvs->_lookVector*delta_center;break;
|
||||
case(LOOK_VECTOR_DISTANCE):depth = -center.z();break;
|
||||
case(OBJECT_EYE_POINT_DISTANCE):
|
||||
default: depth = delta_center.length2();break;
|
||||
default: depth = center.length2();break;
|
||||
}
|
||||
|
||||
if (stateset) pushStateSet(stateset);
|
||||
@ -567,14 +488,13 @@ void NewCullVisitor::apply(Billboard& node)
|
||||
{
|
||||
center = pos;
|
||||
}
|
||||
Vec3 delta_center = center-_tvs->_eyePoint;
|
||||
|
||||
float depth;
|
||||
switch(_tsm)
|
||||
{
|
||||
case(LOOK_VECTOR_DISTANCE):depth = _tvs->_lookVector*delta_center;break;
|
||||
case(LOOK_VECTOR_DISTANCE):depth = -center.z();break;
|
||||
case(OBJECT_EYE_POINT_DISTANCE):
|
||||
default: depth = delta_center.length2();break;
|
||||
default: depth = center.length2();break;
|
||||
}
|
||||
|
||||
if (stateset) pushStateSet(stateset);
|
||||
@ -657,14 +577,13 @@ void NewCullVisitor::apply(Transform& node)
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
ref_ptr<osg::Matrix> matrix = createOrReuseMatrix();
|
||||
ref_ptr<osg::Matrix> inverse = createOrReuseMatrix();
|
||||
node.getLocalToWorldMatrix(*matrix,this);
|
||||
node.getWorldToLocalMatrix(*inverse,this);
|
||||
pushCullViewState_ModelView(matrix.get(),inverse.get());
|
||||
matrix->postMult(*getCurrentMatrix());
|
||||
pushModelViewMatrix(matrix.get());
|
||||
|
||||
traverse(node);
|
||||
|
||||
popCullViewState();
|
||||
popModelViewMatrix();
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
@ -691,11 +610,11 @@ void NewCullVisitor::apply(Projection& node)
|
||||
|
||||
ref_ptr<osg::Matrix> matrix = createOrReuseMatrix();
|
||||
*matrix = node.getMatrix();
|
||||
pushCullViewState_Projection(matrix.get());
|
||||
pushProjectionMatrix(matrix.get());
|
||||
|
||||
traverse(node);
|
||||
|
||||
popCullViewState();
|
||||
popProjectionMatrix();
|
||||
|
||||
// pop the node's state off the render graph stack.
|
||||
if (node_state) popStateSet();
|
||||
@ -791,7 +710,7 @@ void NewCullVisitor::apply(Impostor& node)
|
||||
// traverse the appropriate child of the LOD.
|
||||
node.getChild(eval)->accept(*this);
|
||||
}
|
||||
else if (!_viewport.valid())
|
||||
else if (_viewportStack.empty())
|
||||
{
|
||||
// need to use impostor but no valid viewport is defined to simply
|
||||
// default to using the LOD child as above.
|
||||
@ -799,6 +718,7 @@ void NewCullVisitor::apply(Impostor& node)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// within the impostor distance threshold therefore attempt
|
||||
// to use impostor instead.
|
||||
|
||||
@ -810,8 +730,8 @@ void NewCullVisitor::apply(Impostor& node)
|
||||
if (impostorSprite)
|
||||
{
|
||||
// impostor found, now check to see if it is good enough to use
|
||||
float error = impostorSprite->calcPixelError(*_camera,*_viewport,matrix);
|
||||
|
||||
float error = impostorSprite->calcPixelError(getMVPW());
|
||||
|
||||
if (error>_impostorPixelErrorThreshold)
|
||||
{
|
||||
// chosen impostor sprite pixel error is too great to use
|
||||
@ -853,14 +773,13 @@ void NewCullVisitor::apply(Impostor& node)
|
||||
{
|
||||
center = node.getCenter();
|
||||
}
|
||||
Vec3 delta_center = center-_tvs->_eyePoint;
|
||||
|
||||
float depth;
|
||||
switch(_tsm)
|
||||
{
|
||||
case(LOOK_VECTOR_DISTANCE):depth = _tvs->_lookVector*delta_center;break;
|
||||
case(LOOK_VECTOR_DISTANCE):depth = -center.z();break;
|
||||
case(OBJECT_EYE_POINT_DISTANCE):
|
||||
default: depth = delta_center.length2();break;
|
||||
default: depth = center.length2();break;
|
||||
}
|
||||
|
||||
addDrawableAndDepth(impostorSprite,matrix,depth);
|
||||
@ -878,8 +797,8 @@ void NewCullVisitor::apply(Impostor& node)
|
||||
}
|
||||
else
|
||||
{
|
||||
// no impostor has been selected or created so default to
|
||||
// traversing the usual LOD selected child.
|
||||
// no impostor has been selected or created so default to
|
||||
// traversing the usual LOD selected child.
|
||||
node.getChild(eval)->accept(*this);
|
||||
}
|
||||
|
||||
@ -894,10 +813,10 @@ void NewCullVisitor::apply(Impostor& node)
|
||||
|
||||
ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
{
|
||||
if (!_camera.valid()) return NULL;
|
||||
|
||||
bool isPerspectiveCamera = _camera->getProjectionType()==Camera::FRUSTUM ||
|
||||
_camera->getProjectionType()==Camera::PERSPECTIVE;
|
||||
|
||||
// default to true right now, will dertermine if perspective from the
|
||||
// projection matrix...
|
||||
bool isPerspectiveProjection = true;
|
||||
|
||||
Matrix* matrix = getCurrentMatrix();
|
||||
const BoundingSphere& bs = node.getBound();
|
||||
@ -906,11 +825,12 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
|
||||
if (!bs.isValid())
|
||||
{
|
||||
cout << "bb invalid"<<&node<<endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Vec3 eye_world = _tvs->_eyePoint;
|
||||
Vec3 eye_world(0.0,0.0,0.0);
|
||||
Vec3 center_world = bs.center()*(*matrix);
|
||||
|
||||
// no appropriate sprite has been found therefore need to create
|
||||
@ -929,13 +849,10 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
clear_color[3] = 0.0f; // set the alpha to zero.
|
||||
rtts->setClearColor(clear_color);
|
||||
rtts->setClearMask(previous_stage->getClearMask());
|
||||
|
||||
|
||||
// set up to charge the same RenderStageLighting is the parent previous stage.
|
||||
rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());
|
||||
|
||||
|
||||
osg::Camera* camera = osgNew osg::Camera(*_camera);
|
||||
rtts->setCamera(camera);
|
||||
|
||||
|
||||
// record the render bin, to be restored after creation
|
||||
// of the render to text
|
||||
@ -944,86 +861,10 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
// set the current renderbin to be the newly created stage.
|
||||
_currentRenderBin = rtts.get();
|
||||
|
||||
// store the previous camera setting
|
||||
|
||||
Vec3 rotate_from = bs.center()-eye_local;
|
||||
Vec3 rotate_to = getLookVectorLocal();
|
||||
|
||||
osg::Matrix* rotate_matrix = osgNew osg::Matrix(
|
||||
osg::Matrix::translate(-eye_local)*
|
||||
osg::Matrix::rotate(rotate_from,rotate_to)*
|
||||
osg::Matrix::translate(eye_local));
|
||||
|
||||
// pushing the cull view state will update it so it takes
|
||||
// into account the new camera orientation.
|
||||
pushCullViewState_ModelView(rotate_matrix);
|
||||
|
||||
// what shall we do about the near far?
|
||||
// we could need to save the near and far, or switch it off.
|
||||
// simplicist to save near and far. will do this for now.
|
||||
|
||||
float previous_znear = _calculated_znear;
|
||||
float previous_zfar = _calculated_zfar;
|
||||
|
||||
_calculated_znear = FLT_MAX;
|
||||
_calculated_zfar = -FLT_MAX;
|
||||
|
||||
ref_ptr<StateSet> dummyState = osgNew StateSet;
|
||||
|
||||
|
||||
// dummyState->setMode(GL_BLEND,osg::StateAttribute::OVERRIDE_OFF);
|
||||
|
||||
pushStateSet(dummyState.get());
|
||||
|
||||
|
||||
// switch off the view frustum culling, since we will have
|
||||
// the whole subgraph in view.
|
||||
_cullingModeStack.push_back((_cullingModeStack.back() & ~CullViewState::VIEW_FRUSTUM_CULLING));
|
||||
|
||||
{
|
||||
|
||||
// traversing the usual LOD selected child.
|
||||
node.getChild(eval)->accept(*this);
|
||||
|
||||
}
|
||||
|
||||
popStateSet();
|
||||
|
||||
// restore the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
|
||||
float local_znear = _calculated_znear;
|
||||
float local_zfar = _calculated_zfar;
|
||||
|
||||
// restore the previous near and far.
|
||||
_calculated_znear = previous_znear;
|
||||
_calculated_zfar = previous_zfar;
|
||||
|
||||
// restor the previous renderbin.
|
||||
_currentRenderBin = previousRenderBin;
|
||||
|
||||
// restore the previous _tvs and _cvs;
|
||||
popCullViewState();
|
||||
|
||||
|
||||
if (rtts->_renderGraphList.size()==0 && rtts->_bins.size()==0)
|
||||
{
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (local_znear>local_zfar)
|
||||
{
|
||||
notify(WARN) << "Warning : problem with osg::NewCullVisitor::creatImpostorSprite() local_znear ("<<local_znear<<") "<<" > ("<<local_zfar<<") local_zfar"<< std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// create texture quad coords (in local coords)
|
||||
// create quad coords (in local coords)
|
||||
|
||||
Vec3 center_local = bs.center();
|
||||
Vec3 camera_up_local = _cvs->_upVector;
|
||||
Vec3 camera_up_local = getUpLocal();
|
||||
Vec3 lv_local = center_local-eye_local;
|
||||
|
||||
float distance_local = lv_local.length();
|
||||
@ -1037,7 +878,7 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
|
||||
|
||||
float width = bs.radius();
|
||||
if (isPerspectiveCamera)
|
||||
if (isPerspectiveProjection)
|
||||
{
|
||||
// expand the width to account for projection onto sprite.
|
||||
width *= (distance_local/sqrtf(distance_local*distance_local-bs.radius2()));
|
||||
@ -1055,55 +896,33 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
|
||||
// adjust camera left,right,up,down to fit (in world coords)
|
||||
|
||||
#define USE_SPHERE_NEAR_FAR
|
||||
|
||||
#ifdef USE_SPHERE_NEAR_FAR
|
||||
Vec3 near_local ( center_local-lv_local*width );
|
||||
Vec3 far_local ( center_local+lv_local*width );
|
||||
#endif
|
||||
Vec3 top_local ( center_local+up_local);
|
||||
Vec3 right_local ( center_local+sv_local);
|
||||
|
||||
#ifdef USE_SPHERE_NEAR_FAR
|
||||
Vec3 near_world;
|
||||
Vec3 far_world;
|
||||
#endif
|
||||
Vec3 top_world;
|
||||
Vec3 right_world;
|
||||
|
||||
if (matrix)
|
||||
{
|
||||
#ifdef USE_SPHERE_NEAR_FAR
|
||||
near_world = near_local * (*matrix);
|
||||
far_world = far_local * (*matrix);
|
||||
#endif
|
||||
top_world = top_local * (*matrix);
|
||||
right_world = right_local * (*matrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SPHERE_NEAR_FAR
|
||||
near_world = near_local;
|
||||
far_world = far_local;
|
||||
#endif
|
||||
top_world = top_local;
|
||||
right_world = right_local;
|
||||
}
|
||||
|
||||
#ifdef USE_SPHERE_NEAR_FAR
|
||||
float znear = (near_world-eye_world).length();
|
||||
float zfar = (far_world-eye_world).length();
|
||||
#else
|
||||
float znear = local_znear;
|
||||
float zfar = local_zfar;
|
||||
#endif
|
||||
|
||||
if (local_zfar>=local_znear)
|
||||
{
|
||||
znear = local_znear;
|
||||
zfar = local_zfar;
|
||||
}
|
||||
|
||||
|
||||
float top = (top_world-center_world).length();
|
||||
float right = (right_world-center_world).length();
|
||||
@ -1111,62 +930,89 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
znear *= 0.9f;
|
||||
zfar *= 1.1f;
|
||||
|
||||
if (isPerspectiveCamera)
|
||||
// set up projection.
|
||||
osg::Matrix* projection = osgNew osg::Matrix;
|
||||
if (isPerspectiveProjection)
|
||||
{
|
||||
// deal with projection issue move the top and right points
|
||||
// onto the near plane.
|
||||
float ratio = znear/(center_world-eye_world).length();
|
||||
float ratio = znear/(center_world-eye_world).length();
|
||||
top *= ratio;
|
||||
right *= ratio;
|
||||
camera->setFrustum(-right,right,-top,top,znear,zfar);
|
||||
|
||||
projection->makeFrustum(-right,right,-top,top,znear,zfar);
|
||||
}
|
||||
else
|
||||
{
|
||||
// othographic projection.
|
||||
|
||||
camera->setOrtho(-right,right,-top,top,znear,zfar);
|
||||
projection->makeOrtho(-right,right,-top,top,znear,zfar);
|
||||
}
|
||||
|
||||
if (local_znear<znear)
|
||||
|
||||
pushProjectionMatrix(projection);
|
||||
|
||||
Vec3 rotate_from = bs.center()-eye_local;
|
||||
Vec3 rotate_to = getLookVectorLocal();
|
||||
|
||||
osg::Matrix* rotate_matrix = osgNew osg::Matrix(
|
||||
osg::Matrix::translate(-eye_local)*
|
||||
osg::Matrix::rotate(rotate_from,rotate_to)*
|
||||
osg::Matrix::translate(eye_local)*
|
||||
getModelViewMatrix());
|
||||
|
||||
// pushing the cull view state will update it so it takes
|
||||
// into account the new camera orientation.
|
||||
pushModelViewMatrix(rotate_matrix);
|
||||
|
||||
ref_ptr<StateSet> dummyState = osgNew StateSet;
|
||||
|
||||
pushStateSet(dummyState.get());
|
||||
|
||||
|
||||
// switch off the view frustum culling, since we will have
|
||||
// the whole subgraph in view.
|
||||
_cullingModeStack.push_back((_cullingModeStack.back() & ~CullViewState::VIEW_FRUSTUM_CULLING));
|
||||
|
||||
{
|
||||
znear = local_znear;
|
||||
|
||||
// traversing the usual LOD selected child.
|
||||
node.getChild(eval)->accept(*this);
|
||||
|
||||
}
|
||||
|
||||
if (local_zfar>zfar)
|
||||
|
||||
// restore the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
|
||||
popStateSet();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
popModelViewMatrix();
|
||||
|
||||
// restore the previous model view matrix.
|
||||
popProjectionMatrix();
|
||||
|
||||
// restore the previous renderbin.
|
||||
_currentRenderBin = previousRenderBin;
|
||||
|
||||
|
||||
|
||||
if (rtts->_renderGraphList.size()==0 && rtts->_bins.size()==0)
|
||||
{
|
||||
zfar = local_zfar;
|
||||
// getting to this point means that all the subgraph has been
|
||||
// culled by small feature culling or is beyond LOD ranges.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// restore the previous near and far.
|
||||
local_znear = previous_znear;
|
||||
local_zfar = previous_zfar;
|
||||
|
||||
|
||||
// calc texture size for eye, bs.
|
||||
|
||||
Vec3 c00_world;
|
||||
Vec3 c11_world;
|
||||
|
||||
if (matrix)
|
||||
{
|
||||
c00_world = c00 * (*matrix);
|
||||
c11_world = c11 * (*matrix);
|
||||
}
|
||||
else
|
||||
{
|
||||
c00_world = c00;
|
||||
c11_world = c11;
|
||||
}
|
||||
const osg::Viewport& viewport = *getViewport();
|
||||
|
||||
|
||||
// calc texture size for eye, bs.
|
||||
|
||||
// convert the corners of the sprite (in world coords) into their
|
||||
// equivilant window coordinates by using the camera's project method.
|
||||
Vec3 c00_win;
|
||||
Vec3 c11_win;
|
||||
_camera->project(c00_world,*_viewport,c00_win);
|
||||
_camera->project(c11_world,*_viewport,c11_win);
|
||||
|
||||
const osg::Matrix& MVPW = getMVPW();
|
||||
Vec3 c00_win = c00 * MVPW;
|
||||
Vec3 c11_win = c11 * MVPW;
|
||||
|
||||
// adjust texture size to be nearest power of 2.
|
||||
|
||||
@ -1193,21 +1039,21 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
int new_t = (int)(powf(2.0f,rounded_tp2));
|
||||
|
||||
// if dimension is bigger than window divide it down.
|
||||
while (new_s>_viewport->width()) new_s /= 2;
|
||||
while (new_s>viewport.width()) new_s /= 2;
|
||||
|
||||
// if dimension is bigger than window divide it down.
|
||||
while (new_t>_viewport->height()) new_t /= 2;
|
||||
while (new_t>viewport.height()) new_t /= 2;
|
||||
|
||||
|
||||
// offset the impostor viewport from the center of the main window
|
||||
// viewport as often the edges of the viewport might be obscured by
|
||||
// other windows, which can cause image/reading writing problems.
|
||||
int center_x = _viewport->x()+_viewport->width()/2;
|
||||
int center_y = _viewport->y()+_viewport->height()/2;
|
||||
int center_x = viewport.x()+viewport.width()/2;
|
||||
int center_y = viewport.y()+viewport.height()/2;
|
||||
|
||||
Viewport* viewport = osgNew Viewport;
|
||||
viewport->setViewport(center_x-new_s/2,center_y-new_t/2,new_s,new_t);
|
||||
rtts->setViewport(viewport);
|
||||
Viewport* new_viewport = osgNew Viewport;
|
||||
new_viewport->setViewport(center_x-new_s/2,center_y-new_t/2,new_s,new_t);
|
||||
rtts->setViewport(new_viewport);
|
||||
|
||||
// create the impostor sprite.
|
||||
|
||||
@ -1252,7 +1098,7 @@ ImpostorSprite* NewCullVisitor::createImpostorSprite(Impostor& node)
|
||||
|
||||
Vec3* controlcoords = impostorSprite->getControlCoords();
|
||||
|
||||
if (isPerspectiveCamera)
|
||||
if (isPerspectiveProjection)
|
||||
{
|
||||
// deal with projection issue by moving the coorners of the quad
|
||||
// towards the eye point.
|
||||
|
@ -30,7 +30,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous)
|
||||
|
||||
}
|
||||
|
||||
//state.applyProjectionMatrix(_projection.get());
|
||||
state.applyProjectionMatrix(_projection.get());
|
||||
state.applyModelViewMatrix(_modelview.get());
|
||||
|
||||
_drawable->draw(state);
|
||||
@ -42,7 +42,7 @@ void RenderLeaf::render(State& state,RenderLeaf* previous)
|
||||
// send state changes and matrix changes to OpenGL.
|
||||
state.apply(_parent->_stateset.get());
|
||||
|
||||
//state.applyProjectionMatrix(_projection.get());
|
||||
state.applyProjectionMatrix(_projection.get());
|
||||
state.applyModelViewMatrix(_modelview.get());
|
||||
|
||||
_drawable->draw(state);
|
||||
|
@ -97,9 +97,6 @@ void RenderStage::draw(osg::State& state,RenderLeaf*& previous)
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
#endif
|
||||
|
||||
// set up projection
|
||||
state.applyProjectionMatrix(&(_camera->getProjectionMatrix()));
|
||||
|
||||
glMatrixMode( GL_MODELVIEW );
|
||||
glLoadIdentity();
|
||||
|
||||
|
@ -233,6 +233,7 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
}
|
||||
|
||||
// get the camera's modelview
|
||||
osg::Matrix* projection = osgNew osg::Matrix(camera->getProjectionMatrix());
|
||||
osg::Matrix* modelview = osgNew osg::Matrix(camera->getModelViewMatrix());
|
||||
|
||||
|
||||
@ -243,8 +244,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
|
||||
|
||||
cullVisitor->setLODBias(_lodBias);
|
||||
cullVisitor->setCamera(*local_camera);
|
||||
cullVisitor->setViewport(_viewport.get());
|
||||
cullVisitor->setEarthSky(NULL); // reset earth sky on each frame.
|
||||
|
||||
cullVisitor->setRenderGraph(rendergraph);
|
||||
@ -266,7 +265,6 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
rendergraph->clean();
|
||||
|
||||
renderStage->setViewport(_viewport.get());
|
||||
renderStage->setCamera(local_camera);
|
||||
renderStage->setClearColor(_backgroundColor);
|
||||
|
||||
|
||||
@ -285,7 +283,9 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
if (_globalState.valid()) cullVisitor->pushStateSet(_globalState.get());
|
||||
|
||||
|
||||
cullVisitor->pushCullViewState_ModelView(modelview);
|
||||
cullVisitor->pushViewport(_viewport.get());
|
||||
cullVisitor->pushProjectionMatrix(projection);
|
||||
cullVisitor->pushModelViewMatrix(modelview);
|
||||
|
||||
|
||||
// traverse the scene graph to generate the rendergraph.
|
||||
@ -293,7 +293,9 @@ void SceneView::cullStage(osg::Camera* camera, osgUtil::CullVisitor* cullVisitor
|
||||
|
||||
if (_globalState.valid()) cullVisitor->popStateSet();
|
||||
|
||||
cullVisitor->popCullViewState();
|
||||
cullVisitor->popModelViewMatrix();
|
||||
cullVisitor->popProjectionMatrix();
|
||||
cullVisitor->popViewport();
|
||||
|
||||
|
||||
const osg::EarthSky* earthSky = cullVisitor->getEarthSky();
|
||||
|
Loading…
Reference in New Issue
Block a user