forgot the attachment...

J.P. Delport wrote:
Hi,

J.P. Delport wrote:
Hi,

Jean-Sébastien Guay wrote:
Hi Ulrich,

Warning:: Picked up error in TriangleIntersect
(-1.81147 0.476811 -0.118829, -1.78078 0.471588 -0.0661082, -1.79068
0.886959 -0.0813922)
(1.#QNAN, 1.#QNAN, 1.#QNAN)
Warning:: Picked up error in TriangleIntersect
(-1.79068 0.886959 -0.0813922, -1.78078 0.471588 -0.0661082, -1.78498

This won't help you directly, but as a first step in identifying the source of the problem, the one time I've seen this error is when some objects were moved too far from the origin (to DBL_MAX in this case...). The LineSegmentIntersector at that time used floats, so when DBL_MAX was truncated to a float, it gave QNAN as above, and I got similar messages. And, as you describe, the messages would be printed so often that the application slowed to a crawl.

You could scrutinize the placement of objects which you're picking. If there are any objects which might move very far away, or any object you don't want to pick against actually, use nodemasks to prevent the IntersectionVisitor from visiting them.

Then again, your problem might be caused by something completely different. It's pretty much a shot in the dark... If you have access to the OSG sources and a debug OSG binary, place a breakpoint where the error message is printed, then run the simulation and try to reproduce the problem. When it breaks, it might at least tell you which node was being tested for intersection, and in which circumstances.

Hope this helps,

A colleague of mine encountered something similar, it was caused in an intersector by converting small doubles to floats which then became 0's.

I've asked him for the details and will post asap.


Two things you could try.

1) Attached is my colleague's modified IntersectVisitor.cpp, there is a check for the size of TriangleIntersect.

2) You could try make the "struct TriangleIntersect" in IntersectVisitor.cpp use Vec3d instead of Vec3.

Let us know if either works.

regards
jp



--
This message is subject to the CSIR's copyright terms and conditions, e-mail legal notice, and implemented Open Document Format (ODF) standard. The full disclaimer details can be found at http://www.csir.co.za/disclaimer.html.

This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean. MailScanner thanks Transtec Computers for their support.

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 
 *
 * This library is open source and may be redistributed and/or modified under  
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * OpenSceneGraph Public License for more details.
*/
#include <osgUtil/IntersectVisitor>
#include <osg/Transform>
#include <osg/Geode>
#include <osg/LOD>
#include <osg/Billboard>
#include <osg/Notify>
#include <osg/TriangleFunctor>
#include <osg/Geometry>
#include <osg/Projection>
#include <osg/Camera>
#include <osg/io_utils>

#include <float.h>
#include <algorithm>
#include <map>

using namespace osg;
using namespace osgUtil;



Hit::Hit()
{
}


Hit::Hit(const Hit& hit)
{
    // copy data across.
    _ratio = hit._ratio;
    _originalLineSegment = hit._originalLineSegment;
    _localLineSegment = hit._localLineSegment;
    _nodePath = hit._nodePath;
    _geode = hit._geode;
    _drawable = hit._drawable;
    _matrix = hit._matrix;
    _inverse = hit._inverse;

    _vecIndexList = hit._vecIndexList;
    _primitiveIndex = hit._primitiveIndex;
    _intersectPoint = hit._intersectPoint;
    _intersectNormal = hit._intersectNormal;
}


Hit::~Hit()
{
}


Hit& Hit::operator = (const Hit& hit)
{
    if (&hit==this) return *this;

    _matrix = hit._matrix;
    _inverse = hit._inverse;
    _originalLineSegment = hit._originalLineSegment;
    _localLineSegment = hit._localLineSegment;

    // copy data across.
    _ratio = hit._ratio;
    _nodePath = hit._nodePath;
    _geode = hit._geode;
    _drawable = hit._drawable;

    _vecIndexList = hit._vecIndexList;
    _primitiveIndex = hit._primitiveIndex;
    _intersectPoint = hit._intersectPoint;
    _intersectNormal = hit._intersectNormal;

    return *this;
}

const osg::Vec3 Hit::getWorldIntersectNormal() const
{
    if (_inverse.valid()) 
    {
        osg::Vec3 norm = osg::Matrix::transform3x3(*_inverse,_intersectNormal); 
        norm.normalize();
        return norm;
    }
    else return _intersectNormal;
}



