示例#1
0
bool
intersect( const SbVec3f& p0, const SbVec3f& p1,
		   const SbVec3f& q0, const SbVec3f& q1,
		   SbVec3f& intersectPoint )
{
	if( SbLine(p0, p1).getClosestPoints( SbLine(q0, q1), intersectPoint, intersectPoint ) )
	{
		return	belongToSegment( intersectPoint, p0, p1 ) &&
				belongToSegment( intersectPoint, q0, q1 );
	}
	return false;
}
void TranslateRadialDragger::
dragStart()
{
  // Display the 'active' parts...
  SoSwitch *sw;
  sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
  setSwitchValue(sw, 1);
  sw = SO_GET_ANY_PART(this, "feedbackSwitch", SoSwitch);
  setSwitchValue(sw, 1);

  // Establish the projector line.
  // The direction of translation goes from the center of the
  // dragger toward the point that was hit, in local space.
  // For the center, use (0,0,0).
  SbVec3f startLocalHitPt = getLocalStartingPoint();
  lineProj->setLine(SbLine(SbVec3f(0, 0, 0), startLocalHitPt));

  // orient the feedback geometry.
  orientFeedbackGeometry(startLocalHitPt);
}
示例#3
0
SbLineProjector::SbLineProjector()
{
    setLine(SbLine(SbVec3f(0,0,0), SbVec3f(0,1,0)));
}
示例#4
0
/*! \COININTERNAL
  Called when dragger is selected (picked) by the user.
*/
void
SoHandleBoxDragger::dragStart(void)
{
  SoHandleBoxDragger_invalidate_surroundscale(this);

  static const char translatorname[] = "translator";
  static const char extrudername[] = "extruder";
  static const char uniformname[] = "uniform";

  const SoPath *pickpath = this->getPickPath();

  SbBool found = FALSE;
  this->whatkind = WHATKIND_NONE;
  this->whatnum = 0;

  int i;
  SbString str;
  if (!found) {
    for (i = 1; i <= 6; i++) {
      str.sprintf("%s%d", translatorname, i);
      if (pickpath->findNode(this->getNodeFieldNode(str.getString())) >= 0||
          this->getSurrogatePartPickedName() == str.getString()) break;
    }
    if (i <= 6) {
      found = TRUE;
      this->whatkind = WHATKIND_TRANSLATOR;
      this->whatnum = i;
    }
  }

  if (!found) {
    for (i = 1; i <= 6; i++) {
      str.sprintf("%s%d", extrudername, i);
      if (pickpath->findNode(this->getNodeFieldNode(str.getString()))>= 0 ||
          this->getSurrogatePartPickedName() == str.getString()) break;
    }
    if (i <= 6) {
      found = TRUE;
      this->whatkind = WHATKIND_EXTRUDER;
      this->whatnum = i;
    }
  }
  if (!found) {
    for (i = 1; i <= 8; i++) {
      str.sprintf("%s%d", uniformname, i);
      if (pickpath->findNode(this->getNodeFieldNode(str.getString()))>= 0 ||
          this->getSurrogatePartPickedName() == str.getString()) break;
    }
    if (i <= 8) {
      found = TRUE;
      this->whatkind = WHATKIND_UNIFORM;
      this->whatnum = i;
    }
  }
  assert(found);
  if (!found) return;

  SbVec3f startPt = this->getLocalStartingPoint();

  switch(this->whatkind) {
  case WHATKIND_TRANSLATOR:
    {
      SbVec3f n;
      if (this->whatnum <= 2) {
        n = SbVec3f(0.0f, 1.0f, 0.0f);
      }
      else if (this->whatnum <= 4) {
        n = SbVec3f(1.0f, 0.0f, 0.0f);
      }
      else {
        n = SbVec3f(0.0f, 0.0f, 1.0f);
      }
      SbVec3f localPt;
      {
        SbMatrix mat, inv;
        this->getSurroundScaleMatrices(mat, inv);
        inv.multVecMatrix(startPt, localPt);
      }
      this->planeProj->setPlane(SbPlane(n, startPt));
      SbLine myline(SbVec3f(0.0f, 0.0f, 0.0f), n);
      SoTranslation *t = SO_GET_ANY_PART(this, "arrowTranslation", SoTranslation);
      t->translation = myline.getClosestPoint(localPt);
      if (this->getEvent()->wasShiftDown()) {
        this->getLocalToWorldMatrix().multVecMatrix(startPt, this->worldRestartPt);
        this->constraintState = CONSTRAINT_WAIT;
      }
    }
    break;
  case WHATKIND_EXTRUDER:
    this->lineProj->setLine(SbLine(this->getDraggerCenter(), startPt));
    this->ctrlOffset = this->calcCtrlOffset(startPt);
    break;
  case WHATKIND_UNIFORM:
    this->lineProj->setLine(SbLine(this->getDraggerCenter(), startPt));
    this->ctrlOffset = this->calcCtrlOffset(startPt);
    break;
  }
  this->ctrlDown = this->getEvent()->wasCtrlDown();
  this->updateSwitches();
}
void
SoDragPointDragger::metaKeyChangeCB( void *, SoDragger *inDragger )
//
////////////////////////////////////////////////////////////////////////
{
    SoDragPointDragger *dp = (SoDragPointDragger *) inDragger;

    SoHandleEventAction *ha = dp->getHandleEventAction();

    // We care if the shift key is down for drawing feedback.
	const SoEvent *event = dp->getEvent();
        dp->shftDown = event->wasShiftDown();

    // Don't check for grabber yet.
    // CONTROL key press overrides if the grabber is a childDragger.

    // [1] We only respond to CONTROL key press events.
	if ( !SO_KEY_PRESS_EVENT(event,  LEFT_CONTROL) &&
	     !SO_KEY_PRESS_EVENT(event, RIGHT_CONTROL))
	     return;

    //[2] Should we return?
    //    Stay here if there's no grabber and the mouse is over us,
    //         or over a surrogate part.
    //    Stay here if we are the grabber.
    //    Stay here if our currentDragger is grabbing events.
    //    Return if anyone else is grabbing.
	SbBool takeIt = FALSE;
	if ( ha->getGrabber() == NULL  ) {

	    // grabber is NULL...
	    const SoPickedPoint *p = ha->getPickedPoint();

	    if ( p && p->getPath()) {

		// Are we on the pickPath?
		// Or is the path a surrogate path for us or any draggers 
		// contained within us?
	        if (  p->getPath()->containsNode(dp) ||
		     dp->isPathSurrogateInMySubgraph(p->getPath()) )
		        takeIt = TRUE;
	    }
	}
	else if ( ha->getGrabber() == dp )
	    takeIt = TRUE;
	else if ( ha->getGrabber() == dp->currentDragger )
	    takeIt = TRUE;
	else 
	    takeIt = FALSE;

	if ( !takeIt )
	    return;

    //[3] Now, switch the set of visible draggers...
	dp->showNextDraggerSet();

    //[4] If a child is grabbing, release events and hand it all over to 
    //    the next one...
	SoDragger *oldDragger = dp->currentDragger;
	if (oldDragger) {

	    // Ref the oldDragger.
		oldDragger->ref();

	    // Release the grabber. This will call grabEventsCleanUp() if 
	    // the grabber is a dragger.
		ha->releaseGrabber();

	    // If there was an oldDragger, 
	    // [a] select a new dragger to grab events.
	    // [b] Set up a plane or line projector oriented like newDragger.
	    // [c] Find out where current mouse position intersects that new 
	    //     plane or line. The new gesture will continue from there.
		SoDragger *newDragger;
		SbVec3f    projPt;
		SbLineProjector  lp;
		SbPlaneProjector pp;
		lp.setViewVolume( dp->getViewVolume() );
		pp.setViewVolume( dp->getViewVolume() );
		lp.setWorkingSpace( dp->getLocalToWorldMatrix() );
		pp.setWorkingSpace( dp->getLocalToWorldMatrix() );

		if (      oldDragger == dp->xTranslator.getValue() ) {
		    newDragger = (SoDragger *) dp->yTranslator.getValue();
		    lp.setLine( SbLine( SbVec3f(0,0,0), SbVec3f(0,1,0)));
		    projPt = lp.project(dp->getNormalizedLocaterPosition());
		}
		else if ( oldDragger == dp->yTranslator.getValue() ) {
		    newDragger = (SoDragger *) dp->zTranslator.getValue();
		    lp.setLine( SbLine( SbVec3f(0,0,0), SbVec3f(0,0,1)));
		    projPt = lp.project(dp->getNormalizedLocaterPosition());
		}
		else if ( oldDragger == dp->zTranslator.getValue() ) {
		    newDragger = (SoDragger *) dp->xTranslator.getValue();
		    lp.setLine( SbLine( SbVec3f(0,0,0), SbVec3f(1,0,0)));
		    projPt = lp.project(dp->getNormalizedLocaterPosition());
		}
		else if ( oldDragger == dp->yzTranslator.getValue() ) {
		    newDragger = (SoDragger *) dp->xzTranslator.getValue();
		    pp.setPlane( SbPlane( SbVec3f(0,1,0), SbVec3f(0,0,0)));
		    projPt = pp.project(dp->getNormalizedLocaterPosition());
		}
		else if ( oldDragger == dp->xzTranslator.getValue() ) {
		    newDragger = (SoDragger *) dp->xyTranslator.getValue();
		    pp.setPlane( SbPlane( SbVec3f(0,0,1), SbVec3f(0,0,0)));
		    projPt = pp.project(dp->getNormalizedLocaterPosition());
		}
		else if ( oldDragger == dp->xyTranslator.getValue() ) {
		    newDragger = (SoDragger *) dp->yzTranslator.getValue();
		    pp.setPlane( SbPlane( SbVec3f(1,0,0), SbVec3f(0,0,0)));
		    projPt = pp.project(dp->getNormalizedLocaterPosition());
		}

	    // unref oldDragger. We don't need it any more.
		oldDragger->unref();

	    // Give newDragger our handleEvent action. 
		newDragger->setHandleEventAction(ha);

	    // Cast the projPt into world space for the new starting point.
		dp->getLocalToWorldMatrix().multVecMatrix(projPt,projPt);
		newDragger->setStartingPoint( projPt );

	    // Give the newDragger a path to itself
		SoPath *pathToDragger;

		    // We must ref() & unref() dpThisPath to dispose of it.
		    SoPath *dpThisPath = dp->createPathToThis();
		    if (dpThisPath) dpThisPath->ref();
		    pathToDragger = dp->createPathToPart(
			dp->getPartString(newDragger), TRUE, dpThisPath );
		    if (dpThisPath) dpThisPath->unref();

		if (pathToDragger)
		    pathToDragger->ref();
		newDragger->setTempPathToThis( pathToDragger );
		if (pathToDragger)
		    pathToDragger->unref();

	    // Give the newDragger our viewing information.
		newDragger->setViewVolume(dp->getViewVolume());
		newDragger->setViewportRegion(dp->getViewportRegion());

	    // Set the grabber. This will call starting callbacks on the new
	    // grabber, as well as it's registered parent, moi!
		ha->setGrabber( newDragger );
	}

    //[5] set handled
	ha->setHandled();
}