From 378dc18f1c99f2a1933bc3e824199603dd10d186 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 22 Dec 2005 14:06:33 +0000 Subject: [PATCH] Seperated out the view and model matrices in IntersectVisitor to allow handling of world coordinates better when using PickVisitor. --- include/osgUtil/IntersectVisitor | 11 ++-- src/osgUtil/IntersectVisitor.cpp | 102 +++++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 33 deletions(-) diff --git a/include/osgUtil/IntersectVisitor b/include/osgUtil/IntersectVisitor index 8a45db9bc..1b25bc36c 100644 --- a/include/osgUtil/IntersectVisitor +++ b/include/osgUtil/IntersectVisitor @@ -160,8 +160,10 @@ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor IntersectState(); - osg::ref_ptr _matrix; - osg::ref_ptr _inverse; + osg::ref_ptr _view_matrix; + osg::ref_ptr _view_inverse; + osg::ref_ptr _model_matrix; + osg::ref_ptr _model_inverse; typedef std::pair,osg::ref_ptr > LineSegmentPair; typedef std::vector< LineSegmentPair > LineSegmentList; @@ -174,10 +176,7 @@ class OSGUTIL_EXPORT IntersectVisitor : public osg::NodeVisitor bool isCulled(const osg::BoundingSphere& bs,LineSegmentMask& segMaskOut); bool isCulled(const osg::BoundingBox& bb,LineSegmentMask& segMaskOut); - void addLineSegmentPair(osg::LineSegment* first,osg::LineSegment* second) - { - _segList.push_back(LineSegmentPair(first,second)); - } + void addLineSegment(osg::LineSegment* seg); protected: diff --git a/src/osgUtil/IntersectVisitor.cpp b/src/osgUtil/IntersectVisitor.cpp index a3dbf251e..835dcf7e4 100644 --- a/src/osgUtil/IntersectVisitor.cpp +++ b/src/osgUtil/IntersectVisitor.cpp @@ -127,7 +127,6 @@ bool IntersectVisitor::IntersectState::isCulled(const BoundingSphere& bs,LineSeg return !hit; } - bool IntersectVisitor::IntersectState::isCulled(const BoundingBox& bb,LineSegmentMask& segMaskOut) { bool hit = false; @@ -148,6 +147,36 @@ bool IntersectVisitor::IntersectState::isCulled(const BoundingBox& bb,LineSegmen 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() { @@ -211,10 +240,16 @@ bool IntersectVisitor::hits() osg::Vec3 IntersectVisitor::getEyePoint() const { const IntersectState* cis = _intersectStateStack.empty() ? 0 : _intersectStateStack.back().get(); - if (cis && cis->_inverse.valid()) + if (cis && (cis->_model_inverse.valid() || cis->_view_inverse.valid())) { - //osg::notify(osg::NOTICE)<<"IntersectVisitor::getEyePoint()"<<_pseudoEyePoint * (*(cis->_inverse))<_inverse)); + + 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()"<first == seg) return; } - // create a new segment transformed to local coordintes. - LineSegment* ns = new LineSegment; - - if (cis->_inverse.valid()) ns->mult(*seg,*(cis->_inverse)); - else *ns = *seg; - - cis->addLineSegmentPair(seg,ns); + cis->addLineSegment(seg); } @@ -268,20 +297,38 @@ void IntersectVisitor::pushMatrix(RefMatrix* matrix, osg::Transform::ReferenceFr IntersectState* nis = new IntersectState; IntersectState* cis = _intersectStateStack.back().get(); - if (rf == osg::Transform::RELATIVE_RF && - cis->_matrix.valid()) + + if (rf == osg::Transform::RELATIVE_RF) { - nis->_matrix = matrix; - nis->_matrix->postMult(*(cis->_matrix)); + // 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 { - nis->_matrix = matrix; + // 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; } - RefMatrix* inverse_world = new RefMatrix; - inverse_world->invert(*(nis->_matrix)); - nis->_inverse = inverse_world; IntersectState::LineSegmentMask segMaskIn = cis->_segmentMaskStack.back(); IntersectState::LineSegmentMask mask = 0x00000001; @@ -291,9 +338,7 @@ void IntersectVisitor::pushMatrix(RefMatrix* matrix, osg::Transform::ReferenceFr { if ((segMaskIn & mask)) { - LineSegment* seg = new LineSegment; - seg->mult(*(sitr->first),*inverse_world); - nis->addLineSegmentPair(sitr->first.get(),seg); + nis->addLineSegment(sitr->first.get()); } mask = mask << 1; } @@ -559,8 +604,8 @@ bool IntersectVisitor::intersect(Drawable& drawable) Hit hit; hit._nodePath = _nodePath; - hit._matrix = cis->_matrix; - hit._inverse = cis->_inverse; + hit._matrix = cis->_model_matrix; + hit._inverse = cis->_model_inverse; hit._drawable = &drawable; if (_nodePath.empty()) hit._geode = NULL; else hit._geode = dynamic_cast(_nodePath.back()); @@ -710,9 +755,12 @@ PickVisitor::PickVisitor(const osg::Viewport* viewport, const osg::Matrixd& proj IntersectState* cis = !_intersectStateStack.empty() ? _intersectStateStack.back().get() : 0; if (cis) { - cis->_matrix = new RefMatrix(view); - cis->_inverse = new RefMatrix; - cis->_inverse->invert(*(cis->_matrix)); + 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 {