IntersectVisitor::IntersectState::IntersectState()
{
    _segmentMaskStack.push_back(0xffffffff);
}


IntersectVisitor::IntersectState::~IntersectState()
{
}


bool IntersectVisitor::IntersectState::isCulled(const BoundingSphere& bs,LineSegmentMask& segMaskOut)
{
    bool hit = false;
    LineSegmentMask mask = 0x00000001;
    segMaskOut = 0x00000000;
    LineSegmentMask segMaskIn = _segmentMaskStack.back();
    for(IntersectState::LineSegmentList::iterator sitr=_segList.begin();
        sitr!=_segList.end();
        ++sitr)
    {
        if ((segMaskIn & mask) && (sitr->second)->intersect(bs))
        {
            segMaskOut = segMaskOut| mask;
            hit = true;
        }
        mask = mask << 1;
    }
    return !hit;
}

bool IntersectVisitor::IntersectState::isCulled(const BoundingBox& bb,LineSegmentMask& segMaskOut)
{
    bool hit = false;
    LineSegmentMask mask = 0x00000001;
    segMaskOut = 0x00000000;
    LineSegmentMask segMaskIn = _segmentMaskStack.back();
    for(IntersectState::LineSegmentList::iterator sitr=_segList.begin();
        sitr!=_segList.end();
        ++sitr)
    {
        if ((segMaskIn & mask) && (sitr->second)->intersect(bb))
        {
            segMaskOut = segMaskOut| mask;
            hit = true;
        }
        mask = mask << 1;
    }
    return !hit;
}

void IntersectVisitor::IntersectState::addLineSegment(osg::LineSegment* seg)
{
    // create a new segment transformed to local coordintes.
    LineSegment* ns = new LineSegment;

    if (_model_inverse.valid()) 
    {
        if (_view_inverse.valid())
        {
            osg::Matrix matrix = (*(_view_inverse)) * (*(_model_inverse));
            ns->mult(*seg,matrix);
        }
        else
        { 
            ns->mult(*seg,*(_model_inverse));
        }
    }
    else if (_view_inverse.valid())
    {
        ns->mult(*seg,*(_view_inverse));
    }
    else
    {
        *ns = *seg;
    }
    
    _segList.push_back(LineSegmentPair(seg,ns));
}


IntersectVisitor::IntersectVisitor()
{

    // override the default node visitor mode.
    setTraversalMode(NodeVisitor::TRAVERSE_ACTIVE_CHILDREN);
    
    // Initialize eyepoint to 0,0,0
    setEyePoint(Vec3(0.0f,0.0f,0.0f));

    setLODSelectionMode(USE_HIGHEST_LEVEL_OF_DETAIL); // original IntersectVisitor behavior
    //setLODSelectionMode(USE_SEGMENT_START_POINT_AS_EYE_POINT_FOR_LOD_LEVEL_SELECTION);

    reset();
}


IntersectVisitor::~IntersectVisitor()
{
}


void IntersectVisitor::reset()
{
    _intersectStateStack.clear();

    // create a empty IntersectState on the the intersectStateStack.
    _intersectStateStack.push_back(new IntersectState);

    _segHitList.clear();

}

float IntersectVisitor::getDistanceToEyePoint(const Vec3& pos, bool /*withLODScale*/) const
{
    if (_lodSelectionMode==USE_SEGMENT_START_POINT_AS_EYE_POINT_FOR_LOD_LEVEL_SELECTION)
    {
        // osg::notify(osg::NOTICE)<<"IntersectVisitor::getDistanceToEyePoint)"<<(pos-getEyePoint()).length()<<std::endl;
        // LODScale is not available to IntersectVisitor, so we ignore the withLODScale argument
        //if (withLODScale) return (pos-getEyePoint()).length()*getLODScale();
        //else return (pos-getEyePoint()).length();
        return (pos-getEyePoint()).length();
    }
    else
    {
        return 0.0f;
    }
}


bool IntersectVisitor::hits()
{
    for(LineSegmentHitListMap::iterator itr = _segHitList.begin();
        itr != _segHitList.end();
        ++itr)
    {
        if (!(itr->second.empty())) return true;
    }
    return false;
}

