void FakeInstanceNode::doDisplay(FrameContext & frameContext, const RenderParam & rp) { if(fakePrototype.isNull()) { Node::doDisplay(frameContext, rp); return; } auto camera = static_cast<AbstractCameraNode*>(frameContext.getCamera()->clone()); const Geometry::Matrix4x4f & cameraMatrix = frameContext.getCamera()->getWorldTransformationMatrix(); camera->setRelTransformation( fakePrototype->getWorldTransformationMatrix() * getWorldToLocalMatrix() * cameraMatrix); frameContext.pushAndSetCamera(camera); frameContext.displayNode(fakePrototype.get(), rp); frameContext.popCamera(); }
void SoDragPointDragger::checkBoxLimits() // //////////////////////////////////////////////////////////////////////// { // The limit box is defined in a space aligned and scaled as LOCAL // space, but with it's center remaining fixed in WORLD space. // We need to do this work in LOCAL space, so to begin with, // get the location of the center of this box in LOCAL space. SbMatrix worldToLocal = getWorldToLocalMatrix(); SbVec3f limitBoxCenterInLocal = limitBox.getCenter(); worldToLocal.multVecMatrix( limitBoxCenterInLocal, limitBoxCenterInLocal ); // Now, if our current position is out of range, we need to move // the limit box center accordingly. We continue to do our work // in LOCAL space. SbBool changed = FALSE; SbVec3f boxSize = limitBox.getMax() - limitBox.getMin(); for (int i = 0; i < 3; i++) { float length = boxSize[i]; float halfLength = length * 0.5; // Check the location of startLocalHitPt against boundaries of the limit // box (keeping in mind the jump limit as a % of the total length). // Have we gone too far in the positive direction? float high = limitBoxCenterInLocal[i] + halfLength; while ( (high - startLocalHitPt[i]) / length < jumpLimit ) { limitBoxCenterInLocal[i] += halfLength; high += halfLength; changed = TRUE; } // Have we gone too far in the negative direction? float low = limitBoxCenterInLocal[i] - halfLength; while (( startLocalHitPt[i] - low ) / length < jumpLimit ) { limitBoxCenterInLocal[i] -= halfLength; low -= halfLength; changed = TRUE; } } if (changed == TRUE ) { // First, convert the changed limitBoxCenterInLocal // into WORLD space... SbMatrix localToWorld = getLocalToWorldMatrix(); SbVec3f newCenter; localToWorld.multVecMatrix(limitBoxCenterInLocal,newCenter); // Next, set the bounds of the limit box to have the same size // as before, but centered about this new point. SbVec3f diag = limitBox.getMax() - limitBox.getCenter(); limitBox.setBounds( newCenter - diag, newCenter + diag ); } }
//////////////////////////////////////////////////////////////////////// // // Description: // Sets the feedback geometry depending on which dragger is active. // A 1-D translator results in that line's feedback turning on. // A 2-D translator results in that plane's feedback turning on. // // Use: private // void SoDragPointDragger::setFeedbackGeometry() // //////////////////////////////////////////////////////////////////////// { // First, figure out if we need to know a constrained translation // direction. This happens if a plane dragger is in use, but is // being constrained. int translateDir = -1; #define TINY .0001 if ( shftDown ) { SbVec3f current = getMotionMatrix()[3]; SbVec3f start = getStartMotionMatrix()[3]; SbVec3f motion = current - start; if ( fabs( motion[0]) > fabs( motion[1]) && fabs( motion[0]) > fabs( motion[2])) translateDir = 0; else if ( fabs( motion[1]) > fabs( motion[2])) translateDir = 1; else if ( fabs( motion[2] ) > TINY ) translateDir = 2; } #undef TINY // Turn on appropriate parts, based on state. if (currentDragger == NULL) { setSwitchValue(xFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(yFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(zFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(planeFeedbackSwitch.getValue(), SO_SWITCH_NONE ); } else if (currentDragger == xTranslator.getValue() ) { setSwitchValue(xFeedbackSwitch.getValue(), 0 ); setSwitchValue(yFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(zFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(planeFeedbackSwitch.getValue(), SO_SWITCH_NONE ); } else if (currentDragger == yTranslator.getValue() ) { setSwitchValue(xFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(yFeedbackSwitch.getValue(), 0 ); setSwitchValue(zFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(planeFeedbackSwitch.getValue(), SO_SWITCH_NONE ); } else if (currentDragger == zTranslator.getValue() ) { setSwitchValue(xFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(yFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(zFeedbackSwitch.getValue(), 0 ); setSwitchValue(planeFeedbackSwitch.getValue(), SO_SWITCH_NONE ); } else if (currentDragger == yzTranslator.getValue() ) { setSwitchValue(xFeedbackSwitch.getValue(), SO_SWITCH_NONE ); if ( translateDir == -1 || translateDir == 1 ) setSwitchValue(yFeedbackSwitch.getValue(), 0 ); else setSwitchValue(yFeedbackSwitch.getValue(), SO_SWITCH_NONE ); if ( translateDir == -1 || translateDir == 2 ) setSwitchValue(zFeedbackSwitch.getValue(), 0 ); else setSwitchValue(zFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(planeFeedbackSwitch.getValue(), 0 ); } else if (currentDragger == xzTranslator.getValue() ) { if ( translateDir == -1 || translateDir == 0 ) setSwitchValue(xFeedbackSwitch.getValue(), 0 ); else setSwitchValue(xFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(yFeedbackSwitch.getValue(), SO_SWITCH_NONE ); if ( translateDir == -1 || translateDir == 2 ) setSwitchValue(zFeedbackSwitch.getValue(), 0 ); else setSwitchValue(zFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(planeFeedbackSwitch.getValue(), 1 ); } else if (currentDragger == xyTranslator.getValue() ) { if ( translateDir == -1 || translateDir == 0 ) setSwitchValue(xFeedbackSwitch.getValue(), 0 ); else setSwitchValue(xFeedbackSwitch.getValue(), SO_SWITCH_NONE ); if ( translateDir == -1 || translateDir == 1 ) setSwitchValue(yFeedbackSwitch.getValue(), 0 ); else setSwitchValue(yFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(zFeedbackSwitch.getValue(), SO_SWITCH_NONE ); setSwitchValue(planeFeedbackSwitch.getValue(), 2 ); } checkBoxLimits(); //************************************** // Set the transforms for the feedback axes and/or planes. //************************************** // First, find the center and scale for each part, in LOCAL space. // The limit box is defined in a space aligned and scaled as // LOCAL space, but with it's center remaining fixed in WORLD // space. // We need to transform the center of the limitBox // from WORLD space to LOCAL space to // find the location of the center of the limit box feedback. SbMatrix worldToLocal = getWorldToLocalMatrix(); SbVec3f limitBoxCenterInLocal = limitBox.getCenter(); worldToLocal.multVecMatrix( limitBoxCenterInLocal, limitBoxCenterInLocal ); SbVec3f xAxisSpot = limitBoxCenterInLocal; SbVec3f yAxisSpot = limitBoxCenterInLocal; SbVec3f zAxisSpot = limitBoxCenterInLocal; SbVec3f planeSpot = limitBoxCenterInLocal; //With center matching mouse location... // The point under the mouse is stored as 'startLocalHitPt', which is // expressed in LOCAL space. xAxisSpot[1] = startLocalHitPt[1]; xAxisSpot[2] = startLocalHitPt[2]; yAxisSpot[0] = startLocalHitPt[0]; yAxisSpot[2] = startLocalHitPt[2]; zAxisSpot[0] = startLocalHitPt[0]; zAxisSpot[1] = startLocalHitPt[1]; if ( currentDragger == yzTranslator.getValue()) { planeSpot[0] = startLocalHitPt[0]; } else if ( currentDragger == xzTranslator.getValue()) { planeSpot[1] = startLocalHitPt[1]; } else if ( currentDragger == xyTranslator.getValue()) { planeSpot[2] = startLocalHitPt[2]; } SoTranslation *transNode; // Set position of each axis feedback if ( xFeedbackTranslation.getValue() == NULL ) setAnyPart( "xFeedbackTranslation", new SoTranslation ); transNode = (SoTranslation *) xFeedbackTranslation.getValue(); transNode->translation = xAxisSpot; if ( yFeedbackTranslation.getValue() == NULL ) setAnyPart( "yFeedbackTranslation", new SoTranslation ); transNode = (SoTranslation *) yFeedbackTranslation.getValue(); transNode->translation = yAxisSpot; if ( zFeedbackTranslation.getValue() == NULL ) setAnyPart( "zFeedbackTranslation", new SoTranslation ); transNode = (SoTranslation *) zFeedbackTranslation.getValue(); transNode->translation = zAxisSpot; // Set position of plane feedback if ( planeFeedbackTranslation.getValue() == NULL ) setAnyPart( "planeFeedbackTranslation", new SoTranslation ); transNode = (SoTranslation *) planeFeedbackTranslation.getValue(); transNode->translation = planeSpot; }