Hi,
I have been trying to compute intersection with the ground in an Earth-Centered coordinates frame lastly. Using Intersect Visitor I had bad results (imprecise), due to float computations according to Robert Osfield and some of you fellow members of the OpenSceneGraph community.
It happens that my DEM is computed with osgDEM --celestiocentric, so at runtime it is already in CelestrioCentric (read Earth-Centered) coordinates.
So I wondered why, even if it had some imprecisions compared to the real position of the ground, the intersect visitor couldn't give me a precise intersection with the ground from an initial point only about a hundreds of meters above the ground THAT WE SEE (this initial point corresponds to the initial position of the 'flying' tank that I try to put on ground).
Then, I tried the DRIVE_MANIPULATOR above my database, which, when you activate it, places the camera on the ground. And it works pretty precisely!
So I moved to try using the code of DRIVE MANIPULATOR to compute my tank's ground position.
I admit that I do not understand everything in that code, but I thought that I could get the essentials out of it. The thing is that I see it uses the Intersect Visitor too! So now, I wonder what is the tiny thing in that code that makes IntersectVisitor work with PRECISION on MY database??
This is the code that I made, inspired from DRIVE MANIPULATOR, not working better than my initial use of IntersectVisitor though :
(I only reused the code to compute intersection from an above point..)
float _modelScale=0.01f;
float _height=0.0f;
osg::Node* _node=_e->getNode();
const osg::BoundingSphere& boundingSphere=_node->getBound();
osg::Vec3d ep = boundingSphere._center;
osg::Vec3d bp = ep;
//osg::CoordinateFrame cf=getCoordinateFrame(ep);
ep -= osg::Vec3(0.0f,0.0f,1.0f)* _modelScale*0.0001;
bp -= osg::Vec3(0.0f,0.0f,1.0f)* _modelScale;
// check to see if any obstruction in front.
osgUtil::IntersectVisitor iv;
// iv.setTraversalMask(this->getIntersectTraversalMask());
bool positionSet = false;
osg::ref_ptr<osg::LineSegment> segDown = new osg::LineSegment;
segDown->set(ep,bp);
iv.addLineSegment(segDown.get());
_node->accept(iv);
if (iv.hits())
{
osgUtil::IntersectVisitor::HitList& hitList = iv.getHitList(segDown.get());
if (!hitList.empty())
{
std::cout << "Hit terrain ok"<< std::endl;
osg::Vec3d ip = hitList.front().getWorldIntersectPoint();
osg::Vec3d np = hitList.front().getWorldIntersectNormal();
osg::Vec3d uv;
if (np * osg::Vec3(0.0f,0.0f,1.0f)>0.0) uv = np;
else uv = -np;
ep = ip;
ep += osg::Vec3(0.0f,0.0f,1.0f)*_height;
osg::Vec3 lv = uv^osg::Vec3d(1.0,0.0,0.0);
_e->setPosition(ep+lv);
positionSet = true;
}
}
If anyone can give me some lights,...
David
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/