osg::Vec3 IntersectVisitor::getEyePoint() const
{
    const IntersectState* cis = _intersectStateStack.empty() ? 0 : _intersectStateStack.back().get();
    if (cis && (cis->_model_inverse.valid() || cis->_view_inverse.valid()))
    {
        
        osg::Vec3 eyePoint = _pseudoEyePoint;
        if (cis->_view_inverse.valid()) eyePoint = eyePoint * (*(cis->_view_inverse));
        if (cis->_model_inverse.valid()) eyePoint = eyePoint * (*(cis->_model_inverse));
        
        //osg::notify(osg::NOTICE)<<"IntersectVisitor::getEyePoint()"<<eyePoint<<std::endl;

        return eyePoint;
    }
    else
    {
        return _pseudoEyePoint;
    }
}

void IntersectVisitor::addLineSegment(LineSegment* seg)
{
    if (!seg) return;
    
    if (!seg->valid())
    {
        notify(WARN)<<"Warning: invalid line segment passed to IntersectVisitor::addLineSegment(..)"<<std::endl;
        notify(WARN)<<"         "<<seg->start()<<" "<<seg->end()<<" segment ignored.."<< std::endl;
        return;
    }
    
    IntersectState* cis = _intersectStateStack.back().get();
    
    if (cis->_segList.size()>=32)
    {
        notify(WARN)<<"Warning: excessive number of line segmenets passed to IntersectVisitor::addLineSegment(..), maximum permitted is 32 line segments."<<std::endl;
        notify(WARN)<<"         "<<seg->start()<<" "<<seg->end()<<" segment ignored.."<< std::endl;
        return;
    }

    setEyePoint(seg->start()); // set start of line segment to be pseudo EyePoint for billboarding and LOD purposes

    // first check to see if segment has already been added.
    for(IntersectState::LineSegmentList::iterator itr = cis->_segList.begin();
        itr != cis->_segList.end();
        ++itr)
    {
        if (itr->first == seg) return;
    }

    cis->addLineSegment(seg);

}


void IntersectVisitor::pushMatrix(RefMatrix* matrix, osg::Transform::ReferenceFrame rf)
{
    IntersectState* nis = new IntersectState;

    IntersectState* cis = _intersectStateStack.back().get();

    if (rf == osg::Transform::RELATIVE_RF)
    {
        // share the original view matrix
        nis->_view_matrix = cis->_view_matrix;
        nis->_view_inverse = cis->_view_inverse;
        
        // set up new model matrix
        nis->_model_matrix = matrix;
        if (cis->_model_matrix.valid())
        {
            nis->_model_matrix->postMult(*(cis->_model_matrix));
        }

        RefMatrix* inverse_world = new RefMatrix;
        inverse_world->invert(*(nis->_model_matrix));
        nis->_model_inverse = inverse_world;
    }
    else
    {
        // set a new view matrix
        nis->_view_matrix = matrix;

        RefMatrix* inverse_world = new RefMatrix;
        inverse_world->invert(*(nis->_view_matrix));
        nis->_view_inverse = inverse_world;

        // model matrix now blank.
        nis->_model_matrix = 0;
        nis->_model_inverse = 0;
    }


    IntersectState::LineSegmentMask segMaskIn = cis->_segmentMaskStack.back();
    IntersectState::LineSegmentMask mask = 0x00000001;
    for(IntersectState::LineSegmentList::iterator sitr=cis->_segList.begin();
        sitr!=cis->_segList.end();
        ++sitr)
    {
        if ((segMaskIn & mask))
        {
            nis->addLineSegment(sitr->first.get());
        }
        mask = mask << 1;
    }

    _intersectStateStack.push_back(nis);
}


void IntersectVisitor::popMatrix()
{
    if (!_intersectStateStack.empty())
    {
        _intersectStateStack.pop_back();
    }
}


bool IntersectVisitor::enterNode(Node& node)
{
    const BoundingSphere& bs = node.getBound();
    if (bs.valid() && node.isCullingActive())
    {
        IntersectState* cis = _intersectStateStack.back().get();
        IntersectState::LineSegmentMask sm=0xffffffff;
        if (cis->isCulled(bs,sm)) return false;
        cis->_segmentMaskStack.push_back(sm);
        return true;
    }
    else
    {
        IntersectState* cis = _intersectStateStack.back().get();
        if (!cis->_segmentMaskStack.empty()) 
            cis->_segmentMaskStack.push_back(cis->_segmentMaskStack.back());
        else
            cis->_segmentMaskStack.push_back(0xffffffff);
        
        return true;
    }
}


