/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014 * * * * 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 namespace { const std::string _loggerCat = "InteractionHandler"; } namespace openspace { namespace interaction { InteractionHandler::InteractionHandler() : _camera(nullptr) , _focusNode(nullptr) , _keyboardController(nullptr) , _mouseController(nullptr) { } 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; } void InteractionHandler::setFocusNode(SceneGraphNode* node) { _focusNode = node; } 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), Keys(key)); auto end = ghoul::HighResClock::now(); LINFO("Keyboard timing: " << std::chrono::duration_cast(end - start).count() << "ns"); } } void InteractionHandler::mouseButtonCallback(int button, int action) { if (_mouseController) _mouseController->button(MouseAction(action), MouseButton(button)); } void InteractionHandler::mousePositionCallback(int x, int y) { if (_mouseController) // TODO Remap screen coordinates to [0,1] _mouseController->move(float(x), float(y)); } void InteractionHandler::mouseScrollWheelCallback(int pos) { if (_mouseController) _mouseController->scrollWheel(float(pos)); } } // namespace interaction } // namespace openspace // //// open space includes //#include //#include //#include ////#include ////#include //#include //#include //#include //#include // //#include // //#include // //namespace { // const std::string _loggerCat = "InteractionHandler"; //} // //namespace openspace { //namespace interaction { // //InteractionHandler::InteractionHandler() // : _camera(nullptr) // , _node(nullptr) // , _dt(0.0) // , _lastTrackballPos(0.f) // , _leftMouseButtonDown(false) // , _isMouseBeingPressedAndHeld(false) //{ //} // //InteractionHandler::~InteractionHandler() { // //for (size_t i = 0; i < _controllers.size(); ++i) { // // delete _controllers[i]; // //} //} // ////void InteractionHandler::init() { //// assert( ! this_); //// this_ = new InteractionHandler(); ////} //// ////void InteractionHandler::deinit() { //// assert(this_); //// delete this_; //// this_ = nullptr; ////} //// ////InteractionHandler& InteractionHandler::ref() { //// assert(this_); //// return *this_; ////} // ////bool InteractionHandler::isInitialized() { //// return this_ != nullptr; ////} // ////void InteractionHandler::connectDevices() { //// //assert(this_); //// assert(DeviceIdentifier::ref().isInitialized()); //// //// // for each device found //// for(int i = 0; i < DeviceIdentifier::ref().numberOfDevices(); ++i) { //// //// // TODO //// //if(DeviceIdentifier::ref().type(i) == InputDevice::XBOX) { //// //// // // found xbox, use xbox python controller //// // JoystickExternalControl *joystickexcontrol = new JoystickExternalControl(RELATIVE_PATH"pyinput/Xbox.py"); //// // joystickexcontrol->setInputDevice(i); //// // addExternalControl(joystickexcontrol); //// //// //} else if(DeviceIdentifier::ref().type(i) == InputDevice::SPACENAVIGATOR) { //// //// // // found SpaceNavigator, use SpaceNavigator python controller //// // JoystickExternalControl *joystickexcontrol = new JoystickExternalControl(RELATIVE_PATH"pyinput/SpaceNavigator.py"); //// // joystickexcontrol->setInputDevice(i); //// // addExternalControl(joystickexcontrol); //// //} //// //// } ////} //// ////void InteractionHandler::addExternalControl(ExternalControl* controller) { //// //assert(this_); //// if (controller != nullptr) { //// _controllers.push_back(controller); //// } ////} // //void InteractionHandler::setCamera(Camera *camera) { // //assert(this_); // _camera = camera; //} // //Camera * InteractionHandler::getCamera() const { // return _camera; //} // //const psc InteractionHandler::getOrigin() const { // if(_node) // return _node->worldPosition(); // return psc(); //} // //void InteractionHandler::lockControls() { // //assert(this_); // _cameraGuard.lock(); //} // //void InteractionHandler::unlockControls() { // //assert(this_); // _cameraGuard.unlock(); //} // //void InteractionHandler::setFocusNode(SceneGraphNode *node) { // //assert(this_); // _node = node; //} // //void InteractionHandler::rotate(const glm::quat &rotation) { // //assert(this_); // lockControls(); // _camera->rotate(rotation); // unlockControls(); //} // //void InteractionHandler::orbit(const glm::quat &rotation) { // //assert(this_); // lockControls(); // // // the camera position // psc relative = _camera->position(); // // // should be changed to something more dynamic =) // psc origin; // if (_node) { // origin = _node->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; // // _camera->setPosition(relative); // //camera_->rotate(rotation); // //camera_->setRotation(glm::mat4_cast(rotation)); // // glm::mat4 la = glm::lookAt(_camera->position().vec3(), origin.vec3(), glm::rotate(rotation, _camera->lookUpVector())); // _camera->setRotation(la); // //camera_->setLookUpVector(); // // unlockControls(); //} // //void InteractionHandler::distance(const PowerScaledScalar &distance) { // //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 * distance[0]; // relative_origin_coordinate = newdir; // relative_origin_coordinate[3] = distance[1]; // relative = relative + relative_origin_coordinate; // // relative_origin_coordinate = relative - origin; // 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); // // unlockControls(); //} // //void InteractionHandler::lookAt(const glm::quat &rotation) { // //assert(this_); // lockControls(); // // unlockControls(); //} // //void InteractionHandler::setRotation(const glm::quat &rotation) { // //assert(this_); // lockControls(); // // unlockControls(); //} // //void InteractionHandler::update(const double dt) { // //assert(this_); // // setting dt_ for use in callbacks // _dt = dt; // if (_camera) { // // fetch data from joysticks // DeviceIdentifier::ref().update(); // // //// update all controllers // //for (size_t i = 0; i < _controllers.size(); ++i) { // // _controllers[i]->update(); // //} // } //} // //double InteractionHandler::getDt() { // //assert(this_); // return _dt; //} // //glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) { // const float RADIUS = 0.5; // Sphere radius // glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0); // // // Mapping according to Holroyds trackball // // Piece-wise sphere + hyperbolic sheet // if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) { // //Spherical Region // out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y); // out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0; // } else { //Hyperbolic Region - for smooth z values // out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y)); // } // // return glm::normalize(out); //} // //glm::vec3 InteractionHandler::mapToCamera(glm::vec3 trackballPos) { //// return glm::vec3((sgct::Engine::instance()->getActiveViewMatrix() * glm::vec4(trackballPos,0))); // // //Get x,y,z axis vectors of current camera view // glm::vec3 currentViewYaxis = glm::normalize(_camera->lookUpVector()); // psc viewDir = _camera->position() - _node->worldPosition(); // glm::vec3 currentViewZaxis = glm::normalize(viewDir.vec3()); // glm::vec3 currentViewXaxis = glm::normalize(glm::cross(currentViewYaxis, currentViewZaxis)); // // //mapping to camera co-ordinate // currentViewXaxis*=trackballPos.x; // currentViewYaxis*=trackballPos.y; // currentViewZaxis*=trackballPos.z; // return (currentViewXaxis + currentViewYaxis + currentViewZaxis); //} // //void InteractionHandler::trackballRotate(int x, int y) { // // Normalize mouse coordinates to [0,1] // float width = sgct::Engine::instance()->getActiveXResolution(); // float height = sgct::Engine::instance()->getActiveYResolution(); // glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height); // // mousePos = glm::clamp(mousePos, -0.5, 1.5); // Ugly fix #1: Camera position becomes NaN on mouse values outside [-0.5, 1.5] // //mousePos[1] = 0.5; // Ugly fix #2: Tempoarily only allow rotation around y // // glm::vec3 curTrackballPos = mapToTrackball(mousePos); //// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z); // // // Disable movement on the first click for extra smoothness // if (!_isMouseBeingPressedAndHeld) { // _lastTrackballPos = curTrackballPos; // _isMouseBeingPressedAndHeld = true; // } // // if (curTrackballPos != _lastTrackballPos) { // // calculate rotation angle (in radians) // float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos); // rotationAngle *= getDt()*100.0f; // // // Map trackballpos to camera //// glm::vec3 trackballMappedToCamera = mapToCamera(_lastTrackballPos - curTrackballPos); //// psc currentCamPos = camera_->getPosition(); //// glm::vec3 nextCamPos = currentCamPos.getVec3f() + trackballMappedToCamera; //// glm::vec3 rotationAxis = glm::cross(currentCamPos.getVec3f(), nextCamPos); // // glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos); // rotationAxis = glm::normalize(rotationAxis); // glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis); // // // Apply quaternion to camera // orbit(quaternion); // // _lastTrackballPos = curTrackballPos; // } //} //double acc = 1; // //void InteractionHandler::keyboardCallback(int key, int action) { // // TODO package in script // const double speed = 2.75; // const double dt = getDt(); // if(action == SGCT_PRESS || action == SGCT_REPEAT) { // if (key == SGCT_KEY_S) { // glm::vec3 euler(speed * dt, 0.0, 0.0); // glm::quat rot = glm::quat(euler); // orbit(rot); // } // if (key == SGCT_KEY_W) { // glm::vec3 euler(-speed * dt, 0.0, 0.0); // glm::quat rot = glm::quat(euler); // orbit(rot); // } // if (key == SGCT_KEY_A) { // glm::vec3 euler(0.0, -speed * dt, 0.0); // glm::quat rot = glm::quat(euler); // orbit(rot); // } // if (key == SGCT_KEY_D) { // glm::vec3 euler(0.0, speed * dt, 0.0); // glm::quat rot = glm::quat(euler); // orbit(rot); // } // if (key == SGCT_KEY_Q) { // Time::ref().advanceTime(dt); // } // if (key == 262) { // glm::vec3 euler(0.0, speed * dt, 0.0); // glm::quat rot = glm::quat(euler); // rotate(rot); // } // if (key == 263) { // glm::vec3 euler(0.0, -speed * dt, 0.0); // glm::quat rot = glm::quat(euler); // rotate(rot); // } // if (key == 264) { // glm::vec3 euler(speed * dt, 0.0, 0.0); // glm::quat rot = glm::quat(euler); // rotate(rot); // } // if (key == 265) { // glm::vec3 euler(-speed * dt, 0.0, 0.0); // glm::quat rot = glm::quat(euler); // rotate(rot); // } // if (key == SGCT_KEY_R) { // PowerScaledScalar dist(-speed * dt, 0.0); // distance(dist); // } // if (key == SGCT_KEY_F) { // PowerScaledScalar dist(speed * dt, 0.0); // distance(dist); // } // if (key == SGCT_KEY_T) { // PowerScaledScalar dist(-speed * pow(10, 11) * dt, 0.0); // distance(dist); // } // if (key == SGCT_KEY_G) { // acc += 0.001; // PowerScaledScalar dist(speed * pow(10, 8 * acc) * dt, 0.0); // distance(dist); // } // if (key == SGCT_KEY_Y) { // PowerScaledScalar dist(-speed * 100.0 * dt, 6.0); // distance(dist); // } // if (key == SGCT_KEY_H) { // PowerScaledScalar dist(speed * 100.0 * dt, 6.0); // distance(dist); // } // // if (key == SGCT_KEY_KP_SUBTRACT) { // glm::vec2 s = OsEng.renderEngine().camera()->scaling(); // s[1] -= 0.5; // OsEng.renderEngine().camera()->setScaling(s); // } // if (key == SGCT_KEY_KP_ADD) { // glm::vec2 s = OsEng.renderEngine().camera()->scaling(); // s[1] += 0.5; // OsEng.renderEngine().camera()->setScaling(s); // } // } // /* // if (key == '1') { // SceneGraphNode* node = getSceneGraphNode("sun"); // // setFocusNode(node); // getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 10.0)); // getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); // } // // if (key == '2') { // SceneGraphNode* node = getSceneGraphNode("earth"); // // setFocusNode(node); // getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 1.0, 8.0)); // getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); // } // // // if (key == '3') { // SceneGraphNode* node = getSceneGraphNode("moon"); // // setFocusNode(node); // getCamera()->setPosition(node->getWorldPosition() + psc(0.0, 0.0, 0.5, 8.0)); // getCamera()->setCameraDirection(glm::vec3(0.0, 0.0, -1.0)); // } //*/ // // std::pair >::iterator, std::multimap >::iterator> ret; // if(action == SGCT_PRESS) { // auto ret = _keyCallbacks.equal_range(key); // for (auto it=ret.first; it!=ret.second; ++it) // it->second(); // } // // //} // //void InteractionHandler::mouseButtonCallback(int key, int action) { // //if(mouseControl_ != nullptr) { // // mouseControl_->mouseButtonCallback(key,action); // //} // if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_PRESS) // _leftMouseButtonDown = true; // else if (key == SGCT_MOUSE_BUTTON_LEFT && action == SGCT_RELEASE) { // _leftMouseButtonDown = false; // _isMouseBeingPressedAndHeld = false; // } //} // //void InteractionHandler::mousePositionCallback(int x, int y) { // if (_leftMouseButtonDown) // trackballRotate(x,y); // // //if(mouseControl_ != nullptr) { // // mouseControl_->mousePosCallback(x,y); // //} //} // //void InteractionHandler::mouseScrollWheelCallback(int pos) { // //if(mouseControl_ != nullptr) { // // mouseControl_->mouseScrollCallback(pos); // //} // const double speed = 4.75; // const double dt = getDt(); // if(pos < 0) { // PowerScaledScalar dist(speed * dt, 0.0); // distance(dist); // } else if(pos > 0) { // PowerScaledScalar dist(-speed * dt, 0.0); // distance(dist); // } //} // ////void InteractionHandler::addKeyCallback(int key, std::function f) { //// //std::map > > _keyCallbacks; //// //// _keyCallbacks.insert(std::make_pair(key, f)); ////} // //} // namespace interaction //} // namespace openspace