void MouseDialogNavigationTool::startPanning(void) { /* Calculate initial motion position: */ motionStart=calcScreenPos(); preScale=getNavigationTransformation(); }
void MapEntity::SetMapTilePosition(Vector2 tilePos, Vector2 scrollOffset, float tileSize) { m_mapTilePos = tilePos; m_mapPos = Vector2(tilePos.x * tileSize, tilePos.y * tileSize); updateScreenPos(calcScreenPos(scrollOffset)); }
void MouseNavigationTool::startPanning(void) { /* Calculate initial motion position: */ motionStart=calcScreenPos(); preScale=getNavigationTransformation(); /* Go to panning mode: */ navigationMode=PANNING; }
void MouseDialogNavigationTool::startScaling(void) { /* Calculate the scaling center: */ screenCenter=calcScreenCenter(); /* Calculate initial motion position: */ motionStart=calcScreenPos(); preScale=NavTrackerState::translateFromOriginTo(screenCenter); postScale=NavTrackerState::translateToOriginFrom(screenCenter); postScale*=getNavigationTransformation(); }
void MouseDialogNavigationTool::startDollying(void) { /* Calculate the dollying direction: */ if(mouseAdapter!=0&&mouseAdapter->getWindow()!=0) dollyDirection=mouseAdapter->getWindow()->getViewer()->getHeadPosition()-calcScreenCenter(); else dollyDirection=getMainViewer()->getHeadPosition()-calcScreenCenter(); dollyDirection.normalize(); /* Calculate initial motion position: */ motionStart=calcScreenPos(); preScale=getNavigationTransformation(); }
void MouseDialogNavigationTool::startRotating(void) { /* Calculate the rotation center: */ screenCenter=calcScreenCenter(); /* Calculate initial rotation position: */ lastRotationPos=calcScreenPos(); /* Calculate the rotation offset vector: */ rotateOffset=getMainScreen()->getScreenTransformation().transform(Vector(0,0,factory->rotatePlaneOffset)); preScale=NavTrackerState::translateFromOriginTo(screenCenter); rotation=NavTrackerState::identity; postScale=NavTrackerState::translateToOriginFrom(screenCenter); postScale*=getNavigationTransformation(); }
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(); }
void MapEntity::SetMapPosition(Vector2 pos, Vector2 scrollOffset, float tileSize) { static const float S_DEGREE_OF_ACCURACY = 0.001f; // Degree of accuracy float mapTileX = pos.x / tileSize; float mapTileY = pos.y / tileSize; m_mapPos = pos; m_mapTilePos = Vector2(floor(mapTileX), floor(mapTileY)); float ceilTileX = ceil(mapTileX); float ceilTileY = ceil(mapTileY); if (mapTileX + S_DEGREE_OF_ACCURACY > ceilTileX) { m_mapTilePos.x = ceilTileX; m_mapPos.x = ceilTileX * tileSize + S_DEGREE_OF_ACCURACY; } if (mapTileY + S_DEGREE_OF_ACCURACY > ceilTileY) { m_mapTilePos.y = ceilTileY; m_mapPos.y = ceilTileY * tileSize + S_DEGREE_OF_ACCURACY; } updateScreenPos(calcScreenPos(scrollOffset)); }
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: ; } }
void MouseNavigationTool::buttonCallback(int buttonSlotIndex,InputDevice::ButtonCallbackData* cbData) { /* Process based on which button was pressed: */ switch(buttonSlotIndex) { case 0: if(cbData->newButtonState) // Button has just been pressed { /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: case SPINNING: if(factory->interactWithWidgets) { /* Check if the GUI interactor accepts the event: */ GUIInteractor::updateRay(); if(GUIInteractor::buttonDown(false)) { /* Deactivate this tool if it is spinning: */ if(navigationMode==SPINNING) deactivate(); /* Go to widget interaction mode: */ navigationMode=WIDGETING; } else { /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startRotating(); } } else { /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startRotating(); } break; case PANNING: if(dolly) startDollying(); else startScaling(); break; default: /* This shouldn't happen; just ignore the event */ break; } } else // Button has just been released { /* Act depending on this tool's current state: */ switch(navigationMode) { case WIDGETING: { if(GUIInteractor::isActive()) { /* Deliver the event: */ GUIInteractor::buttonUp(); } /* Deactivate this tool: */ navigationMode=IDLE; break; } case ROTATING: { /* Check if the input device is still moving: */ Point currentPos=calcScreenPos(); Vector delta=currentPos-lastRotationPos; if(Geometry::mag(delta)>factory->spinThreshold) { /* Calculate spinning angular velocity: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; Vector axis=Geometry::cross(offset,delta); Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*(getApplicationTime()-lastMoveTime)); spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag()); /* Go to spinning mode: */ navigationMode=SPINNING; } else { /* Deactivate this tool: */ deactivate(); /* Go to idle mode: */ navigationMode=IDLE; } break; } case DOLLYING: case SCALING: startPanning(); break; default: /* This shouldn't happen; just ignore the event */ break; } } break; case 1: if(cbData->newButtonState) // Button has just been pressed { /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: case SPINNING: /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startPanning(); break; case ROTATING: if(dolly) startDollying(); else startScaling(); break; default: /* This shouldn't happen; just ignore the event */ break; } } else // Button has just been released { /* Act depending on this tool's current state: */ switch(navigationMode) { case PANNING: /* Deactivate this tool: */ deactivate(); /* Go to idle mode: */ navigationMode=IDLE; break; case DOLLYING: case SCALING: startRotating(); break; default: /* This shouldn't happen; just ignore the event */ break; } } break; case 2: /* Set the dolly flag: */ dolly=cbData->newButtonState; if(factory->invertDolly) dolly=!dolly; if(dolly) // Dollying has just been enabled { /* Act depending on this tool's current state: */ switch(navigationMode) { case SCALING: startDollying(); break; default: /* Nothing to do */ break; } } else { /* Act depending on this tool's current state: */ switch(navigationMode) { case DOLLYING: startScaling(); break; default: /* Nothing to do */ break; } } break; } }
void MouseDialogNavigationTool::buttonCallback(int,InputDevice::ButtonCallbackData* cbData) { if(cbData->newButtonState) // Button has just been pressed { bool takeEvent=true; if(factory->interactWithWidgets) { /* Check if the GUI interactor accepts the event: */ GUIInteractor::updateRay(); if(GUIInteractor::buttonDown(false)) { /* Deactivate this tool if it is spinning: */ if(spinning) deactivate(); spinning=false; /* Disable navigation: */ takeEvent=false; } } if(takeEvent) { /* Deactivate spinning: */ spinning=false; /* Start navigating according to the current navigation mode: */ switch(navigationMode) { case ROTATING: if(activate()) startRotating(); break; case PANNING: if(activate()) startPanning(); break; case DOLLYING: if(activate()) startDollying(); break; case SCALING: if(activate()) startScaling(); break; } } } else // Button has just been released { if(GUIInteractor::isActive()) { /* Deliver the event: */ GUIInteractor::buttonUp(); } else { /* Check for spinning if currently in rotating mode: */ if(navigationMode==ROTATING) { /* Check if the input device is still moving: */ Point currentPos=calcScreenPos(); Vector delta=currentPos-lastRotationPos; if(Geometry::mag(delta)>factory->spinThreshold) { /* Calculate spinning angular velocity: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; Vector axis=Geometry::cross(offset,delta); Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*(getApplicationTime()-lastMoveTime)); spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag()); /* Enable spinning: */ spinning=true; } else { /* Deactivate the tool: */ deactivate(); } } else { /* Deactivate the tool: */ deactivate(); } } } }
void MouseNavigationTool::frame(void) { /* Update the current mouse position: */ currentPos=calcScreenPos(); /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: /* Do nothing */ break; case WIDGETING: { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(calcSelectionRay()); getWidgetManager()->pointerMotion(event); if(draggedWidget!=0) { /* Update the dragged widget's transformation: */ NavTrackerState current=NavTrackerState::translateFromOriginTo(calcScreenPos()); current*=preScale; getWidgetManager()->setPrimaryWidgetTransformation(draggedWidget,GLMotif::WidgetManager::Transformation(current)); } break; } 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*getCurrentFrameTime()))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); 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: */ Vector dollyingDirection; if(mouseAdapter!=0) dollyingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenDollyingDirection); else dollyingDirection=getMainScreen()->getScreenTransformation().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: */ Vector scalingDirection; if(mouseAdapter!=0) scalingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenScalingDirection); else scalingDirection=getMainScreen()->getScreenTransformation().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; } } }
void MouseNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData) { /* Process based on which button was pressed: */ switch(buttonIndex) { case 0: if(cbData->newButtonState) // Button has just been pressed { /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: case SPINNING: if(factory->interactWithWidgets) { /* Check if the mouse pointer is over a GLMotif widget: */ GLMotif::Event event(false); event.setWorldLocation(calcSelectionRay()); if(getWidgetManager()->pointerButtonDown(event)) { if(navigationMode==SPINNING) { /* Deactivate this tool: */ deactivate(); } /* Go to widget interaction mode: */ navigationMode=WIDGETING; /* Drag the entire root widget if the event's target widget is a title bar: */ if(dynamic_cast<GLMotif::TitleBar*>(event.getTargetWidget())!=0) { /* Start dragging: */ draggedWidget=event.getTargetWidget(); /* Calculate the dragging transformation: */ NavTrackerState initialTracker=NavTrackerState::translateFromOriginTo(calcScreenPos()); preScale=Geometry::invert(initialTracker); GLMotif::WidgetManager::Transformation initialWidget=getWidgetManager()->calcWidgetTransformation(draggedWidget); preScale*=NavTrackerState(initialWidget); } else draggedWidget=0; } else { /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startRotating(); } } else { /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startRotating(); } break; case PANNING: if(dolly) startDollying(); else startScaling(); break; default: /* This shouldn't happen; just ignore the event */ break; } } else // Button has just been released { /* Act depending on this tool's current state: */ switch(navigationMode) { case WIDGETING: { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(calcSelectionRay()); getWidgetManager()->pointerButtonUp(event); /* Deactivate this tool: */ navigationMode=IDLE; draggedWidget=0; break; } case ROTATING: { /* Check if the input device is still moving: */ Point currentPos=calcScreenPos(); Vector delta=currentPos-lastRotationPos; if(Geometry::mag(delta)>factory->spinThreshold) { /* Calculate spinning angular velocity: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; Vector axis=Geometry::cross(offset,delta); Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*getCurrentFrameTime()); spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag()); /* Go to spinning mode: */ navigationMode=SPINNING; } else { /* Deactivate this tool: */ deactivate(); /* Go to idle mode: */ navigationMode=IDLE; } break; } case DOLLYING: case SCALING: startPanning(); break; default: /* This shouldn't happen; just ignore the event */ break; } } break; case 1: if(cbData->newButtonState) // Button has just been pressed { /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: case SPINNING: /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startPanning(); break; case ROTATING: if(dolly) startDollying(); else startScaling(); break; default: /* This shouldn't happen; just ignore the event */ break; } } else // Button has just been released { /* Act depending on this tool's current state: */ switch(navigationMode) { case PANNING: /* Deactivate this tool: */ deactivate(); /* Go to idle mode: */ navigationMode=IDLE; break; case DOLLYING: case SCALING: startRotating(); break; default: /* This shouldn't happen; just ignore the event */ break; } } break; case 2: /* Set the dolly flag: */ dolly=cbData->newButtonState; if(factory->invertDolly) dolly=!dolly; if(dolly) // Dollying has just been enabled { /* Act depending on this tool's current state: */ switch(navigationMode) { case SCALING: startDollying(); break; default: /* Nothing to do */ break; } } else { /* Act depending on this tool's current state: */ switch(navigationMode) { case DOLLYING: startScaling(); break; default: /* Nothing to do */ break; } } break; } }
void MouseDialogNavigationTool::frame(void) { /* Update the current mouse position: */ currentPos=calcScreenPos(); /* Act depending on this tool's current state: */ if(isActive()) { if(spinning) { /* Calculate incremental rotation: */ rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getFrameTime()))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); } else { 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 PANNING: { /* Update the navigation transformation: */ NavTrackerState t=NavTrackerState::translate(currentPos-motionStart); t*=preScale; setNavigationTransformation(t); break; } case DOLLYING: { /* Calculate the current dollying direction: */ Vector dollyingDirection; if(mouseAdapter!=0) dollyingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenDollyingDirection); else dollyingDirection=getMainScreen()->getScreenTransformation().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: */ Vector scalingDirection; if(mouseAdapter!=0) scalingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenScalingDirection); else scalingDirection=getMainScreen()->getScreenTransformation().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; } } } } }
void MouseDialogNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData) { if(cbData->newButtonState) // Button has just been pressed { /* Deactivate spinning: */ spinning=false; /* Start navigating according to the current navigation mode: */ switch(navigationMode) { case ROTATING: if(activate()) startRotating(); break; case PANNING: if(activate()) startPanning(); break; case DOLLYING: if(activate()) startDollying(); break; case SCALING: if(activate()) startScaling(); break; } } else // Button has just been released { /* Check for spinning if currently in rotating mode: */ if(navigationMode==ROTATING) { /* Check if the input device is still moving: */ Point currentPos=calcScreenPos(); Vector delta=currentPos-lastRotationPos; if(Geometry::mag(delta)>factory->spinThreshold) { /* Calculate spinning angular velocity: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; Vector axis=Geometry::cross(offset,delta); Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*getFrameTime()); spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag()); /* Enable spinning: */ spinning=true; } else { /* Deactivate the tool: */ deactivate(); } } else { /* Deactivate the tool: */ deactivate(); } } }