void MouseDialogNavigationTool::display(GLContextData& contextData) const { if(showScreenCenter) { /* Save and set up OpenGL state: */ glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT|GL_LINE_BIT|GL_TEXTURE_BIT); glDisable(GL_LIGHTING); glDepthFunc(GL_LEQUAL); /* Go to screen coordinates: */ glPushMatrix(); Scalar viewport[4]; glMultMatrix(getMouseScreenTransform(mouseAdapter,viewport)); /* Determine the crosshair colors: */ Color bgColor=getBackgroundColor(); Color fgColor; for(int i=0;i<3;++i) fgColor[i]=1.0f-bgColor[i]; fgColor[3]=bgColor[3]; /* Calculate the window's or screen's center: */ Scalar centerPos[2]; for(int i=0;i<2;++i) centerPos[i]=Math::mid(viewport[2*i+0],viewport[2*i+1]); /* Calculate the endpoints of the screen's crosshair lines in screen coordinates: */ Point l=Point(viewport[0],centerPos[1],Scalar(0)); Point r=Point(viewport[1],centerPos[1],Scalar(0)); Point b=Point(centerPos[0],viewport[2],Scalar(0)); Point t=Point(centerPos[0],viewport[3],Scalar(0)); /* Draw the screen crosshairs: */ glLineWidth(3.0f); glColor(bgColor); glBegin(GL_LINES); glVertex(l); glVertex(r); glVertex(b); glVertex(t); glEnd(); glLineWidth(1.0f); glColor(fgColor); glBegin(GL_LINES); glVertex(l); glVertex(r); glVertex(b); glVertex(t); glEnd(); /* Go back to physical coordinates: */ glPopMatrix(); /* Restore OpenGL state: */ glPopAttrib(); } }
Point MouseNavigationTool::calcScreenCenter(void) const { /* Get the transformation of the screen currently containing the input device: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); /* Calculate the screen's center: */ Point center; center[0]=Math::mid(viewport[0],viewport[1]); center[1]=Math::mid(viewport[2],viewport[3]); center[2]=Scalar(0); /* Transform the center position to physical coordinates: */ return screenT.transform(center); }
void MouseDialogNavigationTool::startRotating(void) { /* Calculate the rotation center: */ screenCenter=calcScreenCenter(); /* Calculate initial rotation position: */ lastRotationPos=calcScreenPos(); /* Get the transformation of the screen currently containing the input device: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); /* Calculate the rotation offset vector: */ rotateOffset=screenT.transform(Vector(0,0,factory->rotatePlaneOffset)); preScale=NavTrackerState::translateFromOriginTo(screenCenter); rotation=NavTrackerState::identity; postScale=NavTrackerState::translateToOriginFrom(screenCenter); postScale*=getNavigationTransformation(); }
Point MouseNavigationTool::calcScreenPos(void) const { /* Calculate the ray equation: */ Ray ray=getButtonDeviceRay(0); /* Get the transformation of the screen currently containing the input device: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); /* Intersect the device ray with the screen: */ Vector normal=screenT.getDirection(2); Scalar d=normal*screenT.getOrigin(); Scalar divisor=normal*ray.getDirection(); if(divisor==Scalar(0)) return Point::origin; Scalar lambda=(d-ray.getOrigin()*normal)/divisor; if(lambda<Scalar(0)) return Point::origin; return ray(lambda); }
void MouseNavigationTool::display(GLContextData& contextData) const { #if 0 // Don't draw the interaction ray -- it's a mouse tool, it should be invisible if(factory->interactWithWidgets) { /* Draw the GUI interactor's state: */ GUIInteractor::glRenderAction(3.0f,GLColor<GLfloat,4>(1.0f,0.0f,0.0f),contextData); } #endif if(factory->showScreenCenter&&navigationMode!=IDLE&&navigationMode!=WIDGETING) { /* Save and set up OpenGL state: */ glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_ENABLE_BIT|GL_LINE_BIT); glDisable(GL_LIGHTING); glDepthFunc(GL_LEQUAL); /* Go to screen coordinates: */ glPushMatrix(); Scalar viewport[4]; glMultMatrix(getMouseScreenTransform(mouseAdapter,viewport)); /* Determine the crosshair colors: */ Color bgColor=getBackgroundColor(); Color fgColor; for(int i=0;i<3;++i) fgColor[i]=1.0f-bgColor[i]; fgColor[3]=bgColor[3]; /* Calculate the window's or screen's center: */ Scalar centerPos[2]; for(int i=0;i<2;++i) centerPos[i]=Math::mid(viewport[2*i+0],viewport[2*i+1]); /* Calculate the endpoints of the screen's crosshair lines in screen coordinates: */ Point l=Point(viewport[0],centerPos[1],Scalar(0)); Point r=Point(viewport[1],centerPos[1],Scalar(0)); Point b=Point(centerPos[0],viewport[2],Scalar(0)); Point t=Point(centerPos[0],viewport[3],Scalar(0)); /* Draw the screen crosshairs: */ glLineWidth(3.0f); glColor(bgColor); glBegin(GL_LINES); glVertex(l); glVertex(r); glVertex(b); glVertex(t); glEnd(); glLineWidth(1.0f); glColor(fgColor); glBegin(GL_LINES); glVertex(l); glVertex(r); glVertex(b); glVertex(t); glEnd(); /* Go back to physical coordinates: */ glPopMatrix(); /* Restore OpenGL state: */ glPopAttrib(); } }
void MouseNavigationTool::frame(void) { /* Update the current mouse position: */ Point newCurrentPos=calcScreenPos(); if(currentPos!=newCurrentPos) { currentPos=calcScreenPos(); lastMoveTime=getApplicationTime(); } if(factory->interactWithWidgets) { /* Update the GUI interactor: */ GUIInteractor::updateRay(); GUIInteractor::move(); } /* Act depending on this tool's current state: */ switch(navigationMode) { case ROTATING: { /* Calculate the rotation position: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; /* Calculate mouse displacement vector: */ Point rotationPos=currentPos; Vector delta=rotationPos-lastRotationPos; lastRotationPos=rotationPos; /* Calculate incremental rotation: */ Vector axis=Geometry::cross(offset,delta); Scalar angle=Geometry::mag(delta)/factory->rotateFactor; if(angle!=Scalar(0)) rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateAxis(axis,angle))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); break; } case SPINNING: { /* Calculate incremental rotation: */ rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getFrameTime()))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); scheduleUpdate(getApplicationTime()+1.0/125.0); break; } case PANNING: { /* Update the navigation transformation: */ NavTrackerState t=NavTrackerState::translate(currentPos-motionStart); t*=preScale; setNavigationTransformation(t); break; } case DOLLYING: { /* Calculate the current dollying direction: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); Vector dollyingDirection=screenT.transform(factory->screenDollyingDirection); /* Update the navigation transformation: */ Scalar dollyDist=((currentPos-motionStart)*dollyingDirection)/factory->dollyFactor; NavTrackerState t=NavTrackerState::translate(dollyDirection*dollyDist); t*=preScale; setNavigationTransformation(t); break; } case SCALING: { /* Calculate the current scaling direction: */ Scalar viewport[4]; ONTransform screenT=getMouseScreenTransform(mouseAdapter,viewport); Vector scalingDirection=screenT.transform(factory->screenScalingDirection); /* Update the navigation transformation: */ Scalar scale=((currentPos-motionStart)*scalingDirection)/factory->scaleFactor; NavTrackerState t=preScale; t*=NavTrackerState::scale(Math::exp(scale)); t*=postScale; setNavigationTransformation(t); break; } case DOLLYING_WHEEL: { /* Update the navigation transformation: */ Scalar scale=currentValue; currentWheelScale+=factory->wheelDollyFactor*scale; NavTrackerState t=NavTrackerState::translate(dollyDirection*currentWheelScale); t*=preScale; setNavigationTransformation(t); break; } case SCALING_WHEEL: { /* Update the navigation transformation: */ Scalar scale=currentValue; currentWheelScale*=Math::pow(factory->wheelScaleFactor,scale); NavTrackerState t=preScale; t*=NavTrackerState::scale(currentWheelScale); t*=postScale; setNavigationTransformation(t); break; } default: ; } }