dmz::Boolean dmz::RenderPluginPickOSG::source_to_world ( const Int32 SourcePosX, const Int32 SourcePosY, Vector &worldPosition, Vector &normal, Handle &objectHandle) { Boolean result (False); if (_core && _view.valid () && _viewport.valid ()) { const float Height = _viewport->height (); osgUtil::LineSegmentIntersector::Intersections isect; if (_view->computeIntersections ( (float)SourcePosX, Height - (float)SourcePosY, isect, _isectMask)) { osgUtil::LineSegmentIntersector::Intersections::iterator it = isect.begin (); while (!result && (it != isect.end ())) { Boolean disabled (False); osg::NodePath path = it->nodePath; for (osg::NodePath::iterator node = path.begin (); (node != path.end ()) && !disabled; node++) { if (*node) { osg::Referenced *ref ((*node)->getUserData ()); if (ref) { RenderObjectDataOSG *data ( dynamic_cast<RenderObjectDataOSG *> (ref)); if (data) { if (!data->do_isect ()) { disabled = True; } else { objectHandle = data->get_handle (); } } } } } if (!disabled) { worldPosition = to_dmz_vector (it->getWorldIntersectPoint ()); normal = to_dmz_vector (it->getWorldIntersectNormal ()); result = True; } else { it++; } } } } return result; }
dmz::Boolean dmz::RenderModuleIsectOSG::do_isect ( const IsectParameters &Parameters, const IsectTestContainer &TestValues, IsectResultContainer &resultContainer) { if (_core) { osg::ref_ptr<osg::Group> scene = _core->get_isect (); // osg::ref_ptr<osg::Group> scene = _core->get_static_objects (); osg::BoundingSphere bs = scene->getBound(); std::vector<osg::LineSegment*> lsList;// = new osg::LineSegment[TestValues]; osgUtil::IntersectVisitor visitor; visitor.setTraversalMask (_isectMask); UInt32 testHandle; IsectTestTypeEnum testType; Vector vec1, vec2; std::vector<UInt32> handleArray; std::vector<Vector> sourceArray; TestValues.get_first_test (testHandle, testType, vec1, vec2); do { if (testType == IsectRayTest) { vec2 = (vec1 + (vec2 * (bs.radius () * 2))); } osg::LineSegment *ls = new osg::LineSegment; ls->set (to_osg_vector (vec1), to_osg_vector (vec2)); visitor.addLineSegment (ls); lsList.push_back (ls); handleArray.push_back (testHandle); sourceArray.push_back (vec1); } while (TestValues.get_next_test (testHandle, testType, vec1, vec2)); scene->accept (visitor); IsectTestResultTypeEnum param = Parameters.get_test_result_type (); bool closestPoint = (param == IsectClosestPoint); bool firstPoint = (param == IsectFirstPoint); if (closestPoint && !Parameters.get_calculate_distance ()) { firstPoint = true; closestPoint = false; } Boolean result (False); for (unsigned int ix = 0; ix < lsList.size () && !result; ix++) { osgUtil::IntersectVisitor::HitList resultHits; resultHits = visitor.getHitList (lsList[ix]); if (!resultHits.empty ()) { for (unsigned int jy = 0; jy < resultHits.size (); jy++) { Handle objHandle (0); osgUtil::Hit currentHit = resultHits[jy]; Boolean disabled (False); osg::CullFace *cf (0); osg::NodePath path = currentHit.getNodePath (); for ( osg::NodePath::iterator it = path.begin (); (it != path.end ()) && !disabled; it++) { osg::Node *node (*it); if (node) { osg::StateSet *sSet = (node->getStateSet ()); if (sSet) { osg::CullFace *cfTmp ( (osg::CullFace*)(sSet->getAttribute ( osg::StateAttribute::CULLFACE))); if (cfTmp) { cf = cfTmp; } } osg::Referenced *r (node->getUserData ()); if (r) { RenderObjectDataOSG *data ( dynamic_cast<RenderObjectDataOSG *> (r)); if (data) { if (!data->do_isect ()) { // Should never reach here now disabled = True; } else { objHandle = data->get_handle (); } } } } } if (!disabled) { Vector lsPoint = to_dmz_vector (currentHit.getWorldIntersectPoint ()); IsectResult lsResult; lsResult.set_isect_test_id (handleArray[ix]); lsResult.set_point (lsPoint); if (Parameters.get_calculate_object_handle ()) { lsResult.set_object_handle (objHandle); } if (Parameters.get_calculate_normal ()) { lsResult.set_normal ( to_dmz_vector (currentHit.getWorldIntersectNormal ())); } if (Parameters.get_calculate_distance ()) { lsResult.set_distance ((lsPoint - sourceArray[ix]).magnitude ()); } if (Parameters.get_calculate_cull_mode ()) { UInt32 cullMask = 0; if (cf) { if (cf->getMode () == osg::CullFace::FRONT || cf->getMode () == osg::CullFace::FRONT_AND_BACK) { cullMask |= IsectPolygonFrontCulledMask; } if (cf->getMode () == osg::CullFace::BACK || cf->getMode () == osg::CullFace::FRONT_AND_BACK) { cullMask |= IsectPolygonBackCulledMask; } } else { cullMask |= IsectPolygonBackCulledMask; } lsResult.set_cull_mode (cullMask); } if (Parameters.get_calculate_object_handle ()) { osg::Geode *hitObject = currentHit.getGeode (); } resultContainer.add_result (lsResult); if (firstPoint) { result = true; } } } } } if (closestPoint && resultContainer.get_result_count () > 1) { IsectResult current; resultContainer.get_first (current); IsectResult closest (current); double closestDist; current.get_distance (closestDist); while (resultContainer.get_next (current)) { double testDist; if (current.get_distance (testDist)) { if (testDist < closestDist) { closest = current; } } } IsectResultContainer closestContainer; closestContainer.add_result (closest); resultContainer = closestContainer; } } return resultContainer.get_result_count () > 0; }