From 89f9aa2dddbcf9a42e0e4b27383d95e061c384bf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 20 Dec 2010 17:04:59 +0000 Subject: [PATCH] =?UTF-8?q?From=20Andy=20Skinner,=20"In=20this=20file=20I?= =?UTF-8?q?=E2=80=99ve=20changed=20TriangleFunctor=20to=20TemplatePrimitiv?= =?UTF-8?q?eFunctor,=20and=20added=20operator()=20methods=20for:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit · points (just look at points in frustum) · lines (simple line clip—replace the external point) · quadrilaterals (call operator() for triangles twice)" --- src/osgUtil/CullVisitor.cpp | 168 ++++++++++++++++++++++++++++++++++-- 1 file changed, 161 insertions(+), 7 deletions(-) diff --git a/src/osgUtil/CullVisitor.cpp b/src/osgUtil/CullVisitor.cpp index d02bcfcb0..4013334a7 100644 --- a/src/osgUtil/CullVisitor.cpp +++ b/src/osgUtil/CullVisitor.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include @@ -325,13 +325,161 @@ struct ComputeNearestPointFunctor Polygon _pointCache; + // Handle Points + inline void operator() ( const osg::Vec3 &v1, bool) + { + CullVisitor::value_type n1 = distance(v1,_matrix); + + // check if point is behind znear, if so discard + if (n1 >= _znear) + { + //OSG_NOTICE<<"Point beyond znear"<begin(); + pitr != _planes->end(); + ++pitr) + { + const osg::Plane& plane = *pitr; + float d1 = plane.distance(v1); + + if (d1<0.0) + { + //OSG_NOTICE<<"Point outside frustum "<= _znear && + n2 >= _znear) + { + //OSG_NOTICE<<"Line totally beyond znear"<begin(); + pitr != _planes->end(); + ++pitr) + { + const osg::Plane& plane = *pitr; + float d1 = plane.distance(v1); + float d2 = plane.distance(v2); + + unsigned int numOutside = ((d1<0.0)?1:0) + ((d2<0.0)?1:0); + if (numOutside==2) + { + //OSG_NOTICE<<"Line totally outside frustum "<=0.0)?1:0) + ((d2>=0.0)?1:0); + if (numInside<2) + { + active_mask = active_mask | selector_mask; + } + + //OSG_NOTICE<<"Line ok w.r.t plane "<begin(); + pitr != _planes->end(); + ++pitr) + { + if (active_mask & selector_mask) + { + // clip line to plane + const osg::Plane& plane = *pitr; + + // assign the distance from the current plane. + p1.first = plane.distance(p1.second); + p2.first = plane.distance(p2.second); + + if (p1.first >= 0.0f) + { + // p1 is in. + if (p2.first < 0.0) + { + // p2 is out. + // replace p2 with intersection + float r = p1.first/(p1.first-p2.first); + p2 = DistancePoint(0.0f, p1.second*(1.0f-r) + p2.second*r); + + } + } + else if (p2.first >= 0.0f) + { + // p1 is out and p2 is in. + // replace p1 with intersection + float r = p1.first/(p1.first-p2.first); + p1 = DistancePoint(0.0f, p1.second*(1.0f-r) + p2.second*r); + } + // The case where both are out was handled above. + } + selector_mask <<= 1; + } + + n1 = distance(p1.second,_matrix); + n2 = distance(p2.second,_matrix); + _znear = osg::minimum(n1, n2); + //OSG_NOTICE<<"Near plane updated "<<_znear<= _znear && n2 >= _znear && n3 >= _znear) @@ -349,7 +497,7 @@ struct ComputeNearestPointFunctor return; } - // check which planes the points + // Check each vertex to each frustum plane. osg::Polytope::ClippingMask selector_mask = 0x1; osg::Polytope::ClippingMask active_mask = 0x0; @@ -392,7 +540,7 @@ struct ComputeNearestPointFunctor //return; // numPartiallyInside>0) so we have a triangle cutting an frustum wall, - // this means that use brute force methods for deviding up triangle. + // this means that use brute force methods for dividing up triangle. //OSG_NOTICE<<"Using brute force method of triangle cutting frustum walls"<begin(); pitr != _planes->end() && !_polygonOriginal.empty(); ++pitr) @@ -462,13 +609,20 @@ struct ComputeNearestPointFunctor } } } + + // Handle Quadrilaterals + inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3, const osg::Vec3 &v4, bool treatVertexDataAsTemporary) + { + this->operator()(v1, v2, v3, treatVertexDataAsTemporary); + this->operator()(v1, v3, v4, treatVertexDataAsTemporary); + } }; CullVisitor::value_type CullVisitor::computeNearestPointInFrustum(const osg::Matrix& matrix, const osg::Polytope::PlaneList& planes,const osg::Drawable& drawable) { // OSG_WARN<<"CullVisitor::computeNearestPointInFrustum("< cnpf; + osg::TemplatePrimitiveFunctor cnpf; cnpf.set(_computed_znear, matrix, &planes); drawable.accept(cnpf); @@ -495,7 +649,7 @@ bool CullVisitor::updateCalculatedNearFar(const osg::Matrix& matrix,const osg::B if (d_far<0.0) { - // whole object behind the eye point so disguard + // whole object behind the eye point so discard return false; }