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;
	}
    }
}
Beispiel #2
0
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;
        }
    }
}
Beispiel #7
0
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();
    }
}