Generalised the osg::ClusterCullingCallback so that it coud be attached
to Node as well as Drawables. Changed the osgTerrain::DataSet so that it moves the ClusterCullingCallback up to the Node level. Added support to the .ive plugin for attaching the ClusterCullingCallback to nodes.
This commit is contained in:
parent
bba69b288b
commit
93c439ba01
@ -15,13 +15,14 @@
|
||||
#define OSG_CLUSTERCULLINGCALLBACK 1
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/NodeCallback>
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** Implements cluster culling to cull back facing drawables. Derived from
|
||||
* Drawable::CullCallback.
|
||||
*/
|
||||
class SG_EXPORT ClusterCullingCallback : public Drawable::CullCallback
|
||||
class SG_EXPORT ClusterCullingCallback : public Drawable::CullCallback, public NodeCallback
|
||||
{
|
||||
public:
|
||||
|
||||
@ -35,6 +36,9 @@ class SG_EXPORT ClusterCullingCallback : public Drawable::CullCallback
|
||||
/** Computes the control point, normal, and deviation from the
|
||||
* given drawable contents. */
|
||||
void computeFrom(const osg::Drawable* drawable);
|
||||
|
||||
/** Transform the ClusterCullingCallback's positional members to a new coordinate frame.*/
|
||||
void transform(const osg::Matrixd& matrix);
|
||||
|
||||
void set(const osg::Vec3& controlPoint, const osg::Vec3& normal, float deviation, float radius);
|
||||
|
||||
@ -52,6 +56,9 @@ class SG_EXPORT ClusterCullingCallback : public Drawable::CullCallback
|
||||
|
||||
virtual bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const;
|
||||
|
||||
/** Callback method called by the NodeVisitor when visiting a node.*/
|
||||
virtual void operator()(Node* node, NodeVisitor* nv);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~ClusterCullingCallback() {}
|
||||
|
@ -143,6 +143,13 @@ void ClusterCullingCallback::set(const osg::Vec3& controlPoint, const osg::Vec3&
|
||||
_radius = radius;
|
||||
}
|
||||
|
||||
void ClusterCullingCallback::transform(const osg::Matrixd& matrix)
|
||||
{
|
||||
_controlPoint = Vec3d(_controlPoint)*matrix;
|
||||
_normal = Matrixd::transform3x3(Matrixd::inverse(matrix),Vec3d(_normal));
|
||||
_normal.normalize();
|
||||
}
|
||||
|
||||
|
||||
bool ClusterCullingCallback::cull(osg::NodeVisitor* nv, osg::Drawable* , osg::State*) const
|
||||
{
|
||||
@ -162,7 +169,10 @@ bool ClusterCullingCallback::cull(osg::NodeVisitor* nv, osg::Drawable* , osg::St
|
||||
osg::Vec3 eye_cp = nv->getEyePoint() - _controlPoint;
|
||||
float radius = eye_cp.length();
|
||||
|
||||
if (radius<_radius) return false;
|
||||
if (radius<_radius)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
float deviation = (eye_cp * _normal)/radius;
|
||||
@ -172,3 +182,14 @@ bool ClusterCullingCallback::cull(osg::NodeVisitor* nv, osg::Drawable* , osg::St
|
||||
|
||||
return deviation < _deviation;
|
||||
}
|
||||
|
||||
|
||||
void ClusterCullingCallback::operator()(Node* node, NodeVisitor* nv)
|
||||
{
|
||||
if (nv)
|
||||
{
|
||||
if (cull(nv,0,0)) return;
|
||||
|
||||
traverse(node,nv);
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,13 @@
|
||||
compatibility (if implemented). VERSION is
|
||||
stored in the 2nd 4 bytes of the file */
|
||||
|
||||
#define VERSION_0002 0x00000002
|
||||
#define VERSION_0003 0x00000003
|
||||
#define VERSION_0004 0x00000004
|
||||
#define VERSION_0005 0x00000005
|
||||
#define VERSION VERSION_0005
|
||||
#define VERSION_0001 1
|
||||
#define VERSION_0002 2
|
||||
#define VERSION_0003 3
|
||||
#define VERSION_0004 4
|
||||
#define VERSION_0005 5
|
||||
#define VERSION_0006 6
|
||||
#define VERSION VERSION_0006
|
||||
|
||||
|
||||
/* The BYTE_SEX tag is used to check the endian
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "Object.h"
|
||||
#include "StateSet.h"
|
||||
#include "AnimationPathCallback.h"
|
||||
#include "ClusterCullingCallback.h"
|
||||
|
||||
using namespace ive;
|
||||
|
||||
@ -62,9 +63,19 @@ void Node::write(DataOutputStream* out){
|
||||
{
|
||||
((ive::AnimationPathCallback*)(nc))->write(out);
|
||||
}
|
||||
|
||||
if (out->getVersion() >= VERSION_0006)
|
||||
{
|
||||
osg::ClusterCullingCallback* ccc = dynamic_cast<osg::ClusterCullingCallback*>(getCullCallback());
|
||||
out->writeBool(ccc!=0);
|
||||
if(ccc)
|
||||
{
|
||||
((ive::ClusterCullingCallback*)(ccc))->write(out);
|
||||
}
|
||||
}
|
||||
|
||||
// Write NodeMask
|
||||
out->writeUInt(getNodeMask());
|
||||
// Write NodeMask
|
||||
out->writeUInt(getNodeMask());
|
||||
}
|
||||
|
||||
|
||||
@ -95,6 +106,7 @@ void Node::read(DataInputStream* in){
|
||||
{
|
||||
setStateSet(in->readStateSet());
|
||||
}
|
||||
|
||||
// Read UpdateCallback if any
|
||||
if(in->readBool())
|
||||
{
|
||||
@ -102,8 +114,19 @@ void Node::read(DataInputStream* in){
|
||||
((ive::AnimationPathCallback*)(nc))->read(in);
|
||||
setUpdateCallback(nc);
|
||||
}
|
||||
// Read NodeMask
|
||||
setNodeMask(in->readUInt());
|
||||
|
||||
if (in->getVersion() >= VERSION_0006)
|
||||
{
|
||||
if(in->readBool())
|
||||
{
|
||||
osg::ClusterCullingCallback* ccc = new osg::ClusterCullingCallback();
|
||||
((ive::ClusterCullingCallback*)(ccc))->read(in);
|
||||
setCullCallback(ccc);
|
||||
}
|
||||
}
|
||||
|
||||
// Read NodeMask
|
||||
setNodeMask(in->readUInt());
|
||||
}
|
||||
else{
|
||||
throw Exception("Node::read(): Expected Node identification");
|
||||
|
@ -2303,9 +2303,10 @@ osg::Node* DataSet::DestinationTile::createPolygonal()
|
||||
|
||||
float local_dot_product = -sin(theta + phi);
|
||||
float local_m = globe_radius*( 1.0/ cos(theta+phi) - 1.0);
|
||||
float local_radius = static_cast<float>(globe_radius * tan(beta)); // beta*globe_radius;
|
||||
min_dot_product = osg::minimum(min_dot_product, local_dot_product);
|
||||
max_cluster_culling_height = osg::maximum(max_cluster_culling_height,local_m);
|
||||
max_cluster_culling_radius = osg::maximum(max_cluster_culling_radius,static_cast<float>(beta*globe_radius));
|
||||
max_cluster_culling_radius = osg::maximum(max_cluster_culling_radius,local_radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2838,6 +2839,66 @@ std::string DataSet::CompositeDestination::getSubTileName()
|
||||
return _name+"_subtile"+_dataSet->getDestinationTileExtension();
|
||||
}
|
||||
|
||||
|
||||
class CollectClusterCullingCallbacks : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
struct Triple
|
||||
{
|
||||
Triple():
|
||||
_drawable(0),
|
||||
_callback(0) {}
|
||||
|
||||
Triple(osg::NodePath nodePath, osg::Drawable* drawable, osg::ClusterCullingCallback* callback):
|
||||
_nodePath(nodePath),
|
||||
_drawable(drawable),
|
||||
_callback(callback) {}
|
||||
|
||||
Triple(const Triple& t):
|
||||
_nodePath(t._nodePath),
|
||||
_drawable(t._drawable),
|
||||
_callback(t._callback) {}
|
||||
|
||||
Triple& operator = (const Triple& t)
|
||||
{
|
||||
_nodePath = t._nodePath;
|
||||
_drawable = t._drawable;
|
||||
_callback = t._callback;
|
||||
return *this;
|
||||
}
|
||||
|
||||
osg::NodePath _nodePath;
|
||||
osg::Drawable* _drawable;
|
||||
osg::ClusterCullingCallback* _callback;
|
||||
};
|
||||
|
||||
typedef std::vector<Triple> ClusterCullingCallbackList;
|
||||
|
||||
CollectClusterCullingCallbacks():
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
|
||||
|
||||
virtual void apply(osg::Geode& geode)
|
||||
{
|
||||
for(unsigned int i=0; i<geode.getNumDrawables();++i)
|
||||
{
|
||||
osg::ClusterCullingCallback* callback = dynamic_cast<osg::ClusterCullingCallback*>(geode.getDrawable(i)->getCullCallback());
|
||||
if (callback)
|
||||
{
|
||||
_callbackList.push_back(Triple(getNodePath(),geode.getDrawable(i),callback));
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" Note found"<<geode.getDrawable(i)->getCullCallback()<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClusterCullingCallbackList _callbackList;
|
||||
|
||||
};
|
||||
|
||||
osg::Node* DataSet::CompositeDestination::createPagedLODScene()
|
||||
{
|
||||
if (_children.empty() && _tiles.empty()) return 0;
|
||||
@ -2909,6 +2970,33 @@ osg::Node* DataSet::CompositeDestination::createPagedLODScene()
|
||||
pagedLOD->addChild(group);
|
||||
}
|
||||
|
||||
|
||||
// find cluster culling callbacks on drawables and move them to the PagedLOD level.
|
||||
{
|
||||
CollectClusterCullingCallbacks collect;
|
||||
pagedLOD->accept(collect);
|
||||
|
||||
if (!collect._callbackList.empty())
|
||||
{
|
||||
if (collect._callbackList.size()==1)
|
||||
{
|
||||
CollectClusterCullingCallbacks::Triple& triple = collect._callbackList.front();
|
||||
|
||||
osg::Matrixd matrix = osg::computeLocalToWorld(triple._nodePath);
|
||||
|
||||
triple._callback->transform(matrix);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"cluster culling matrix "<<matrix<<std::endl;
|
||||
|
||||
// moving cluster culling callback pagedLOD node.
|
||||
pagedLOD->setCullCallback(triple._callback);
|
||||
|
||||
// remove it from the drawable.
|
||||
triple._drawable->setCullCallback(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cutOffDistance = pagedLOD->getBound().radius()*_dataSet->getRadiusToMaxVisibleDistanceRatio();
|
||||
|
||||
pagedLOD->setRange(0,cutOffDistance,farDistance);
|
||||
|
Loading…
Reference in New Issue
Block a user