I've attached a small demo app that illustrates an issue I've
discovered (known?) with AutoTransform nodes and small feature
culling. Briefly summarized, if I add a custom AutoTransform node (see
code for trivial example) to the scenegraph just under the root node
everything seems fine, with or without small feature culling enabled.
However, if I add this AutoTransform node as a member of a osg::Group
and then add the group to the scenegraph then this node's accept
function no longer is called after the first traversal if small
feature culling is enabled. However, if I disable small feature
culling all is well.

Is this a bug or am I doing something wrong?
#include <iostream>
#include <direct.h>

#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/Geode>
#include <osg/Geometry>
#include <osgGA/TrackballManipulator>
#include <osg/ShapeDrawable>
#include <osg/AutoTransform>
#include <osg/MatrixTransform>


static osg::Vec3d cairoPos;

#pragma message(" ")
#pragma message("!!!! Please define your own earth model !!!!")
#pragma message(" ")
static std::string earthFileName = "http://somewhere.org/earth.ive";;

class CustomeAutoTransform : public osg::AutoTransform
{
public:

  CustomeAutoTransform()
  {
    _maxScale = 2500 * 1000;
  }

  void CustomeAutoTransform::accept(osg::NodeVisitor& nv)
  {
    if(nv.getVisitorType() == osg::NodeVisitor::NODE_VISITOR)
    {
      osg::AutoTransform::accept(nv);
      return;
    };

    osg::Vec3d pos = getPosition();
    osg::Vec3 eye_cp = nv.getEyePoint() - pos;

    pos.normalize();
    eye_cp.normalize();        

    double deviation = (eye_cp * pos);

    //crude scaling
    double scaleCoefficient = osg::minimum(1.0, osg::maximum(0.0, deviation));

    const double epsilon = 0.0001;
    setMaximumScale(__max(_maxScale * scaleCoefficient, epsilon));


    osg::AutoTransform::accept(nv);
  }

  double _maxScale;

};

int main(int argc, char** argv)
{
  //calculate Cairo, Egypt position in ECEF
  {
    osg::EllipsoidModel em;
    osg::Vec3d pos(osg::DegreesToRadians(30.08), osg::DegreesToRadians(31.25), 
0);
    em.convertLatLongHeightToXYZ(pos[0], pos[1], pos[2], pos[0], pos[1], 
pos[2]);
    cairoPos = pos;
  }

  osgViewer::Viewer viewer;
  viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
  viewer.addEventHandler( new osgViewer::WindowSizeHandler );
  viewer.addEventHandler( new osgViewer::StatsHandler );
  viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);
  viewer.setReleaseContextAtEndOfFrameHint(false);

  //comment this line out to demonstrate the bug
  //viewer.getCamera()->setCullingMode(viewer.getCamera()->getCullingMode() 
&~osg::CullSettings::SMALL_FEATURE_CULLING);

  osg::ref_ptr<osg::Group> root = new osg::Group;

  {
    osg::ref_ptr<osg::Node> earth = osgDB::readNodeFile(earthFileName); 
    earth->getOrCreateStateSet()->setMode(GL_LIGHTING, 
osg::StateAttribute::OFF);
    root->addChild(earth.get());
  }

  viewer.setCameraManipulator(new osgGA::TrackballManipulator());

  {
    osg::ref_ptr<osg::ShapeDrawable> sphere = new osg::ShapeDrawable( new 
osg::Sphere( cairoPos, 5000 ) ) ;
    sphere->setColor(osg::Vec4(1., 0., 0., 1.));
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    geode->addDrawable(sphere.get());
    root->addChild(geode.get());
  }

  //simple autotransform
  {
    osg::ref_ptr<osgText::Text> text = new osgText::Text;

    text->setFont("Arial.ttf");
    text->setCharacterSizeMode( 
osgText::TextBase::OBJECT_COORDS_WITH_MAXIMUM_SCREEN_SIZE_CAPPED_BY_FONT_HEIGHT 
);
    text->setCharacterSize(128);
    text->setFontResolution(128, 128);
    text->setColor(osg::Vec4(1,1,1,1));
    text->setText("Cairo");

    osgText::Text::BackdropType type = osgText::Text::OUTLINE;
    text->setBackdropType(type);
    text->setBackdropColor(osg::Vec4(0,0,0,1));

    text->setAlignment(osgText::TextBase::CENTER_CENTER);
    text->setAxisAlignment(osgText::TextBase::XY_PLANE);
    text->setPosition(osg::Vec3(0,75,0));

    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    geode->addDrawable(text.get());

    osg::ref_ptr<CustomeAutoTransform> at = new CustomeAutoTransform();
    at->setAutoScaleToScreen(true);
    at->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN);
    at->addChild(geode.get());
    at->setPosition(cairoPos);
    at->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
    at->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);

    osg::ref_ptr<osg::Group> group = new osg::Group();
    
    const bool demonstrateBug = true;
    if(demonstrateBug)
    {
      //the AutoTransform node will fail if and only if
      //small feature culling is enabled
      group->addChild(at.get());
      root->addChild(group.get());
    }
    else
    {
      //if we add the AutoTransform directly to the root node
      //then it makes no difference if small feature culling is
      //enabled or not, everything still works
      root->addChild(at.get());
    }
    
  }

  viewer.setSceneData( root.get() );
  viewer.realize();

  osg::Camera *_camera = viewer.getCamera();
  osgViewer::GraphicsWindow* window = 
dynamic_cast<osgViewer::GraphicsWindow*>(_camera->getGraphicsContext());
  window->setWindowRectangle(250,150,640,480);
  window->setWindowDecoration(true);
  
  while(viewer.done() == false)
  {
    viewer.frame();
  }

  return 0;
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to