void IntersectVisitor::leaveNode()
{
    IntersectState* cis = _intersectStateStack.back().get();
    cis->_segmentMaskStack.pop_back();
}



void IntersectVisitor::apply(Node& node)
{
    if (!enterNode(node)) return;

    traverse(node);

    leaveNode();
}


struct TriangleHit
{
    TriangleHit(unsigned int index, const osg::Vec3& normal, float r1, const osg::Vec3* v1, float r2, const osg::Vec3* v2, float r3, const osg::Vec3* v3):
        _index(index),
        _normal(normal),
        _r1(r1),
        _v1(v1),        
        _r2(r2),
        _v2(v2),        
        _r3(r3),
        _v3(v3) {}

    unsigned int        _index;
    const osg::Vec3     _normal;
    float               _r1;
    const osg::Vec3*    _v1;        
    float               _r2;
    const osg::Vec3*    _v2;        
    float               _r3;
    const osg::Vec3*    _v3;        
};


struct TriangleIntersect
{
    osg::ref_ptr<LineSegment> _seg;

    Vec3    _s;
    Vec3    _d;
    float   _length;

    int _index;
    float _ratio;
    bool _hit;
    
    

    typedef std::multimap<float,TriangleHit> TriangleHitList;
    
    TriangleHitList _thl;

    TriangleIntersect()
    {
    }

    TriangleIntersect(const LineSegment& seg,float ratio=FLT_MAX)
    {
        set(seg,ratio);
    }
    
    void set(const LineSegment& seg,float ratio=FLT_MAX)
    {
        _seg=new LineSegment(seg);
        _hit=false;
        _index = 0;
        _ratio = ratio;

        _s = _seg->start();
        _d = _seg->end()-_seg->start();
        _length = _d.length();
        _d /= _length;
    }

    //   bool intersect(const Vec3& v1,const Vec3& v2,const Vec3& v3,float& r)
    inline void operator () (const Vec3& v1,const Vec3& v2,const Vec3& v3, bool treatVertexDataAsTemporary)
    {
        ++_index;

        if (v1==v2 || v2==v3 || v1==v3) return;

        Vec3 v12 = v2-v1;
        Vec3 n12 = v12^_d;
        float ds12 = (_s-v1)*n12;
        float d312 = (v3-v1)*n12;
        if (d312>=0.0f)
        {
            if (ds12<0.0f) return;
            if (ds12>d312) return;
        }
        else                     // d312 < 0
        {
            if (ds12>0.0f) return;
            if (ds12<d312) return;
        }

        Vec3 v23 = v3-v2;
        Vec3 n23 = v23^_d;
        float ds23 = (_s-v2)*n23;
        float d123 = (v1-v2)*n23;
        if (d123>=0.0f)
        {
            if (ds23<0.0f) return;
            if (ds23>d123) return;
        }
        else                     // d123 < 0
        {
            if (ds23>0.0f) return;
            if (ds23<d123) return;
        }

        Vec3 v31 = v1-v3;
        Vec3 n31 = v31^_d;
        float ds31 = (_s-v3)*n31;
        float d231 = (v2-v3)*n31;
        if (d231>=0.0f)
        {
            if (ds31<0.0f) return;
            if (ds31>d231) return;
        }
        else                     // d231 < 0
        {
            if (ds31>0.0f) return;
            if (ds31<d231) return;
        }
        

        float r3;
        if (ds12==0.0f) r3=0.0f;
        else if (d312!=0.0f) r3 = ds12/d312;
        else return; // the triangle and the line must be parallel intersection.
        
        float r1;
        if (ds23==0.0f) r1=0.0f;
        else if (d123!=0.0f) r1 = ds23/d123;
        else return; // the triangle and the line must be parallel intersection.
        
        float r2;
        if (ds31==0.0f) r2=0.0f;
        else if (d231!=0.0f) r2 = ds31/d231;
        else return; // the triangle and the line must be parallel intersection.

        float total_r = (r1+r2+r3);
        if (total_r!=1.0f)
        {
            if (total_r==0.0f) return; // the triangle and the line must be parallel intersection.
            float inv_total_r = 1.0f/total_r;
            r1 *= inv_total_r;
            r2 *= inv_total_r;
            r3 *= inv_total_r;
        }
        
        Vec3 in = v1*r1+v2*r2+v3*r3;
        if (!in.valid())
        {
            osg::notify(WARN)<<"Warning:: Picked up error in TriangleIntersect"<<std::endl;
            osg::notify(WARN)<<"   ("<<v1<<",\t"<<v2<<",\t"<<v3<<")"<<std::endl;
            osg::notify(WARN)<<"   ("<<r1<<",\t"<<r2<<",\t"<<r3<<")"<<std::endl;
            return;
        }

        float d = (in-_s)*_d;

        if (d<0.0f) return;
        if (d>_length) return;

        osg::Vec3 normal = v12^v23;
        normal.normalize();

        float r = d/_length;

        
        if (treatVertexDataAsTemporary)
        {
            _thl.insert(std::pair<const float,TriangleHit>(r,TriangleHit(_index-1,normal,r1,0,r2,0,r3,0)));
        }
        else
        {
            _thl.insert(std::pair<const float,TriangleHit>(r,TriangleHit(_index-1,normal,r1,&v1,r2,&v2,r3,&v3)));
        }
        _hit = true;

    }

};

