Hi J-S,

Thanks for keeping this post going with what you've done.  I've been keeping an 
eye on it with keen interest.  I do have one question though out of curiosity 
... what dimensions (particularly the radius) did you use to generate the 
skydome?  I see that you use the radius to determine the far plane value, but 
didn't know what you used.  I'm assuming that it has to be great enough to 
still be viewed as being far field.

Thanks.

Chuck

> -----Original Message-----
> From: osg-users-boun...@lists.openscenegraph.org [mailto:osg-users-
> boun...@lists.openscenegraph.org] On Behalf Of Jean-Sébastien Guay
> Sent: Tuesday, April 28, 2009 10:14 AM
> To: OpenSceneGraph Users
> Subject: Re: [osg-users] Geometryconsidered in near+far plane auto
> computation
> 
> Hello Chris,
> 
> >>   I wonder if there were somehow a callback you could apply
> somewhere
> >> that would hork with
> >> the near/far clip, or if it's just easier to use multiple cameras at
> >> that point.
> >
> > Perhaps in a Drawable DrawCallback? Something like:
> 
> OK, I've finally got this to work well, without the need to add an
> extra
> camera. It's a classic two-pronged attack:
> 
> 1. Use a CullCallback that sets the compute near/far mode to off,
> traverses the skydome and resets it to the previous value.
> 2. Use a drawable DrawCallback on all the skydome's drawables that will
> calculate the maximum possible value the far plane would need to be at
> for the skydome to be visible from the current camera position, draws
> the drawable, and resets the old far plane after drawing.
> 
> One thing I found I needed to do is keep the same near plane value as
> was set before, otherwise the skydome seemed to move when the camera
> moved.
> 
> Here's the code I'm using:
> 
> struct DoNotIncludeInNearFarComputationCallback
>      : public osg::NodeCallback
> {
>      virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
>      {
>          osgUtil::CullVisitor *cv =
>              dynamic_cast< osgUtil::CullVisitor*>( nv );
> 
>          // Default value
>          osg::CullSettings::ComputeNearFarMode oldMode =
> 
> osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES;
> 
>          if( cv )
>          {
>              oldMode = cv->getComputeNearFarMode();
>              cv->setComputeNearFarMode(
>                  osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
>          }
> 
>          traverse(node, nv);
> 
>          if( cv )
>          {
>              cv->setComputeNearFarMode(oldMode);
>          }
>      }
> };
> 
> struct OverrideNearFarValuesCallback
>      : public osg::Drawable::DrawCallback
> {
>      OverrideNearFarValuesCallback(SkyDome* skyDome)
>          : m_skyDome(skyDome) {}
> 
>      virtual void drawImplementation(osg::RenderInfo& renderInfo,
>                                      const osg::Drawable* drawable)
> const
>      {
>          osg::Camera* currentCamera = renderInfo.getCurrentCamera();
>          if (currentCamera)
>          {
>              // Get the current camera position.
>              osg::Vec3 eye, center, up;
>              renderInfo.getCurrentCamera()->getViewMatrixAsLookAt(
>                  eye, center, up);
> 
>              // Get the max distance we need the far plane to be at,
>              // which is the distance between the eye and the skydome's
>              // center, plus the skydome's radius.
>              double distance = (m_skyDome->getCenter() - eye).length()
> +
>                                 m_skyDome->getRadius();
> 
>              // Save old values.
>              osg::ref_ptr<osg::RefMatrixd> oldProjectionMatrix =
>                  new osg::RefMatrix;
>              oldProjectionMatrix->set(
>                  renderInfo.getState()->getProjectionMatrix());
> 
>              // Get the individual values
>              double left, right, bottom, top, zNear, zFar;
>              oldProjectionMatrix->getFrustum(
>                  left, right, bottom, top, zNear, zFar);
> 
>              // Build a new projection matrix with a modified far plane
>              osg::ref_ptr<osg::RefMatrixd> projectionMatrix =
>                  new osg::RefMatrix;
>              projectionMatrix->makeFrustum(
>                  left, right, bottom, top, zNear, distance);
>              renderInfo.getState()->applyProjectionMatrix(
>                  projectionMatrix.get());
> 
>              // Draw the drawable
>              drawable->drawImplementation(renderInfo);
> 
>              // Reset the far plane to the old value.
>              renderInfo.getState()->applyProjectionMatrix(
>                  oldProjectionMatrix.get());
>          }
>          else
>          {
>              drawable->drawImplementation(renderInfo);
>          }
>      }
> 
>      SkyDome* m_skyDome;
> };
> 
> struct AddCallbackToDrawablesVisitor : public osg::NodeVisitor
> {
>      AddCallbackToDrawablesVisitor(SkyDome* skyDome)
>          : osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
>            m_skyDome(skyDome) {}
> 
>      virtual void apply(osg::Geode& node)
>      {
>          for (unsigned int i = 0; i < node.getNumDrawables(); i++)
>          {
>              node.getDrawable(i)->setDrawCallback(
>                  new OverrideNearFarValuesCallback(m_skyDome));
>              // Do not use display lists otherwise the callback will
> only
>              // be called once on initial compile.
>              node.getDrawable(i)->setUseDisplayList(false);
>          }
>      }
> 
>      SkyDome* m_skyDome;
> };
> 
> 
> Then when adding the dome to the scene I do these extra steps:
> 
>      // Setup rendering so that the skydome does not affect the
> automatic
>      // near/far plane calculation.
>      m_node->setCullCallback(
>          new DoNotIncludeInNearFarComputationCallback);
>      AddCallbackToDrawablesVisitor visitor(this);
>      m_node->accept(visitor);
> 
>      // Transparent bin is #10 by default so render just before
>      // transparent objects.
>      ss->setRenderBinDetails(9, "RenderBin");
>      ss->setAttributeAndModes(
>          new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0),
>          osg::StateAttribute::ON);
> 
> 
> I'm open to suggestions as to how to improve this, especially the
> DrawCallback (OverrideNearFarValuesCallback) which seems heavy to me
> (two new RefMatrix per drawable per frame...). But it works well and I
> like it better than the camera approach, no need to change anything
> else
> in the scene graph or viewer setup.
> 
> Hope this can help someone.
> 
> J-S
> --
> ______________________________________________________
> Jean-Sebastien Guay    jean-sebastien.g...@cm-labs.com
>                                 http://www.cm-labs.com/
>                          http://whitestar02.webhop.org/
> _______________________________________________
> osg-users mailing list
> osg-users@lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-
> openscenegraph.org
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
            • ... Jean-Sébastien Guay
            • ... Doug McCorkle
            • ... Chris 'Xenon' Hanson
            • ... David Spilling
            • ... Jean-Sébastien Guay
            • ... David Spilling
            • ... Jean-Sébastien Guay
            • ... Jean-Sébastien Guay
            • ... Jean-Sébastien Guay
            • ... Jean-Sébastien Guay
            • ... Cole, Charles E. (LARC-B702)[RAYTHEON TECHNICAL SERVICES COMPANY]
            • ... Jean-Sébastien Guay
            • ... Jean-Sébastien Guay
            • ... Cole, Charles E. (LARC-B702)[RAYTHEON TECHNICAL SERVICES COMPANY]
            • ... Jean-Sébastien Guay
            • ... Jean-Sébastien Guay
          • ... David Spilling
            • ... Paul Martz
  • Re: [osg... Jean-Sébastien Guay

Reply via email to