diff --git a/cmake/modules/FindATL.cmake b/cmake/modules/FindATL.cmake new file mode 100644 index 0000000000..f95b0267eb --- /dev/null +++ b/cmake/modules/FindATL.cmake @@ -0,0 +1,29 @@ +# +# FindATL.cmake +# +# Try to find the ATL library needed to use the LibOVR +# +# Once done this will define +# +# ATL_FOUND - system found ATL +# ATL_LIBRARIES - Link this to use ATL +# +# Created on 8/13/2013 by Stephen Birarda +# Copyright 2014 High Fidelity, Inc. +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +if (WIN32) + find_library(ATL_LIBRARY_RELEASE atls PATH_SUFFIXES "7600.16385.1/lib/ATL/i386" HINTS "C:\\WinDDK") + find_library(ATL_LIBRARY_DEBUG atlsd PATH_SUFFIXES "7600.16385.1/lib/ATL/i386" HINTS "C:\\WinDDK") + + include(SelectLibraryConfigurations) + select_library_configurations(ATL) +endif () + +set(ATL_LIBRARIES "${ATL_LIBRARY}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ATL DEFAULT_MSG ATL_LIBRARIES) \ No newline at end of file diff --git a/cmake/modules/FindLibOVR.cmake b/cmake/modules/FindLibOVR.cmake index e1fce969e5..a1d75add3f 100644 --- a/cmake/modules/FindLibOVR.cmake +++ b/cmake/modules/FindLibOVR.cmake @@ -27,8 +27,8 @@ find_path(LIBOVR_SRC_DIR Util_Render_Stereo.h PATH_SUFFIXES Src/Util HINTS ${LIB include(SelectLibraryConfigurations) if (APPLE) - find_library(LIBOVR_LIBRARY_DEBUG NAMES ovr PATH_SUFFIXES Lib/MacOS/Debug HINTS ${LIBOVR_SEARCH_DIRS}) - find_library(LIBOVR_LIBRARY_RELEASE NAMES ovr PATH_SUFFIXES Lib/MacOS/Release HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARY_DEBUG NAMES ovr PATH_SUFFIXES Lib/Mac/Debug HINTS ${LIBOVR_SEARCH_DIRS}) + find_library(LIBOVR_LIBRARY_RELEASE NAMES ovr PATH_SUFFIXES Lib/Mac/Release HINTS ${LIBOVR_SEARCH_DIRS}) find_library(ApplicationServices ApplicationServices) find_library(IOKit IOKit) elseif (UNIX) @@ -50,24 +50,27 @@ elseif (UNIX) elseif (WIN32) find_library(LIBOVR_LIBRARY_DEBUG NAMES libovrd PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) find_library(LIBOVR_LIBRARY_RELEASE NAMES libovr PATH_SUFFIXES Lib/Win32/VS2010 HINTS ${LIBOVR_SEARCH_DIRS}) + find_package(ATL) endif () select_library_configurations(LIBOVR) -set(LIBOVR_LIBRARIES "${LIBOVR_LIBRARY}") +set(LIBOVR_LIBRARIES ${LIBOVR_LIBRARY}) + +list(APPEND LIBOVR_ARGS_LIST LIBOVR_INCLUDE_DIRS LIBOVR_SRC_DIR LIBOVR_LIBRARY) if (APPLE) - set(LIBOVR_LIBRARIES "${LIBOVR_LIBRARIES}" ${IOKit} ${ApplicationServices}) + list(APPEND LIBOVR_LIBRARIES ${IOKit} ${ApplicationServices}) + list(APPEND LIBOVR_ARGS_LIST IOKit ApplicationServices) elseif (UNIX) - set(LIBOVR_LIBRARIES "${LIBOVR_LIBRARIES}" "${UDEV_LIBRARY}" "${XINERAMA_LIBRARY}") + list(APPEND LIBOVR_LIBRARIES "${UDEV_LIBRARY}" "${XINERAMA_LIBRARY}") + list(APPEND LIBOVR_ARGS_LIST UDEV_LIBRARY XINERAMA_LIBRARY) +elseif (WIN32) + list(APPEND LIBOVR_LIBRARIES ${ATL_LIBRARIES}) + list(APPEND LIBOVR_ARGS_LIST ATL_LIBRARIES) endif () include(FindPackageHandleStandardArgs) -if (APPLE) - find_package_handle_standard_args(LibOVR DEFAULT_MSG LIBOVR_INCLUDE_DIRS LIBOVR_SRC_DIR LIBOVR_LIBRARIES IOKit ApplicationServices) -elseif (UNIX) - find_package_handle_standard_args(LibOVR DEFAULT_MSG LIBOVR_INCLUDE_DIRS LIBOVR_SRC_DIR LIBOVR_LIBRARIES UDEV_LIBRARY XINERAMA_LIBRARY) -else () - find_package_handle_standard_args(LibOVR DEFAULT_MSG LIBOVR_INCLUDE_DIRS LIBOVR_SRC_DIR LIBOVR_LIBRARIES) -endif () -mark_as_advanced(LIBOVR_INCLUDE_DIRS LIBOVR_LIBRARIES OCULUS_SEARCH_DIRS) +find_package_handle_standard_args(LibOVR DEFAULT_MSG ${LIBOVR_ARGS_LIST}) + +mark_as_advanced(LIBOVR_INCLUDE_DIRS LIBOVR_LIBRARIES LIBOVR_SEARCH_DIRS) diff --git a/cmake/modules/FindQxmpp.cmake b/cmake/modules/FindQxmpp.cmake index 8d8c0e22a2..8fbc63e9dc 100644 --- a/cmake/modules/FindQxmpp.cmake +++ b/cmake/modules/FindQxmpp.cmake @@ -34,6 +34,6 @@ select_library_configurations(QXMPP) set(QXMPP_LIBRARIES "${QXMPP_LIBRARY}" Qt5::Xml) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(QXmpp DEFAULT_MSG QXMPP_INCLUDE_DIRS QXMPP_LIBRARIES) +find_package_handle_standard_args(QXmpp DEFAULT_MSG QXMPP_INCLUDE_DIRS QXMPP_LIBRARIES QXMPP_LIBRARY) mark_as_advanced(QXMPP_INCLUDE_DIRS QXMPP_LIBRARIES QXMPP_SEARCH_DIRS) \ No newline at end of file diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 73d7442c6c..32070a4427 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -8,7 +8,6 @@ foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) string(TOLOWER ${EXTERNAL} ${EXTERNAL}_LOWERCASE) set(${${EXTERNAL}_UPPERCASE}_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/external/${${EXTERNAL}_LOWERCASE}") - message("Dir for ${EXTERNAL} is ${${${EXTERNAL}_UPPERCASE}_ROOT_DIR}") endif () endforeach() diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3007943643..9d49dc6281 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1440,6 +1440,15 @@ void Application::setEnable3DTVMode(bool enable3DTVMode) { } void Application::setEnableVRMode(bool enableVRMode) { + if (enableVRMode) { + if (!OculusManager::isConnected()) { + // attempt to reconnect the Oculus manager - it's possible this was a workaround + // for the sixense crash + OculusManager::disconnect(); + OculusManager::connect(); + } + } + resizeGL(_glWidget->width(), _glWidget->height()); } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f59064732c..08d33ff252 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -255,6 +255,12 @@ void MyAvatar::updateFromTrackers(float deltaTime) { estimatedRotation.x *= -1.0f; estimatedRotation.z *= -1.0f; + } else if (OculusManager::isConnected()) { + estimatedPosition = OculusManager::getRelativePosition(); + estimatedPosition.x *= -1.0f; + + const float OCULUS_LEAN_SCALE = 0.05f; + estimatedPosition /= OCULUS_LEAN_SCALE; } else { FaceTracker* tracker = Application::getInstance()->getActiveFaceTracker(); if (tracker) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index 49164cc8dd..7d7375fad5 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -44,7 +44,7 @@ ovrFovPort OculusManager::_eyeFov[ovrEye_Count]; ovrEyeRenderDesc OculusManager::_eyeRenderDesc[ovrEye_Count]; ovrSizei OculusManager::_renderTargetSize; ovrVector2f OculusManager::_UVScaleOffset[ovrEye_Count][2]; -GLuint OculusManager::_vertices[ovrEye_Count] = { 0, 0 }; +GLuint OculusManager::_vertices[ovrEye_Count] = { 0, 0 }; GLuint OculusManager::_indices[ovrEye_Count] = { 0, 0 }; GLsizei OculusManager::_meshSize[ovrEye_Count] = { 0, 0 }; ovrFrameTiming OculusManager::_hmdFrameTiming; @@ -66,12 +66,14 @@ void OculusManager::connect() { UserActivityLogger::getInstance().connectedDevice("hmd", "oculus"); } _isConnected = true; - +#if defined(__APPLE__) || defined(_WIN32) + _eyeFov[0] = _ovrHmd->DefaultEyeFov[0]; + _eyeFov[1] = _ovrHmd->DefaultEyeFov[1]; +#else ovrHmd_GetDesc(_ovrHmd, &_ovrHmdDesc); - _eyeFov[0] = _ovrHmdDesc.DefaultEyeFov[0]; _eyeFov[1] = _ovrHmdDesc.DefaultEyeFov[1]; - +#endif //Get texture size ovrSizei recommendedTex0Size = ovrHmd_GetFovTextureSize(_ovrHmd, ovrEye_Left, _eyeFov[0], 1.0f); @@ -86,11 +88,21 @@ void OculusManager::connect() { _eyeRenderDesc[0] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Left, _eyeFov[0]); _eyeRenderDesc[1] = ovrHmd_GetRenderDesc(_ovrHmd, ovrEye_Right, _eyeFov[1]); +#if defined(__APPLE__) || defined(_WIN32) + ovrHmd_SetEnabledCaps(_ovrHmd, ovrHmdCap_LowPersistence); +#else ovrHmd_SetEnabledCaps(_ovrHmd, ovrHmdCap_LowPersistence | ovrHmdCap_LatencyTest); +#endif +#if defined(__APPLE__) || defined(_WIN32) + ovrHmd_ConfigureTracking(_ovrHmd, ovrTrackingCap_Orientation | ovrTrackingCap_Position | + ovrTrackingCap_MagYawCorrection, + ovrTrackingCap_Orientation); +#else ovrHmd_StartSensor(_ovrHmd, ovrSensorCap_Orientation | ovrSensorCap_YawCorrection | ovrSensorCap_Position, ovrSensorCap_Orientation); +#endif if (!_camera) { _camera = new Camera; @@ -123,6 +135,10 @@ void OculusManager::connect() { } else { _isConnected = false; + + // we're definitely not in "VR mode" so tell the menu that + Menu::getInstance()->getActionForOption(MenuOption::EnableVRMode)->setChecked(false); + ovrHmd_Destroy(_ovrHmd); ovr_Shutdown(); } @@ -183,6 +199,16 @@ void OculusManager::generateDistortionMesh() { DistortionVertex* v = pVBVerts; ovrDistortionVertex* ov = meshData.pVertexData; for (unsigned int vertNum = 0; vertNum < meshData.VertexCount; vertNum++) { +#if defined(__APPLE__) || defined(_WIN32) + v->pos.x = ov->ScreenPosNDC.x; + v->pos.y = ov->ScreenPosNDC.y; + v->texR.x = ov->TanEyeAnglesR.x; + v->texR.y = ov->TanEyeAnglesR.y; + v->texG.x = ov->TanEyeAnglesG.x; + v->texG.y = ov->TanEyeAnglesG.y; + v->texB.x = ov->TanEyeAnglesB.x; + v->texB.y = ov->TanEyeAnglesB.y; +#else v->pos.x = ov->Pos.x; v->pos.y = ov->Pos.y; v->texR.x = ov->TexR.x; @@ -191,6 +217,7 @@ void OculusManager::generateDistortionMesh() { v->texG.y = ov->TexG.y; v->texB.x = ov->TexB.x; v->texB.y = ov->TexB.y; +#endif v->color.r = v->color.g = v->color.b = (GLubyte)(ov->VignetteFactor * 255.99f); v->color.a = (GLubyte)(ov->TimeWarpFactor * 255.99f); v++; @@ -291,12 +318,23 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p glPushMatrix(); glm::quat orientation; - + glm::vec3 trackerPosition; + +#if defined(__APPLE__) || defined(_WIN32) + ovrTrackingState ts = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); + ovrVector3f ovrHeadPosition = ts.HeadPose.ThePose.Position; + + trackerPosition = glm::vec3(ovrHeadPosition.x, ovrHeadPosition.y, ovrHeadPosition.z); + trackerPosition = bodyOrientation * trackerPosition; +#endif + //Render each eye into an fbo for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) { - +#if defined(__APPLE__) || defined(_WIN32) + ovrEyeType eye = _ovrHmd->EyeRenderOrder[eyeIndex]; +#else ovrEyeType eye = _ovrHmdDesc.EyeRenderOrder[eyeIndex]; - +#endif //Set the camera rotation for this eye eyeRenderPose[eye] = ovrHmd_GetEyePose(_ovrHmd, eye); orientation.x = eyeRenderPose[eye].Orientation.x; @@ -305,7 +343,8 @@ void OculusManager::display(const glm::quat &bodyOrientation, const glm::vec3 &p orientation.w = eyeRenderPose[eye].Orientation.w; _camera->setTargetRotation(bodyOrientation * orientation); - _camera->setTargetPosition(position); + _camera->setTargetPosition(position + trackerPosition); + _camera->update(1.0f / Application::getInstance()->getFps()); Matrix4f proj = ovrMatrix4f_Projection(_eyeRenderDesc[eye].Fov, whichCamera.getNearClip(), whichCamera.getFarClip(), true); @@ -425,19 +464,32 @@ void OculusManager::renderDistortionMesh(ovrPosef eyeRenderPose[ovrEye_Count]) { //Tries to reconnect to the sensors void OculusManager::reset() { #ifdef HAVE_LIBOVR - disconnect(); - connect(); + if (_isConnected) { + ovrHmd_RecenterPose(_ovrHmd); + } #endif } //Gets the current predicted angles from the oculus sensors void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { #ifdef HAVE_LIBOVR +#if defined(__APPLE__) || defined(_WIN32) + ovrTrackingState ts = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); +#else ovrSensorState ss = ovrHmd_GetSensorState(_ovrHmd, _hmdFrameTiming.ScanoutMidpointSeconds); - +#endif +#if defined(__APPLE__) || defined(_WIN32) + if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { +#else if (ss.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { - ovrPosef pose = ss.Predicted.Pose; - Quatf orientation = Quatf(pose.Orientation); +#endif + +#if defined(__APPLE__) || defined(_WIN32) + ovrPosef headPose = ts.HeadPose.ThePose; +#else + ovrPosef headPose = ss.Predicted.Pose; +#endif + Quatf orientation = Quatf(headPose.Orientation); orientation.GetEulerAngles(&yaw, &pitch, &roll); } else { yaw = 0.0f; @@ -450,6 +502,18 @@ void OculusManager::getEulerAngles(float& yaw, float& pitch, float& roll) { roll = 0.0f; #endif } + +glm::vec3 OculusManager::getRelativePosition() { +#if defined(__APPLE__) || defined(_WIN32) + ovrTrackingState trackingState = ovrHmd_GetTrackingState(_ovrHmd, ovr_GetTimeInSeconds()); + ovrVector3f headPosition = trackingState.HeadPose.ThePose.Position; + + return glm::vec3(headPosition.x, headPosition.y, headPosition.z); +#else + // no positional tracking in Linux yet + return glm::vec3(0.0f, 0.0f, 0.0f); +#endif +} //Used to set the size of the glow framebuffers QSize OculusManager::getRenderTargetSize() { diff --git a/interface/src/devices/OculusManager.h b/interface/src/devices/OculusManager.h index 8c929bb50a..3959ea1ab7 100644 --- a/interface/src/devices/OculusManager.h +++ b/interface/src/devices/OculusManager.h @@ -40,6 +40,7 @@ public: /// param \pitch[out] pitch in radians /// param \roll[out] roll in radians static void getEulerAngles(float& yaw, float& pitch, float& roll); + static glm::vec3 getRelativePosition(); static QSize getRenderTargetSize(); private: diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 089d478198..803060e5d3 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -19,6 +19,7 @@ #include "UserActivityLogger.h" #ifdef HAVE_SIXENSE + const int CALIBRATION_STATE_IDLE = 0; const int CALIBRATION_STATE_X = 1; const int CALIBRATION_STATE_Y = 2; @@ -41,8 +42,9 @@ SixenseManager::SixenseManager() { // By default we assume the _neckBase (in orb frame) is as high above the orb // as the "torso" is below it. _neckBase = glm::vec3(NECK_X, -NECK_Y, NECK_Z); - + sixenseInit(); + #endif _hydrasConnected = false; _triggerPressed[0] = false; diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 91f9e9884f..664c102f76 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -71,7 +71,7 @@ private: glm::vec3 _reachUp; glm::vec3 _reachForward; float _lastDistance; - + #endif bool _hydrasConnected; quint64 _lastMovement;