bool IntersectVisitor::intersect(Drawable& drawable)
{
    bool hitFlag = false;

    IntersectState* cis = _intersectStateStack.back().get();

    const BoundingBox& bb = drawable.getBound();

    for(IntersectState::LineSegmentList::iterator sitr=cis->_segList.begin();
        sitr!=cis->_segList.end();
        ++sitr)
    {
        if (sitr->second->intersect(bb))
        {
            TriangleFunctor<TriangleIntersect> ti;
            ti.set(*sitr->second);

			if ((ti._d.valid())&&(ti._length>0.00000000001))
			{
				drawable.accept(ti);
				if (ti._hit)
				{
	            
					osg::Geometry* geometry = drawable.asGeometry();
	                

					for(TriangleIntersect::TriangleHitList::iterator thitr=ti._thl.begin();
						thitr!=ti._thl.end();
						++thitr)
					{
	                
						Hit hit;
						hit._nodePath = _nodePath;
						hit._matrix = cis->_model_matrix;
						hit._inverse = cis->_model_inverse;
						hit._drawable = &drawable;
						if (_nodePath.empty()) hit._geode = NULL;
						else hit._geode = dynamic_cast<Geode*>(_nodePath.back());

						TriangleHit& triHit = thitr->second;
	                    
						hit._ratio = thitr->first;
						hit._primitiveIndex = triHit._index;
						hit._originalLineSegment = sitr->first;
						hit._localLineSegment = sitr->second;

						hit._intersectPoint = sitr->second->start()*(1.0f-hit._ratio)+
							sitr->second->end()*hit._ratio;

						hit._intersectNormal = triHit._normal;
	                    
						if (geometry)
						{
							osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
							if (vertices)
							{
								osg::Vec3* first = &(vertices->front());
								if (triHit._v1) hit._vecIndexList.push_back(triHit._v1-first);
								if (triHit._v2) hit._vecIndexList.push_back(triHit._v2-first);
								if (triHit._v3) hit._vecIndexList.push_back(triHit._v3-first);
							}
						}
	                    

						_segHitList[sitr->first.get()].push_back(hit);

						std::sort(_segHitList[sitr->first.get()].begin(),_segHitList[sitr->first.get()].end());

						hitFlag = true;

					}
				}
			} else
			{
				int breakpoint=0;
			}
        }
    }

    return hitFlag;

}

void IntersectVisitor::apply(Geode& geode)
{
    if (!enterNode(geode)) return;

    for(unsigned int i = 0; i < geode.getNumDrawables(); i++ )
    {
        intersect(*geode.getDrawable(i));
    }
    
    leaveNode();
}


void IntersectVisitor::apply(Billboard& node)
{
    if (!enterNode(node)) return;

    // IntersectVisitor doesn't have getEyeLocal(), can we use NodeVisitor::getEyePoint()?
    const Vec3& eye_local = getEyePoint();

    for(unsigned int i = 0; i < node.getNumDrawables(); i++ )
    {
        const Vec3& pos = node.getPosition(i);
        osg::ref_ptr<RefMatrix> billboard_matrix = new RefMatrix;
        node.computeMatrix(*billboard_matrix,eye_local,pos);

        pushMatrix(billboard_matrix.get(), osg::Transform::RELATIVE_RF);

        intersect(*node.getDrawable(i));

        popMatrix();

    }

    leaveNode();
}


void IntersectVisitor::apply(Group& node)
{
    if (!enterNode(node)) return;

    traverse(node);

    leaveNode();
}


