/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2016 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include // #include #include #include #include #include #include #include #include #include namespace { const std::string _loggerCat = "InteractionHandler"; } #include "interactionhandler_lua.inl" namespace openspace { namespace interaction { #ifdef USE_OLD_INTERACTIONHANDLER InteractionHandler::InteractionHandler() : properties::PropertyOwner() , _camera(nullptr) , _focusNode(nullptr) , _deltaTime(0.0) //, _validKeyLua(false) , _controllerSensitivity(1.f) , _invertRoll(true) , _invertRotation(false) , _keyboardController(nullptr) , _mouseController(nullptr) , _origin("origin", "Origin", "") , _coordinateSystem("coordinateSystem", "Coordinate System", "") , _currentKeyframeTime(-1.0) { setName("Interaction"); _origin.onChange([this](){ SceneGraphNode* node = sceneGraphNode(_origin.value()); if (!node) { LWARNING("Could not find a node in scenegraph called '" << _origin.value() <<"'"); return; } setFocusNode(node); }); addProperty(_origin); _coordinateSystem.onChange([this](){ OsEng.renderEngine().changeViewPoint(_coordinateSystem.value()); }); addProperty(_coordinateSystem); } InteractionHandler::~InteractionHandler() { delete _keyboardController; delete _mouseController; for (size_t i = 0; i < _controllers.size(); ++i) delete _controllers[i]; } void InteractionHandler::setKeyboardController(KeyboardController* controller) { assert(controller); delete _keyboardController; _keyboardController = controller; _keyboardController->setHandler(this); } void InteractionHandler::setMouseController(MouseController* controller) { assert(controller); delete _mouseController; _mouseController = controller; _mouseController->setHandler(this); } void InteractionHandler::addController(Controller* controller) { assert(controller); _controllers.push_back(controller); controller->setHandler(this); } void InteractionHandler::lockControls() { _mutex.lock(); } void InteractionHandler::unlockControls() { _mutex.unlock(); } void InteractionHandler::update(double deltaTime) { _deltaTime = deltaTime; _mouseController->update(deltaTime); bool hasKeys = false; psc pos; glm::quat q; _keyframeMutex.lock(); if (_keyframes.size() > 4){ //wait until enough samples are buffered hasKeys = true; openspace::network::datamessagestructures::PositionKeyframe p0, p1, p2, p3; p0 = _keyframes[0]; p1 = _keyframes[1]; p2 = _keyframes[2]; p3 = _keyframes[3]; //interval check if (_currentKeyframeTime < p1._timeStamp){ _currentKeyframeTime = p1._timeStamp; } double t0 = p1._timeStamp; double t1 = p2._timeStamp; double fact = (_currentKeyframeTime - t0) / (t1 - t0); //glm::dvec4 v = positionInterpCR.interpolate(fact, _keyframes[0]._position.dvec4(), _keyframes[1]._position.dvec4(), _keyframes[2]._position.dvec4(), _keyframes[3]._position.dvec4()); glm::dvec4 v = ghoul::interpolateLinear(fact, p1._position.dvec4(), p2._position.dvec4()); pos = psc(v.x, v.y, v.z, v.w); q = ghoul::interpolateLinear(fact, p1._viewRotationQuat, p2._viewRotationQuat); //we're done with this sample interval if (_currentKeyframeTime >= p2._timeStamp){ _keyframes.erase(_keyframes.begin()); _currentKeyframeTime = p1._timeStamp; } _currentKeyframeTime += deltaTime; } _keyframeMutex.unlock(); if (hasKeys) { _camera->setPosition(pos); _camera->setRotation(q); } } void InteractionHandler::setFocusNode(SceneGraphNode* node) { if (_focusNode == node){ return; } _focusNode = node; //orient the camera to the new node psc focusPos = node->worldPosition(); psc camToFocus = focusPos - _camera->position(); glm::vec3 viewDir = glm::normalize(camToFocus.vec3()); glm::vec3 cameraView = glm::normalize(_camera->viewDirectionWorldSpace()); //set new focus position _camera->setFocusPosition(node->worldPosition()); float dot = glm::dot(viewDir, cameraView); //static const float Epsilon = 0.001f; if (dot < 1.f && dot > -1.f) { //if (glm::length(viewDir - cameraView) < 0.001) { //if (viewDir != cameraView) { glm::vec3 rotAxis = glm::normalize(glm::cross(viewDir, cameraView)); float angle = glm::angle(viewDir, cameraView); glm::quat q = glm::angleAxis(angle, rotAxis); //rotate view to target new focus _camera->rotate(q); } } const SceneGraphNode* const InteractionHandler::focusNode() const { return _focusNode; } void InteractionHandler::setCamera(Camera* camera) { assert(camera); _camera = camera; } const Camera* const InteractionHandler::camera() const { return _camera; } //void InteractionHandler::keyboardCallback(int key, int action) { // if (_keyboardController) { // auto start = ghoul::HighResClock::now(); // _keyboardController->keyPressed(KeyAction(action), Key(key), KeyModifier::None); // auto end = ghoul::HighResClock::now(); // LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); // } //} void InteractionHandler::mouseButtonCallback(MouseButton button, MouseAction action) { if (_mouseController) _mouseController->button(button, action); } void InteractionHandler::mousePositionCallback(double x, double y) { if (_mouseController) // TODO Remap screen coordinates to [0,1] _mouseController->move(static_cast(x), static_cast(y)); } void InteractionHandler::mouseScrollWheelCallback(double pos) { if (_mouseController) _mouseController->scrollWheel(static_cast(pos)); } void InteractionHandler::orbit(const float &dx, const float &dy, const float &dz, const float &dist){ lockControls(); glm::vec3 cameraUp = glm::normalize((glm::inverse(_camera->viewRotationMatrix()) * glm::vec4(_camera->lookUpVectorCameraSpace(), 0))).xyz(); glm::vec3 cameraRight = glm::cross(glm::vec3(_camera->viewDirectionWorldSpace()), cameraUp); glm::mat4 transform; transform = glm::rotate(glm::radians(dx * 100.f), cameraUp) * transform; transform = glm::rotate(glm::radians(dy * 100.f), cameraRight) * transform; transform = glm::rotate(glm::radians(dz * 100.f), glm::vec3(_camera->viewDirectionWorldSpace())) * transform; //get "old" focus position psc camPos = _camera->position(); psc focusPos = _camera->focusPosition(); float distToFocusNodeCenter = (focusPos - camPos).length().lengthf(); float focusNodeBounds = _focusNode ? _focusNode->boundingSphere().lengthf() : 0.f; float speedFactor = distToFocusNodeCenter - 0.098*focusNodeBounds; float rotationSpeed = glm::min(0.00001f * speedFactor, 100.0f); float zoomSpeed = glm::min(0.0000001f * speedFactor, 1.0f); float rollSpeed = 100.0f; glm::mat4 transform; transform = glm::rotate(glm::radians(dx * rotationSpeed), cameraUp) * transform; transform = glm::rotate(glm::radians(dy * rotationSpeed), cameraRight) * transform; transform = glm::rotate(glm::radians(dz * rollSpeed), _camera->viewDirection()) * transform; //// get camera position //psc relative = _camera->position(); // get camera position (UNSYNCHRONIZED) psc relative = _camera->unsynchedPosition(); //get relative vector psc relative_focus_coordinate = relative - focusPos; //rotate relative vector relative_focus_coordinate = glm::inverse(transform) * relative_focus_coordinate.vec4(); //get new new position of focus node psc origin; if (_focusNode) { origin = _focusNode->worldPosition(); } //new camera position relative = origin + relative_focus_coordinate; psc target = relative + relative_focus_coordinate * dist * zoomSpeed; //don't fly into objects if ((target - origin).length() < focusNodeBounds){ //target = relative; } unlockControls(); _camera->setFocusPosition(origin); _camera->setPosition(target); _camera->rotate(glm::quat_cast(transform)); } //void InteractionHandler::distance(const float &d){ // // lockControls(); // // psc relative = _camera->position(); // const psc origin = (_focusNode) ? _focusNode->worldPosition() : psc(); // psc relative_origin_coordinate = relative - origin; // // addition 100% of bounds (fix later to something node specific?) // float bounds = 2.f * (_focusNode ? _focusNode->boundingSphere().lengthf() : 0.f); // // psc target = relative + relative_origin_coordinate * d;// *fmaxf(bounds, (1.f - d)); // //don't fly into objects // if ((target - origin).length() < bounds){ // target = relative; // } // _camera->setPosition(target); // // unlockControls(); //} void InteractionHandler::orbitDelta(const glm::quat& rotation) { lockControls(); // the camera position psc relative = _camera->position(); // should be changed to something more dynamic =) psc origin; if (_focusNode) { origin = _focusNode->worldPosition(); } psc relative_origin_coordinate = relative - origin; //glm::mat4 rotation_matrix = glm::mat4_cast(glm::inverse(rotation)); //relative_origin_coordinate = relative_origin_coordinate.vec4() * glm::inverse(rotation); relative_origin_coordinate = glm::inverse(rotation) * relative_origin_coordinate.vec4(); relative = relative_origin_coordinate + origin; glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, glm::vec3(_camera->lookUpVectorCameraSpace()))); unlockControls(); _camera->setPosition(relative); //camera_->rotate(rotation); //camera_->setRotation(glm::mat4_cast(rotation)); _camera->setRotation(glm::quat_cast(la)); //camera_->setLookUpVector(); } //<<<<<<< HEAD //void InteractionHandler::distance(const PowerScaledScalar &dist, size_t iterations) { // if (iterations > 5) // return; // //assert(this_); // lockControls(); // // psc relative = _camera->position(); // const psc origin = (_node) ? _node->worldPosition() : psc(); // // psc relative_origin_coordinate = relative - origin; // const glm::vec3 dir(relative_origin_coordinate.direction()); // glm::vec3 newdir = dir * dist[0]; //======= void InteractionHandler::rotateDelta(const glm::quat& rotation) { _camera->rotate(rotation); } void InteractionHandler::distanceDelta(const PowerScaledScalar& distance, size_t iterations) { if (iterations > 5) return; //assert(this_); lockControls(); psc relative = _camera->position(); const psc origin = (_focusNode) ? _focusNode->worldPosition() : psc(); unlockControls(); psc relative_origin_coordinate = relative - origin; const glm::vec3 dir(relative_origin_coordinate.direction()); glm::vec3 newdir = dir * distance[0]; relative_origin_coordinate = newdir; relative_origin_coordinate[3] = distance[1]; relative = relative + relative_origin_coordinate; relative_origin_coordinate = relative - origin; if (relative_origin_coordinate.vec4().x == 0.f && relative_origin_coordinate.vec4().y == 0.f && relative_origin_coordinate.vec4().z == 0.f) // TODO: this shouldn't be allowed to happen; a mechanism to prevent the camera to coincide with the origin is necessary (ab) return; newdir = relative_origin_coordinate.direction(); // update only if on the same side of the origin if (glm::angle(newdir, dir) < 90.0f) { _camera->setPosition(relative); } else { PowerScaledScalar d2 = distance; d2[0] *= 0.75f; d2[1] *= 0.85f; distanceDelta(d2, iterations + 1); } } void InteractionHandler::lookAt(const glm::quat& rotation) { } void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) { // TODO package in script const float speed = _controllerSensitivity; const float dt = static_cast(_deltaTime); if (action == KeyAction::Press || action == KeyAction::Repeat) { if ((key == Key::Right) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(0.0, speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } if ((key == Key::Left) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(0.0, -speed * dt*0.4, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } if ((key == Key::Down) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(speed * dt*0.4, 0.0, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } if ((key == Key::Up) && (modifier == KeyModifier::NoModifier)) { glm::vec3 euler(-speed * dt*0.4, 0.0, 0.0); glm::quat rot = glm::quat(euler); rotateDelta(rot); } if ((key == Key::KeypadSubtract) && (modifier == KeyModifier::NoModifier)) { glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] -= 0.5f; OsEng.renderEngine().camera()->setScaling(s); } if ((key == Key::KeypadAdd) && (modifier == KeyModifier::NoModifier)) { glm::vec2 s = OsEng.renderEngine().camera()->scaling(); s[1] += 0.5f; OsEng.renderEngine().camera()->setScaling(s); } // iterate over key bindings //_validKeyLua = true; auto ret = _keyLua.equal_range({ key, modifier }); for (auto it = ret.first; it != ret.second; ++it) { //OsEng.scriptEngine()->runScript(it->second); OsEng.scriptEngine().queueScript(it->second); //if (!_validKeyLua) { // break; //} } } } void InteractionHandler::resetKeyBindings() { _keyLua.clear(); //_validKeyLua = false; } void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) { _keyLua.insert({ {key, modifier}, lua }); } scripting::ScriptEngine::LuaLibrary InteractionHandler::luaLibrary() { return { "", { { "clearKeys", &luascriptfunctions::clearKeys, "", "Clear all key bindings" }, { "bindKey", &luascriptfunctions::bindKey, "string, string", "Binds a key by name to a lua string command" }, { "dt", &luascriptfunctions::dt, "", "Get current frame time" }, { "distance", &luascriptfunctions::distance, "number", "Change distance to origin", true }, { "setInteractionSensitivity", &luascriptfunctions::setInteractionSensitivity, "number", "Sets the global interaction sensitivity" }, { "interactionSensitivity", &luascriptfunctions::interactionSensitivity, "", "Gets the current global interaction sensitivity" }, { "setInvertRoll", &luascriptfunctions::setInvertRoll, "bool", "Sets the setting if roll movements are inverted" }, { "invertRoll", &luascriptfunctions::invertRoll, "", "Returns the status of roll movement inversion" }, { "setInvertRotation", &luascriptfunctions::setInvertRotation, "bool", "Sets the setting if rotation movements are inverted" }, { "invertRotation", &luascriptfunctions::invertRotation, "", "Returns the status of rotation movement inversion" } } }; } void InteractionHandler::setRotation(const glm::quat& rotation) { _camera->setRotation(rotation); } double InteractionHandler::deltaTime() const { return _deltaTime; } void InteractionHandler::setInteractionSensitivity(float sensitivity) { _controllerSensitivity = sensitivity; } float InteractionHandler::interactionSensitivity() const { return _controllerSensitivity; } void InteractionHandler::setInvertRoll(bool invert) { _invertRoll = invert; } bool InteractionHandler::invertRoll() const { return _invertRoll; } void InteractionHandler::setInvertRotation(bool invert) { _invertRotation = invert; } bool InteractionHandler::invertRotation() const { return _invertRotation; } void InteractionHandler::addKeyframe(const network::datamessagestructures::PositionKeyframe &kf){ _keyframeMutex.lock(); //save a maximum of 10 samples (1 seconds of buffer) if (_keyframes.size() >= 10){ _keyframes.erase(_keyframes.begin()); } _keyframes.push_back(kf); _keyframeMutex.unlock(); } void InteractionHandler::clearKeyframes(){ _keyframeMutex.lock(); _keyframes.clear(); _keyframeMutex.unlock(); } #else // USE_OLD_INTERACTIONHANDLER // InputState InputState::InputState() { } InputState::~InputState() { } void InputState::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) { if (action == KeyAction::Press) { _keysDown.push_back(std::pair(key, modifier)); } else if (action == KeyAction::Release) { // Remove all key pressings for 'key' _keysDown.remove_if([key](std::pair keyModPair) { return keyModPair.first == key; }); } } void InputState::mouseButtonCallback(MouseButton button, MouseAction action) { if (action == MouseAction::Press) { _mouseButtonsDown.push_back(button); } else if (action == MouseAction::Release) { // Remove all key pressings for 'button' _mouseButtonsDown.remove_if([button](MouseButton buttonInList) { return button == buttonInList; }); } } void InputState::mousePositionCallback(double mouseX, double mouseY) { _mousePosition = glm::dvec2(mouseX, mouseY); } void InputState::mouseScrollWheelCallback(double mouseScrollDelta) { _mouseScrollDelta = mouseScrollDelta; } const std::list >& InputState::getPressedKeys() { return _keysDown; } const std::list& InputState::getPressedMouseButtons() { return _mouseButtonsDown; } glm::dvec2 InputState::getMousePosition() { return _mousePosition; } double InputState::getMouseScrollDelta() { return _mouseScrollDelta; } bool InputState::isKeyPressed(std::pair keyModPair) { for (auto it = _keysDown.begin(); it != _keysDown.end(); it++) { if (*it == keyModPair) { return true; } } return false; } bool InputState::isMouseButtonPressed(MouseButton mouseButton) { for (auto it = _mouseButtonsDown.begin(); it != _mouseButtonsDown.end(); it++) { if (*it == mouseButton) { return true; } } return false; } // InteractionMode InteractionMode::InteractionMode(std::shared_ptr inputState) : _inputState(inputState) , _focusNode(nullptr) , _camera(nullptr) { } InteractionMode::~InteractionMode() { } void InteractionMode::setFocusNode(SceneGraphNode* focusNode) { _focusNode = focusNode; } void InteractionMode::setCamera(Camera* camera) { _camera = camera; } SceneGraphNode* InteractionMode::focusNode() { return _focusNode; } Camera* InteractionMode::camera() { return _camera; } // OrbitalInteractionMode OrbitalInteractionMode::OrbitalInteractionMode( std::shared_ptr inputState, double sensitivity, double velocityScaleFactor) : InteractionMode(inputState) , _sensitivity(sensitivity) , _globalRotationMouseState(velocityScaleFactor) , _localRotationMouseState(velocityScaleFactor) , _truckMovementMouseState(velocityScaleFactor) , _rollMouseState(velocityScaleFactor) { } OrbitalInteractionMode::~OrbitalInteractionMode() { } void OrbitalInteractionMode::updateMouseStatesFromInput(double deltaTime) { glm::dvec2 mousePosition = _inputState->getMousePosition(); bool button1Pressed = _inputState->isMouseButtonPressed(MouseButton::Button1); bool button2Pressed = _inputState->isMouseButtonPressed(MouseButton::Button2); bool button3Pressed = _inputState->isMouseButtonPressed(MouseButton::Button3); bool keyCtrlPressed = _inputState->isKeyPressed( std::pair(Key::LeftControl, KeyModifier::Control)); // Update the mouse states if (button1Pressed) { if (keyCtrlPressed) { glm::dvec2 mousePositionDelta = _localRotationMouseState.previousPosition - mousePosition; _localRotationMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity); } else { glm::dvec2 mousePositionDelta = _globalRotationMouseState.previousPosition - mousePosition; _globalRotationMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity); } } else { //!button1Pressed _globalRotationMouseState.previousPosition = mousePosition; _localRotationMouseState.previousPosition = mousePosition; _globalRotationMouseState.velocity.set(glm::dvec2(0, 0)); _localRotationMouseState.velocity.set(glm::dvec2(0, 0)); } if (button2Pressed) { glm::dvec2 mousePositionDelta = _truckMovementMouseState.previousPosition - mousePosition; _truckMovementMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity); } else { // !button2Pressed _truckMovementMouseState.previousPosition = mousePosition; _truckMovementMouseState.velocity.set(glm::dvec2(0, 0)); } if (button3Pressed) { glm::dvec2 mousePositionDelta = _rollMouseState.previousPosition - mousePosition; _rollMouseState.velocity.set(mousePositionDelta * deltaTime * _sensitivity); } else { // !button3Pressed _rollMouseState.previousPosition = mousePosition; _rollMouseState.velocity.set(glm::dvec2(0, 0)); } } void OrbitalInteractionMode::updateCameraStateFromMouseStates() { if (_focusNode) { // Declare variables to use in interaction calculations glm::dvec3 centerPos = _focusNode->worldPosition().dvec3(); glm::dvec3 camPos = _camera->positionVec3(); glm::dvec3 posDiff = camPos - centerPos; glm::dvec3 newPosition = camPos; { // Do local rotation glm::dvec3 eulerAngles(_localRotationMouseState.velocity.get().y, 0, 0); glm::dquat rotationDiff = glm::dquat(eulerAngles); _localCameraRotation = _localCameraRotation * rotationDiff; } { // Do global rotation glm::dvec3 eulerAngles( -_globalRotationMouseState.velocity.get().y, -_globalRotationMouseState.velocity.get().x, 0); glm::dquat rotationDiffCamSpace = glm::dquat(eulerAngles); glm::dquat newRotationCamspace = _globalCameraRotation * rotationDiffCamSpace; glm::dquat rotationDiffWorldSpace = newRotationCamspace * glm::inverse(_globalCameraRotation); glm::dvec3 rotationDiffVec3 = posDiff * rotationDiffWorldSpace - posDiff; newPosition = camPos + rotationDiffVec3; glm::dvec3 lookUp = _camera->lookUpVectorWorldSpace(); glm::dmat4 lookAtMat = glm::lookAt( glm::dvec3(0, 0, 0), glm::normalize(centerPos - newPosition), lookUp); _globalCameraRotation = glm::normalize(glm::quat_cast(glm::inverse(lookAtMat))); } { // Move position towards or away from focus node newPosition += -posDiff * _truckMovementMouseState.velocity.get().y; } { // Do roll glm::dquat cameraRollRotation = glm::angleAxis(_rollMouseState.velocity.get().x, glm::normalize(posDiff)); _globalCameraRotation = cameraRollRotation * _globalCameraRotation; } // Update the camera state _camera->setRotation(_globalCameraRotation * _localCameraRotation); _camera->setPositionVec3(newPosition); } } void OrbitalInteractionMode::update(double deltaTime) { updateMouseStatesFromInput(deltaTime); updateCameraStateFromMouseStates(); } // InteractionHandler InteractionHandler::InteractionHandler() : _origin("origin", "Origin", "") , _coordinateSystem("coordinateSystem", "Coordinate System", "") { setName("Interaction"); _origin.onChange([this]() { SceneGraphNode* node = sceneGraphNode(_origin.value()); if (!node) { LWARNING("Could not find a node in scenegraph called '" << _origin.value() << "'"); return; } setFocusNode(node); }); addProperty(_origin); _coordinateSystem.onChange([this]() { OsEng.renderEngine().changeViewPoint(_coordinateSystem.value()); }); addProperty(_coordinateSystem); _inputState = std::shared_ptr(new InputState()); _interactor = std::shared_ptr( new OrbitalInteractionMode(_inputState, 0.002, 0.02)); } InteractionHandler::~InteractionHandler() { } void InteractionHandler::setKeyboardController(KeyboardController* controller) { //_interactor->setKeyboardController(controller); } void InteractionHandler::setMouseController(MouseController* controller) { //_interactor->setMouseController(controller); } void InteractionHandler::setFocusNode(SceneGraphNode* node) { _interactor->setFocusNode(node); } void InteractionHandler::setCamera(Camera* camera) { _interactor->setCamera(camera); } void InteractionHandler::lockControls() { } void InteractionHandler::unlockControls() { } void InteractionHandler::update(double deltaTime) { _interactor->update(deltaTime); } const SceneGraphNode* const InteractionHandler::focusNode() const { return _interactor->focusNode(); } const Camera* const InteractionHandler::camera() const { return _interactor->camera(); } void InteractionHandler::mouseButtonCallback(MouseButton button, MouseAction action) { _inputState->mouseButtonCallback(button, action); } void InteractionHandler::mousePositionCallback(double x, double y) { _inputState->mousePositionCallback(x, y); } void InteractionHandler::mouseScrollWheelCallback(double pos) { _inputState->mouseScrollWheelCallback(pos); } void InteractionHandler::keyboardCallback(Key key, KeyModifier modifier, KeyAction action) { _inputState->keyboardCallback(key, modifier, action); if (action == KeyAction::Press || action == KeyAction::Repeat) { // iterate over key bindings auto ret = _keyLua.equal_range({ key, modifier }); for (auto it = ret.first; it != ret.second; ++it) { //OsEng.scriptEngine()->runScript(it->second); OsEng.scriptEngine().queueScript(it->second); } } } void InteractionHandler::resetKeyBindings() { _keyLua.clear(); } void InteractionHandler::bindKey(Key key, KeyModifier modifier, std::string lua) { _keyLua.insert({ { key, modifier }, lua }); } scripting::ScriptEngine::LuaLibrary InteractionHandler::luaLibrary() { return{ "", { { "clearKeys", &luascriptfunctions::clearKeys, "", "Clear all key bindings" }, { "bindKey", &luascriptfunctions::bindKey, "string, string", "Binds a key by name to a lua string command" }, { "dt", &luascriptfunctions::dt, "", "Get current frame time" }, { "distance", &luascriptfunctions::distance, "number", "Change distance to origin", true }, { "setInteractionSensitivity", &luascriptfunctions::setInteractionSensitivity, "number", "Sets the global interaction sensitivity" }, { "interactionSensitivity", &luascriptfunctions::interactionSensitivity, "", "Gets the current global interaction sensitivity" }, { "setInvertRoll", &luascriptfunctions::setInvertRoll, "bool", "Sets the setting if roll movements are inverted" }, { "invertRoll", &luascriptfunctions::invertRoll, "", "Returns the status of roll movement inversion" }, { "setInvertRotation", &luascriptfunctions::setInvertRotation, "bool", "Sets the setting if rotation movements are inverted" }, { "invertRotation", &luascriptfunctions::invertRotation, "", "Returns the status of rotation movement inversion" } } }; } void InteractionHandler::addKeyframe(const network::datamessagestructures::PositionKeyframe &kf) { } void InteractionHandler::clearKeyframes() { } #endif // USE_OLD_INTERACTIONHANDLER } // namespace interaction } // namespace openspace