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); }
SbLineProjector::SbLineProjector() { setLine(SbLine(SbVec3f(0,0,0), SbVec3f(0,1,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(); }