Additions for the support for ConvexPlaneOccluder. Work still underway.
This commit is contained in:
@@ -149,6 +149,10 @@ SOURCE=..\..\src\osg\CullFace.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osg\CullingSet.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\src\osg\Depth.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -397,10 +401,6 @@ SOURCE=..\..\Include\Osg\ClipNode
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Osg\ClippingVolume
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Osg\ClipPlane
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -429,6 +429,10 @@ SOURCE=..\..\Include\Osg\CullFace
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Osg\CullingSet
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Osg\Depth
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -589,6 +593,10 @@ SOURCE=..\..\Include\Osg\PolygonOffset
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Osg\Polytope
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\Include\Osg\PositionAttitudeTransform
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include <osg/Referenced>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Quat>
|
||||
#include <osg/ClippingVolume>
|
||||
#include <osg/Viewport>
|
||||
#include <osg/DisplaySettings>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace osg {
|
||||
|
||||
class OccluderVolume;
|
||||
|
||||
/** A ClippingVolume class for representing convex clipping volumes made up.
|
||||
/** A class for representing convex clipping volumes made up.
|
||||
* When adding planes, their normals should point inwards (into the volume) */
|
||||
class SG_EXPORT ConvexPlanerOccluder : public Referenced
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace osg {
|
||||
class BoundingBox;
|
||||
class BoundingSphere;
|
||||
|
||||
/** A ClippingVolume class for representing convex clipping volumes made up.
|
||||
/** A class for representing convex clipping volumes made up.
|
||||
* When adding planes, their normals should point inwards (into the volume) */
|
||||
class SG_EXPORT ConvexPlanerPolygon
|
||||
{
|
||||
|
||||
@@ -126,13 +126,17 @@ class SG_EXPORT Node : public Object
|
||||
* to the cull traversal.*/
|
||||
void setCullingActive(const bool active);
|
||||
|
||||
/** Get the view frustum/small feature _cullingActive flag. Used a guide
|
||||
/** Get the view frustum/small feature _cullingActive flag for this node. Used a guide
|
||||
* to the cull traversal.*/
|
||||
inline const bool getCullingActive() const { return _cullingActive; }
|
||||
|
||||
/** Get the number of Children of this node which have culling disabled.*/
|
||||
inline const int getNumChildrenWithCullingDisabled() const { return _numChildrenWithCullingDisabled; }
|
||||
|
||||
/** Return true if this node can be culled by view frustum, occlusion or small feature culling during the cull traversal.
|
||||
* note, return true only if no children have culling disabled, and the local _cullingActive flag is true.*/
|
||||
inline const bool isCullingActive() const { return _numChildrenWithCullingDisabled==0 && _cullingActive && _bsphere.isValid(); }
|
||||
|
||||
|
||||
/**
|
||||
* Set user data, data must be subclased from Referenced to allow
|
||||
|
||||
@@ -2,48 +2,48 @@
|
||||
//Distributed under the terms of the GNU Library General Public License (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#ifndef OSG_CLIPPINGVOLUME
|
||||
#define OSG_CLIPPINGVOLUME 1
|
||||
#ifndef OSG_POLYTOPE
|
||||
#define OSG_POLYTOPE 1
|
||||
|
||||
#include <osg/Plane>
|
||||
|
||||
#include <vector>
|
||||
#include <osg/fast_back_stack>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** A ClippingVolume class for representing convex clipping volumes made up.
|
||||
|
||||
/** A Polytope class for representing convex clipping volumes made up.
|
||||
* When adding planes, their normals should point inwards (into the volume) */
|
||||
class SG_EXPORT ClippingVolume
|
||||
class SG_EXPORT Polytope
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef unsigned int ClippingMask;
|
||||
typedef std::vector<osg::Plane> PlaneList;
|
||||
|
||||
inline ClippingVolume() {setupMask();}
|
||||
inline Polytope() {setupMask();}
|
||||
|
||||
inline ClippingVolume(const ClippingVolume& cs, const unsigned int mask)
|
||||
{
|
||||
set(cs,mask);
|
||||
}
|
||||
|
||||
inline ClippingVolume(const ClippingVolume& cv) : _localMask(cv._localMask), _planeList(cv._planeList) {}
|
||||
inline Polytope(const Polytope& cv) :
|
||||
_maskStack(cv._maskStack),
|
||||
_resultsMask(cv._resultsMask),
|
||||
_planeList(cv._planeList) {}
|
||||
|
||||
inline ClippingVolume(const PlaneList& pl) : _planeList(pl) {setupMask();}
|
||||
inline Polytope(const PlaneList& pl) : _planeList(pl) {setupMask();}
|
||||
|
||||
inline ~ClippingVolume() {}
|
||||
inline ~Polytope() {}
|
||||
|
||||
inline void clear() { _planeList.clear(); setupMask(); }
|
||||
|
||||
inline ClippingVolume& operator = (const ClippingVolume& cv)
|
||||
inline Polytope& operator = (const Polytope& cv)
|
||||
{
|
||||
if (&cv==this) return *this;
|
||||
_localMask = cv._localMask;
|
||||
_planeList = cv._planeList;
|
||||
return *this;
|
||||
_maskStack = cv._maskStack;
|
||||
_resultsMask = cv._resultsMask;
|
||||
_planeList = cv._planeList;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Create a ClippingVolume with is cube, centered at 0,0,0, with sides of 2 units.*/
|
||||
/** Create a Polytope with is cube, centered at 0,0,0, with sides of 2 units.*/
|
||||
void setToUnitFrustum()
|
||||
{
|
||||
_planeList.erase(_planeList.begin(),_planeList.end());
|
||||
@@ -66,22 +66,6 @@ class SG_EXPORT ClippingVolume
|
||||
setupMask();
|
||||
}
|
||||
|
||||
inline void set(const ClippingVolume& cs, const unsigned int mask)
|
||||
{
|
||||
_planeList.erase(_planeList.begin(),_planeList.end());
|
||||
unsigned int selector_mask = 0x1;
|
||||
for(PlaneList::const_iterator itr=cs._planeList.begin();
|
||||
itr!=cs._planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (mask&selector_mask) _planeList.push_back(*itr);
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
setupMask();
|
||||
}
|
||||
|
||||
inline void set(const ClippingVolume& cs) { _planeList = cs._planeList; setupMask(); }
|
||||
|
||||
inline void set(const PlaneList& pl) { _planeList = pl; setupMask(); }
|
||||
|
||||
inline void add(const osg::Plane& pl) { _planeList.push_back(pl); setupMask(); }
|
||||
@@ -92,37 +76,44 @@ class SG_EXPORT ClippingVolume
|
||||
|
||||
inline void setupMask()
|
||||
{
|
||||
_localMask = 0;
|
||||
_resultsMask = 0;
|
||||
for(unsigned int i=0;i<_planeList.size();++i)
|
||||
{
|
||||
_localMask = (_localMask<<1) | 1;
|
||||
_resultsMask = (_resultsMask<<1) | 1;
|
||||
}
|
||||
_maskStack.back() = _resultsMask;
|
||||
}
|
||||
|
||||
unsigned int getLocalMask() const { return _localMask; }
|
||||
|
||||
inline ClippingMask& getCurrentMask() { return _maskStack.back(); }
|
||||
|
||||
inline ClippingMask getCurrentMask() const { return _maskStack.back(); }
|
||||
|
||||
inline ClippingMask getResultsMask() const
|
||||
{
|
||||
return _resultsMask;
|
||||
}
|
||||
|
||||
inline void pushCurrentMask()
|
||||
{
|
||||
_maskStack.push_back(_resultsMask);
|
||||
}
|
||||
|
||||
inline void popCurrentMask()
|
||||
{
|
||||
_maskStack.pop_back();
|
||||
}
|
||||
|
||||
/** Check whether a vertex is contained with clipping set.*/
|
||||
inline const bool contains(const osg::Vec3& v) const
|
||||
{
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->distance(v)<0.0f) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline const bool contains(const osg::Vec3& v,const unsigned int mask) const
|
||||
{
|
||||
if (!(mask & _localMask)) return true;
|
||||
if (!_maskStack.back()) return true;
|
||||
|
||||
unsigned int selector_mask = 0x1;
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (mask&selector_mask && (itr->distance(v)<0.0f)) return false;
|
||||
if ((_maskStack.back()&selector_mask) && (itr->distance(v)<0.0f)) return false;
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
@@ -133,95 +124,97 @@ class SG_EXPORT ClippingVolume
|
||||
modifying the mask to turn off planes which wouldn't contribute to clipping
|
||||
of any internal objects. This feature is used in osgUtil::CullVisitor
|
||||
to prevent redundant plane checking.*/
|
||||
inline const bool contains(const osg::BoundingSphere& bs,unsigned int& mask) const
|
||||
inline const bool contains(const osg::BoundingSphere& bs)
|
||||
{
|
||||
if (!(mask & _localMask)) return true;
|
||||
if (!_maskStack.back()) return true;
|
||||
|
||||
_resultsMask = _maskStack.back();
|
||||
ClippingMask selector_mask = 0x1;
|
||||
|
||||
unsigned int selector_mask = 0x1;
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (mask&selector_mask)
|
||||
if (_resultsMask&selector_mask)
|
||||
{
|
||||
int res=itr->intersect(bs);
|
||||
if (res<0) return false; // outside clipping set.
|
||||
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
else if (res>0) _resultsMask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
}
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding sphere is contained within clipping set.*/
|
||||
inline const bool contains(const osg::BoundingSphere& bs) const
|
||||
{
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->intersect(bs)<0) return false; // outside clipping set.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding box is contained within clipping set.
|
||||
Using a mask to determine which planes should be used for the check, and
|
||||
modifying the mask to turn off planes which wouldn't contribute to clipping
|
||||
of any internal objects. This feature is used in osgUtil::CullVisitor
|
||||
to prevent redundant plane checking.*/
|
||||
inline const bool contains(const osg::BoundingBox& bb,unsigned int& mask) const
|
||||
inline const bool contains(const osg::BoundingBox& bb)
|
||||
{
|
||||
if (!(mask & _localMask)) return true;
|
||||
if (!_maskStack.back()) return true;
|
||||
|
||||
_resultsMask = _maskStack.back();
|
||||
ClippingMask selector_mask = 0x1;
|
||||
|
||||
unsigned int selector_mask = 0x1;
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (mask&selector_mask)
|
||||
if (_resultsMask&selector_mask)
|
||||
{
|
||||
int res=itr->intersect(bb);
|
||||
if (res<0) return false; // outside clipping set.
|
||||
else if (res>0) mask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
else if (res>0) _resultsMask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
}
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether any part of a bounding box is contained within clipping set.*/
|
||||
inline const bool contains(const osg::BoundingBox& bb) const
|
||||
{
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->intersect(bb)<0) return false; // outside clipping set.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether the entire bounding sphere is contained within clipping set.*/
|
||||
inline const bool containsAllOf(const osg::BoundingSphere& bs) const
|
||||
inline const bool containsAllOf(const osg::BoundingSphere& bs)
|
||||
{
|
||||
if (!_maskStack.back()) return false;
|
||||
|
||||
_resultsMask = _maskStack.back();
|
||||
ClippingMask selector_mask = 0x1;
|
||||
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->intersect(bs)<1) return false; // intersects, or is below plane.
|
||||
if (_resultsMask&selector_mask)
|
||||
{
|
||||
int res=itr->intersect(bs);
|
||||
if (res<1) return false; // intersects, or is below plane.
|
||||
_resultsMask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
}
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check whether the entire bounding box is contained within clipping set.*/
|
||||
inline const bool containsAllOf(const osg::BoundingBox& bb) const
|
||||
inline const bool containsAllOf(const osg::BoundingBox& bb)
|
||||
{
|
||||
if (!_maskStack.back()) return false;
|
||||
|
||||
_resultsMask = _maskStack.back();
|
||||
ClippingMask selector_mask = 0x1;
|
||||
|
||||
for(PlaneList::const_iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->intersect(bb)<1) return false; // intersects, or is below plane.
|
||||
if (_resultsMask&selector_mask)
|
||||
{
|
||||
int res=itr->intersect(bb);
|
||||
if (res<1) return false; // intersects, or is below plane.
|
||||
_resultsMask ^= selector_mask; // subsequent checks against this plane not required.
|
||||
}
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -244,19 +237,28 @@ class SG_EXPORT ClippingVolume
|
||||
* see transform for details. */
|
||||
inline void transformProvidingInverse(const osg::Matrix& matrix)
|
||||
{
|
||||
if (!_maskStack.back()) return;
|
||||
|
||||
_resultsMask = _maskStack.back();
|
||||
ClippingMask selector_mask = 0x1;
|
||||
for(PlaneList::iterator itr=_planeList.begin();
|
||||
itr!=_planeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->transformProvidingInverse(matrix);
|
||||
if (_resultsMask&selector_mask)
|
||||
{
|
||||
itr->transformProvidingInverse(matrix);
|
||||
selector_mask <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
unsigned int _localMask;
|
||||
PlaneList _planeList;
|
||||
fast_back_stack<ClippingMask> _maskStack;
|
||||
ClippingMask _resultsMask;
|
||||
PlaneList _planeList;
|
||||
|
||||
};
|
||||
|
||||
@@ -6,24 +6,27 @@
|
||||
#define OSG_SHADOWOCCLUDERVOLUME 1
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/ClippingVolume>
|
||||
#include <osg/Polytope>
|
||||
#include <osg/ConvexPlanerOccluder>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** ShadowOccluderVolume is a helper class for implementating shadow occlusion culling. */
|
||||
class SG_EXPORT ShadowOccluderVolume : public Referenced
|
||||
class SG_EXPORT ShadowOccluderVolume
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
typedef std::vector<Polytope> HoleList;
|
||||
|
||||
ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP);
|
||||
|
||||
ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP);
|
||||
|
||||
typedef std::vector<ClippingVolume> ClippingHoleList;
|
||||
|
||||
inline void pushCurrentMask();
|
||||
inline void popCurrentMask();
|
||||
|
||||
/** Convert shadow occluder into local coords by multiplying the
|
||||
* clip space occluder by the ModelViewProjectionMatrix.*/
|
||||
void set(const ShadowOccluderVolume& soc,Matrix& MVP);
|
||||
@@ -34,23 +37,46 @@ class SG_EXPORT ShadowOccluderVolume : public Referenced
|
||||
|
||||
/** return true if the specified bounding sphere is contaned entirely
|
||||
* within this shadow occluder volume.*/
|
||||
bool contains(const BoundingSphere& bs);
|
||||
bool contains(const BoundingSphere& bound);
|
||||
|
||||
/** return true if the specified bounding box is contained entirely
|
||||
* within this shadow occluder volume.*/
|
||||
bool contains(const BoundingBox& bs);
|
||||
|
||||
|
||||
bool contains(const BoundingBox& bound);
|
||||
|
||||
protected:
|
||||
|
||||
// the original shadow occluder computed in clip space
|
||||
ref_ptr<ShadowOccluderVolume> _clipSpaceOccluder;
|
||||
|
||||
ClippingVolume _occluderVolume;
|
||||
ClippingHoleList _clippingHoleList;
|
||||
Polytope _occluderVolume;
|
||||
HoleList _holeList;
|
||||
};
|
||||
|
||||
inline void ShadowOccluderVolume::pushCurrentMask()
|
||||
{
|
||||
_occluderVolume.pushCurrentMask();
|
||||
if (!_holeList.empty())
|
||||
{
|
||||
for(HoleList::iterator itr=_holeList.begin();
|
||||
itr!=_holeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->pushCurrentMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void ShadowOccluderVolume::popCurrentMask()
|
||||
{
|
||||
_occluderVolume.popCurrentMask();
|
||||
if (!_holeList.empty())
|
||||
{
|
||||
for(HoleList::iterator itr=_holeList.begin();
|
||||
itr!=_holeList.end();
|
||||
++itr)
|
||||
{
|
||||
itr->popCurrentMask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/DisplaySettings>
|
||||
#include <osg/ClippingVolume>
|
||||
#include <osg/Polytope>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@@ -100,8 +100,7 @@ class SG_EXPORT State : public Referenced
|
||||
}
|
||||
|
||||
|
||||
ClippingVolume getClippingVolume() const;
|
||||
|
||||
Polytope getViewFrustum() const;
|
||||
|
||||
|
||||
/** Apply stateset.*/
|
||||
|
||||
@@ -82,7 +82,6 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
StateAttribute(text,copyop),
|
||||
_handleList(),
|
||||
_modifiedTag(),
|
||||
_textureObjectSize(text._textureObjectSize),
|
||||
_image(copyop(text._image.get())),
|
||||
_target(text._target),
|
||||
_textureUnit(text._textureUnit),
|
||||
@@ -232,11 +231,6 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
/** return the OpenGL texture object for specified context.*/
|
||||
inline const uint getTextureObject(const uint contextID) const { if (contextID<_handleList.size()) return _handleList[contextID]; else return 0;}
|
||||
|
||||
/** return the memory size of texture object.
|
||||
* Texture object size can be used for estimating the cost of
|
||||
* uploading the texture to graphics hardware, which in turn can
|
||||
* be used for setting texture residence priorities. */
|
||||
inline const uint getTextureObjectSize() const { return _textureObjectSize; }
|
||||
|
||||
enum SubloadMode {
|
||||
OFF,
|
||||
@@ -339,9 +333,6 @@ class SG_EXPORT Texture : public StateAttribute
|
||||
typedef std::vector<uint> ImageModifiedTag;
|
||||
mutable ImageModifiedTag _modifiedTag;
|
||||
|
||||
// size of the created OpenGL texture object, may be estimated.
|
||||
mutable uint _textureObjectSize;
|
||||
|
||||
|
||||
// not ideal that _image is mutable, but its required since
|
||||
// Image::ensureDimensionsArePowerOfTwo() can only be called
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef OSG_FAST_BACK_STACK
|
||||
#define OSG_FAST_BACK_STACK 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** Simple stack implementation that keeps the back() cached locally for fast access
|
||||
@@ -22,8 +24,17 @@ class fast_back_stack
|
||||
|
||||
inline fast_back_stack():_value(),_stack(),_size(0) {}
|
||||
|
||||
inline fast_back_stack(const fast_back_stack& fbs):_value(fbs._value),_stack(fbs._stack),_size(fbs._size) {}
|
||||
|
||||
inline fast_back_stack(const T& value):_value(value),_stack(),_size(1) {}
|
||||
|
||||
fast_back_stack& operator = (const fast_back_stack& fbs)
|
||||
{
|
||||
_value = fbs._value;
|
||||
_stack = fbs._stack;
|
||||
_size = fbs._size;
|
||||
}
|
||||
|
||||
inline void clear() { _stack.clear(); _size = 0; }
|
||||
|
||||
inline bool empty() const { return _size==0; }
|
||||
@@ -34,6 +45,15 @@ class fast_back_stack
|
||||
|
||||
inline const T& back() const { return _value; }
|
||||
|
||||
inline void push_back()
|
||||
{
|
||||
if (_size>0)
|
||||
{
|
||||
_stack.push_back(_value);
|
||||
}
|
||||
++_size;
|
||||
}
|
||||
|
||||
inline void push_back(const T& value)
|
||||
{
|
||||
if (_size>0)
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include <osg/Impostor>
|
||||
#include <osg/EarthSky>
|
||||
#include <osg/Notify>
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osg/CullingSet>
|
||||
#include <osg/fast_back_stack>
|
||||
|
||||
#include <osgUtil/RenderGraph>
|
||||
@@ -240,31 +242,50 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
|
||||
v.y()*mvpw(1,3)+
|
||||
v.z()*mvpw(2,3)+
|
||||
mvpw(3,3);
|
||||
|
||||
|
||||
return fabs(radius*_windowToModelFactor/W);
|
||||
|
||||
}
|
||||
|
||||
|
||||
osg::ClippingVolume& getCurrentClippingVolume() { return _modelviewClippingVolumeStack.back(); }
|
||||
|
||||
inline bool isCulled(const osg::BoundingSphere& sp,CullingMode& mode)
|
||||
inline float pixelSize2(const osg::Vec3& v, float const radius)
|
||||
{
|
||||
if (!sp.isValid()) return true;
|
||||
const float R2 = osg::square(_viewportStack.back()->width()/osg::DegreesToRadians(38.0f))*1.15f;
|
||||
|
||||
if (!(_modelviewClippingVolumeStack.back().contains(sp,mode))) return true;
|
||||
//float p1 = fabs(radius*_windowToModelFactor/W);
|
||||
return R2*radius*radius/(v-getEyeLocal()).length2();
|
||||
|
||||
if (mode&SMALL_FEATURE_CULLING)
|
||||
}
|
||||
|
||||
inline bool isCulled(const osg::Node& node)
|
||||
{
|
||||
if (node.isCullingActive())
|
||||
{
|
||||
if (pixelSize(sp.center(),sp.radius())<_smallFeatureCullingPixelSize) return true;
|
||||
const osg::BoundingSphere& sp = node.getBound();
|
||||
if (!(_modelviewPolytopeStack.back().contains(sp))) return true;
|
||||
// if (pixelSize(sp.center(),sp.radius())<_smallFeatureCullingPixelSize) return true;
|
||||
if (pixelSize2(sp.center(),sp.radius())<osg::square(_smallFeatureCullingPixelSize)) return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
inline const bool isCulled(const osg::BoundingBox& bb,CullingMode mode)
|
||||
inline const bool isCulled(const osg::BoundingBox& bb)
|
||||
{
|
||||
if (!bb.isValid()) return true;
|
||||
|
||||
return !_modelviewClippingVolumeStack.back().contains(bb,mode);
|
||||
//return !_modelviewPolytopeStack.back().contains(bb,mode);
|
||||
return !_modelviewPolytopeStack.back().contains(bb);
|
||||
//return false;
|
||||
}
|
||||
|
||||
inline void pushCurrentMask()
|
||||
{
|
||||
_modelviewPolytopeStack.back().pushCurrentMask();
|
||||
}
|
||||
|
||||
inline void popCurrentMask()
|
||||
{
|
||||
_modelviewPolytopeStack.back().popCurrentMask();
|
||||
}
|
||||
|
||||
const CullingMode getCurrentCullingMode() const { return _cullingModeStack.back(); }
|
||||
@@ -327,23 +348,23 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
|
||||
|
||||
|
||||
|
||||
void pushClippingVolume();
|
||||
void popClippingVolume();
|
||||
void pushPolytope();
|
||||
void popPolytope();
|
||||
|
||||
|
||||
// typedef std::vector<osg::ClippingVolume> ClippingVolumeStack;
|
||||
// typedef std::vector<osg::Polytope> PolytopeStack;
|
||||
// typedef std::vector<osg::ref_ptr<osg::Matrix> > MatrixStack;
|
||||
|
||||
typedef osg::fast_back_stack<osg::ClippingVolume> ClippingVolumeStack;
|
||||
typedef osg::fast_back_stack<osg::Polytope> PolytopeStack;
|
||||
typedef osg::fast_back_stack< osg::ref_ptr<osg::Matrix> > MatrixStack;
|
||||
|
||||
MatrixStack _projectionStack;
|
||||
MatrixStack _PW_Stack;
|
||||
ClippingVolumeStack _projectionClippingVolumeStack;
|
||||
PolytopeStack _projectionPolytopeStack;
|
||||
|
||||
MatrixStack _modelviewStack;
|
||||
MatrixStack _MVPW_Stack;
|
||||
ClippingVolumeStack _modelviewClippingVolumeStack;
|
||||
PolytopeStack _modelviewPolytopeStack;
|
||||
|
||||
bool _windowToModelFactorDirty;
|
||||
float _windowToModelFactor;
|
||||
@@ -358,6 +379,10 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor
|
||||
|
||||
typedef osg::fast_back_stack<CullingMode> CullingModeStack;
|
||||
CullingModeStack _cullingModeStack;
|
||||
|
||||
typedef osg::fast_back_stack<osg::ref_ptr<osg::CullingSet> > ClippingStack;
|
||||
ClippingStack _clippingSet;
|
||||
|
||||
|
||||
unsigned int _bbCornerNear;
|
||||
unsigned int _bbCornerFar;
|
||||
|
||||
@@ -20,7 +20,7 @@ Camera::Camera(DisplaySettings* ds)
|
||||
}
|
||||
|
||||
setPerspective(fovy,1.0,1.0,1000.0);
|
||||
|
||||
|
||||
// look at details.
|
||||
_lookAtType =USE_HOME_POSITON;
|
||||
|
||||
|
||||
11
src/osg/CullingSet.cpp
Normal file
11
src/osg/CullingSet.cpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <osg/CullingSet>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
CullingSet::CullingSet()
|
||||
{
|
||||
}
|
||||
|
||||
CullingSet::~CullingSet()
|
||||
{
|
||||
}
|
||||
@@ -16,6 +16,7 @@ CXXFILES =\
|
||||
ConvexPlanerOccluder.cpp\
|
||||
CopyOp.cpp\
|
||||
CullFace.cpp\
|
||||
CullingSet.cpp\
|
||||
Depth.cpp\
|
||||
DisplaySettings.cpp\
|
||||
Drawable.cpp\
|
||||
|
||||
@@ -1,3 +1,54 @@
|
||||
#include <osg/ShadowOccluderVolume>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
|
||||
ShadowOccluderVolume::ShadowOccluderVolume(const ShadowOccluderVolume& soc,Matrix& MVP)
|
||||
{
|
||||
set(soc,MVP);
|
||||
}
|
||||
|
||||
ShadowOccluderVolume::ShadowOccluderVolume(const ConvexPlanerOccluder& occluder,Matrix& MVP)
|
||||
{
|
||||
set(occluder,MVP);
|
||||
}
|
||||
|
||||
void ShadowOccluderVolume::set(const ShadowOccluderVolume& soc,Matrix& MVP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ShadowOccluderVolume::set(const ConvexPlanerOccluder& occluder,Matrix& MVP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ShadowOccluderVolume::contains(const BoundingSphere& bound)
|
||||
{
|
||||
if (_occluderVolume.containsAllOf(bound))
|
||||
{
|
||||
for(HoleList::iterator itr=_holeList.begin();
|
||||
itr!=_holeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->contains(bound)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ShadowOccluderVolume::contains(const BoundingBox& bound)
|
||||
{
|
||||
if (_occluderVolume.containsAllOf(bound))
|
||||
{
|
||||
for(HoleList::iterator itr=_holeList.begin();
|
||||
itr!=_holeList.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->contains(bound)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -599,9 +599,9 @@ const StateAttribute* State::getLastAppliedAttribute(const StateAttribute::Type
|
||||
}
|
||||
|
||||
|
||||
ClippingVolume State::getClippingVolume() const
|
||||
Polytope State::getViewFrustum() const
|
||||
{
|
||||
ClippingVolume cv;
|
||||
Polytope cv;
|
||||
cv.setToUnitFrustum();
|
||||
cv.transformProvidingInverse((*_modelView)*(*_projection));
|
||||
return cv;
|
||||
|
||||
@@ -40,8 +40,6 @@ Texture::Texture()
|
||||
|
||||
_textureWidth = _textureHeight = 0;
|
||||
|
||||
_textureObjectSize = 0;
|
||||
|
||||
_subloadMode = OFF;
|
||||
_subloadOffsX = _subloadOffsY = 0;
|
||||
_subloadWidth = _subloadHeight = 0;
|
||||
@@ -445,9 +443,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
|
||||
(GLenum)image->getDataType(),
|
||||
image->data() );
|
||||
|
||||
// just estimate estimate it right now..
|
||||
// note, ignores texture compression..
|
||||
_textureObjectSize = image->s()*image->t()*4;
|
||||
}
|
||||
else if(glCompressedTexImage2D_ptr)
|
||||
{
|
||||
@@ -458,7 +453,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
|
||||
size,
|
||||
image->data());
|
||||
|
||||
_textureObjectSize = size;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -470,14 +464,10 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
|
||||
image->s(),image->t(),
|
||||
(GLenum)image->getPixelFormat(), (GLenum)image->getDataType(),
|
||||
image->data() );
|
||||
// just estimate size it right now..
|
||||
// crude x2 multiplier to account for minmap storage.
|
||||
// note, ignores texture compression..
|
||||
_textureObjectSize = image->s()*image->t()*4;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
_textureObjectSize = 0;
|
||||
size_t no_mipmaps = image->getNumMipmaps();
|
||||
int width = image->s();
|
||||
int height = image->t();
|
||||
@@ -498,7 +488,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
|
||||
(GLenum)image->getDataType(),
|
||||
image->getMipmapData(k));
|
||||
|
||||
_textureObjectSize += width*height*4;
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
@@ -518,7 +507,6 @@ void Texture::applyTexImage(GLenum target, Image* image, State& state) const
|
||||
glCompressedTexImage2D_ptr(target, k, internalFormat,
|
||||
width, height, 0, size, image->getMipmapData(k));
|
||||
|
||||
_textureObjectSize += size;
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
}
|
||||
|
||||
@@ -125,10 +125,10 @@ void CullVisitor::reset()
|
||||
// first unref all referenced objects and then empty the containers.
|
||||
//
|
||||
_projectionStack.clear();
|
||||
_projectionClippingVolumeStack.clear();
|
||||
_projectionPolytopeStack.clear();
|
||||
|
||||
_modelviewStack.clear();
|
||||
_modelviewClippingVolumeStack.clear();
|
||||
_modelviewPolytopeStack.clear();
|
||||
|
||||
_viewportStack.clear();
|
||||
|
||||
@@ -139,7 +139,6 @@ void CullVisitor::reset()
|
||||
_cullingModeStack.clear();
|
||||
|
||||
// reset the calculated near far planes.
|
||||
_computeNearFar = COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
|
||||
_computed_znear = FLT_MAX;
|
||||
_computed_zfar = -FLT_MAX;
|
||||
|
||||
@@ -167,13 +166,11 @@ void CullVisitor::reset()
|
||||
_windowToModelFactor = 1.0f;
|
||||
}
|
||||
|
||||
void CullVisitor::pushClippingVolume()
|
||||
void CullVisitor::pushPolytope()
|
||||
{
|
||||
_modelviewClippingVolumeStack.push_back(osg::ClippingVolume());
|
||||
osg::ClippingVolume& cv = _modelviewClippingVolumeStack.back();
|
||||
//cv.set(_projectionClippingVolumeStack.back());
|
||||
cv.set(_projectionClippingVolumeStack.back(),_cullingModeStack.back());
|
||||
_cullingModeStack.push_back(cv.getLocalMask() | (_cullingModeStack.back()&SMALL_FEATURE_CULLING));
|
||||
_modelviewPolytopeStack.push_back();
|
||||
osg::Polytope& cv = _modelviewPolytopeStack.back();
|
||||
cv = _projectionPolytopeStack.back();
|
||||
|
||||
if (!_modelviewStack.empty()) cv.transformProvidingInverse(*_modelviewStack.back());
|
||||
|
||||
@@ -182,11 +179,10 @@ void CullVisitor::pushClippingVolume()
|
||||
_windowToModelFactorDirty = true;
|
||||
}
|
||||
|
||||
void CullVisitor::popClippingVolume()
|
||||
void CullVisitor::popPolytope()
|
||||
{
|
||||
_modelviewClippingVolumeStack.pop_back();
|
||||
_modelviewPolytopeStack.pop_back();
|
||||
_MVPW_Stack.pop_back();
|
||||
_cullingModeStack.pop_back();
|
||||
|
||||
_windowToModelFactorDirty = true;
|
||||
}
|
||||
@@ -207,11 +203,11 @@ void CullVisitor::pushProjectionMatrix(Matrix* matrix)
|
||||
{
|
||||
_projectionStack.push_back(matrix);
|
||||
|
||||
_projectionClippingVolumeStack.push_back(ClippingVolume());
|
||||
_projectionClippingVolumeStack.back().setToUnitFrustumWithoutNearFar();
|
||||
_projectionClippingVolumeStack.back().transformProvidingInverse(*matrix);
|
||||
_projectionPolytopeStack.push_back();
|
||||
_projectionPolytopeStack.back().setToUnitFrustumWithoutNearFar();
|
||||
_projectionPolytopeStack.back().transformProvidingInverse(*matrix);
|
||||
|
||||
pushClippingVolume();
|
||||
pushPolytope();
|
||||
}
|
||||
|
||||
void CullVisitor::popProjectionMatrix()
|
||||
@@ -243,16 +239,16 @@ void CullVisitor::popProjectionMatrix()
|
||||
}
|
||||
|
||||
_projectionStack.pop_back();
|
||||
_projectionClippingVolumeStack.pop_back();
|
||||
_projectionPolytopeStack.pop_back();
|
||||
|
||||
popClippingVolume();
|
||||
popPolytope();
|
||||
}
|
||||
|
||||
void CullVisitor::pushModelViewMatrix(Matrix* matrix)
|
||||
{
|
||||
_modelviewStack.push_back(matrix);
|
||||
|
||||
pushClippingVolume();
|
||||
pushPolytope();
|
||||
|
||||
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
|
||||
const float x_0 = (*matrix)(0,0);
|
||||
@@ -289,7 +285,7 @@ void CullVisitor::popModelViewMatrix()
|
||||
{
|
||||
_modelviewStack.pop_back();
|
||||
_eyePointStack.pop_back();
|
||||
popClippingVolume();
|
||||
popPolytope();
|
||||
|
||||
|
||||
osg::Vec3 lookVector(0.0f,0.0f,-1.0f);
|
||||
@@ -364,14 +360,10 @@ CullVisitor::CullingMode CullVisitor::getCullingMode() const
|
||||
|
||||
void CullVisitor::apply(Node& node)
|
||||
{
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the culling mode.
|
||||
_cullingModeStack.push_back(mode);
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -383,19 +375,13 @@ void CullVisitor::apply(Node& node)
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
|
||||
void CullVisitor::apply(Geode& node)
|
||||
{
|
||||
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -414,7 +400,7 @@ void CullVisitor::apply(Geode& node)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isCulled(bb,mode)) continue;
|
||||
if (isCulled(bb)) continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -490,12 +476,7 @@ void CullVisitor::apply(Geode& node)
|
||||
|
||||
void CullVisitor::apply(Billboard& node)
|
||||
{
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -602,15 +583,10 @@ void CullVisitor::apply(ClipNode& node)
|
||||
|
||||
void CullVisitor::apply(Group& node)
|
||||
{
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the culling mode.
|
||||
_cullingModeStack.push_back(mode);
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -622,20 +598,15 @@ void CullVisitor::apply(Group& node)
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void CullVisitor::apply(Transform& node)
|
||||
{
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the culling mode.
|
||||
_cullingModeStack.push_back(mode);
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -653,20 +624,15 @@ void CullVisitor::apply(Transform& node)
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void CullVisitor::apply(Projection& node)
|
||||
{
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
// push the culling mode.
|
||||
_cullingModeStack.push_back(mode);
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -695,7 +661,7 @@ void CullVisitor::apply(Projection& node)
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void CullVisitor::apply(Switch& node)
|
||||
@@ -706,18 +672,13 @@ void CullVisitor::apply(Switch& node)
|
||||
|
||||
void CullVisitor::apply(LOD& node)
|
||||
{
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
int eval = node.evaluate(getEyeLocal(),_LODBias);
|
||||
if (eval<0) return;
|
||||
|
||||
// push the culling mode.
|
||||
_cullingModeStack.push_back(mode);
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
@@ -730,7 +691,7 @@ void CullVisitor::apply(LOD& node)
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
void CullVisitor::apply(osg::EarthSky& node)
|
||||
@@ -752,29 +713,22 @@ void CullVisitor::apply(osg::EarthSky& node)
|
||||
|
||||
void CullVisitor::apply(Impostor& node)
|
||||
{
|
||||
const BoundingSphere& bs = node.getBound();
|
||||
|
||||
// return if object's bounding sphere is culled.
|
||||
CullingMode mode = _cullingModeStack.back();
|
||||
|
||||
if (!node.getCullingActive()) mode = 0;
|
||||
else if (node.getNumChildrenWithCullingDisabled()==0 &&
|
||||
isCulled(node.getBound(),mode)) return;
|
||||
if (isCulled(node)) return;
|
||||
|
||||
osg::Vec3 eyeLocal = getEyeLocal();
|
||||
|
||||
int eval = node.evaluate(eyeLocal,_LODBias);
|
||||
if (eval<0){
|
||||
return;
|
||||
}
|
||||
if (eval<0) return;
|
||||
|
||||
// push the culling mode.
|
||||
_cullingModeStack.push_back(mode);
|
||||
pushCurrentMask();
|
||||
|
||||
// push the node's state.
|
||||
StateSet* node_state = node.getStateSet();
|
||||
if (node_state) pushStateSet(node_state);
|
||||
|
||||
const BoundingSphere& bs = node.getBound();
|
||||
|
||||
float distance2 = (eyeLocal-bs.center()).length2();
|
||||
if (!_impostorActive ||
|
||||
@@ -875,7 +829,7 @@ void CullVisitor::apply(Impostor& node)
|
||||
if (node_state) popStateSet();
|
||||
|
||||
// pop the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
}
|
||||
|
||||
ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
@@ -1030,7 +984,7 @@ ImpostorSprite* CullVisitor::createImpostorSprite(Impostor& node)
|
||||
}
|
||||
|
||||
// restore the culling mode.
|
||||
_cullingModeStack.pop_back();
|
||||
popCurrentMask();
|
||||
|
||||
popStateSet();
|
||||
|
||||
|
||||
@@ -194,6 +194,9 @@ void SceneView::cull()
|
||||
|
||||
if (!projection) projection = osgNew osg::Matrix(_camera->getProjectionMatrix());
|
||||
if (!modelview) modelview = osgNew osg::Matrix(_camera->getModelViewMatrix());
|
||||
|
||||
//cout <<"fovx="<<_camera->calc_fovx()<<endl;
|
||||
|
||||
}
|
||||
|
||||
if (!projection) projection = osgNew osg::Matrix();
|
||||
|
||||
Reference in New Issue
Block a user