void InteractionManager::createMouseDragEvents(bool single) { if(!_mouseActive) { return; } int numEvents = 0; if(single) { numEvents = 1; _dragEventTime = 0; } else { static const double slice = 1.0 / 60.0; _dragEventTime += CVRViewer::instance()->getLastFrameDuration(); numEvents = (int)(_dragEventTime / slice); _dragEventTime -= slice * ((double)numEvents); } for(int j = 0; j < numEvents; j++) { unsigned int bit = 1; for(int i = 0; i < 10; i++) { if((_mouseButtonMask & bit)) { MouseInteractionEvent * dEvent = new MouseInteractionEvent(); dEvent->setInteraction(BUTTON_DRAG); //TODO: make config file flag // makes the right click button 1 if(i == 1) { dEvent->setButton(2); } else if(i == 2) { dEvent->setButton(1); } else { dEvent->setButton(i); } dEvent->setX(_mouseX); dEvent->setY(_mouseY); dEvent->setTransform(_mouseMat); dEvent->setHand(-1); dEvent->setMasterScreenNum( CVRViewer::instance()->getActiveMasterScreen()); _mouseQueue.push(dEvent); } bit = bit << 1; } } }
bool OsgEarth::processEvent(InteractionEvent * event) { MouseInteractionEvent * mie = event->asMouseEvent(); if(mie) { return mouseButtonEvent(mie->getInteraction(),mie->getButton(),mie->getX(),mie->getY(),mie->getTransform()); } TrackedButtonInteractionEvent * tie = event->asTrackedButtonEvent(); if(tie) { return buttonEvent(tie->getInteraction(),tie->getButton(),tie->getHand(),tie->getTransform()); } return false; }
void InteractionManager::createMouseDoubleClickEvent(int button) { if(!_mouseActive) { return; } unsigned int bit = 1; for(int i = 0; i < 10; i++) { if((button & bit)) { MouseInteractionEvent * dcEvent = new MouseInteractionEvent(); dcEvent->setInteraction(BUTTON_DOUBLE_CLICK); //TODO: make config file flag // makes the right click button 1 if(i == 1) { dcEvent->setButton(2); } else if(i == 2) { dcEvent->setButton(1); } else { dcEvent->setButton(i); } dcEvent->setX(_mouseX); dcEvent->setY(_mouseY); dcEvent->setTransform(_mouseMat); dcEvent->setHand(-1); dcEvent->setMasterScreenNum( CVRViewer::instance()->getActiveMasterScreen()); _mouseQueue.push(dcEvent); _mouseButtonMask |= button; _lastMouseButtonMask |= button; return; } bit = bit << 1; } }
void InteractionManager::processMouse() { if(!_mouseActive) { return; } // TODO: get max mouse buttons from somewhere unsigned int bit = 1; for(int i = 0; i < 10; i++) { if((_lastMouseButtonMask & bit) != (_mouseButtonMask & bit)) { MouseInteractionEvent * buttonEvent = new MouseInteractionEvent(); if(_lastMouseButtonMask & bit) { buttonEvent->setInteraction(BUTTON_UP); } else { buttonEvent->setInteraction(BUTTON_DOWN); } //TODO: make config file flag // makes the right click button 1 if(i == 1) { buttonEvent->setButton(2); } else if(i == 2) { buttonEvent->setButton(1); } else { buttonEvent->setButton(i); } buttonEvent->setX(_mouseX); buttonEvent->setY(_mouseY); buttonEvent->setTransform(_mouseMat); buttonEvent->setHand(-1); buttonEvent->setMasterScreenNum( CVRViewer::instance()->getActiveMasterScreen()); _mouseQueue.push(buttonEvent); } bit = bit << 1; } _lastMouseButtonMask = _mouseButtonMask; }
void BubbleMenuRangeValueCompactGeometry::processEvent(InteractionEvent * event) { if(event->asMouseEvent()) { MouseInteractionEvent * mie = event->asMouseEvent(); if(event->getInteraction() == BUTTON_DOWN || event->getInteraction() == BUTTON_DOUBLE_CLICK) { int x, y; x = mie->getX(); y = mie->getY(); _lastMouseX = x; _lastMouseY = y; return; } if(event->getInteraction() == BUTTON_DRAG || event->getInteraction() == BUTTON_UP) { int x, y; x = mie->getX(); y = mie->getY(); MenuRangeValueCompact * mrv = (MenuRangeValueCompact*)_item; float min, max, current; if(mrv->getIsLog()) { min = log(mrv->getMin()) / log(mrv->getLogBase()); max = log(mrv->getMax()) / log(mrv->getLogBase()); current = log(mrv->getValue()) / log(mrv->getLogBase()); } else { min = mrv->getMin(); max = mrv->getMax(); current = mrv->getValue(); } float pixelRange = 800; bool valueUpdated = false; if(x > _lastMouseX) { if(mrv->getValue() != mrv->getMax()) { float change = (x - _lastMouseX) * (max - min) / pixelRange; float newValue; if(mrv->getIsLog()) { newValue = pow(mrv->getLogBase(),current + change); newValue = std::max(newValue,mrv->getMin()); } else { newValue = std::max(mrv->getValue() + change, mrv->getMin()); } mrv->setValue(newValue); valueUpdated = true; } } else if(x < _lastMouseX) { if(mrv->getValue() != mrv->getMin()) { float change = (x - _lastMouseX) * (max - min) / pixelRange; float newValue; if(mrv->getIsLog()) { newValue = pow(mrv->getLogBase(),current + change); newValue = std::min(newValue,mrv->getMax()); } else { newValue = std::min(mrv->getValue() + change, mrv->getMax()); } mrv->setValue(newValue); valueUpdated = true; } } if(valueUpdated) { if(mrv->getCallback()) { mrv->getCallback()->menuCallback(_item); } } _lastMouseY = y; _lastMouseX = x; return; } } else if(event->asTrackedButtonEvent()) { TrackedButtonInteractionEvent * tie = event->asTrackedButtonEvent(); if(event->getInteraction() == BUTTON_DOWN || event->getInteraction() == BUTTON_DOUBLE_CLICK) { _point = tie->getTransform().getTrans(); osg::Vec3 forward = osg::Vec3(0,1.0,0) * tie->getTransform(); forward = forward - _point; _normal = forward ^ osg::Vec3(0,0,1.0); _normal.normalize(); _lastDistance = 0.0; return; } if(event->getInteraction() == BUTTON_DRAG || event->getInteraction() == BUTTON_UP) { MenuRangeValueCompact * mrv = (MenuRangeValueCompact*)_item; float min, max, current; if(mrv->getIsLog()) { min = log(mrv->getMin()) / log(mrv->getLogBase()); max = log(mrv->getMax()) / log(mrv->getLogBase()); current = log(mrv->getValue()) / log(mrv->getLogBase()); } else { min = mrv->getMin(); max = mrv->getMax(); current = mrv->getValue(); } osg::Vec3 vec = tie->getTransform().getTrans(); vec = vec - _point; float newDistance = vec * _normal; float range = 1000; bool valueUpdated = false; if(newDistance < _lastDistance) { if(mrv->getValue() != mrv->getMin()) { float change = (newDistance - _lastDistance) * (max - min) / range; float newValue; if(mrv->getIsLog()) { newValue = pow(mrv->getLogBase(),current + change); newValue = std::max(newValue,mrv->getMin()); } else { newValue = std::max(mrv->getValue() + change, mrv->getMin()); } mrv->setValue(newValue); valueUpdated = true; } } else if(newDistance > _lastDistance) { if(mrv->getValue() != mrv->getMax()) { float change = (newDistance - _lastDistance) * (max - min) / range; float newValue; if(mrv->getIsLog()) { newValue = pow(mrv->getLogBase(),current + change); newValue = std::min(newValue,mrv->getMax()); } else { newValue = std::min(mrv->getValue() + change, mrv->getMax()); } mrv->setValue(newValue); valueUpdated = true; } } if(valueUpdated) { if(mrv->getCallback()) { mrv->getCallback()->menuCallback(_item); } } _lastDistance = newDistance; return; } } }
void BoardMenuListGeometry::processEvent(InteractionEvent * event) { if(event->getInteraction() == BUTTON_UP) { _geodeSelected->removeDrawables(0,_geodeSelected->getNumDrawables()); _geodeSelected->addDrawable(_valuesSelected[_listItem->getFocus()]); _clicked = false; _listItem->setDirty(true); } if(event->asMouseEvent()) { MouseInteractionEvent * mie = event->asMouseEvent(); if(event->getInteraction() == BUTTON_DOWN || event->getInteraction() == BUTTON_DOUBLE_CLICK) { int y = mie->getY(); _lastMouseY = y; _clicked = true; _listItem->setDirty(true); return; } if(event->getInteraction() == BUTTON_DRAG || event->getInteraction() == BUTTON_UP) { int y = mie->getY(); float pixelRange = 400; bool valueUpdated = false; int valueMax = _listItem->getListSize(); int index = _listItem->getIndex(); if(y != _lastMouseY) { int change = (int)((y - _lastMouseY) * _listItem->getSensitivity() / pixelRange); if(change) { index -= change; if(index > valueMax) index = valueMax; else if(index < 0) index = 0; _listItem->setIndex(index); valueUpdated = true; } } if(valueUpdated) { if(_listItem->getCallback()) { _listItem->getCallback()->menuCallback(_item); } _lastMouseY = y; } return; } } else if(event->asTrackedButtonEvent()) { TrackedButtonInteractionEvent * tie = event->asTrackedButtonEvent(); if(event->getInteraction() == BUTTON_DOWN || event->getInteraction() == BUTTON_DOUBLE_CLICK) { _point = tie->getTransform().getTrans(); _lastDistance = 0.0; _clicked = true; _listItem->setDirty(true); return; } if(event->getInteraction() == BUTTON_DRAG || event->getInteraction() == BUTTON_UP) { MenuList * _listItem = (MenuList*)_item; osg::Vec3 vec = tie->getTransform().getTrans(); ; vec = vec - _point; float newDistance = vec.z(); float range = 400; bool valueUpdated = false; int valueMax = _listItem->getListSize(); int index = _listItem->getIndex(); if(newDistance != _lastDistance) { int change = (int)((newDistance - _lastDistance) * _listItem->getSensitivity() / range); if(change) { index -= change; if(index > valueMax) index = valueMax; else if(index < 0) index = 0; _listItem->setIndex(index); valueUpdated = true; } } if(valueUpdated) { if(_listItem->getCallback()) { _listItem->getCallback()->menuCallback(_item); } _lastDistance = newDistance; } return; } } }
void TrackerMouse::update( std::map<int,std::list<InteractionEvent*> > & eventMap) { if(!_handListInit) { if(_debug) { std::cerr << "TrackerMouse: hand list init:" << std::endl; } int mySystem = -1; for(int i = 0; i < TrackingManager::instance()->getNumTrackingSystems(); i++) { if(TrackingManager::instance()->getTrackingSystem(i) == this) { mySystem = i; break; } } if(mySystem < 0) { std::cerr << "TrackerMouse: Error: Unable to find own system in list" << std::endl; } else { if(_debug) { std::cerr << "Mouse system: " << mySystem << std::endl; for(int i = 0; i < TrackingManager::instance()->getNumHands(); i++) { std::cerr << "Hand: " << i << " buttonFilter: " << TrackingManager::instance()->getButtonFilter(i,mySystem) << std::endl; } } int bhand, bbutton; for(int i = 0; i < CVR_NUM_MOUSE_BUTTONS; i++) { TrackingManager::instance()->getHandButtonFromSystemButton(mySystem,i,bhand,bbutton); _handButtonList.push_back(std::pair<int,int>(bhand,bbutton)); } for(int i = 0; i < _handButtonList.size(); i++) { if(_handButtonList[i].first < 0) { _handValidList.push_back(false); continue; } int hsystem, hindex; TrackingManager::instance()->getHandAddress(_handButtonList[i].first,hsystem,hindex); if(hsystem < 0 || hindex < 0) { _handValidList.push_back(false); continue; } if(hsystem >= 0 && hsystem < TrackingManager::instance()->getNumTrackingSystems() && TrackingManager::instance()->getTrackingSystem(hsystem) && hindex >= 0 && hindex < TrackingManager::instance()->getNumBodies(hsystem)) { _handValidList.push_back(true); } else { _handValidList.push_back(false); } } if(_debug) { for(int i = 0; i < _handButtonList.size(); i++) { std::cerr << "Button: " << i << " hand: " << _handButtonList[i].first << " handButton: " << _handButtonList[i].second << " valid: " << _handValidList[i] << std::endl; } } } _handListInit = true; } osg::Matrix m = InteractionManager::instance()->getMouseMat(); osg::Vec3 pos = m.getTrans(); osg::Quat rot = m.getRotate(); _mouseBody.x = pos.x(); _mouseBody.y = pos.y(); _mouseBody.z = pos.z(); _mouseBody.qx = rot.x(); _mouseBody.qy = rot.y(); _mouseBody.qz = rot.z(); _mouseBody.qw = rot.w(); _mouseButtonMask = InteractionManager::instance()->getMouseButtonMask(); int mouseWheel = InteractionManager::instance()->getMouseWheel(); if(mouseWheel > 0) { _mouseValuator = 1.0; } else if(mouseWheel < 0) { _mouseValuator = -1.0; } else { _mouseValuator = 0.0; } if(!_handButtonList.size()) { return; } std::queue<InteractionEvent *,std::list<InteractionEvent *> > tempQueue; //std::cerr << "Mouse queue size: " << InteractionManager::instance()->_mouseQueue.size() << std::endl; while(InteractionManager::instance()->_mouseQueue.size()) { MouseInteractionEvent * mie = dynamic_cast<MouseInteractionEvent*>(InteractionManager::instance()->_mouseQueue.front()); if(!mie) { tempQueue.push(InteractionManager::instance()->_mouseQueue.front()); InteractionManager::instance()->_mouseQueue.pop(); continue; } InteractionManager::instance()->_mouseQueue.pop(); if(mie->getButton() < 0 || mie->getButton() >= _handButtonList.size() || !_handValidList[mie->getButton()]) { tempQueue.push(mie); continue; } InteractionEvent * event; if(TrackingManager::instance()->getHandTrackerType(_handButtonList[mie->getButton()].first) == TrackerBase::MOUSE) { mie->setHand(_handButtonList[mie->getButton()].first); mie->setButton(_handButtonList[mie->getButton()].second); event = mie; } else { TrackedButtonInteractionEvent * tie = new TrackedButtonInteractionEvent; tie->setInteraction(mie->getInteraction()); tie->setHand(_handButtonList[mie->getButton()].first); tie->setButton(_handButtonList[mie->getButton()].second); int hsystem, hindex; TrackingManager::instance()->getHandAddress(_handButtonList[mie->getButton()].first,hsystem,hindex); if(TrackingManager::instance()->getTrackingSystem(hsystem)) { TrackerBase::TrackedBody * body = TrackingManager::instance()->getTrackingSystem(hsystem)->getBody(hindex); tie->setTransform(TrackingManager::instance()->getHandTransformFromTrackedBody(_handButtonList[mie->getButton()].first,body)); } delete mie; event = tie; } eventMap[event->getEventType()].push_back(event); } // put unusable events back in the mouse interaction queue so they will be cleaned up later while(tempQueue.size()) { InteractionManager::instance()->_mouseQueue.push(tempQueue.front()); tempQueue.pop(); } }