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