//! intersection test Action::ResultE DVRVolume::intersect(Action * action) { FDEBUG(("DVRVolume::intersect\n")); IntersectAction *ia = dynamic_cast<IntersectAction*>(action); #ifndef OSG_2_PREP const DynamicVolume &vol = ia->getActNode()->getVolume(); #else const BoxVolume &vol = ia->getActNode()->getVolume(); #endif if(vol.isValid() && !vol.intersect(ia->getLine())) { return Action::Skip; //bv missed -> can not hit children } //!! FIXME: simulate hit when bounding volume is hit Real32 t, v; Vec3f norm; if(vol.intersect(ia->getLine(), t, v)) ia->setHit(t, ia->getActNode(), 0, norm); return Action::Continue; }
/*! The IntersectAction callback for Geometry. It computes if the ray used in the IntersectAction \a action hits this object and if that is the case, which triangle is hit. \param[in] action IntersectAction performing the intersect test. \return Action result code, \see OSG::Action. \note This method is registered with the IntersectAction and automatically called from there, you probably never have to call it manually. */ Action::ResultE Geometry::intersect(Action * action) { IntersectAction *ia = dynamic_cast<IntersectAction*>(action); ia->getActNode()->updateVolume(); const BoxVolume &bv = ia->getActNode()->getVolume(); if(bv.isValid() && !bv.intersect(ia->getLine())) { return Action::Skip; //bv missed -> can not hit children } TriangleIterator it = this->beginTriangles(); TriangleIterator end = this->endTriangles (); Real32 t; Vec3f norm; Line ia_line(ia->getLine()); for(; it != end; ++it) { if(ia_line.intersect(it.getPosition(0), it.getPosition(1), it.getPosition(2), t, &norm)) { ia->setHit(t, ia->getActNode(), it.getIndex(), norm, -1); } } // If we need to test lines, iterate over lines and test for // lines that are within width distance from the line if(ia->getTestLines()) { Real32 range_sq = ia->getTestLineWidth(); range_sq = range_sq * range_sq; LineIterator it = this->beginLines(); LineIterator end = this->endLines (); Pnt3f pt1, pt2; OSG::Vec3f norm; // Find closest points and if they are within the range, then add a hit for(; it != end; ++it) { Line cur_line(it.getPosition(0), it.getPosition(1)); ia_line.getClosestPoints(cur_line, pt1, pt2); Real32 dist_sq( pt1.dist2(pt2) ); if (dist_sq <= range_sq) { t = ia_line.getPosition().dist(pt1); ia->setHit(t, ia->getActNode(), -1, norm, it.getIndex()); } } } return Action::Continue; }
ActionBase::ResultE Joint::intersectEnter(Action *action) { // Use parent class for trivial reject if(Inherited::intersect(action) == Action::Skip) return Action::Skip; // Need to check children IntersectAction *ia = dynamic_cast<IntersectAction *>(action); Matrix m = this->getMatrix(); m.mult(this->getJointTransformation()); m.invert(); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); Real32 length = dir.length(); if(length < TypeTraits<Real32>::getDefaultEps()) SWARNING << "Joint::intersectEnter: Near-zero scale!" << std::endl; ia->setLine(Line(pos, dir), ia->getMaxDist()); ia->scale (length ); return ActionBase::Continue; }
Action::ResultE DynamicTerrain::intersectEnter(Action* action ) { IntersectAction *ia = dynamic_cast< IntersectAction* >( action ); #ifndef OSG_2_PREP const DynamicVolume &vol = ia->getActNode()->editVolume(true); #else const BoxVolume &vol = ia->getActNode()->editVolume(true); #endif Real32 enter = 0, exit = 0; if(vol.isValid() && !vol.intersect(ia->getLine(), enter, exit)) { return Action::Skip; //bv missed -> can not hit children } Real32 t = enter; Vec3f normal(0,0,0); Int32 index = -1; //if( geoClipmaps_.findFirstIntersection( ia->getLine(), t, normal ) ) { ia->setHit( t, ia->getActNode(), index, normal ); } return Action::Continue; }
Action::ResultE IconLabel::intersectEnter(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); const BoxVolume &bv = ia->getActNode()->getVolume(); if(bv.isValid() && ! bv.intersect(ia->getLine())) { return Action::Skip; //bv missed -> can not hit children } return Action::Continue; }
Action::ResultE DistanceLOD::intersect(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); #ifndef OSG_2_PREP const DynamicVolume &vol = ia->getActNode()->getVolume(); #else const BoxVolume &vol = ia->getActNode()->getVolume(); #endif UInt32 numLevels = action->getNNodes(); // early out: no children or lod set missed, cannot hit anything if (numLevels == 0 || vol.isValid() && !vol.intersect(ia->getLine())) { return Action::Skip; } const MFReal32 &range = (*getMFRange()); UInt32 numRanges = range.size(); UInt32 index = 0; if (numRanges > 0) { if (numRanges >= numLevels) numRanges = numLevels - 1; if (numRanges == 0) { index = 0; } else if (_lastDist >= range[numRanges - 1]) { index = numRanges; } else { for (index = 0; index < numRanges; ++index) { if (_lastDist < range[index]) break; } } } const NodePtr nodePtr = action->getNode(index); ia->addNode(nodePtr); return Action::Continue; }
Action::ResultE transformLeave(CNodePtr& node, Action * action) { IntersectAction * ia = dynamic_cast<IntersectAction*>(action); NodePtr n( node ); Transform* core = dynamic_cast<Transform*>(get_pointer(n->getCore())); Matrix &m = core->editMatrix(); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); ia->setLine( Line( pos, dir ), ia->getMaxDist() ); return Action::Continue; }
Action::ResultE Group::intersect(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); #ifndef OSG_2_PREP const DynamicVolume &vol = ia->getActNode()->getVolume(); #else const BoxVolume &vol = ia->getActNode()->getVolume(); #endif if(vol.isValid() && ! vol.intersect(ia->getLine())) { return Action::Skip; //bv missed -> can not hit children } return Action::Continue; }
Action::ResultE InverseTransform::intersectLeave(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); Matrix m(_invWorld); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); ia->setLine(Line(pos, dir), ia->getMaxDist()); ia->scale(dir.length()); return Action::Continue; }
ActionBase::ResultE Joint::intersectLeave(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); Matrix m = this->getMatrix(); m.mult(this->getJointTransformation()); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); ia->setLine(Line(pos, dir), ia->getMaxDist()); ia->scale(dir.length()); return ActionBase::Continue; }
Action::ResultE SkeletonBlendedGeometry::intersectEnter(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); Matrix m(_invWorld); m.invert(); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); ia->setLine(Line(pos, dir), ia->getMaxDist()); ia->scale(dir.length()); return Inherited::intersectEnter(action); }
Action::ResultE ScreenGroup::intersectEnter(Action *action) { IntersectAction *ia = dynamic_cast<IntersectAction *>(action); Matrix m(_camTransform); m.invert(); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); ia->setLine(Line(pos, dir), ia->getMaxDist()); ia->scale(dir.length()); return Action::Continue; }
/* virtual */ Action::ResultE KDTreeIntersectProxyAttachment::intersectEnter(Node *node, Action *action) { Action::ResultE res = Inherited::intersectEnter(node, action); IntersectAction *iact = boost::polymorphic_downcast<IntersectAction *>(action); Real32 closestHitT = iact->didHit() ? iact->getHitT() : iact->getMaxDist(); Vec3f hitNormal; UInt32 hitTriangle; if(_mfTreeNodes.empty() == false) { UInt32 numTris = 0; bool hit = intersectIntersectKDTree(iact->getLine(), node->getVolume(), _sfGeometry.getValue(), &_mfTreeNodes, &_mfTriIndices, closestHitT, hitNormal, hitTriangle, &numTris ); if(hit == true) { iact->setHit(closestHitT, node, hitTriangle, hitNormal, 0); } iact->getStatCollector()->getElem( IntersectAction::statNTriangles)->add(numTris); } else { // tree was empty - skip this proxy and use conventional // intersect res = Action::Continue; } return res; }
Action::ResultE geometryEnter(CNodePtr& node, Action * action) { IntersectAction * ia = dynamic_cast<IntersectAction*>(action); NodePtr n( node ); Geometry* core = dynamic_cast<Geometry*>(get_pointer(n->getCore())); TriangleIterator it; Real32 t; Vec3f norm; for ( it = core->beginTriangles(); it != core->endTriangles(); ++it ) { if ( ia->getLine().intersect( it.getPosition(0), it.getPosition(1), it.getPosition(2), t, &norm ) ) { ia->setHit( t, NodePtr(node), it.getIndex(), norm ); } } return Action::Continue; }
void key( unsigned char key, int , int ) { switch ( key ) { case 27: exit(0); } // Intersect IntersectAction * act = IntersectAction::create(); static Pnt3f pnts[] = { Pnt3f( 0,0,1 ), Pnt3f( 1,0,1), Pnt3f( 2,0,1), Pnt3f( 3,0,1), Pnt3f( 0,0,1 ), Pnt3f( 0,0,1 ), Pnt3f( 0,0,1 ),Pnt3f( 0,0,1 ), Pnt3f( 0.9,0.9,1 ), Pnt3f(-Inf,-Inf,-Inf) }; static Vec3f dirs[] = { Vec3f( 0,0,-1), Vec3f( 0,0,-1), Vec3f( 0,0,-1), Vec3f( 0,0,-1), Vec3f( 0,-.2,-1), Vec3f( 0,.2,-1), Vec3f( -.2,-.2,-1), Vec3f( .2,.2,-1), Vec3f( 0,0,-1 ), Vec3f(-Inf,-Inf,-Inf) }; static int i = 0; act->setLine( Line( pnts[i], dirs[i]) ); act->apply( iroot ); std::cerr << "Line " << act->getLine().getPosition() << " dir " << act->getLine().getDirection() << " hit: " << act->didHit() << " "; beginEditCP(points); points->setValue( pnts[i], 0 ); points->setValue( pnts[i] + (dirs[i] * Real32(3.0)), 1 ); if ( act->didHit() ) { std::cerr << " object " << act->getHitObject() << " tri " << act->getHitTriangle() << " at " << act->getHitPoint(); TriangleIterator it( act->getHitObject() ); it.seek( act->getHitTriangle() ); Matrix m; act->getHitObject()->getToWorld(m); Pnt3f p = it.getPosition(0); m.mult(p, p); points->setValue( p, 2 ); p = it.getPosition(1); m.mult(p, p); points->setValue( p, 3 ); p = it.getPosition(2); m.mult(p, p); points->setValue( p, 4 ); } else { points->setValue( Pnt3f(0,0,0), 2 ); points->setValue( Pnt3f(0,0,0), 3 ); points->setValue( Pnt3f(0,0,0), 4 ); } endEditCP(points); std::cerr << std::endl; glutPostRedisplay(); if ( pnts[++i][0] == -Inf ) i = 0; }