Merge branch 'refs/heads/Rift'
This commit is contained in:
commit
6561b99347
|
@ -151,6 +151,7 @@ OPTION(BUILD_SPREADSHEET "Build the FreeCAD spreadsheet module" ON)
|
||||||
OPTION(BUILD_START "Build the FreeCAD start module" ON)
|
OPTION(BUILD_START "Build the FreeCAD start module" ON)
|
||||||
OPTION(BUILD_TEST "Build the FreeCAD test module" ON)
|
OPTION(BUILD_TEST "Build the FreeCAD test module" ON)
|
||||||
OPTION(BUILD_WEB "Build the FreeCAD web module" ON)
|
OPTION(BUILD_WEB "Build the FreeCAD web module" ON)
|
||||||
|
OPTION(BUILD_VR "Build the FreeCAD Oculus Rift support (need Oculus SDK 4.x or higher)" OFF)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
OPTION(FREECAD_USE_3DCONNEXION "Use the 3D connexion SDK to support 3d mouse." ON)
|
OPTION(FREECAD_USE_3DCONNEXION "Use the 3D connexion SDK to support 3d mouse." ON)
|
||||||
|
@ -647,6 +648,10 @@ else(FREECAD_LIBPACK_USE)
|
||||||
|
|
||||||
endif(FREECAD_LIBPACK_USE)
|
endif(FREECAD_LIBPACK_USE)
|
||||||
|
|
||||||
|
if(BUILD_VR)
|
||||||
|
find_package(Rift)
|
||||||
|
endif(BUILD_VR)
|
||||||
|
|
||||||
# copy build convenient files for M$
|
# copy build convenient files for M$
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if (EXISTS BuildAll.bat)
|
if (EXISTS BuildAll.bat)
|
||||||
|
@ -680,7 +685,7 @@ IF(MSVC)
|
||||||
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHa")
|
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /EHa")
|
||||||
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFC_DEBUG")
|
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DFC_DEBUG")
|
||||||
# set default libs
|
# set default libs
|
||||||
SET (CMAKE_C_STANDARD_LIBRARIES "kernel32.lib user32.lib gdi32.lib winspool.lib SHFolder.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib ")
|
SET (CMAKE_C_STANDARD_LIBRARIES "kernel32.lib user32.lib gdi32.lib winspool.lib SHFolder.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib winmm.lib comsupp.lib Ws2_32.lib dbghelp.lib ")
|
||||||
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}")
|
set (CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES}")
|
||||||
# set linker flag /nodefaultlib
|
# set linker flag /nodefaultlib
|
||||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB")
|
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB")
|
||||||
|
|
100
cMake/FindRift.cmake
Normal file
100
cMake/FindRift.cmake
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# Find OCULUS
|
||||||
|
#
|
||||||
|
# This module defines
|
||||||
|
# OCULUS_FOUND
|
||||||
|
# OCULUS_INCLUDE_DIRS
|
||||||
|
# OCULUS_LIBRARIES
|
||||||
|
#
|
||||||
|
# Copyright (c) 2012 I-maginer
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
|
# Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
||||||
|
# http://www.gnu.org/copyleft/lesser.txt
|
||||||
|
#
|
||||||
|
|
||||||
|
# On a new cmake run, we do not need to be verbose
|
||||||
|
IF(OCULUS_INCLUDE_DIR AND OCULUS_LIBRARY)
|
||||||
|
SET(OCULUS_FIND_QUIETLY FALSE)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# If OCULUS_ROOT was defined in the environment, use it.
|
||||||
|
if (NOT OCULUS_ROOT)
|
||||||
|
if(NOT "$ENV{OCULUS_ROOT}" STREQUAL "")
|
||||||
|
set(OCULUS_ROOT $ENV{OCULUS_ROOT})
|
||||||
|
else()
|
||||||
|
set(OCULUS_ROOT $ENV{SCOL_DEPENDENCIES_PATH}/oculus/LibOVR)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# concat all the search paths
|
||||||
|
IF(OCULUS_ROOT)
|
||||||
|
SET(OCULUS_INCLUDE_SEARCH_DIRS
|
||||||
|
${OCULUS_INCLUDE_SEARCH_DIRS}
|
||||||
|
${OCULUS_ROOT}/include
|
||||||
|
)
|
||||||
|
SET(OCULUS_LIBRARY_SEARCH_RELEASE_DIRS
|
||||||
|
${OCULUS_LIBRARY_SEARCH_DIRS}
|
||||||
|
${OCULUS_ROOT}/Lib/x64/VS2012
|
||||||
|
)
|
||||||
|
SET(OCULUS_LIBRARY_SEARCH_DEBUG_DIRS
|
||||||
|
${OCULUS_LIBRARY_SEARCH_DIRS}
|
||||||
|
${OCULUS_ROOT}/Lib/x64/VS2012
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# log message
|
||||||
|
IF (NOT OCULUS_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS "Checking for OCULUS library")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Search for header files
|
||||||
|
FIND_PATH(OCULUS_INCLUDE_DIR OVR.h
|
||||||
|
PATHS ${OCULUS_INCLUDE_SEARCH_DIRS})
|
||||||
|
|
||||||
|
# Search for libraries files (release mode)
|
||||||
|
FIND_LIBRARY(OCULUS_LIBRARY_RELEASE libovr64
|
||||||
|
PATHS ${OCULUS_LIBRARY_SEARCH_RELEASE_DIRS})
|
||||||
|
|
||||||
|
# Search for libraries files (debug mode)
|
||||||
|
FIND_LIBRARY(OCULUS_LIBRARY_DEBUG libovr64d
|
||||||
|
PATHS ${OCULUS_LIBRARY_SEARCH_DEBUG_DIRS})
|
||||||
|
|
||||||
|
# Configure libraries for debug/release
|
||||||
|
SET(OCULUS_INCLUDE_DIRS ${OCULUS_INCLUDE_DIR} CACHE PATH "Directory containing OCULUS header files")
|
||||||
|
SET(OCULUS_LIBRARY debug ${OCULUS_LIBRARY_DEBUG} optimized ${OCULUS_LIBRARY_RELEASE})
|
||||||
|
SET(OCULUS_LIBRARIES ${OCULUS_LIBRARY} CACHE STRING "OCULUS libraries files")
|
||||||
|
|
||||||
|
#IF(OCULUS_INCLUDE_DIR AND OCULUS_LIBRARY)
|
||||||
|
SET(OCULUS_FOUND TRUE)
|
||||||
|
#ENDIF()
|
||||||
|
|
||||||
|
# Hide those variables in GUI
|
||||||
|
SET(OCULUS_INCLUDE_DIR ${OCULUS_INCLUDE_DIR} CACHE INTERNAL "")
|
||||||
|
SET(OCULUS_LIBRARY_RELEASE ${OCULUS_LIBRARY_RELEASE} CACHE INTERNAL "")
|
||||||
|
SET(OCULUS_LIBRARY_DEBUG ${OCULUS_LIBRARY_DEBUG} CACHE INTERNAL "")
|
||||||
|
SET(OCULUS_LIBRARY ${OCULUS_LIBRARY} CACHE INTERNAL "")
|
||||||
|
|
||||||
|
# log find result
|
||||||
|
IF(OCULUS_FOUND)
|
||||||
|
IF(NOT OCULUS_FIND_QUIETLY)
|
||||||
|
MESSAGE(STATUS " libraries: ${OCULUS_LIBRARIES}")
|
||||||
|
MESSAGE(STATUS " includes: ${OCULUS_INCLUDE_DIRS}")
|
||||||
|
ENDIF()
|
||||||
|
ELSE(OCULUS_FOUND)
|
||||||
|
IF(NOT OCULUS_LIBRARIES)
|
||||||
|
MESSAGE(STATUS, "OCULUS library or one of it dependencies could not be found.")
|
||||||
|
ENDIF()
|
||||||
|
IF(NOT OCULUS_INCLUDE_DIRS)
|
||||||
|
MESSAGE(STATUS "OCULUS include files could not be found.")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF(OCULUS_FOUND)
|
|
@ -1,13 +1,17 @@
|
||||||
#add_subdirectory(Icons)
|
#add_subdirectory(Icons)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_definitions(-DFCGui -DQIIS_MAKEDLL)
|
add_definitions(-DFCGui -DQIIS_MAKEDLL -DOVR_OS_WIN32)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
if (FREECAD_USE_3DCONNEXION)
|
if (FREECAD_USE_3DCONNEXION)
|
||||||
add_definitions(-D_USE_3DCONNEXION_SDK)
|
add_definitions(-D_USE_3DCONNEXION_SDK)
|
||||||
endif(FREECAD_USE_3DCONNEXION)
|
endif(FREECAD_USE_3DCONNEXION)
|
||||||
|
|
||||||
|
if (BUILD_VR)
|
||||||
|
add_definitions(-DBUILD_VR )
|
||||||
|
endif(BUILD_VR)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
|
@ -61,6 +65,17 @@ IF(SPNAV_FOUND)
|
||||||
)
|
)
|
||||||
ENDIF(SPNAV_FOUND)
|
ENDIF(SPNAV_FOUND)
|
||||||
|
|
||||||
|
IF(OCULUS_FOUND)
|
||||||
|
add_definitions(-DOCULUS_FOUND)
|
||||||
|
include_directories(
|
||||||
|
${OCULUS_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
set(FreeCADGui_LIBS
|
||||||
|
${FreeCADGui_LIBS}
|
||||||
|
${OCULUS_LIBRARIES}
|
||||||
|
)
|
||||||
|
ENDIF(OCULUS_FOUND)
|
||||||
|
|
||||||
if(SHIBOKEN_INCLUDE_DIR)
|
if(SHIBOKEN_INCLUDE_DIR)
|
||||||
add_definitions(-DHAVE_SHIBOKEN)
|
add_definitions(-DHAVE_SHIBOKEN)
|
||||||
include_directories(
|
include_directories(
|
||||||
|
@ -645,6 +660,8 @@ SET(View3D_CPP_SRCS
|
||||||
View3DInventor.cpp
|
View3DInventor.cpp
|
||||||
View3DInventorExamples.cpp
|
View3DInventorExamples.cpp
|
||||||
View3DInventorViewer.cpp
|
View3DInventorViewer.cpp
|
||||||
|
View3DInventorRiftViewer.cpp
|
||||||
|
CoinRiftWidget.cpp
|
||||||
View3DPy.cpp
|
View3DPy.cpp
|
||||||
)
|
)
|
||||||
SET(View3D_SRCS
|
SET(View3D_SRCS
|
||||||
|
@ -659,6 +676,9 @@ SET(View3D_SRCS
|
||||||
View3DInventorExamples.h
|
View3DInventorExamples.h
|
||||||
View3DInventorViewer.h
|
View3DInventorViewer.h
|
||||||
View3DPy.h
|
View3DPy.h
|
||||||
|
View3DInventorRiftViewer.h
|
||||||
|
CoinRiftWidget.h
|
||||||
|
|
||||||
)
|
)
|
||||||
SOURCE_GROUP("View3D" FILES ${View3D_SRCS})
|
SOURCE_GROUP("View3D" FILES ${View3D_SRCS})
|
||||||
|
|
||||||
|
|
505
src/Gui/CoinRiftWidget.cpp
Normal file
505
src/Gui/CoinRiftWidget.cpp
Normal file
|
@ -0,0 +1,505 @@
|
||||||
|
/**************************************************************************\
|
||||||
|
* Copyright (c) Bastiaan Veelo (Bastiaan a_t Veelo d_o_t net) & Juergen Riegel (FreeCAD@juergen-riegel.net)
|
||||||
|
* All rights reserved. Contact me if the below is too restrictive for you.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
\**************************************************************************/
|
||||||
|
|
||||||
|
#include "PreCompiled.h"
|
||||||
|
#include "CoinRiftWidget.h"
|
||||||
|
|
||||||
|
#include <Base/Console.h>
|
||||||
|
|
||||||
|
#if BUILD_VR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#undef max
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CoinRiftWidget::CoinRiftWidget() : QGLWidget()
|
||||||
|
{
|
||||||
|
for (int eye = 0; eye < 2; eye++) {
|
||||||
|
reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye])->TexId = 0;
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
frameBufferID[eye] = 0;
|
||||||
|
depthBufferID[eye] = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// OVR will do the swapping.
|
||||||
|
setAutoBufferSwap(false);
|
||||||
|
|
||||||
|
hmd = ovrHmd_Create(0);
|
||||||
|
if (!hmd) {
|
||||||
|
qDebug() << "Could not find Rift device.";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ovrHmd_ConfigureTracking (hmd, ovrTrackingCap_Orientation |
|
||||||
|
ovrTrackingCap_MagYawCorrection |
|
||||||
|
ovrTrackingCap_Position,
|
||||||
|
ovrTrackingCap_Orientation |
|
||||||
|
ovrTrackingCap_MagYawCorrection |
|
||||||
|
ovrTrackingCap_Position
|
||||||
|
)) { // Capabilities we require.
|
||||||
|
qDebug() << "Could not start Rift motion sensor.";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(hmd->Resolution.w, hmd->Resolution.h);
|
||||||
|
|
||||||
|
// Configure stereo settings.
|
||||||
|
ovrSizei recommenedTex0Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Left,
|
||||||
|
hmd->DefaultEyeFov[0], 1.0f);
|
||||||
|
ovrSizei recommenedTex1Size = ovrHmd_GetFovTextureSize(hmd, ovrEye_Right,
|
||||||
|
hmd->DefaultEyeFov[1], 1.0f);
|
||||||
|
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
renderer = new SoOffscreenRenderer(SbViewportRegion(std::max(recommenedTex0Size.w, recommenedTex0Size.w),
|
||||||
|
std::max(recommenedTex1Size.h, recommenedTex1Size.h)));
|
||||||
|
renderer->setComponents(SoOffscreenRenderer::RGB_TRANSPARENCY);
|
||||||
|
BackgroundColor = SbColor(.0f, .0f, .8f);
|
||||||
|
renderer->setBackgroundColor(BackgroundColor);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
m_sceneManager = new SoSceneManager();
|
||||||
|
m_sceneManager->setViewportRegion(SbViewportRegion(std::max(recommenedTex0Size.w, recommenedTex0Size.w),
|
||||||
|
std::max(recommenedTex1Size.h, recommenedTex1Size.h)));
|
||||||
|
m_sceneManager->setBackgroundColor(SbColor(.0f, .0f, .8f));
|
||||||
|
#endif
|
||||||
|
basePosition = SbVec3f(0.0f, 0.0f, -2.0f);
|
||||||
|
|
||||||
|
// light handling
|
||||||
|
SoDirectionalLight *light = new SoDirectionalLight();
|
||||||
|
light->direction.setValue(1,-1,-1);
|
||||||
|
|
||||||
|
SoDirectionalLight *light2 = new SoDirectionalLight();
|
||||||
|
light2->direction.setValue(-1,-1,-1);
|
||||||
|
light2->intensity.setValue(0.6);
|
||||||
|
light2->color.setValue(0.8,0.8,1);
|
||||||
|
|
||||||
|
|
||||||
|
scene = new SoSeparator(0); // Placeholder.
|
||||||
|
for (int eye = 0; eye < 2; eye++) {
|
||||||
|
rootScene[eye] = new SoSeparator();
|
||||||
|
rootScene[eye]->ref();
|
||||||
|
camera[eye] = new SoFrustumCamera();
|
||||||
|
camera[eye]->position.setValue(basePosition);
|
||||||
|
camera[eye]->focalDistance.setValue(5.0f);
|
||||||
|
camera[eye]->viewportMapping.setValue(SoCamera::LEAVE_ALONE);
|
||||||
|
rootScene[eye]->addChild(camera[eye]);
|
||||||
|
rootScene[eye]->addChild(light);
|
||||||
|
rootScene[eye]->addChild(light2);
|
||||||
|
rootScene[eye]->addChild(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate ovrEyeDesc[2].
|
||||||
|
eyeRenderDesc[0].Eye = ovrEye_Left;
|
||||||
|
eyeRenderDesc[1].Eye = ovrEye_Right;
|
||||||
|
eyeRenderDesc[0].Fov = hmd->DefaultEyeFov[0];
|
||||||
|
eyeRenderDesc[1].Fov = hmd->DefaultEyeFov[1];
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
eyeTexture[0].Header.TextureSize.w = renderer->getViewportRegion().getViewportSizePixels().getValue()[0];
|
||||||
|
eyeTexture[0].Header.TextureSize.h = renderer->getViewportRegion().getViewportSizePixels().getValue()[1];
|
||||||
|
eyeTexture[1].Header.TextureSize = eyeTexture[0].Header.TextureSize;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
eyeTexture[0].Header.TextureSize = recommenedTex0Size;
|
||||||
|
eyeTexture[1].Header.TextureSize = recommenedTex1Size;
|
||||||
|
#endif
|
||||||
|
eyeTexture[0].Header.RenderViewport.Pos.x = 0;
|
||||||
|
eyeTexture[0].Header.RenderViewport.Pos.y = 0;
|
||||||
|
eyeTexture[0].Header.RenderViewport.Size = eyeTexture[0].Header.TextureSize;
|
||||||
|
eyeTexture[1].Header.RenderViewport.Pos = eyeTexture[0].Header.RenderViewport.Pos;
|
||||||
|
eyeTexture[1].Header.RenderViewport.Size = eyeTexture[1].Header.TextureSize;
|
||||||
|
|
||||||
|
const int backBufferMultisample = 0; // TODO This is a guess?
|
||||||
|
ovrGLConfig cfg;
|
||||||
|
cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
|
||||||
|
cfg.OGL.Header.RTSize = hmd->Resolution;
|
||||||
|
cfg.OGL.Header.Multisample = backBufferMultisample;
|
||||||
|
cfg.OGL.Window = reinterpret_cast<HWND>(winId());
|
||||||
|
makeCurrent();
|
||||||
|
//cfg.OGL.WglContext = wglGetCurrentContext(); // http://stackoverflow.com/questions/17532033/qglwidget-get-gl-contextes-for-windows
|
||||||
|
cfg.OGL.DC = wglGetCurrentDC();
|
||||||
|
qDebug() << "Window:" << cfg.OGL.Window;
|
||||||
|
//qDebug() << "Context:" << cfg.OGL.WglContext;
|
||||||
|
qDebug() << "DC:" << cfg.OGL.DC;
|
||||||
|
|
||||||
|
int DistortionCaps = 0;
|
||||||
|
DistortionCaps |= ovrDistortionCap_Chromatic;
|
||||||
|
// DistortionCaps |= ovrDistortionCap_TimeWarp; // Produces black screen...
|
||||||
|
DistortionCaps |= ovrDistortionCap_Vignette;
|
||||||
|
DistortionCaps |= ovrDistortionCap_HqDistortion;
|
||||||
|
|
||||||
|
bool VSyncEnabled(false); // TODO This is a guess.
|
||||||
|
if (!ovrHmd_ConfigureRendering( hmd,
|
||||||
|
&cfg.Config,
|
||||||
|
/*(VSyncEnabled ? 0 : ovrHmdCap_NoVSync),*/
|
||||||
|
DistortionCaps,
|
||||||
|
hmd->DefaultEyeFov,//eyes,
|
||||||
|
eyeRenderDesc)) {
|
||||||
|
qDebug() << "Could not configure OVR rendering.";
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
static const float nearPlane = 0.01;
|
||||||
|
|
||||||
|
for (int eye = 0; eye < 2; eye++) {
|
||||||
|
camera[eye]->aspectRatio.setValue((eyeRenderDesc[eye].Fov.LeftTan + eyeRenderDesc[eye].Fov.RightTan) /
|
||||||
|
(eyeRenderDesc[eye].Fov.UpTan + eyeRenderDesc[eye].Fov.DownTan));
|
||||||
|
camera[eye]->nearDistance.setValue(nearPlane);
|
||||||
|
camera[eye]->farDistance.setValue(10000.0f);
|
||||||
|
camera[eye]->left.setValue(-eyeRenderDesc[eye].Fov.LeftTan * nearPlane);
|
||||||
|
camera[eye]->right.setValue(eyeRenderDesc[eye].Fov.RightTan * nearPlane);
|
||||||
|
camera[eye]->top.setValue(eyeRenderDesc[eye].Fov.UpTan * nearPlane);
|
||||||
|
camera[eye]->bottom.setValue(-eyeRenderDesc[eye].Fov.DownTan * nearPlane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CoinRiftWidget::~CoinRiftWidget()
|
||||||
|
{
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
delete renderer;
|
||||||
|
#endif
|
||||||
|
for (int eye = 0; eye < 2; eye++) {
|
||||||
|
rootScene[eye]->unref();
|
||||||
|
ovrGLTextureData *texData = reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye]);
|
||||||
|
if (texData->TexId) {
|
||||||
|
glDeleteTextures(1, &texData->TexId);
|
||||||
|
texData->TexId = 0;
|
||||||
|
}
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
if (frameBufferID[eye] != 0) {
|
||||||
|
// OVR::CAPI::GL::glDeleteFramebuffersExt(1, &frameBufferID[eye]); // TODO
|
||||||
|
frameBufferID[eye] = 0;
|
||||||
|
}
|
||||||
|
if (depthBufferID[eye] != 0) {
|
||||||
|
// OVR::CAPI::GL::glDeleteRenderbuffersExt(1, &depthBufferID[eye]); // TODO
|
||||||
|
depthBufferID[eye] = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
scene = 0;
|
||||||
|
//ovrHmd_StopSensor(hmd);
|
||||||
|
ovrHmd_Destroy(hmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoinRiftWidget::setBackgroundColor(const SbColor &Col)
|
||||||
|
{
|
||||||
|
BackgroundColor = Col;
|
||||||
|
renderer->setBackgroundColor(BackgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoinRiftWidget::setSceneGraph(SoNode *sceneGraph)
|
||||||
|
{
|
||||||
|
rootScene[0]->replaceChild(scene, sceneGraph);
|
||||||
|
rootScene[1]->replaceChild(scene, sceneGraph);
|
||||||
|
scene = sceneGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoinRiftWidget::resizeGL(int width, int height) {
|
||||||
|
int side = qMin(width, height);
|
||||||
|
glViewport((width - side) / 2, (height - side) / 2, side, side);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 1000.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoinRiftWidget::initializeGL()
|
||||||
|
{
|
||||||
|
makeCurrent();
|
||||||
|
// Infer hardware capabilites.
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
OVR::CAPI::GL::InitGLExtensions();
|
||||||
|
if (OVR::CAPI::GL::glBindFramebuffer == NULL) {
|
||||||
|
qDebug() << "No GL extensions found.";
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store old framebuffer.
|
||||||
|
GLint oldfb;
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &oldfb);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Create rendering target textures.
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
for (int eye = 0; eye < 2; eye++) {
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
OVR::CAPI::GL::glGenFramebuffers(1, &frameBufferID[eye]);
|
||||||
|
OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, frameBufferID[eye]);
|
||||||
|
// Create the render buffer.
|
||||||
|
// TODO: need to check for OpenGl 3 or higher and load the functions JR 2014
|
||||||
|
/*OVR::CAPI::GL::*/glGenRenderbuffers(1, &depthBufferID[eye]);
|
||||||
|
/*OVR::CAPI::GL::*/glBindRenderbuffer(GL_RENDERBUFFER_EXT, depthBufferID[eye]);
|
||||||
|
/*OVR::CAPI::GL::*/glRenderbufferStorage(GL_RENDERBUFFER_EXT,
|
||||||
|
GL_DEPTH_COMPONENT16,
|
||||||
|
eyeTexture[eye].Header.TextureSize.w,
|
||||||
|
eyeTexture[eye].Header.TextureSize.h);
|
||||||
|
// Attach renderbuffer to framebuffer.
|
||||||
|
OVR::CAPI::GL::glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_DEPTH_ATTACHMENT_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT,
|
||||||
|
depthBufferID[eye]);
|
||||||
|
#endif
|
||||||
|
ovrGLTextureData *texData = reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye]);
|
||||||
|
texData->Header.API = ovrRenderAPI_OpenGL;
|
||||||
|
texData->Header.TextureSize = eyeTexture[eye].Header.TextureSize;
|
||||||
|
texData->Header.RenderViewport = eyeTexture[eye].Header.RenderViewport;
|
||||||
|
glGenTextures(1, &texData->TexId);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texData->TexId);
|
||||||
|
Q_ASSERT(!glGetError());
|
||||||
|
// Allocate storage for the texture.
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, eyeTexture[eye].Header.TextureSize.w, eyeTexture[eye].Header.TextureSize.h, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||||
|
Q_ASSERT(!glGetError());
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
// Attach texture to framebuffer color object.
|
||||||
|
OVR::CAPI::GL::glFramebufferTexture2D(GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_COLOR_ATTACHMENT0_EXT,
|
||||||
|
GL_TEXTURE_2D, texData->TexId, 0);
|
||||||
|
if (OVR::CAPI::GL::glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
|
||||||
|
GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
qDebug() << "ERROR: FrameBuffer is not operational!";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
// Continue rendering to the orgiginal frame buffer (likely 0, the onscreen buffer).
|
||||||
|
OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, oldfb);
|
||||||
|
#endif
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CoinRiftWidget::paintGL()
|
||||||
|
{
|
||||||
|
const int ms(1000 / 75 /*fps*/);
|
||||||
|
QTimer::singleShot(ms, this, SLOT(updateGL()));
|
||||||
|
|
||||||
|
// handling the sfety warning
|
||||||
|
handlingSafetyWarning();
|
||||||
|
|
||||||
|
makeCurrent();
|
||||||
|
|
||||||
|
ovrPosef eyePose[2];
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
ovrFrameTiming hmdFrameTiming = ovrHmd_BeginFrame(hmd, 0);
|
||||||
|
for (int eyeIndex = 0; eyeIndex < ovrEye_Count; eyeIndex++) {
|
||||||
|
ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
|
||||||
|
eyePose[eye] = ovrHmd_GetEyePose(hmd, eye);
|
||||||
|
|
||||||
|
|
||||||
|
SbRotation riftOrientation( eyePose[eye].Orientation.x,
|
||||||
|
eyePose[eye].Orientation.y,
|
||||||
|
eyePose[eye].Orientation.z,
|
||||||
|
eyePose[eye].Orientation.w);
|
||||||
|
|
||||||
|
camera[eye]->orientation.setValue(riftOrientation);
|
||||||
|
|
||||||
|
SbVec3f riftPosition = SbVec3f(eyePose[eye].Position.x,
|
||||||
|
eyePose[eye].Position.y,
|
||||||
|
eyePose[eye].Position.z);
|
||||||
|
|
||||||
|
|
||||||
|
//SbVec3f originalPosition(camera[eye]->position.getValue());
|
||||||
|
SbVec3f viewAdjust(eyeRenderDesc[eye].ViewAdjust.x,
|
||||||
|
eyeRenderDesc[eye].ViewAdjust.y,
|
||||||
|
eyeRenderDesc[eye].ViewAdjust.z);
|
||||||
|
|
||||||
|
riftOrientation.multVec(viewAdjust,viewAdjust);
|
||||||
|
|
||||||
|
camera[eye]->position.setValue(basePosition - viewAdjust + riftPosition);
|
||||||
|
|
||||||
|
//Base::Console().Log("Eye(%d) Pos: %f, %f, %f ViewAdjust: %f, %f, %f \n",eye, eyePose[eye].Position.x,
|
||||||
|
// eyePose[eye].Position.y,
|
||||||
|
// eyePose[eye].Position.z,
|
||||||
|
// eyeRenderDesc[eye].ViewAdjust.x,
|
||||||
|
// eyeRenderDesc[eye].ViewAdjust.y,
|
||||||
|
// eyeRenderDesc[eye].ViewAdjust.z);
|
||||||
|
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
ovrGLTextureData *texData = reinterpret_cast<ovrGLTextureData*>(&eyeTexture[eye]);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texData->TexId);
|
||||||
|
renderer->render(rootScene[eye]);
|
||||||
|
Q_ASSERT(!glGetError());
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||||
|
eyeTexture[eye].Header.TextureSize.w,
|
||||||
|
eyeTexture[eye].Header.TextureSize.h,
|
||||||
|
0, GL_RGBA /*GL_BGRA*/, GL_UNSIGNED_BYTE, renderer->getBuffer());
|
||||||
|
Q_ASSERT(!glGetError());
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
// Clear state pollution from OVR SDK.
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0); // You need this, at least if (hmdDesc.DistortionCaps & ovrDistortion_Chromatic).
|
||||||
|
OVR::CAPI::GL::glUseProgram(0); // You need this even more.
|
||||||
|
|
||||||
|
GLint oldfb;
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &oldfb);
|
||||||
|
// Set up framebuffer for rendering.
|
||||||
|
OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, frameBufferID[eye]);
|
||||||
|
|
||||||
|
m_sceneManager->setSceneGraph(rootScene[eye]);
|
||||||
|
// m_sceneManager->setCamera(camera[eye]); // SoSceneManager does this implicitly.
|
||||||
|
m_sceneManager->render();
|
||||||
|
|
||||||
|
// Continue rendering to the orgiginal frame buffer (likely 0, the onscreen buffer).
|
||||||
|
OVR::CAPI::GL::glBindFramebuffer(GL_FRAMEBUFFER_EXT, oldfb);
|
||||||
|
Q_ASSERT(!glGetError());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//camera[eye]->position.setValue(originalPosition);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit the texture for distortion.
|
||||||
|
ovrHmd_EndFrame(hmd, eyePose, eyeTexture);
|
||||||
|
|
||||||
|
// Swap buffers.
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
//ovrHmd_EndFrame(hmd);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glClearDepth(1.0);
|
||||||
|
|
||||||
|
doneCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CoinRiftWidget::handlingSafetyWarning(void)
|
||||||
|
{
|
||||||
|
// Health and Safety Warning display state.
|
||||||
|
ovrHSWDisplayState hswDisplayState;
|
||||||
|
ovrHmd_GetHSWDisplayState(hmd, &hswDisplayState);
|
||||||
|
if (hswDisplayState.Displayed)
|
||||||
|
{
|
||||||
|
// Dismiss the warning if the user pressed the appropriate key or if the user
|
||||||
|
// is tapping the side of the HMD.
|
||||||
|
// If the user has requested to dismiss the warning via keyboard or controller input...
|
||||||
|
//if (Util_GetAndResetHSWDismissedState())
|
||||||
|
ovrHmd_DismissHSWDisplay(hmd);
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// // Detect a moderate tap on the side of the HMD.
|
||||||
|
// ovrTrackingState ts = ovrHmd_GetTrackingState(hmd, ovr_GetTimeInSeconds());
|
||||||
|
// if (ts.StatusFlags & ovrStatus_OrientationTracked)
|
||||||
|
// {
|
||||||
|
// const OVR::Vector3f v(ts.RawSensorData.Accelerometer.x,
|
||||||
|
// ts.RawSensorData.Accelerometer.y,
|
||||||
|
// ts.RawSensorData.Accelerometer.z);
|
||||||
|
// // Arbitrary value and representing moderate tap on the side of the DK2 Rift.
|
||||||
|
// if (v.LengthSq() > 250.f)
|
||||||
|
// ovrHmd_DismissHSWDisplay(hmd);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BUILD_RIFT_TEST_MAIN
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SoDB::init();
|
||||||
|
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
qAddPostRoutine(cleanup);
|
||||||
|
|
||||||
|
// Moved here because of https://developer.oculusvr.com/forums/viewtopic.php?f=17&t=7915&p=108503#p108503
|
||||||
|
// Init libovr.
|
||||||
|
if (!ovr_Initialize()) {
|
||||||
|
qDebug() << "Could not initialize Oculus SDK.";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoinRiftWidget window;
|
||||||
|
window.show();
|
||||||
|
|
||||||
|
// An example scene.
|
||||||
|
static const char * inlineSceneGraph[] = {
|
||||||
|
"#Inventor V2.1 ascii\n",
|
||||||
|
"\n",
|
||||||
|
"Separator {\n",
|
||||||
|
" Rotation { rotation 1 0 0 0.3 }\n",
|
||||||
|
" Cone { }\n",
|
||||||
|
" BaseColor { rgb 1 0 0 }\n",
|
||||||
|
" Scale { scaleFactor .7 .7 .7 }\n",
|
||||||
|
" Cube { }\n",
|
||||||
|
"\n",
|
||||||
|
" DrawStyle { style LINES }\n",
|
||||||
|
" ShapeHints { vertexOrdering COUNTERCLOCKWISE }\n",
|
||||||
|
" Coordinate3 {\n",
|
||||||
|
" point [\n",
|
||||||
|
" -2 -2 1.1, -2 -1 1.1, -2 1 1.1, -2 2 1.1,\n",
|
||||||
|
" -1 -2 1.1, -1 -1 1.1, -1 1 1.1, -1 2 1.1\n",
|
||||||
|
" 1 -2 1.1, 1 -1 1.1, 1 1 1.1, 1 2 1.1\n",
|
||||||
|
" 2 -2 1.1, 2 -1 1.1, 2 1 1.1, 2 2 1.1\n",
|
||||||
|
" ]\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" Complexity { value 0.7 }\n",
|
||||||
|
" NurbsSurface {\n",
|
||||||
|
" numUControlPoints 4\n",
|
||||||
|
" numVControlPoints 4\n",
|
||||||
|
" uKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n",
|
||||||
|
" vKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n",
|
||||||
|
" }\n",
|
||||||
|
"}\n",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
SoInput in;
|
||||||
|
in.setStringArray(inlineSceneGraph);
|
||||||
|
|
||||||
|
window.setSceneGraph(SoDB::readAll(&in));
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //BUILD_RIFT_TEST_MAIN
|
||||||
|
|
||||||
|
#endif //BUILD_VR
|
118
src/Gui/CoinRiftWidget.h
Normal file
118
src/Gui/CoinRiftWidget.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/**************************************************************************\
|
||||||
|
* Copyright (c) Bastiaan Veelo (Bastiaan a_t Veelo d_o_t net) & Juergen Riegel (FreeCAD@juergen-riegel.net)
|
||||||
|
* All rights reserved. Contact me if the below is too restrictive for you.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
\**************************************************************************/
|
||||||
|
#ifndef GUI_CoinRiftWidget
|
||||||
|
#define GUI_CoinRiftWidget
|
||||||
|
|
||||||
|
#if BUILD_VR
|
||||||
|
|
||||||
|
// defines which methode to use to render
|
||||||
|
#define USE_SO_OFFSCREEN_RENDERER
|
||||||
|
//#define USE_FRAMEBUFFER
|
||||||
|
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
# ifdef USE_FRAMEBUFFER
|
||||||
|
# error "Mutually exclusive options defined."
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QGLWidget>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <Inventor/SoDB.h>
|
||||||
|
#include <Inventor/SoInput.h>
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
# include <Inventor/SoOffscreenRenderer.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
# include <Inventor/SoSceneManager.h>
|
||||||
|
#endif
|
||||||
|
#include <Inventor/nodes/SoSeparator.h>
|
||||||
|
#include <Inventor/nodes/SoFrustumCamera.h>
|
||||||
|
#include <Inventor/nodes/SoDirectionalLight.h>
|
||||||
|
|
||||||
|
#include <OVR.h>
|
||||||
|
#include <OVR_Kernel.h>
|
||||||
|
#include <OVR_Version.h>
|
||||||
|
//#include <OVR_CAPI_GL.h>
|
||||||
|
#include <../Src/OVR_CAPI_GL.h>
|
||||||
|
#include <../Src/CAPI/GL/CAPI_GL_Util.h> // For framebuffer functions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class CoinRiftWidget : public QGLWidget
|
||||||
|
{
|
||||||
|
ovrHmd hmd;
|
||||||
|
//ovrHmdDesc hmdDesc;
|
||||||
|
//ovrEyeType eyes[2];
|
||||||
|
ovrEyeRenderDesc eyeRenderDesc[2];
|
||||||
|
ovrTexture eyeTexture[2];
|
||||||
|
|
||||||
|
#ifdef USE_FRAMEBUFFER
|
||||||
|
GLuint frameBufferID[2], depthBufferID[2];
|
||||||
|
// A SoSceneManager has a SoRenderManager to do the rendering -- should we not use SoRenderManager instead?
|
||||||
|
// We are probably not that interested in events. SoSceneManager::setSceneGraph() searches for the camera
|
||||||
|
// and sets it in SoRenderManager, but its is actually only used for built-in stereo rendering. We sould
|
||||||
|
// probably eliminate that search...
|
||||||
|
SoSceneManager *m_sceneManager;
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SO_OFFSCREEN_RENDERER
|
||||||
|
SoOffscreenRenderer *renderer;
|
||||||
|
#endif
|
||||||
|
SoSeparator *rootScene[2];
|
||||||
|
SoFrustumCamera *camera[2];
|
||||||
|
SoNode *scene;
|
||||||
|
public:
|
||||||
|
explicit CoinRiftWidget();
|
||||||
|
~CoinRiftWidget();
|
||||||
|
virtual void setSceneGraph(SoNode *sceneGraph);
|
||||||
|
void setBase(const SbVec3f &pos){basePosition=pos;}
|
||||||
|
void setBackgroundColor(const SbColor &Col);
|
||||||
|
|
||||||
|
SbVec3f basePosition;
|
||||||
|
SbRotation baseOrientation;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void handlingSafetyWarning(void);
|
||||||
|
void initializeGL();
|
||||||
|
void paintGL();
|
||||||
|
void resizeGL(int width, int height);
|
||||||
|
|
||||||
|
SbColor BackgroundColor;
|
||||||
|
SoTranslation *lightTranslation;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //BUILD_VR
|
||||||
|
|
||||||
|
#endif GUI_CoinRiftWidget
|
|
@ -1408,6 +1408,37 @@ bool StdViewDockUndockFullscreen::isActive(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// Std_ViewVR
|
||||||
|
//===========================================================================
|
||||||
|
DEF_STD_CMD_A(StdCmdViewVR);
|
||||||
|
|
||||||
|
StdCmdViewVR::StdCmdViewVR()
|
||||||
|
: Command("Std_ViewVR")
|
||||||
|
{
|
||||||
|
sGroup = QT_TR_NOOP("Standard-View");
|
||||||
|
sMenuText = QT_TR_NOOP("FreeCAD-VR");
|
||||||
|
sToolTipText = QT_TR_NOOP("Extend the FreeCAD 3D Window to a Oculus Rift");
|
||||||
|
sWhatsThis = "Std_ViewVR";
|
||||||
|
sStatusTip = QT_TR_NOOP("Extend the FreeCAD 3D Window to a Oculus Rift");
|
||||||
|
sPixmap = "view-zoom-all";
|
||||||
|
eType = Alter3DView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StdCmdViewVR::activated(int iMsg)
|
||||||
|
{
|
||||||
|
//doCommand(Command::Gui,"Gui.activeDocument().activeView().fitAll()");
|
||||||
|
doCommand(Command::Gui,"Gui.SendMsgToActiveView(\"ViewVR\")");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StdCmdViewVR::isActive(void)
|
||||||
|
{
|
||||||
|
return getGuiApplication()->sendHasMsgToActiveView("ViewVR");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Std_ViewScreenShot
|
// Std_ViewScreenShot
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -2453,6 +2484,7 @@ void CreateViewStdCommands(void)
|
||||||
rcCmdMgr.addCommand(new StdCmdViewTop());
|
rcCmdMgr.addCommand(new StdCmdViewTop());
|
||||||
rcCmdMgr.addCommand(new StdCmdViewAxo());
|
rcCmdMgr.addCommand(new StdCmdViewAxo());
|
||||||
rcCmdMgr.addCommand(new StdCmdViewFitAll());
|
rcCmdMgr.addCommand(new StdCmdViewFitAll());
|
||||||
|
rcCmdMgr.addCommand(new StdCmdViewVR());
|
||||||
rcCmdMgr.addCommand(new StdCmdViewFitSelection());
|
rcCmdMgr.addCommand(new StdCmdViewFitSelection());
|
||||||
rcCmdMgr.addCommand(new StdCmdViewRotateLeft());
|
rcCmdMgr.addCommand(new StdCmdViewRotateLeft());
|
||||||
rcCmdMgr.addCommand(new StdCmdViewRotateRight());
|
rcCmdMgr.addCommand(new StdCmdViewRotateRight());
|
||||||
|
|
|
@ -545,6 +545,11 @@ bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn)
|
||||||
_viewer->viewAll();
|
_viewer->viewAll();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp("ViewVR",pMsg) == 0) {
|
||||||
|
// call the VR portion of the viewer
|
||||||
|
_viewer->viewVR();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if(strcmp("ViewSelection",pMsg) == 0) {
|
else if(strcmp("ViewSelection",pMsg) == 0) {
|
||||||
_viewer->viewSelection();
|
_viewer->viewSelection();
|
||||||
return true;
|
return true;
|
||||||
|
@ -728,6 +733,12 @@ bool View3DInventor::onHasMsg(const char* pMsg) const
|
||||||
return true;
|
return true;
|
||||||
else if(strcmp("ViewFit",pMsg) == 0)
|
else if(strcmp("ViewFit",pMsg) == 0)
|
||||||
return true;
|
return true;
|
||||||
|
else if(strcmp("ViewVR",pMsg) == 0)
|
||||||
|
#ifdef BUILD_VR
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
else if(strcmp("ViewSelection",pMsg) == 0)
|
else if(strcmp("ViewSelection",pMsg) == 0)
|
||||||
return true;
|
return true;
|
||||||
else if(strcmp("ViewBottom",pMsg) == 0)
|
else if(strcmp("ViewBottom",pMsg) == 0)
|
||||||
|
|
228
src/Gui/View3DInventorRiftViewer.cpp
Normal file
228
src/Gui/View3DInventorRiftViewer.cpp
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2014 Juergen Riegel <FreeCAD@juergen-riegel.net> *
|
||||||
|
* *
|
||||||
|
* This file is part of the FreeCAD CAx development system. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this library; see the file COPYING.LIB. If not, *
|
||||||
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||||
|
* Suite 330, Boston, MA 02111-1307, USA *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include "PreCompiled.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if BUILD_VR
|
||||||
|
|
||||||
|
#include <Base/Console.h>
|
||||||
|
#include "View3DInventorRiftViewer.h"
|
||||||
|
#include <App/Application.h>
|
||||||
|
|
||||||
|
#define new DEBUG_CLIENTBLOCK
|
||||||
|
|
||||||
|
using namespace Gui;
|
||||||
|
|
||||||
|
View3DInventorRiftViewer::View3DInventorRiftViewer() : CoinRiftWidget()
|
||||||
|
{
|
||||||
|
workplace = new SoGroup();
|
||||||
|
|
||||||
|
//translation = new SoTranslation ;
|
||||||
|
//translation->translation.setValue(0,-1,0);
|
||||||
|
//workplace->addChild(translation);
|
||||||
|
|
||||||
|
rotation1 = new SoRotationXYZ ;
|
||||||
|
rotation1->axis.setValue(SoRotationXYZ::X);
|
||||||
|
rotation1->angle.setValue(-M_PI/2);
|
||||||
|
workplace->addChild(rotation1);
|
||||||
|
|
||||||
|
rotation2 = new SoRotationXYZ ;
|
||||||
|
rotation2->axis.setValue(SoRotationXYZ::Z);
|
||||||
|
rotation2->angle.setValue(0);
|
||||||
|
workplace->addChild(rotation2);
|
||||||
|
|
||||||
|
|
||||||
|
scale = new SoScale ;
|
||||||
|
scale->scaleFactor.setValue(0.001f,0.001f,0.001f); // scale from mm to m as neede by the Rift
|
||||||
|
workplace->addChild(scale);
|
||||||
|
|
||||||
|
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Oculus");
|
||||||
|
|
||||||
|
this->setGeometry( hGrp->GetInt("RenderWindowPosX",100) ,
|
||||||
|
hGrp->GetInt("RenderWindowPosY",100) ,
|
||||||
|
hGrp->GetInt("RenderWindowSizeW",1920) ,
|
||||||
|
hGrp->GetInt("RenderWindowSizeH",1080)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
setBackgroundColor(SbColor(51,51,101));
|
||||||
|
basePosition = SbVec3f(0.0f, 0.5f, 0.8f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//void saveWinPostion(void)
|
||||||
|
//{
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
View3DInventorRiftViewer::~View3DInventorRiftViewer()
|
||||||
|
{
|
||||||
|
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Oculus");
|
||||||
|
|
||||||
|
// remeber last postion on close
|
||||||
|
hGrp->SetInt("RenderWindowPosX",pos().x());
|
||||||
|
hGrp->SetInt("RenderWindowPosY",pos().y());
|
||||||
|
hGrp->SetInt("RenderWindowSizeW",size().width());
|
||||||
|
hGrp->SetInt("RenderWindowSizeH",size().height());
|
||||||
|
|
||||||
|
Base::Console().Log("pos: %d %d size: %d %d \n",pos().x(),pos().y(),
|
||||||
|
size().width(),size().height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void View3DInventorRiftViewer::setSceneGraph(SoNode *sceneGraph)
|
||||||
|
{
|
||||||
|
|
||||||
|
workplace->addChild(sceneGraph);
|
||||||
|
|
||||||
|
CoinRiftWidget::setSceneGraph(workplace);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void View3DInventorRiftViewer::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
static const float increment = 0.02; // move two centimeter per key
|
||||||
|
static const float rotIncrement = M_PI/4; // move two 90° per key
|
||||||
|
|
||||||
|
|
||||||
|
if (event->key() == Qt::Key_Plus) {
|
||||||
|
scale->scaleFactor.setValue(scale->scaleFactor.getValue() * 2.0f) ;
|
||||||
|
} else if (event->key() == Qt::Key_Minus) {
|
||||||
|
scale->scaleFactor.setValue(scale->scaleFactor.getValue() * 0.2f) ;
|
||||||
|
} else if (event->key() == Qt::Key_S) {
|
||||||
|
basePosition += SbVec3f(0,0,increment) ;
|
||||||
|
} else if (event->key() == Qt::Key_W) {
|
||||||
|
basePosition += SbVec3f(0,0,-increment) ;
|
||||||
|
} else if (event->key() == Qt::Key_Up) {
|
||||||
|
basePosition += SbVec3f(0,-increment,0) ;
|
||||||
|
} else if (event->key() == Qt::Key_Down) {
|
||||||
|
basePosition += SbVec3f(0,increment,0) ;
|
||||||
|
} else if (event->key() == Qt::Key_Left) {
|
||||||
|
rotation2->angle.setValue( rotation2->angle.getValue() + rotIncrement);
|
||||||
|
} else if (event->key() == Qt::Key_Right) {
|
||||||
|
rotation2->angle.setValue( rotation2->angle.getValue() - rotIncrement);
|
||||||
|
} else if (event->key() == Qt::Key_A) {
|
||||||
|
basePosition += SbVec3f(-increment,0,0) ;
|
||||||
|
} else if (event->key() == Qt::Key_D) {
|
||||||
|
basePosition += SbVec3f(increment,0,0) ;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
CoinRiftWidget::keyPressEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// static test code ================================================================================
|
||||||
|
static View3DInventorRiftViewer *window=0;
|
||||||
|
|
||||||
|
void oculusSetTestScene(View3DInventorRiftViewer *window)
|
||||||
|
{
|
||||||
|
assert(window);
|
||||||
|
// An example scene.
|
||||||
|
static const char * inlineSceneGraph[] = {
|
||||||
|
"#Inventor V2.1 ascii\n",
|
||||||
|
"\n",
|
||||||
|
"Separator {\n",
|
||||||
|
" Rotation { rotation 1 0 0 0.3 }\n",
|
||||||
|
" Cone { }\n",
|
||||||
|
" BaseColor { rgb 1 0 0 }\n",
|
||||||
|
" Scale { scaleFactor .7 .7 .7 }\n",
|
||||||
|
" Cube { }\n",
|
||||||
|
"\n",
|
||||||
|
" DrawStyle { style LINES }\n",
|
||||||
|
" ShapeHints { vertexOrdering COUNTERCLOCKWISE }\n",
|
||||||
|
" Coordinate3 {\n",
|
||||||
|
" point [\n",
|
||||||
|
" -2 -2 1.1, -2 -1 1.1, -2 1 1.1, -2 2 1.1,\n",
|
||||||
|
" -1 -2 1.1, -1 -1 1.1, -1 1 1.1, -1 2 1.1\n",
|
||||||
|
" 1 -2 1.1, 1 -1 1.1, 1 1 1.1, 1 2 1.1\n",
|
||||||
|
" 2 -2 1.1, 2 -1 1.1, 2 1 1.1, 2 2 1.1\n",
|
||||||
|
" ]\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" Complexity { value 0.7 }\n",
|
||||||
|
" NurbsSurface {\n",
|
||||||
|
" numUControlPoints 4\n",
|
||||||
|
" numVControlPoints 4\n",
|
||||||
|
" uKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n",
|
||||||
|
" vKnotVector [ 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 ]\n",
|
||||||
|
" }\n",
|
||||||
|
"}\n",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
SoInput in;
|
||||||
|
in.setStringArray(inlineSceneGraph);
|
||||||
|
|
||||||
|
window->setSceneGraph(SoDB::readAll(&in));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void oculusStop()
|
||||||
|
{
|
||||||
|
//SoDB::finish();
|
||||||
|
if(window){
|
||||||
|
delete window;
|
||||||
|
window = 0;
|
||||||
|
ovr_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool oculusUp(void)
|
||||||
|
{
|
||||||
|
return window!=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
View3DInventorRiftViewer* oculusStart(void)
|
||||||
|
{
|
||||||
|
//SoDB::init();
|
||||||
|
|
||||||
|
//QApplication app(argc, argv);
|
||||||
|
//qAddPostRoutine(cleanup);
|
||||||
|
|
||||||
|
// Moved here because of https://developer.oculusvr.com/forums/viewtopic.php?f=17&t=7915&p=108503#p108503
|
||||||
|
// Init libovr.
|
||||||
|
if (!ovr_Initialize()) {
|
||||||
|
qDebug() << "Could not initialize Oculus SDK.";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(window)
|
||||||
|
return window;
|
||||||
|
|
||||||
|
window = new View3DInventorRiftViewer;
|
||||||
|
window->show();
|
||||||
|
|
||||||
|
|
||||||
|
return window;
|
||||||
|
//return app.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //BUILD_VR
|
56
src/Gui/View3DInventorRiftViewer.h
Normal file
56
src/Gui/View3DInventorRiftViewer.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (c) 2014 Juergen Riegel <FreeCAD@juergen-riegel.net> *
|
||||||
|
* *
|
||||||
|
* This file is part of the FreeCAD CAx development system. *
|
||||||
|
* *
|
||||||
|
* This library is free software; you can redistribute it and/or *
|
||||||
|
* modify it under the terms of the GNU Library General Public *
|
||||||
|
* License as published by the Free Software Foundation; either *
|
||||||
|
* version 2 of the License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This library is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Library General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Library General Public *
|
||||||
|
* License along with this library; see the file COPYING.LIB. If not, *
|
||||||
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||||
|
* Suite 330, Boston, MA 02111-1307, USA *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef GUI_View3DInventorRiftViewer_H
|
||||||
|
#define GUI_View3DInventorRiftViewer_H
|
||||||
|
|
||||||
|
#if BUILD_VR
|
||||||
|
|
||||||
|
#include "CoinRiftWidget.h"
|
||||||
|
|
||||||
|
namespace Gui {
|
||||||
|
|
||||||
|
class View3DInventorRiftViewer : public CoinRiftWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
View3DInventorRiftViewer();
|
||||||
|
~View3DInventorRiftViewer();
|
||||||
|
|
||||||
|
virtual void setSceneGraph(SoNode *sceneGraph);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SoGroup *workplace;
|
||||||
|
SoTranslation *translation;
|
||||||
|
SoRotationXYZ *rotation1;
|
||||||
|
SoRotationXYZ *rotation2;
|
||||||
|
SoScale *scale;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent *);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} //namespace Gui
|
||||||
|
|
||||||
|
#endif //BUILD_VR
|
||||||
|
|
||||||
|
#endif //GUI_View3DInventorRiftViewer_H
|
|
@ -103,6 +103,7 @@
|
||||||
#include "SoFCInteractiveElement.h"
|
#include "SoFCInteractiveElement.h"
|
||||||
#include "SoFCBoundingBox.h"
|
#include "SoFCBoundingBox.h"
|
||||||
#include "SoAxisCrossKit.h"
|
#include "SoAxisCrossKit.h"
|
||||||
|
#include "View3DInventorRiftViewer.h"
|
||||||
|
|
||||||
#include "Selection.h"
|
#include "Selection.h"
|
||||||
#include "SoFCSelectionAction.h"
|
#include "SoFCSelectionAction.h"
|
||||||
|
@ -1636,6 +1637,27 @@ void View3DInventorViewer::animatedViewAll(int steps, int ms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BUILD_VR
|
||||||
|
extern View3DInventorRiftViewer* oculusStart(void);
|
||||||
|
extern bool oculusUp (void);
|
||||||
|
extern void oculusStop (void);
|
||||||
|
void oculusSetTestScene(View3DInventorRiftViewer *window);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void View3DInventorViewer::viewVR(void)
|
||||||
|
{
|
||||||
|
#if BUILD_VR
|
||||||
|
if(oculusUp())
|
||||||
|
oculusStop();
|
||||||
|
else{
|
||||||
|
View3DInventorRiftViewer* riftWin = oculusStart();
|
||||||
|
riftWin->setSceneGraph(pcViewProviderRoot);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void View3DInventorViewer::boxZoom(const SbBox2s& box)
|
void View3DInventorViewer::boxZoom(const SbBox2s& box)
|
||||||
{
|
{
|
||||||
navigation->boxZoom(box);
|
navigation->boxZoom(box);
|
||||||
|
|
|
@ -310,6 +310,10 @@ public:
|
||||||
*/
|
*/
|
||||||
void viewAll();
|
void viewAll();
|
||||||
void viewAll(float factor);
|
void viewAll(float factor);
|
||||||
|
|
||||||
|
/// Breaks out a VR window for a Rift
|
||||||
|
void viewVR(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reposition the current camera so we can see all selected objects
|
* Reposition the current camera so we can see all selected objects
|
||||||
* of the scene. Therefore we search for all SOFCSelection nodes, if
|
* of the scene. Therefore we search for all SOFCSelection nodes, if
|
||||||
|
|
|
@ -487,7 +487,11 @@ MenuItem* StdWorkbench::setupMenuBar() const
|
||||||
*view << "Std_ViewCreate" << "Std_OrthographicCamera" << "Std_PerspectiveCamera" << "Separator"
|
*view << "Std_ViewCreate" << "Std_OrthographicCamera" << "Std_PerspectiveCamera" << "Separator"
|
||||||
<< stdviews << "Std_FreezeViews" << "Std_DrawStyle" << "Separator" << view3d << zoom
|
<< stdviews << "Std_FreezeViews" << "Std_DrawStyle" << "Separator" << view3d << zoom
|
||||||
<< "Std_ViewDockUndockFullscreen" << "Std_AxisCross" << "Std_ToggleClipPlane"
|
<< "Std_ViewDockUndockFullscreen" << "Std_AxisCross" << "Std_ToggleClipPlane"
|
||||||
<< "Std_TextureMapping" << "Separator" << visu
|
<< "Std_TextureMapping"
|
||||||
|
#ifdef BUILD_VR
|
||||||
|
<< "Std_ViewVR"
|
||||||
|
#endif
|
||||||
|
<< "Separator" << visu
|
||||||
<< "Std_ToggleVisibility" << "Std_ToggleNavigation"
|
<< "Std_ToggleVisibility" << "Std_ToggleNavigation"
|
||||||
<< "Std_SetAppearance" << "Std_RandomColor" << "Separator"
|
<< "Std_SetAppearance" << "Std_RandomColor" << "Separator"
|
||||||
<< "Std_MeasureDistance" << "Separator"
|
<< "Std_MeasureDistance" << "Separator"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user