If your geometry (such as a skydome) is not changing and always has the same near and far extents, then it would be inefficient to derive an entire new Camera node just to compute near and far values redundantly in every cull traversal. Unless I'm missing something here, why not just disable auto compute for the skydome camera and set the near and far planes explicitly? Then use a separate camera to render the rest of the scene, with auto compute enabled? Paul Martz Skew Matrix Software LLC http://www.skew-matrix.com <http://www.skew-matrix.com/> +1 303 859 9466
_____ From: osg-users-boun...@lists.openscenegraph.org [mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of David Spilling Sent: Tuesday, April 21, 2009 2:30 PM To: OpenSceneGraph Users Subject: Re: [osg-users] Geometry considered in near+far plane autocomputation J-S (and others), You could look at doing this is the same way the depth partition node does it, which is what I do: I use a class based on an OSG camera with an overriden traverse method, that forces the projection matrix to a particular z near and z far. Oh, and the camera has setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR) in its constructor. The skydome is then a child of this camera. You then set the z near and z far to be whatever you want (i.e. enveloping your skydome radius). I typically have a skydome with a radius of 1 void CExtentsCamera::traverse(osg::NodeVisitor &nv) { // If the scene hasn't been defined (i.e. we have no children at all) then don't do anything if(_children.size() == 0) return; // If the visitor is not a cull visitor, then we are not interested in intercepting it, so pass it directly onto the scene. osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv); if(!cv) { Camera::traverse(nv); return; } // Get a reference to the Cull Visitor's projection matrix osg::Matrix* projection = cv->getProjectionMatrix(); // NB : This might be possible to simplify and hence optimise (haven't yet checked) double a = (*projection)(2,2); double b = (*projection)(3,2); double c = (*projection)(2,3); double d = (*projection)(3,3); double trans_near = (-_zNear*a + b) / (-_zNear*c + d); double trans_far = ( -_zFar*a + b) / ( -_zFar*c + d); double ratio = fabs(2.0/(trans_near - trans_far)); double center = -0.5*(trans_near + trans_far); // Set the projection matrix projection->postMult(osg::Matrixd( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, ratio, 0.0, 0.0, 0.0, center*ratio, 1.0)); Camera::traverse(nv); } Probably a better way of doing it, but it works fine for me. I also do this on the "camera"'s stateset { osg::Depth* depth = new osg::Depth; depth->setFunction(osg::Depth::LEQUAL); depth->setRange(1.0,1.0); stateSet->setAttributeAndModes(depth,osg::StateAttribute::ON ); } so that you can render the sky last, and any expensive pixel shaders don't get unnecessarily run. Hope that helps, David
_______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org