Beispiel #1
0
//! 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;
}
Beispiel #2
0
/*! 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;
}
Beispiel #3
0
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;
	}
Beispiel #5
0
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;
}
Beispiel #6
0
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; 
}
Beispiel #8
0
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;
}
Beispiel #10
0
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;
}