void IntersectVisitor::apply(Transform& node)
{
    if (!enterNode(node)) return;

    osg::ref_ptr<RefMatrix> matrix = new RefMatrix;
    node.computeLocalToWorldMatrix(*matrix,this);

    pushMatrix(matrix.get(), node.getReferenceFrame());

    traverse(node);

    popMatrix();

    leaveNode();
}


void IntersectVisitor::apply(Switch& node)
{
    apply((Group&)node);
}


void IntersectVisitor::apply(LOD& node)
{
    apply((Group&)node);
}

PickVisitor::PickVisitor(const osg::Viewport* viewport, const osg::Matrixd& proj, const osg::Matrixd& view, float mx, float my):
    _mx(mx),
    _my(my),
    _lastViewport(viewport),
    _lastProjectionMatrix(proj),
    _lastViewMatrix(view)
{
    setLODSelectionMode(USE_SEGMENT_START_POINT_AS_EYE_POINT_FOR_LOD_LEVEL_SELECTION);

    if (viewport && 
        mx >= static_cast<float>(viewport->x()) && 
        my >= static_cast<float>(viewport->y()) &&
        mx < static_cast<float>(viewport->x()+viewport->width()) &&
        my < static_cast<float>(viewport->y()+viewport->height()))
    {

        // mouse pointer intersect viewport so we can proceed to set up a line segment
        osg::Matrix MVPW = proj * viewport->computeWindowMatrix();
        osg::Matrixd inverseMVPW;
        inverseMVPW.invert(MVPW);

        osg::Vec3 nearPoint = osg::Vec3(mx,my,0.0f) * inverseMVPW;
        osg::Vec3 farPoint = osg::Vec3(mx,my,1.0f) * inverseMVPW;
        osg::LineSegment* lineSegment = new osg::LineSegment;
        lineSegment->set(nearPoint, farPoint);

        IntersectState* cis = !_intersectStateStack.empty() ? _intersectStateStack.back().get() : 0;
        if (cis)
        {
            cis->_view_matrix = new RefMatrix(view);
            cis->_view_inverse = new RefMatrix;
            cis->_view_inverse->invert(*(cis->_view_matrix));

            cis->_model_matrix = 0;
            cis->_model_inverse = 0;
        }
        else
        {
            osg::notify(osg::NOTICE)<<"Warning: PickVisitor not set up correctly, picking errors likely"<<std::endl;
        }
        

        addLineSegment(lineSegment);
    }
}

void PickVisitor::runNestedPickVisitor(osg::Node& node, const osg::Viewport* viewport, const osg::Matrix& proj, const osg::Matrix& view, float mx, float my)
{

    PickVisitor newPickVisitor( viewport, proj, view, mx, my );
    newPickVisitor.setTraversalMask(getTraversalMask());

    newPickVisitor.getNodePath() = getNodePath();

    // the new pickvisitor over the nodes children.
    node.traverse( newPickVisitor );

    for(LineSegmentHitListMap::iterator itr = newPickVisitor._segHitList.begin();
        itr != newPickVisitor._segHitList.end();
        ++itr)
    {
        _segHitList.insert(*itr);
    }
}

void PickVisitor::apply(osg::Projection& projection)
{
    runNestedPickVisitor( projection, 
                          _lastViewport.get(), 
                          projection.getMatrix(),
                          _lastViewMatrix,
                          _mx, _my );
}

void PickVisitor::apply(osg::Camera& camera)
{
    if (!camera.isRenderToTextureCamera())
    {
        if (camera.getReferenceFrame()==osg::Camera::RELATIVE_RF)
        {
            if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY)
            {
                runNestedPickVisitor( camera,
                                      camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
                                      _lastProjectionMatrix * camera.getProjectionMatrix(), 
                                      _lastViewMatrix * camera.getViewMatrix(),
                                      _mx, _my );
            }
            else // PRE_MULTIPLY
            {
                runNestedPickVisitor( camera,
                                      camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
                                      camera.getProjectionMatrix() * _lastProjectionMatrix, 
                                      camera.getViewMatrix() * _lastViewMatrix,
                                      _mx, _my );
            }
        }
        else
        {
            runNestedPickVisitor( camera,
                                  camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
                                  camera.getProjectionMatrix(), 
                                  camera.getViewMatrix(),
                                  _mx, _my );
        }
    }
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to