diff --git a/sgeo-7.1.10/000.bash b/sgeo-7.1.10/000.bash index aff94a9b73..0d3a5df0f8 100644 --- a/sgeo-7.1.10/000.bash +++ b/sgeo-7.1.10/000.bash @@ -9,10 +9,37 @@ gha-cache-restore $cache_id-repo-0000 repo/viewer || ( quiet-clone ${hub:-github.com} $repo $ref repo/viewer pushd repo/viewer - + + git remote add sgeo https://github.com/Sgeo/phoenix-firestorm-alpha + git fetch sgeo VR_Sgeo_2024 git -c user.email=CITEST -c user.name=CITEST \ - am $nunja_dir/VR_Sgeo_2024_Firestor_7.1.10.all-inclusive-working-with-openvrh.patch + merge --no-edit sgeo/VR_Sgeo_2024 + + # NOTES: + # ... capture wholemeal between manually-patched worktree and an original Firestormx worktree + # diff -ur --binary . ../Firestormx/ > ../VR_Sgeo_2024.7.1.10.wholmeal.patch + # ... blindly copy conflicting files from manually patched work tree: + # tar -C ../Fixed -cf - `git status|grep both|sed -e 's@both modified:@@;'` | tar xf - + patch -p1 < $nunja_dir/VR_Sgeo_2024.7.1.10.mergeconflict-fixes.patch + + git -c user.email=CITEST -c user.name=CITEST commit -m "VR_Sgeo_2024.7.1.10 locally patched" + +patch -p1 < <(cat <<'EOF' +diff --git a/indra/newview/llviewerVR.h b/indra/newview/llviewerVR.h +index fd2aa7880..89804262b 100644 +--- a/indra/newview/llviewerVR.h ++++ b/indra/newview/llviewerVR.h +@@ -1,7 +1,6 @@ + #pragma once +-#include "../../../openvr/headers/openvr.h" +-#pragma comment(lib, "../../../openvr/lib/win64/openvr_api.lib") ++#include + #include "llhudtext.h" + #include "llgl.h" + #include "string.h" +EOF +) git diff # git -C repo/viewer diff popd diff --git a/sgeo-7.1.10/VR_Sgeo_2024.7.1.10.mergeconflict-fixes.patch b/sgeo-7.1.10/VR_Sgeo_2024.7.1.10.mergeconflict-fixes.patch new file mode 100644 index 0000000000..4a1bec995d --- /dev/null +++ b/sgeo-7.1.10/VR_Sgeo_2024.7.1.10.mergeconflict-fixes.patch @@ -0,0 +1,275 @@ +diff -ur --binary '--exclude=.git' ../Firestormx/indra/llrender/llrendertarget.h ./indra/llrender/llrendertarget.h +--- ../Firestormx/indra/llrender/llrendertarget.h 2024-10-13 00:20:15.021678600 +0000 ++++ ./indra/llrender/llrendertarget.h 2024-10-13 00:14:01.000000000 +0000 +@@ -144,16 +144,13 @@ + + LLTexUnit::eTextureType getUsage(void) const { return mUsage; } + +-<<<<<<< HEAD + U32 getTexture(U32 attachment = 0) const; + U32 getNumTextures() const; +-======= + // P373R Sgeo + U32 getFBO(); + // END P373R Sgeo + + U32 getDepth(void) const { return mDepth; } +->>>>>>> sgeo/VR_Sgeo_2024 + + U32 getDepth(void) const { return mDepth; } + +diff -ur --binary '--exclude=.git' ../Firestormx/indra/newview/llviewercamera.cpp ./indra/newview/llviewercamera.cpp +--- ../Firestormx/indra/newview/llviewercamera.cpp 2024-10-13 00:20:15.021678600 +0000 ++++ ./indra/newview/llviewercamera.cpp 2024-10-13 00:14:01.000000000 +0000 +@@ -87,7 +87,6 @@ + + LLViewerCamera::LLViewerCamera() : LLCamera() + { +-<<<<<<< HEAD + calcProjection(getFar()); + mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; + mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; +@@ -103,7 +102,7 @@ + // mCameraAngleChangedSignal = gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); + connectCameraAngleSignal(); + // +-======= ++ + calcProjection(getFar()); + mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; + mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW; +@@ -119,7 +118,6 @@ + mVerticalOffset = 0.f; + // END P373R Sgeo + gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); +->>>>>>> sgeo/VR_Sgeo_2024 + } + + LLViewerCamera::~LLViewerCamera() +@@ -215,14 +213,13 @@ + + f = 1/tan(fov_y*0.5f); + +-<<<<<<< HEAD + mProjectionMatrix.setZero(); + mProjectionMatrix.mMatrix[0][0] = f/aspect; + mProjectionMatrix.mMatrix[1][1] = f; + mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far); + mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far); + mProjectionMatrix.mMatrix[2][3] = -1; +-======= ++ + mProjectionMatrix.setZero(); + mProjectionMatrix.mMatrix[0][0] = f/aspect; + mProjectionMatrix.mMatrix[1][1] = f; +@@ -234,7 +231,6 @@ + mProjectionMatrix.mMatrix[2][0] = getHorizontalOffset(); + mProjectionMatrix.mMatrix[2][1] = getVerticalOffset(); + // END P373R Sgeo +->>>>>>> sgeo/VR_Sgeo_2024 + } + + // Sets up opengl state for 3D drawing. If for selection, also +@@ -420,13 +416,11 @@ + proj_mat = translate*proj_mat; + } + +-<<<<<<< HEAD + calcProjection(z_far); // Update the projection matrix cache +-======= ++ + // P373R Sgeo, replaces non-VR version + proj_mat *= gl_perspective_vr(fov_y,aspect,z_near,z_far, getHorizontalOffset(), getVerticalOffset()); + // END P373R Sgeo +->>>>>>> sgeo/VR_Sgeo_2024 + + proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far); + +@@ -949,9 +943,7 @@ + mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); + } + +-<<<<<<< HEAD +-bool LLViewerCamera::isDefaultFOVChanged() +-======= ++ + // P373R Sgeo + // Takes tan angles. Provided directly from OpenVR + // OpenXR provides angles instead. Convert to tan at callsite or here? +@@ -966,8 +958,7 @@ + } + // END P373R Sgeo + +-BOOL LLViewerCamera::isDefaultFOVChanged() +->>>>>>> sgeo/VR_Sgeo_2024 ++bool LLViewerCamera::isDefaultFOVChanged() + { + if(mPrevCameraFOVDefault != mCameraFOVDefault) + { +diff -ur --binary '--exclude=.git' ../Firestormx/indra/newview/llviewercamera.h ./indra/newview/llviewercamera.h +--- ../Firestormx/indra/newview/llviewercamera.h 2024-10-13 00:20:15.021678600 +0000 ++++ ./indra/newview/llviewercamera.h 2024-10-13 00:14:01.000000000 +0000 +@@ -90,10 +90,10 @@ + // Sets the current matrix + /* virtual */ void setView(F32 vertical_fov_rads); // NOTE: broadcasts to simulator + void setViewNoBroadcast(F32 vertical_fov_rads); // set FOV without broadcasting to simulator (for temporary local cameras) +-<<<<<<< HEAD ++ + void setDefaultFOV(F32 fov) ; + F32 getDefaultFOV() { return mCameraFOVDefault; } +-======= ++ + void setDefaultFOV(F32 fov) ; + F32 getDefaultFOV() { return mCameraFOVDefault; } + // P373R Sgeo +@@ -103,7 +103,6 @@ + void setHorizontalOffset(F32 offset) { mHorizontalOffset = offset; } + void setVerticalOffset(F32 offset) { mVerticalOffset = offset; } + // END P373R Sgeo +->>>>>>> sgeo/VR_Sgeo_2024 + + bool isDefaultFOVChanged(); + +@@ -147,16 +146,13 @@ + // END P373R Sgeo + + public: +-<<<<<<< HEAD + // Enable external classes to disconnect and connect the "CameraAngle" settings + // changed signal, so classes can copy and overwrite the camera class and restore + // the signal handler + void connectCameraAngleSignal(); + void disconnectCameraAngleSignal(); + // +-======= + +->>>>>>> sgeo/VR_Sgeo_2024 + }; + + +diff -ur --binary '--exclude=.git' ../Firestormx/indra/newview/llviewerdisplay.cpp ./indra/newview/llviewerdisplay.cpp +--- ../Firestormx/indra/newview/llviewerdisplay.cpp 2024-10-13 00:20:15.021678600 +0000 ++++ ./indra/newview/llviewerdisplay.cpp 2024-10-13 00:14:01.000000000 +0000 +@@ -777,7 +777,6 @@ + gPipeline.mHeroProbeManager.renderProbes(); + } + +-<<<<<<< HEAD + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 1"); + LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) +@@ -795,7 +794,6 @@ + stop_glerror(); + + { +-======= + //################################### P373R ###################################### + sec: + gVR.ProcessVRCamera(); +@@ -806,7 +804,6 @@ + stop_glerror(); + + { +->>>>>>> sgeo/VR_Sgeo_2024 + LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Env Update"); + // update all the sky/atmospheric/water settings + LLEnvironment::instance().update(&camera); // Factor out calls to getInstance +@@ -1133,14 +1130,13 @@ + LLSceneMonitor::getInstance()->capture(); + } + +-<<<<<<< HEAD + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); + if (!for_snapshot) + { + render_ui(); + swap(); + } +-======= ++ + LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); + if (!for_snapshot) + { +@@ -1167,7 +1163,6 @@ + + //################################### END P373R ################################## + } +->>>>>>> sgeo/VR_Sgeo_2024 + + + LLSpatialGroup::sNoDelete = false; +@@ -1706,18 +1701,12 @@ + + // Debugging stuff goes before the UI. + +-<<<<<<< HEAD + stop_glerror(); +- +- gUIProgram.bind(); +-======= +- stop_glerror(); + +- gUIProgram.bind(); ++ gUIProgram.bind(); + //################################### P373R ###################################### + gVR.RenderControllerAxes(); + //################################### END P373R ################################## +->>>>>>> sgeo/VR_Sgeo_2024 + gGL.color4f(1, 1, 1, 1); + + // Coordinate axes +@@ -1745,9 +1734,7 @@ + + void render_ui_2d() + { +-<<<<<<< HEAD + LLGLSUIDefault gls_ui; +-======= + // P373R Sgeo + // LLRenderTarget *priorTarget = NULL; + // if (gVR.m_bVrActive) +@@ -1761,7 +1748,6 @@ + // } + // /P373R Sgeo + LLGLSUIDefault gls_ui; +->>>>>>> sgeo/VR_Sgeo_2024 + + ///////////////////////////////////////////////////////////// + // +@@ -2002,13 +1988,10 @@ + + void display_cleanup() + { +-<<<<<<< HEAD + gDisconnectedImagep = NULL; +-======= + //################################### P373R ###################################### + gVR.vrStartup(TRUE); + //################################### END P373R ###################################### + gDisconnectedImagep = NULL; +->>>>>>> sgeo/VR_Sgeo_2024 + } + +diff -ur --binary '--exclude=.git' ../Firestormx/indra/newview/pipeline.cpp ./indra/newview/pipeline.cpp +--- ../Firestormx/indra/newview/pipeline.cpp 2024-10-13 00:20:15.021678600 +0000 ++++ ./indra/newview/pipeline.cpp 2024-10-13 00:14:02.000000000 +0000 +@@ -914,10 +914,9 @@ + } + } + +-<<<<<<< HEAD + S32 shadow_detail = RenderShadowDetail; + bool ssao = RenderDeferredSSAO; +-======= ++ + if (true || RenderUIBuffer) // P373R Sgeo + { + if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA)) +@@ -925,7 +924,6 @@ + return false; + } + } +->>>>>>> sgeo/VR_Sgeo_2024 + + //allocate deferred rendering color buffers + if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false; diff --git a/sgeo-7.1.10/VR_Sgeo_2024_Firestor_7.1.10.all-inclusive-working-with-openvrh.patch b/sgeo-7.1.10/VR_Sgeo_2024_Firestor_7.1.10.all-inclusive-working-with-openvrh.patch deleted file mode 100644 index 1aafb10a82..0000000000 --- a/sgeo-7.1.10/VR_Sgeo_2024_Firestor_7.1.10.all-inclusive-working-with-openvrh.patch +++ /dev/null @@ -1,3202 +0,0 @@ -From 268538ac5cf212ac502846a8f217d5318bbbaf85 Mon Sep 17 00:00:00 2001 -From: Sgeo -Date: Sat, 27 Jan 2024 21:24:13 -0500 -Subject: [PATCH 1/3] Copy VR patches over, with fixes. Compiles and runs but - camera behaving weirdly. - ---- - indra/llrender/llrender.cpp | 12 + - indra/llrender/llrender.h | 3 + - indra/llrender/llrendertarget.cpp | 6 + - indra/llrender/llrendertarget.h | 4 + - indra/newview/llviewerVR.cpp | 2526 +++++++++++++++++++++++++++++ - indra/newview/llviewerVR.h | 236 +++ - indra/newview/llviewercamera.cpp | 27 +- - indra/newview/llviewercamera.h | 14 + - indra/newview/llviewerdisplay.cpp | 84 +- - indra/newview/pipeline.cpp | 2 +- - 10 files changed, 2911 insertions(+), 3 deletions(-) - create mode 100644 indra/newview/llviewerVR.cpp - create mode 100644 indra/newview/llviewerVR.h - -diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp -index 24b0653d2..80e3c6551 100644 ---- a/indra/llrender/llrender.cpp -+++ b/indra/llrender/llrender.cpp -@@ -2297,6 +2297,18 @@ glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloa - 0, 0, -1.f, 0); - } - -+// P373R Sgeo -+glh::matrix4f gl_perspective_vr(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar, GLfloat hOffset, GLfloat vOffset) -+{ -+ GLfloat f = 1.f/tanf(DEG_TO_RAD*fovy/2.f); -+ -+ return glh::matrix4f(f/aspect, 0, hOffset, 0, -+ 0, f, vOffset, 0, -+ 0, 0, (zFar+zNear)/(zNear-zFar), (2.f*zFar*zNear)/(zNear-zFar), -+ 0, 0, -1.f, 0); -+} -+// END P373R Sgeo -+ - glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up) - { - LLVector3 f = center-eye; -diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h -index 6cc570543..c01a898a1 100644 ---- a/indra/llrender/llrender.h -+++ b/indra/llrender/llrender.h -@@ -564,6 +564,9 @@ void set_current_projection(glh::matrix4f& mat); - - glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar); - glh::matrix4f gl_perspective(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar); -+// P373R Sgeo -+glh::matrix4f gl_perspective_vr(GLfloat fovy, GLfloat aspect, GLfloat zNear, GLfloat zFar, GLfloat hOffset, GLfloat vOffset); -+// END P373R Sgeo - glh::matrix4f gl_lookat(LLVector3 eye, LLVector3 center, LLVector3 up); - - #define LL_SHADER_LOADING_WARNS(...) LL_WARNS() -diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp -index 671b0ceb0..d7786469f 100644 ---- a/indra/llrender/llrendertarget.cpp -+++ b/indra/llrender/llrendertarget.cpp -@@ -184,6 +184,12 @@ void LLRenderTarget::setColorAttachment(LLImageGL* img, LLGLuint use_name) - glBindFramebuffer(GL_FRAMEBUFFER, sCurFBO); - } - -+// P373R Sgeo -+U32 LLRenderTarget::getFBO() { -+ return mFBO; -+} -+// END P373R Sgeo -+ - void LLRenderTarget::releaseColorAttachment() - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; -diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h -index 9fcea35e3..48a1e8f0a 100644 ---- a/indra/llrender/llrendertarget.h -+++ b/indra/llrender/llrendertarget.h -@@ -147,6 +147,10 @@ public: - U32 getTexture(U32 attachment = 0) const; - U32 getNumTextures() const; - -+ // P373R Sgeo -+ U32 getFBO(); -+ // END P373R Sgeo -+ - U32 getDepth(void) const { return mDepth; } - - void bindTexture(U32 index, S32 channel, LLTexUnit::eTextureFilterOptions filter_options = LLTexUnit::TFO_BILINEAR); -diff --git a/indra/newview/llviewerVR.cpp b/indra/newview/llviewerVR.cpp -new file mode 100644 -index 000000000..ce7172233 ---- /dev/null -+++ b/indra/newview/llviewerVR.cpp -@@ -0,0 +1,2526 @@ -+#include "llviewerprecompiledheaders.h" -+#include "llviewerVR.h" -+#include "llviewerwindow.h" -+#ifdef _WIN32 -+#include "llwindowwin32.h" -+#endif -+#include "llviewercontrol.h" -+#include "llviewercamera.h" -+#include "llagentcamera.h" -+#include "pipeline.h" -+#include "llagent.h" -+#include "llerror.h" -+#ifdef _WIN32 -+#include "llkeyboardwin32.h" -+#endif -+#include "llui.h" -+ -+#include "llfloaterreg.h" -+#include -+#include -+#include -+#include -+//#include "llrender.h" -+ -+#ifdef _WIN32 -+#pragma comment(lib, "openvr_api") -+#endif -+ -+#ifndef _WIN32 -+#define sprintf_s(buffer, buffer_size, stringbuffer, ...) (sprintf(buffer, stringbuffer, __VA_ARGS__)) -+#endif -+ -+//#include -+//#include -+llviewerVR::llviewerVR() -+{ -+ gHMD = NULL; -+ gRenderModels = NULL; -+ leftEyeDesc.m_nResolveTextureId = 0; -+ rightEyeDesc.m_nResolveTextureId = 0; -+ uiDesc.m_nResolveTextureId = 0; -+ hud_textp = NULL; -+ m_kEditKey = KEY_F4; -+ m_kDebugKey = KEY_F3; -+ m_kMenuKey = KEY_F5; -+ m_kPlusKey = KEY_F6; -+ m_kMinusKey = KEY_F7; -+ m_fEyeDistance = 40; -+ m_fWorldScale = 1.0; -+ m_fFocusDistance = 10; -+ m_fTextureShift = 0; -+ m_fTextureZoom = 0; -+ m_fFOV = 100; -+ -+ /*if (!LLKeyboard::keyFromString("x", &m_kEditKey)) -+ { -+ // If the call failed, don't match any key. -+ //key = KEY_NONE; -+ }*/ -+} -+LLPanel* panelp = NULL; -+//GLenum err; -+ -+llviewerVR::~llviewerVR() -+{ -+} -+ -+/*glh::matrix4f ConvertSteamVRMatrixToMatrix4(const vr::HmdMatrix34_t &matPose) -+{ -+glh::matrix4f matrixObj( -+matPose.m[0][0], matPose.m[1][0], matPose.m[2][0], 0.0, -+matPose.m[0][1], matPose.m[1][1], matPose.m[2][1], 0.0, -+matPose.m[0][2], matPose.m[1][2], matPose.m[2][2], 0.0, -+matPose.m[0][3], matPose.m[1][3], matPose.m[2][3], 1.0f -+); -+return matrixObj; -+}*/ -+//unused -+vr::HmdQuaternion_t llviewerVR::GetRotation(vr::HmdMatrix34_t matrix) { -+ vr::HmdQuaternion_t q; -+ -+ q.w = sqrt(fmax(0, 1 + matrix.m[0][0] + matrix.m[1][1] + matrix.m[2][2])) / 2; -+ q.x = sqrt(fmax(0, 1 + matrix.m[0][0] - matrix.m[1][1] - matrix.m[2][2])) / 2; -+ q.y = sqrt(fmax(0, 1 - matrix.m[0][0] + matrix.m[1][1] - matrix.m[2][2])) / 2; -+ q.z = sqrt(fmax(0, 1 - matrix.m[0][0] - matrix.m[1][1] + matrix.m[2][2])) / 2; -+ q.x = copysign(q.x, matrix.m[2][1] - matrix.m[1][2]); -+ q.y = copysign(q.y, matrix.m[0][2] - matrix.m[2][0]); -+ q.z = copysign(q.z, matrix.m[1][0] - matrix.m[0][1]); -+ return q; -+} -+ -+LLMatrix4 llviewerVR::ConvertGLHMatrix4ToLLMatrix4(glh::matrix4f m) -+{ -+ LLMatrix4 mout; -+ mout.mMatrix[0][0] = m.element(0, 0); -+ mout.mMatrix[0][1] = m.element(1, 0); -+ mout.mMatrix[0][2] = m.element(2, 0); -+ mout.mMatrix[0][3] = m.element(3, 0); -+ -+ mout.mMatrix[1][0] = m.element(0, 1); -+ mout.mMatrix[1][1] = m.element(1, 1); -+ mout.mMatrix[1][2] = m.element(2, 1); -+ mout.mMatrix[1][3] = m.element(3, 1); -+ -+ mout.mMatrix[2][0] = m.element(0, 2); -+ mout.mMatrix[2][1] = m.element(1, 2); -+ mout.mMatrix[2][2] = m.element(2, 2); -+ mout.mMatrix[2][3] = m.element(3, 2); -+ -+ mout.mMatrix[3][0] = m.element(0, 3); -+ mout.mMatrix[3][1] = m.element(1, 3); -+ mout.mMatrix[3][2] = m.element(2, 3); -+ mout.mMatrix[3][3] = m.element(3, 3); -+ return mout; -+} -+ -+glh::matrix4f llviewerVR::ConvertSteamVRMatrixToMatrix42(const vr::HmdMatrix34_t &matPose) -+{ -+ // SteamVR: x = right, y = up, z = backwards -+ // SL (Cory's Favorite): x = forward, y = left, z = up (http://wiki.secondlife.com/wiki/How_the_camera_works) -+ -+ // Convert SL -> SteamVR: x' = -y; y' = z; z' = -x -+ // Convert SteamVR -> SL: x' = -z; y' = -x; z' = y -+ -+ // SL -> SteamVR matrix: -+ // 0 -1 0 0 -+ // 0 0 1 0 -+ // -1 0 0 0 -+ // 0 0 0 1 -+ -+ // SteamVR -> SL matrix (inverse of above, and matches OGL_TO_CFR_ROTATION) -+ // 0 0 -1 0 -+ // -1 0 0 0 -+ // 0 1 0 0 -+ // 0 0 0 1 -+ -+ // Scale: x y and z on SL->SteamVR multiplied by m_fWorldScale, SteamVR->SL divided by m_fWorldScale -+ -+ // Change of basis: SL-based matrix = (SteamVR -> SL) * (SteamVR-based matrix) * (SL -> SteamVR) -+ // (Incoming SL coordinates get changed to SteamVR coordinates, SteamVR-based matrix transforms SteamVR coords, outgoing SteamVR coordinates get changed back to SL) -+ // (See https://www.youtube.com/watch?v=P2LTAUO1TdA) -+ -+ // Argument: -+ // m_11 m_12 m_13 m_14 -+ // m_21 m_22 m_23 m_24 -+ // m_31 m_32 m_33 m_34 -+ // m_41 m_42 m_43 m_44 -+ -+ // (Note that HmdMatrix34_t omits the last row, which is always 0 0 0 1) -+ -+ // https://www.wolframalpha.com/input/?i=matrix+multiplication+calculator&assumption=%7B%22F%22%2C+%22MatricesOperations%22%2C+%22theMatrix3%22%7D+-%3E%22%7B%7B0%2C+-1%2C+0%2C+0%7D%2C+%7B0%2C+0%2C+1%2C+0%7D%2C+%7B-1%2C+0%2C+0%2C+0%7D%2C+%7B0%2C+0%2C+0%2C+1%7D%7D%22&assumption=%7B%22F%22%2C+%22MatricesOperations%22%2C+%22theMatrix2%22%7D+-%3E%22%7B%7B11%2C+12%2C+13%2C+14%7D%2C+%7B21%2C+22%2C+23%2C+24%7D%2C+%7B31%2C+32%2C+33%2C+34%7D%2C+%7B41%2C+42%2C+43%2C+44%7D%7D%22&assumption=%7B%22F%22%2C+%22MatricesOperations%22%2C+%22theMatrix1%22%7D+-%3E%22%7B%7B0%2C+0%2C+-1%2C+0%7D%2C+%7B-1%2C+0%2C+0%2C+0%7D%2C+%7B0%2C+1%2C+0%2C+0%7D%2C+%7B0%2C+0%2C+0%2C+1%7D%7D%22 -+ -+ // Result: -+ // m_33 m_31 -m_32 -m_34 -+ // m_13 m_11 -m_12 -m_14 -+ // -m_23 -m_21 m_22 m_24 -+ // -m_43 -m_41 m_42 m_44 -+ -+ // Scaled version: -+ // https://www.wolframalpha.com/input/?i=matrix+multiplication+calculator&assumption=%7B%22F%22%2C+%22MatricesOperations%22%2C+%22theMatrix3%22%7D+-%3E%22%7B%7B0%2C+-10%2C+0%2C+0%7D%2C+%7B0%2C+0%2C+10%2C+0%7D%2C+%7B-10%2C+0%2C+0%2C+0%7D%2C+%7B0%2C+0%2C+0%2C+1%7D%7D%22&assumption=%7B%22F%22%2C+%22MatricesOperations%22%2C+%22theMatrix2%22%7D+-%3E%22%7B%7B11%2C+12%2C+13%2C+14%7D%2C+%7B21%2C+22%2C+23%2C+24%7D%2C+%7B31%2C+32%2C+33%2C+34%7D%2C+%7B41%2C+42%2C+43%2C+44%7D%7D%22&assumption=%7B%22F%22%2C+%22MatricesOperations%22%2C+%22theMatrix1%22%7D+-%3E%22%7B%7B0%2C+0%2C+-.1%2C+0%7D%2C+%7B-.1%2C+0%2C+0%2C+0%7D%2C+%7B0%2C+.1%2C+0%2C+0%7D%2C+%7B0%2C+0%2C+0%2C+1%7D%7D%22 -+ -+ // Result -+ -+ // m_33 m_31 -m_32 m_34/scale -+ // m_13 m_11 -m_12 -m_14/scale -+ // -m_23 -m_21 m_22 m_24/scale -+ // -m_43*scale -m_41*scale m_42*scale m_44 -+ -+ // Below constructor is ROW major. It should look as above -+ // Also array indices are -1 from math indices -+ -+ -+ glh::matrix4f matrixObj( -+ matPose.m[2][2], matPose.m[2][0], -matPose.m[2][1], -matPose.m[2][3], -+ matPose.m[0][2], matPose.m[0][0], -matPose.m[0][1], -matPose.m[0][3], -+ -matPose.m[1][2], -matPose.m[1][0], matPose.m[1][1], matPose.m[1][3], -+ 0.0, 0.0, 0.0, 1.0 -+ ); -+ return matrixObj; -+} -+ -+LLVector3 llviewerVR::TransformLLVector(glh::matrix4f transform, LLVector3 vector, F32 w) { -+ // w = 1.0 for position, 0.0 for direction -+ glh::vec4f glhvec(vector[0], vector[1], vector[2], w); -+ glh::vec4f glhresult; -+ //transform.mult_matrix_vec(&glhvec, &glhresult); -+ LLVector3 result(glhresult.v[0], glhresult.v[1], glhresult.v[2]); -+ return result; -+ -+} -+ -+glh::matrix4f llviewerVR::GetHMDMatrixProjectionEye(vr::Hmd_Eye nEye) -+{ -+ if (gHMD == NULL) -+ return glh::matrix4f(); -+ -+ vr::HmdMatrix44_t mat = gHMD->GetProjectionMatrix(nEye, m_fNearClip, m_fFarClip); -+ -+ return glh::matrix4f( -+ mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0], -+ mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1], -+ mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2], -+ mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3] -+ ); -+} -+ -+glh::matrix4f llviewerVR::GetHMDMatrixPoseEye(vr::Hmd_Eye nEye) -+{ -+ if (gHMD == NULL) -+ return glh::matrix4f(); -+ -+ vr::HmdMatrix34_t matEyeRight = gHMD->GetEyeToHeadTransform(nEye); -+ return glh::matrix4f( -+ matEyeRight.m[0][0], matEyeRight.m[1][0], matEyeRight.m[2][0], 0.0, -+ matEyeRight.m[0][1], matEyeRight.m[1][1], matEyeRight.m[2][1], 0.0, -+ matEyeRight.m[0][2], matEyeRight.m[1][2], matEyeRight.m[2][2], 0.0, -+ matEyeRight.m[0][3], matEyeRight.m[1][3], matEyeRight.m[2][3], 1.0f -+ ); -+ //glh::matrix4f mt; -+ //return matrixObj.inverse(); -+ //gluInvertMatrix(matrixObj.m, mt.m); -+ //return matrixObj; -+} -+ -+void llviewerVR::calcUVBounds(vr::EVREye eye, F32 *uMin, F32 *uMax, F32 *vMin, F32 *vMax) { -+ // Relevant code with useful math: -+ // https://github.com/LibreVR/Revive/blob/4843c1bed72c9c7888e6bfa429f263584c7586c1/Revive/CompositorBase.cpp#L481 -+ // https://github.com/ValveSoftware/steamvr_unity_plugin/blob/9442d7d7d447e07aa21c64746633dcb5977bdd1e/Assets/SteamVR/Scripts/SteamVR.cs#L696 -+ // Some more clarity: -+ // https://steamcommunity.com/app/358720/discussions/0/343786746000217310/ -+ -+ // https://github.com/KhronosGroup/OpenXR-SDK/blob/960c4a6aa8cc9f47e357c696b5377d817550bf88/src/common/xr_linear.h#L482 -+ // Normal projection (but shouldn't matter) -+ // Each group of 4 lines represents the output of a coordinate. First group of 4 is new x, second group is new y, third is new z, fourth is new w -+ // Each line in a group is a former coordinate's contribution to the new coordinate. So first line N is x*N getting added to new x -+ // We project the old FOV by multiplying the coordinates (tans) by this projection matrix -+ // Left bound for example is (gameTanAngleLeft, 0, -1, 1) -+ // Note the negative z! -+ -+ -+ F32 gameTanAngleHeight = 2.0f * tan(LLViewerCamera::getInstance()->getView()/2.0f); -+ F32 gameTanAngleUp = gameTanAngleHeight/2.0f; -+ F32 gameTanAngleDown = -gameTanAngleUp; -+ F32 gameTanAngleWidth = gameTanAngleHeight * LLViewerCamera::getInstance()->getAspect(); -+ F32 gameTanAngleRight = gameTanAngleWidth/2.0f; -+ F32 gameTanAngleLeft = -gameTanAngleRight; -+ -+ F32 vrTanAngleLeft = 0.0; -+ F32 vrTanAngleRight = 0.0; -+ F32 vrTanAngleUp = 0.0; -+ F32 vrTanAngleDown = 0.0; -+ gHMD->GetProjectionRaw(eye, &vrTanAngleLeft, &vrTanAngleRight, &vrTanAngleDown, &vrTanAngleUp); // Valve documentation backwards? -+ F32 vrTanAngleWidth = vrTanAngleRight - vrTanAngleLeft; -+ F32 vrTanAngleHeight = vrTanAngleUp - vrTanAngleDown; -+ -+ *uMin = gameTanAngleLeft * (2.0f / vrTanAngleWidth) - (vrTanAngleRight + vrTanAngleLeft) / vrTanAngleWidth; -+ *uMax = gameTanAngleRight * (2.0f / vrTanAngleWidth) - (vrTanAngleRight + vrTanAngleLeft) / vrTanAngleWidth; -+ *vMin = gameTanAngleDown * (2.0f / vrTanAngleHeight) - (vrTanAngleUp + vrTanAngleDown) / vrTanAngleHeight; -+ *vMax = gameTanAngleUp * (2.0f / vrTanAngleHeight) - (vrTanAngleUp + vrTanAngleDown) / vrTanAngleHeight; -+ -+ // Convert [-1,1] to [0,1] -+ -+ *uMin = *uMin * 0.5f + 0.5f; -+ *uMax = *uMax * 0.5f + 0.5f; -+ *vMin = *vMin * 0.5f + 0.5f; -+ *vMax = *vMax * 0.5f + 0.5f; -+ -+ -+ // Temporarily ignore all this -+ *uMin = 0.0f; -+ *uMax = 1.0f; -+ *vMin = 0.0f; -+ *vMax = 1.0f; -+ -+ -+ // // Fix FOV for next frame -+ // F32 tan_half_fov_x = std::max(vr_left_tan, vr_right_tan); -+ // F32 tan_half_fov_y = std::max(vr_up_tan, vr_down_tan); -+ // LLViewerCamera::getInstance()->setDefaultFOV(2.0f * atan(tan_half_fov_x)); -+ // m_fFOV = 2.0f * atan(tan_half_fov_x) * RAD_TO_DEG; -+ // LLViewerCamera::getInstance()->setAspect(tan_half_fov_x / tan_half_fov_y); -+ -+} -+ -+//unused Gives the projection matrix for an eye with HMD and IPD offsets. Add positional camera offset???? -+ -+//Copy both matrices at startup????? -+glh::matrix4f llviewerVR::GetCurrentViewProjectionMatrix(vr::Hmd_Eye nEye) -+{ -+ if (gHMD == NULL) -+ return glh::matrix4f(); -+ return GetHMDMatrixProjectionEye(nEye) * GetHMDMatrixPoseEye(nEye) * m_mat4HMDPose; -+} -+ -+//debug func -+std::string llviewerVR::MatrixToStr(glh::matrix4f mat, std::string name) -+{ -+ -+ std::string str(name); -+ glh::ns_float::vec4 row; -+ row = mat.get_row(0); -+ str.append("\nLf Row 0 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(-row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" >\n "); -+ -+ row = mat.get_row(1); -+ str.append("Up Row 1 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(-row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" > \n "); -+ -+ row = mat.get_row(2); -+ str.append("Fw Row 2 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(-row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" > \n "); -+ -+ row = mat.get_row(3); -+ str.append("po Row 3 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(-row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" > \n\n "); -+ -+ -+ -+ -+ -+ -+ return str; -+} -+ -+//Debug func -+std::string llviewerVR::MatrixToStrLL(glh::matrix4f mat, std::string name) -+{ -+ -+ std::string str(name); -+ glh::ns_float::vec4 row; -+ row = mat.get_row(0); -+ str.append("\nLf Row 0 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" >\n "); -+ -+ row = mat.get_row(1); -+ str.append("Up Row 1 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ -+ str.append(" > \n "); -+ -+ row = mat.get_row(2); -+ str.append("Fw Row 2 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" > \n "); -+ -+ row = mat.get_row(3); -+ str.append("po Row 3 =< "); -+ str.append(std::to_string(row.v[0])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[1])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[2])); -+ str.append(" , "); -+ str.append(std::to_string(row.v[3])); -+ str.append(" > \n\n "); -+ -+ -+ -+ -+ -+ -+ return str; -+} -+ -+bool llviewerVR::gluInvertMatrix(const float m[16], float invOut[16]) -+{ -+ float inv[16], det; -+ int i; -+ -+ inv[0] = m[5] * m[10] * m[15] - -+ m[5] * m[11] * m[14] - -+ m[9] * m[6] * m[15] + -+ m[9] * m[7] * m[14] + -+ m[13] * m[6] * m[11] - -+ m[13] * m[7] * m[10]; -+ -+ inv[4] = -m[4] * m[10] * m[15] + -+ m[4] * m[11] * m[14] + -+ m[8] * m[6] * m[15] - -+ m[8] * m[7] * m[14] - -+ m[12] * m[6] * m[11] + -+ m[12] * m[7] * m[10]; -+ -+ inv[8] = m[4] * m[9] * m[15] - -+ m[4] * m[11] * m[13] - -+ m[8] * m[5] * m[15] + -+ m[8] * m[7] * m[13] + -+ m[12] * m[5] * m[11] - -+ m[12] * m[7] * m[9]; -+ -+ inv[12] = -m[4] * m[9] * m[14] + -+ m[4] * m[10] * m[13] + -+ m[8] * m[5] * m[14] - -+ m[8] * m[6] * m[13] - -+ m[12] * m[5] * m[10] + -+ m[12] * m[6] * m[9]; -+ -+ inv[1] = -m[1] * m[10] * m[15] + -+ m[1] * m[11] * m[14] + -+ m[9] * m[2] * m[15] - -+ m[9] * m[3] * m[14] - -+ m[13] * m[2] * m[11] + -+ m[13] * m[3] * m[10]; -+ -+ inv[5] = m[0] * m[10] * m[15] - -+ m[0] * m[11] * m[14] - -+ m[8] * m[2] * m[15] + -+ m[8] * m[3] * m[14] + -+ m[12] * m[2] * m[11] - -+ m[12] * m[3] * m[10]; -+ -+ inv[9] = -m[0] * m[9] * m[15] + -+ m[0] * m[11] * m[13] + -+ m[8] * m[1] * m[15] - -+ m[8] * m[3] * m[13] - -+ m[12] * m[1] * m[11] + -+ m[12] * m[3] * m[9]; -+ -+ inv[13] = m[0] * m[9] * m[14] - -+ m[0] * m[10] * m[13] - -+ m[8] * m[1] * m[14] + -+ m[8] * m[2] * m[13] + -+ m[12] * m[1] * m[10] - -+ m[12] * m[2] * m[9]; -+ -+ inv[2] = m[1] * m[6] * m[15] - -+ m[1] * m[7] * m[14] - -+ m[5] * m[2] * m[15] + -+ m[5] * m[3] * m[14] + -+ m[13] * m[2] * m[7] - -+ m[13] * m[3] * m[6]; -+ -+ inv[6] = -m[0] * m[6] * m[15] + -+ m[0] * m[7] * m[14] + -+ m[4] * m[2] * m[15] - -+ m[4] * m[3] * m[14] - -+ m[12] * m[2] * m[7] + -+ m[12] * m[3] * m[6]; -+ -+ inv[10] = m[0] * m[5] * m[15] - -+ m[0] * m[7] * m[13] - -+ m[4] * m[1] * m[15] + -+ m[4] * m[3] * m[13] + -+ m[12] * m[1] * m[7] - -+ m[12] * m[3] * m[5]; -+ -+ inv[14] = -m[0] * m[5] * m[14] + -+ m[0] * m[6] * m[13] + -+ m[4] * m[1] * m[14] - -+ m[4] * m[2] * m[13] - -+ m[12] * m[1] * m[6] + -+ m[12] * m[2] * m[5]; -+ -+ inv[3] = -m[1] * m[6] * m[11] + -+ m[1] * m[7] * m[10] + -+ m[5] * m[2] * m[11] - -+ m[5] * m[3] * m[10] - -+ m[9] * m[2] * m[7] + -+ m[9] * m[3] * m[6]; -+ -+ inv[7] = m[0] * m[6] * m[11] - -+ m[0] * m[7] * m[10] - -+ m[4] * m[2] * m[11] + -+ m[4] * m[3] * m[10] + -+ m[8] * m[2] * m[7] - -+ m[8] * m[3] * m[6]; -+ -+ inv[11] = -m[0] * m[5] * m[11] + -+ m[0] * m[7] * m[9] + -+ m[4] * m[1] * m[11] - -+ m[4] * m[3] * m[9] - -+ m[8] * m[1] * m[7] + -+ m[8] * m[3] * m[5]; -+ -+ inv[15] = m[0] * m[5] * m[10] - -+ m[0] * m[6] * m[9] - -+ m[4] * m[1] * m[10] + -+ m[4] * m[2] * m[9] + -+ m[8] * m[1] * m[6] - -+ m[8] * m[2] * m[5]; -+ -+ det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12]; -+ -+ if (det == 0) -+ return false; -+ -+ det = 1.0 / det; -+ -+ for (i = 0; i < 16; i++) -+ invOut[i] = inv[i] * det; -+ -+ return true; -+} -+ -+void llviewerVR::UpdateHMDMatrixPose() -+{ -+ if (gHMD == NULL) -+ return; -+ /// for somebody asking for the default figure out the time from now to photons. -+ /* float fSecondsSinceLastVsync; -+ gHMD->GetTimeSinceLastVsync(&fSecondsSinceLastVsync, NULL); -+ -+ float fDisplayFrequency = gHMD->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_DisplayFrequency_Float); -+ float fFrameDuration = 1.f / fDisplayFrequency; -+ float fVsyncToPhotons = gHMD->GetFloatTrackedDeviceProperty(vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SecondsFromVsyncToPhotons_Float); -+ -+ float fPredictedSecondsFromNow = fFrameDuration - fSecondsSinceLastVsync + fVsyncToPhotons;*/ -+ -+ -+ -+ -+ vr::VRCompositor()->WaitGetPoses(gTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, NULL, 0); -+ -+ m_iValidPoseCount = 0; -+ m_strPoseClasses = ""; -+ for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice) -+ { -+ if (gTrackedDevicePose[nDevice].bPoseIsValid) -+ { -+ m_iValidPoseCount++; -+ m_rmat4DevicePose[nDevice] = ConvertSteamVRMatrixToMatrix42(gTrackedDevicePose[nDevice].mDeviceToAbsoluteTracking); -+ if (m_rDevClassChar[nDevice] == 0) -+ { -+ switch (gHMD->GetTrackedDeviceClass(nDevice)) -+ { -+ case vr::TrackedDeviceClass_Controller: m_rDevClassChar[nDevice] = 'C'; break; -+ case vr::TrackedDeviceClass_HMD: m_rDevClassChar[nDevice] = 'H'; break; -+ case vr::TrackedDeviceClass_Invalid: m_rDevClassChar[nDevice] = 'I'; break; -+ case vr::TrackedDeviceClass_GenericTracker: m_rDevClassChar[nDevice] = 'G'; break; -+ case vr::TrackedDeviceClass_TrackingReference: m_rDevClassChar[nDevice] = 'T'; break; -+ default: m_rDevClassChar[nDevice] = '?'; break; -+ } -+ } -+ m_strPoseClasses += m_rDevClassChar[nDevice]; -+ } -+ } -+ -+ if (gTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid) -+ { -+ m_mat4HMDPose = m_rmat4DevicePose[vr::k_unTrackedDeviceIndex_Hmd]; -+ //gM4HMDPose = ConvertGLHMatrix4ToLLMatrix4(m_mat4HMDPose); -+ //gM4HMDPose.invert; -+ //gluInvertMatrix(m_rmat4DevicePose[vr::k_unTrackedDeviceIndex_Hmd].m, m_mat4HMDPose.m); -+ //m_mat4HMDPose.inverse(); -+ } -+} -+ -+std::string llviewerVR::GetTrackedDeviceString(vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError ) -+{ -+ uint32_t unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty(unDevice, prop, NULL, 0, peError); -+ if (unRequiredBufferLen == 0) -+ return ""; -+ -+ char *pchBuffer = new char[unRequiredBufferLen]; -+ unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty(unDevice, prop, pchBuffer, unRequiredBufferLen, peError); -+ std::string sResult = pchBuffer; -+ delete[] pchBuffer; -+ return sResult; -+} -+ -+void llviewerVR::SetupCameras() -+{ -+ m_mat4ProjectionLeft = GetHMDMatrixProjectionEye(vr::Eye_Left); -+ //gM4eyeProjectionLeft = ConvertGLHMatrix4ToLLMatrix4(m_mat4ProjectionLeft); -+ -+ m_mat4ProjectionRight = GetHMDMatrixProjectionEye(vr::Eye_Right); -+ //gM4eyeProjectionRight = ConvertGLHMatrix4ToLLMatrix4(m_mat4ProjectionRight); -+ -+ m_mat4eyePosLeft = GetHMDMatrixPoseEye(vr::Eye_Left); -+ //gM4eyePosLeft = ConvertGLHMatrix4ToLLMatrix4(m_mat4eyePosLeft); -+ //gM4eyePosLeft.invert(); -+ -+ m_mat4eyePosRight = GetHMDMatrixPoseEye(vr::Eye_Right); -+ //gM4eyePosRight = ConvertGLHMatrix4ToLLMatrix4(m_mat4eyePosRight); -+ //gM4eyePosRight.invert(); -+} -+ -+bool llviewerVR::CreateFrameBuffer(LLRenderTarget &renderTarget, int nWidth, int nHeight, FramebufferDesc &framebufferDesc) -+{ -+ /*glGenFramebuffers(1, &framebufferDesc.m_nRenderFramebufferId); -+ glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.m_nRenderFramebufferId); -+ -+ glGenRenderbuffers(1, &framebufferDesc.m_nDepthBufferId); -+ glBindRenderbuffer(GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId); -+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT, nWidth, nHeight); -+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId); -+ -+ glGenTextures(1, &framebufferDesc.m_nRenderTextureId); -+ glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, framebufferDesc.m_nRenderTextureId); -+ glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, nWidth, nHeight, true); -+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, framebufferDesc.m_nRenderTextureId, 0); -+ */ -+ if (framebufferDesc.m_nResolveTextureId) -+ { -+ glDeleteTextures(1, &framebufferDesc.m_nResolveTextureId); -+ //glDeleteFramebuffers(1, &framebufferDesc.mFBO) -+ } -+ else -+ { -+ glGenFramebuffers(1, &framebufferDesc.mFBO); -+ -+ } -+ glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.mFBO); -+ glGenTextures(1, &framebufferDesc.m_nResolveTextureId); -+ glBindTexture(GL_TEXTURE_2D, framebufferDesc.m_nResolveTextureId); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); -+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); -+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferDesc.m_nResolveTextureId, 0); -+ -+ renderTarget.allocate(nWidth, nHeight, GL_RGBA8, TRUE); -+ framebufferDesc.m_nRenderTextureId = renderTarget.getTexture(); -+ -+ -+ -+ -+ // check FBO status -+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); -+ if (status != GL_FRAMEBUFFER_COMPLETE) -+ { -+ return false; -+ } -+ -+ glBindFramebuffer(GL_FRAMEBUFFER, 0); -+ -+ return true; -+} -+ -+static void UiLayerOverlayPosition(vr::HmdMatrix34_t *matrix) -+{ -+ matrix->m[0][0] = 1; -+ matrix->m[0][1] = 0; -+ matrix->m[0][2] = 0; -+ matrix->m[0][3] = 0; // x -+ matrix->m[1][0] = 0; -+ matrix->m[1][1] = 1; -+ matrix->m[1][2] = 0; -+ matrix->m[1][3] = 0; // y -+ matrix->m[2][0] = 0; -+ matrix->m[2][1] = 0; -+ matrix->m[2][2] = 1; -+ matrix->m[2][3] = -1; // z -+} -+ -+void llviewerVR::vrStartup(bool is_shutdown) -+{ -+ //static LLCachedControl vrEn(gSavedSettings, "EnableVR"); -+ //m_bVrEnabled = false;//gPipeline.EnableSteamVR; -+ -+ /*hud_textp = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT); -+ hud_textp->setZCompare(FALSE); -+ LLColor4 color(1, 1, 1); -+ hud_textp->setColor(color); -+ LLVector3 s = LLViewerCamera::getInstance()->getAtAxis(); -+ -+ hud_textp->setPositionAgent(gAgent.getPositionAgent() - s); -+ std::string str("This is the hud test"); -+ hud_textp->setString(str); -+ hud_textp->setHidden(FALSE);*/ -+ -+ -+ if (m_bVrEnabled && !is_shutdown) -+ { -+ if (gHMD == NULL) -+ { -+ gVRInitComplete = FALSE; -+ vr::EVRInitError eError = vr::VRInitError_None; -+ gHMD = vr::VR_Init(&eError, vr::VRApplication_Scene); -+ m_strHudText="Initializing VR driver!"; -+ //hud_textp->setString(m_strHudText); -+ -+ if (eError != vr::VRInitError_None) -+ { -+ gHMD = NULL; -+ char buf[1024]; -+ sprintf_s(buf, sizeof(buf), "\nERROR Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); -+ m_strHudText.append( buf); -+ //return false; -+ } -+ else -+ { -+ m_strDriver = "No Driver"; -+ m_strDisplay = "No Display"; -+ -+ m_strDriver = GetTrackedDeviceString(gHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_TrackingSystemName_String); -+ m_strDisplay = GetTrackedDeviceString(gHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SerialNumber_String); -+ m_strHudText.append("\nDriver = "); -+ m_strHudText.append(m_strDriver); -+ m_strHudText.append("\nDisplay = "); -+ m_strHudText.append(m_strDriver); -+ m_strHudText.append("\nVR driver! Initialized"); -+ -+ } -+ -+ eError = vr::VRInitError_None; -+ if (gHMD != NULL) -+ gRenderModels = (vr::IVRRenderModels *)vr::VR_GetGenericInterface(vr::IVRRenderModels_Version, &eError); -+ -+ if (!gRenderModels) -+ { -+ gHMD = NULL; -+ vr::VR_Shutdown(); -+ -+ char buf[1024]; -+ sprintf_s(buf, sizeof(buf), "\nERROR Unable to get render model interface: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); -+ m_strHudText.append(buf); -+ //SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "VR_Init Failed", buf, NULL); -+ //return false; -+ } -+ eError = vr::VRInitError_None; -+ -+ if (!vr::VRCompositor()) -+ { -+ -+ char buf[1024]; -+ sprintf_s(buf, sizeof(buf), "\nERROR No compositor interface: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError)); -+ m_strHudText.append(buf); -+ gHMD = NULL; -+ vr::VR_Shutdown(); -+ -+ } -+ if (gHMD != NULL && !gVRInitComplete) -+ { -+ gVRInitComplete = TRUE; -+ vr::VRCompositor()->SetTrackingSpace(vr::TrackingUniverseSeated); -+ gHMD->GetRecommendedRenderTargetSize(&m_nRenderWidth, &m_nRenderHeight); -+ -+ //m_nRenderHeight = 1440; -+ //m_nRenderWidth = 1440; -+ //if (leftEyeDesc.m_nResolveTextureId == NULL) -+ CreateFrameBuffer(lEyeRenderTarget, m_nRenderWidth, m_nRenderHeight, leftEyeDesc); -+ //if (rightEyeDesc.m_nResolveTextureId == NULL) -+ CreateFrameBuffer(rEyeRenderTarget, m_nRenderWidth, m_nRenderHeight, rightEyeDesc); -+ CreateFrameBuffer(uiRenderTarget, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), uiDesc); -+ SetupCameras(); -+ //vr::VRCompositor()->ForceInterleavedReprojectionOn(true); -+ //vr::VRCompositor()->SetTrackingSpace(vr::); -+ //m_tTimer1.start(); -+ -+ m_strHudText.append("\nCreating frame buffers."); -+ -+ -+ -+ -+ } -+ if(gVRInitComplete) -+ m_strHudText.append("\nVR driver ready.\n Press TAB to enter VR mode."); -+ hud_textp->setString(m_strHudText); -+ m_strHudText = ""; -+ hud_textp->setDoFade(FALSE); -+ hud_textp->setHidden(FALSE); -+ vr::VROverlay()->CreateOverlay("FirestormVR_Sgeo_UI", "Firestorm VR UI", &vrUiOverlay); -+ vr::VROverlay()->SetOverlayWidthInMeters(vrUiOverlay, 1.5f); -+ vr::VROverlay()->SetOverlayFromFile(vrUiOverlay, "C:\\Users\\oegs\\Pictures\\com.oculus.rooms-20180508-220251.jpg"); -+ vr::HmdMatrix34_t position; -+ UiLayerOverlayPosition(&position); -+ vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative(vrUiOverlay, vr::k_unTrackedDeviceIndex_Hmd, &position); -+ vr::VROverlay()->ShowOverlay(vrUiOverlay); -+ } -+ } -+ else if (gHMD || is_shutdown) -+ { -+ m_bVrActive = FALSE; -+ vr::VR_Shutdown(); -+ gHMD = NULL; -+ gVRInitComplete = FALSE; -+ //m_tTimer1.stop(); -+ //m_tTimer1.cleanupClass(); -+ } -+ -+} -+ -+bool llviewerVR::ProcessVRCamera() -+{ -+ -+ if (hud_textp == NULL) -+ { -+ -+ -+ hud_textp = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT); -+ if (hud_textp != NULL) -+ { -+ hud_textp->setZCompare(FALSE); -+ LLColor4 color(1, 1, 1); -+ hud_textp->setColor(color); -+ hud_textp->setHidden(FALSE); -+ hud_textp->setMaxLines(-1); -+ -+ m_strHudText.append("Press CTRL+TAB to enable or disable VR mode\n Press TAB to remove this message"); -+ hud_textp->setString(m_strHudText); -+ m_strHudText = ""; -+ } -+ -+ } -+ else -+ { -+ m_vdir = LLViewerCamera::getInstance()->getAtAxis(); -+ m_vpos = LLViewerCamera::getInstance()->getOrigin(); -+ LLVector3 end = m_vpos + (m_vdir)* 1.0f; -+ hud_textp->setPositionAgent(end); -+ } -+ -+ -+ if (gHMD == NULL) -+ { -+ return FALSE; -+ } -+ if (m_bVrActive)//gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) -+ { -+ InitUI(); -+ //m_fNearClip = LLViewerCamera::getInstance()->getNear(); -+ //m_fFarClip = LLViewerCamera::getInstance()->getFar(); -+ LLViewerCamera::getInstance()->setNear(0.001); -+ -+ -+ -+ -+ -+ -+ //Set the windows max size and aspect ratio to fit with the HMD. -+#ifdef _WIN32 -+ int scrsize = GetSystemMetrics(SM_CYSCREEN); -+ if (GetSystemMetrics(SM_CXSCREEN) < scrsize) -+ scrsize = GetSystemMetrics(SM_CXSCREEN); -+#else -+int scrsize = 1080; -+#endif -+ LLWindow * WI; -+ WI = gViewerWindow->getWindow(); -+ // WI->getCursorPosition(&m_MousePos); -+ -+ LLCoordWindow m_ScrSize; -+ LLCoordWindow m_ScrSizeOld; -+ -+ WI->getSize(&m_ScrSizeOld); -+ -+ m_ScrSize.mX = (float)m_nRenderWidth; -+ m_ScrSize.mY = (float)m_nRenderHeight; -+ if (m_ScrSizeOld.mX != m_ScrSize.mX || m_ScrSizeOld.mY != m_ScrSize.mY) -+ { -+ //m_ScrSize.set(m_ScrSize.mX, m_ScrSize.mY); -+ //WI->setSize(m_ScrSize); -+ } -+ // //Constrain the cursor to the viewer window. -+ // if (m_MousePos.mX >= m_ScrSize.mX) -+ // m_MousePos.mX = m_ScrSize.mX - 1; -+ // else if (m_MousePos.mX < 1) -+ // m_MousePos.mX = 1; -+ // if (m_MousePos.mY >= m_ScrSize.mY) -+ // m_MousePos.mY = m_ScrSize.mY - 1; -+ // else if (m_MousePos.mY < 1) -+ // m_MousePos.mY = 1; -+ -+ // m_iHalfWidth = m_ScrSize.mX / 2; -+ // m_iHalfHeight = m_ScrSize.mY / 2; -+ // m_iThirdWidth = m_ScrSize.mX / 3; -+ // m_iThirdHeight = m_ScrSize.mY / 3; -+ -+ -+ //Store current camera values -+ //Only when processing left eye. -+ //Right eye should not use left eye's information as its original camera values -+ if(!leftEyeDesc.IsReady) { -+ m_vdir_orig = LLViewerCamera::getInstance()->getAtAxis(); -+ m_vleft_orig = LLViewerCamera::getInstance()->getLeftAxis(); -+ m_vup_orig = LLViewerCamera::getInstance()->getUpAxis(); -+ m_vpos_orig = LLViewerCamera::getInstance()->getOrigin(); -+ } -+ -+ if (!m_bEditActive)// unlock HMD's rotation input. -+ { -+ glh::matrix4f slCameraMatrix( -+ m_vdir_orig[0], m_vleft_orig[0], m_vup_orig[0], m_vpos_orig[0], -+ m_vdir_orig[1], m_vleft_orig[1], m_vup_orig[1], m_vpos_orig[1], -+ m_vdir_orig[2], m_vleft_orig[2], m_vup_orig[2], m_vpos_orig[2], -+ 0.0, 0.0, 0.0, 1.0 -+ ); -+ -+ glh::matrix4f eyeLocation = glh::matrix4f::identity(); -+ F32 vrTanAngleLeft = 0.0; -+ F32 vrTanAngleRight = 0.0; -+ F32 vrTanAngleUp = 0.0; -+ F32 vrTanAngleDown = 0.0; -+ if (!leftEyeDesc.IsReady) // Rendering left eye -+ { -+ eyeLocation = ConvertSteamVRMatrixToMatrix42(gHMD->GetEyeToHeadTransform(vr::Eye_Left)); -+ gHMD->GetProjectionRaw(vr::Eye_Left, &vrTanAngleLeft, &vrTanAngleRight, &vrTanAngleDown, &vrTanAngleUp); // Valve documentation backwards? -+ } -+ else if (!rightEyeDesc.IsReady) // Rendering right eye -+ { -+ eyeLocation = ConvertSteamVRMatrixToMatrix42(gHMD->GetEyeToHeadTransform(vr::Eye_Right)); -+ gHMD->GetProjectionRaw(vr::Eye_Right, &vrTanAngleLeft, &vrTanAngleRight, &vrTanAngleDown, &vrTanAngleUp); // Valve documentation backwards? -+ } -+ LLViewerCamera::getInstance()->setVRFov(vrTanAngleLeft, vrTanAngleRight, vrTanAngleUp, vrTanAngleDown); -+ -+ glh::matrix4f newCameraMatrix = slCameraMatrix * m_mat4HMDPose * eyeLocation; -+ -+ LLViewerCamera::getInstance()->setAxes( -+ LLVector3(newCameraMatrix.element(0, 0), newCameraMatrix.element(1, 0), newCameraMatrix.element(2, 0)), -+ LLVector3(newCameraMatrix.element(0, 1), newCameraMatrix.element(1, 1), newCameraMatrix.element(2, 1)), -+ LLVector3(newCameraMatrix.element(0, 2), newCameraMatrix.element(1, 2), newCameraMatrix.element(2, 2)) -+ ); -+ LLViewerCamera::getInstance()->setOrigin( -+ newCameraMatrix.element(0, 3), newCameraMatrix.element(1, 3), newCameraMatrix.element(2, 3) -+ ); -+ } -+ else //lock HMD's rotation input for inworld object editing purposes. -+ { -+ m_vdir = m_vdir_orig; -+ m_vup = m_vup_orig; -+ m_vleft = m_vleft_orig; -+ m_vpos = m_vpos_orig; -+ } -+ -+ -+ if (m_iMenuIndex) -+ { -+ hud_textp->setString(Settings()); -+ LLVector3 end = m_vpos + m_vdir * 1.0f; -+ hud_textp->setPositionAgent(end); -+ hud_textp->setDoFade(FALSE); -+ hud_textp->setHidden(FALSE); -+ -+ -+ -+ } -+ else if (m_bDebugKeyDown) -+ { -+ Debug(); -+ } -+ else -+ hud_textp->setHidden(TRUE); -+ -+ -+ -+ -+ -+ // Below code is mostly obsolete -+ // It might make sense to examine to repair HMD lock. -+ -+ // LLVector3 new_dir; -+ // if (m_bEditActive)// lock HMD's rotation input for inworls object editing purposes. -+ // { -+ // if (m_fEyeDistance == 0) -+ // LLViewerCamera::getInstance()->lookDir(m_vdir_orig, m_vup_orig); -+ // new_dir = (m_vleft * (m_fEyeDistance / 1000)); -+ // } -+ // else -+ // { -+ // if (m_fEyeDistance == 0) -+ // LLViewerCamera::getInstance()->lookDir(m_vdir, m_vup); -+ // new_dir = (-m_vleft * (m_fEyeDistance / 1000)); -+ // } -+ -+ -+ // if (m_fEyeDistance > 0) -+ // { -+ // LLVector3 new_fwd_pos = m_vpos + (m_vdir * m_fFocusDistance); -+ -+ // if (!leftEyeDesc.IsReady)//change pos for rendering the left eye texture.Move half IPD distance to the left -+ // { -+ // //LLViewerCamera::getInstance()->updateCameraLocation(m_vpos + new_dir, m_vup, new_fwd_pos); -+ // } -+ // else if (!rightEyeDesc.IsReady)//change pos for rendering the right eye texture. Move full IPD distance to the right since we were on the left eye position. -+ // { -+ // //LLViewerCamera::getInstance()->updateCameraLocation(m_vpos - new_dir, m_vup, new_fwd_pos); -+ // } -+ // } -+ -+ -+ -+ } -+ return TRUE; -+} -+ -+void llviewerVR::swapScreenAndEye(int mode) { -+ if(!m_bVrActive && screenState != 0 && mode == 0) { -+ gPipeline.mRT->screen.bindTarget(); -+ screenState = 0; -+ } -+ if(!m_bVrActive) { -+ return; -+ } -+ switch(mode) { -+ case 0: -+ gPipeline.mRT->screen.bindTarget(); -+ break; -+ case 1: -+ lEyeRenderTarget.bindTarget(); -+ break; -+ case 2: -+ rEyeRenderTarget.bindTarget(); -+ break; -+ } -+ screenState = mode; -+ return; -+ -+ // // Reset state into gPipeline.mRT->screen being the real screen -+ // if(this->screenState == 1) { -+ // std::swap(gPipeline.mRT->screen, this->lEyeRenderTarget); -+ // } else if(this->screenState == 2) { -+ // std::swap(gPipeline.mRT->screen, this->rEyeRenderTarget); -+ // } -+ // this->screenState = 0; -+ // if(!m_bVrActive) { -+ // mode = 0; -+ // } -+ // switch(mode) { -+ // case 1: -+ // std::swap(gPipeline.mRT->screen, this->lEyeRenderTarget); -+ // break; -+ // case 2: -+ // std::swap(gPipeline.mRT->screen, this->rEyeRenderTarget); -+ // } -+ // screenState = mode; -+} -+ -+void llviewerVR::vrDisplay() -+{ -+ if (gHMD != NULL) -+ { -+ if (m_bVrActive)//gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) -+ { -+ -+ -+ if (!leftEyeDesc.IsReady) -+ { -+ bx = 0; -+ by = 0; -+ tx = gPipeline.mRT->screen.getWidth(); -+ ty = gPipeline.mRT->screen.getHeight(); -+ -+ // m_iTextureShift = ((tx / 2) / 100)* m_fTextureShift; -+ -+ // S32 halfx = tx / 2; -+ // S32 halfy = ty / 2; -+ // S32 div8x = tx / 6; -+ // S32 div8y = ty / 6; -+ -+ // S32 thirdx = tx / 3; -+ // S32 thirdy = ty / 3; -+ -+ -+ // if (m_MousePos.mX > tx - div8x && m_MousePos.mY < div8y)//up right -+ // { -+ // m_iZoomIndex = 4; -+ // } -+ // else if (m_MousePos.mX > tx - div8x && m_MousePos.mY > ty - div8y)//down right -+ // { -+ // m_iZoomIndex = 5; -+ // } -+ // else if (m_MousePos.mX < div8x && m_MousePos.mY > ty - div8y)//down left -+ // { -+ // m_iZoomIndex = 6; -+ // } -+ // else if (m_MousePos.mX < div8x && m_MousePos.mY < div8y)//up left -+ // { -+ // m_iZoomIndex = 7; -+ // } -+ // else if (m_MousePos.mX > tx - div8x && m_MousePos.mY > halfy - div8y && m_MousePos.mY < halfy + div8y)//right -+ // { -+ // m_iZoomIndex = 10; -+ // } -+ // else if (m_MousePos.mY > ty - div8y && m_MousePos.mX > halfx - div8x && m_MousePos.mX < halfx + div8x)//down -+ // { -+ // m_iZoomIndex = 9; -+ // } -+ // else if (m_MousePos.mY < div8y && m_MousePos.mX > halfx - div8x && m_MousePos.mX < halfx + div8x)//up -+ // { -+ // m_iZoomIndex = 8; -+ // } -+ // else if (m_MousePos.mX < div8x && m_MousePos.mY > halfy - div8y && m_MousePos.mY < halfy + div8y)//left -+ // { -+ // m_iZoomIndex = 11; -+ // } -+ // else if (m_MousePos.mX > halfx - div8x && m_MousePos.mX < halfx + div8x && m_MousePos.mY > halfy - div8y && m_MousePos.mY < halfy + div8y)//center -+ // { -+ // m_iZoomIndex = 0; -+ // } -+ -+ // ///Zoom in -+ // if (m_iZoomIndex == 0) -+ // { -+ // bx += m_fTextureZoom; -+ // by += m_fTextureZoom; -+ // tx -= m_fTextureZoom; -+ // ty -= m_fTextureZoom; -+ // } -+ // else if (m_iZoomIndex == 4)//up right -+ // { -+ // bx += thirdx; -+ // by += thirdy; -+ // tx += thirdx; -+ // ty += thirdy; -+ // } -+ // else if (m_iZoomIndex == 5)//down right -+ // { -+ // bx += thirdx; -+ // by -= thirdy; -+ // tx += thirdx; -+ // ty -= thirdy; -+ // } -+ // else if (m_iZoomIndex == 6)//down left -+ // { -+ // bx -= thirdx; -+ // by -= thirdy; -+ // tx -= thirdx; -+ // ty -= thirdy; -+ // } -+ // else if (m_iZoomIndex == 7)//up left -+ // { -+ // bx -= thirdx; -+ // by += thirdy; -+ // tx -= thirdx; -+ // ty += thirdy; -+ // } -+ // else if (m_iZoomIndex == 8)//up -+ // { -+ // by += thirdy; -+ // ty += thirdy; -+ // } -+ // else if (m_iZoomIndex == 9)//down -+ // { -+ // by -= thirdy; -+ // ty -= thirdy; -+ // } -+ // else if (m_iZoomIndex == 11)//left -+ // { -+ // bx -= thirdx; -+ // tx -= thirdx; -+ // } -+ // else if (m_iZoomIndex == 10)//right -+ // { -+ // bx += thirdx; -+ // tx += thirdx; -+ // } -+ } -+ -+ -+ //if left camera was active bind left eye buffer for drawing in to -+ if (!leftEyeDesc.IsReady) -+ { -+ glBindFramebuffer(GL_READ_FRAMEBUFFER, lEyeRenderTarget.getFBO()); -+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, leftEyeDesc.mFBO); -+ if (m_iZoomIndex) -+ glClear(GL_COLOR_BUFFER_BIT); -+ //leftEyeDesc.IsReady = TRUE; -+ -+ F32 uMin; -+ F32 uMax; -+ F32 vMin; -+ F32 vMax; -+ -+ calcUVBounds(vr::EVREye::Eye_Left, &uMin, &uMax, &vMin, &vMax); -+ -+ LL_INFOS_ONCE() << "Blitting to left eye texture" << LL_ENDL; -+ -+ glBlitFramebuffer(bx, by, tx, ty, m_nRenderWidth * uMin, m_nRenderHeight * vMin, m_nRenderWidth * uMax, m_nRenderHeight * vMax, GL_COLOR_BUFFER_BIT, GL_LINEAR); -+ -+ } -+ if ((leftEyeDesc.IsReady && !rightEyeDesc.IsReady))//if right camera was active bind left eye buffer for drawing in to -+ { -+ glBindFramebuffer(GL_READ_FRAMEBUFFER, rEyeRenderTarget.getFBO()); -+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rightEyeDesc.mFBO); -+ if (m_iZoomIndex) -+ glClear(GL_COLOR_BUFFER_BIT); -+ rightEyeDesc.IsReady = TRUE; -+ -+ F32 uMin; -+ F32 uMax; -+ F32 vMin; -+ F32 vMax; -+ -+ calcUVBounds(vr::EVREye::Eye_Right, &uMin, &uMax, &vMin, &vMax); -+ -+ LL_INFOS_ONCE() << "Blitting to right eye texture" << LL_ENDL; -+ -+ glBlitFramebuffer(bx, by, tx, ty, m_nRenderWidth * uMin, m_nRenderHeight * vMin, m_nRenderWidth * uMax, m_nRenderHeight * vMax, GL_COLOR_BUFFER_BIT, GL_LINEAR); -+ -+ -+ } -+ if (!leftEyeDesc.IsReady) -+ leftEyeDesc.IsReady = TRUE; -+ -+ //Remove bindings of read and draw buffer -+ glBindFramebuffer(GL_FRAMEBUFFER, 0); -+ -+ if (leftEyeDesc.IsReady && (rightEyeDesc.IsReady)) -+ { -+ LL_INFOS_ONCE() << "Submitting frame to VR, left eye resolve ID" << leftEyeDesc.m_nResolveTextureId << " right eye " <CompositorBringToFront(); could help with no image issues -+ -+ -+ //Update HMD . !!!!! This calls waitGetPoses() which is essential to start the rendering process in the HMD after Submit and gets the current HMD pose(rotation location matrix) -+ //if you do not call that anywhere no image will be processed. -+ -+ -+ //submit the textures to the HMD -+ lEyeTexture = { (void*)(uintptr_t)leftEyeDesc.m_nResolveTextureId, vr::TextureType_OpenGL, vr::ColorSpace_Gamma }; -+ eError = vr::VRCompositor()->Submit(vr::Eye_Left, &lEyeTexture, 0, (vr::EVRSubmitFlags)(vr::Submit_Default )); -+ -+ rEyeTexture = { (void*)(uintptr_t)rightEyeDesc.m_nResolveTextureId, vr::TextureType_OpenGL, vr::ColorSpace_Gamma }; -+ eError = vr::VRCompositor()->Submit(vr::Eye_Right, &rEyeTexture, 0, (vr::EVRSubmitFlags)(vr::Submit_Default)); -+ -+ uiTexture = { (void*)(uintptr_t)gPipeline.mRT->uiScreen.getTexture(), vr::TextureType_OpenGL, vr::ColorSpace_Gamma }; -+ if(gPipeline.mRT->uiScreen.getTexture()) vr::VROverlay()->SetOverlayTexture(vrUiOverlay, &uiTexture); -+ vr::VROverlay()->SetOverlayWidthInMeters(vrUiOverlay, 1.5f); -+ vr::HmdMatrix34_t position; -+ UiLayerOverlayPosition(&position); -+ vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative(vrUiOverlay, vr::k_unTrackedDeviceIndex_Hmd, &position); -+ -+ -+ -+ //vr::VRCompositor()->PostPresentHandoff();// Here we tell the HMD that rendering is done and it can render the image in to the HMD -+ //glFinish(); -+ -+ gViewerWindow->getWindow()->swapBuffers(); -+ -+ -+ //glFlush(); -+ -+ -+ -+ UpdateHMDMatrixPose(); -+ // -+ -+ } -+ -+ } -+ -+ -+ -+ -+ -+ } -+ //else if (vrEnabled) -+ //{ -+ //vrStartup(); -+ //} -+ -+} -+ -+void llviewerVR::vrCaptureUI() { -+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); -+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, uiDesc.mFBO); -+ glBlitFramebuffer(0, 0, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), 0, 0, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), GL_COLOR_BUFFER_BIT, GL_LINEAR); -+ glBindFramebuffer(GL_FRAMEBUFFER, 0); -+} -+ -+void llviewerVR::ProcessVREvent(const vr::VREvent_t & event)//process vr´events -+{ -+ switch (event.eventType) -+ { -+ case vr::VREvent_TrackedDeviceActivated: -+ { -+ //SetupRenderModelForTrackedDevice(event.trackedDeviceIndex); -+ //dprintf("Device %u attached. Setting up render model.\n", event.trackedDeviceIndex); -+ } -+ break; -+ case vr::VREvent_TrackedDeviceDeactivated: -+ { -+ //dprintf("Device %u detached.\n", event.trackedDeviceIndex); -+ } -+ break; -+ case vr::VREvent_TrackedDeviceUpdated: -+ { -+ //dprintf("Device %u updated.\n", event.trackedDeviceIndex); -+ } -+ case vr::VREvent_Quit: -+ { -+ m_bVrActive = FALSE; -+ m_bVrEnabled = FALSE; -+ gHMD = NULL; -+ vr::VR_Shutdown(); -+ vr::VRSystem()->AcknowledgeQuit_Exiting(); -+ } -+ break; -+ } -+} -+ -+void llviewerVR::agentYaw(F32 yaw_inc) // move avatar forward backward and rotate -+{ -+ // Cannot steer some vehicles in mouselook if the script grabs the controls -+ if (gAgentCamera.cameraMouselook() && gSavedSettings.getBOOL("JoystickMouselookYaw")) -+ { -+ gAgent.rotate(-yaw_inc, gAgent.getReferenceUpVector()); -+ -+ } -+ else -+ { -+ if (yaw_inc < 0) -+ { -+ gAgent.setControlFlags(AGENT_CONTROL_YAW_POS); -+ } -+ else if (yaw_inc > 0) -+ { -+ gAgent.setControlFlags(AGENT_CONTROL_YAW_NEG); -+ } -+ -+ gAgent.yaw(-yaw_inc); -+ } -+} -+ -+bool llviewerVR::HandleInput()// handles controller input for now only the stick. -+{ -+ -+ if (gHMD == NULL || !m_bVrActive) -+ return FALSE; -+ bool bRet = false; -+ -+ // Process SteamVR events -+ vr::VREvent_t event; -+ while (gHMD->PollNextEvent(&event, sizeof(event))) -+ { -+ ProcessVREvent(event); -+ } -+ -+ // Process SteamVR controller state -+ /*for (vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++) -+ { -+ vr::VRControllerState_t state; -+ if (gHMD->GetControllerState(unDevice, &state, sizeof(state))) -+ { -+ m_rbShowTrackedDevice[unDevice] = state.ulButtonPressed == 0; -+ if (state.unPacketNum != gPacketNum) -+ { -+ gPacketNum = state.unPacketNum; -+ //add intensity slider here. -+ if (fabs(state.rAxis[2].x) > 0.3)// +x rechts +y fwd -+ agentYaw(state.rAxis[2].x / 20); -+ if (state.rAxis[2].y > 0.5)// +x rechts +y fwd -+ gAgent.moveAt(1, false); -+ else if (state.rAxis[2].y < -0.5)// +x rechts +y fwd -+ gAgent.moveAt(-1, false); -+ gButton = state.ulButtonPressed; -+ -+ -+ -+ LLWindow * WI; -+ WI = gViewerWindow->getWindow(); -+ MASK mask = gKeyboard->currentMask(TRUE); -+ //S32 width = gViewerWindow->getWorldViewWidthScaled(); -+ //S32 height = gViewerWindow->getWindowHeightScaled(); -+ S32 height = gViewerWindow->getWorldViewHeightScaled(); -+ LLCoordWindow size; -+ size.mX = gCtrlscreen[unDevice].mX; -+ //size.mY = gCtrlscreen[unDevice].mY; -+ size.mY = height - gCtrlscreen[unDevice].mY; -+ //gCtrlscreen[unDevice].mY = height - gCtrlscreen[unDevice].mY; -+ -+ -+ if ((state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) && !gRightClick[unDevice]) -+ { -+ -+ gRightClick[unDevice] = TRUE; -+ if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) -+ { -+ -+ WI->setCursorPosition(size); -+ } -+ -+ //LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(mAppWindowHandle, GWLP_USERDATA); -+ -+ gViewerWindow->handleAnyMouseClick(WI, gCtrlscreen[unDevice], mask, LLMouseHandler::CLICK_RIGHT, TRUE); -+ -+ -+ INPUT Inputs[1] { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN; -+ //SendInput(1, Inputs, sizeof(INPUT)); -+ } -+ else if (gRightClick[unDevice] && !(state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip))) -+ { -+ gRightClick[unDevice] = FALSE; -+ -+ gViewerWindow->handleAnyMouseClick(WI, gCtrlscreen[unDevice], mask, LLMouseHandler::CLICK_RIGHT, FALSE); -+ INPUT Inputs[1] = { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP; -+ //SendInput(1, Inputs, sizeof(INPUT)); -+ -+ -+ } -+ -+ -+ if ((state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) && !gLeftClick[unDevice]) -+ { -+ if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) -+ { -+ gLeftClick[unDevice] = TRUE; -+ //LLWindow * WI; -+ //WI = gViewerWindow->getWindow(); -+ //S32 width = gViewerWindow->getWorldViewWidthScaled(); -+ //S32 height = gViewerWindow->getWorldViewHeightScaled(); -+ //LLCoordWindow size; -+ //size.mX = gCtrlscreen[0].mX; -+ //size.mY = height - gCtrlscreen[0].mY; -+ WI->setCursorPosition(size); -+ } -+ INPUT Inputs[1] = { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; -+ SendInput(1, Inputs, sizeof(INPUT)); -+ } -+ else if (gLeftClick[unDevice] && !(state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger))) -+ { -+ gLeftClick[unDevice] = FALSE; -+ INPUT Inputs[1] = { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTUP; -+ SendInput(1, Inputs, sizeof(INPUT)); -+ } -+ -+ } -+ -+ } -+ -+ }*/ -+ -+ return bRet; -+} -+ -+void llviewerVR::HandleKeyboard() -+{ -+ // Don't attempt to update controllers if input is not available -+ //gCtrlNum = 0; -+ -+ if (gKeyboard->getKeyDown(KEY_TAB) && !m_bVrKeyDown) -+ { -+ -+ m_bVrKeyDown = TRUE; -+ -+ -+ } -+ else if (!gKeyboard->getKeyDown(KEY_TAB) && m_bVrKeyDown) -+ { -+ m_bVrKeyDown = FALSE; -+ -+ if (gKeyboard->getKeyDown(KEY_CONTROL)) -+ { -+ if (!m_bVrEnabled) -+ { -+ m_bVrEnabled = TRUE; -+ vrStartup(FALSE); -+ } -+ else -+ { -+ m_bVrActive = FALSE; -+ m_bVrEnabled = FALSE; -+ vrStartup(FALSE); -+ } -+ -+ } -+ else if (gHMD) -+ { -+ if (!m_bVrActive) -+ m_bVrActive = TRUE; -+ else -+ m_bVrActive = FALSE; -+ //LLViewerCamera::getInstance()->setDefaultFOV(1.8); -+ gHmdOffsetPos.mV[2] = 0; -+ INISaveRead(false); -+ // if (m_fFOV > 20) -+ // LLViewerCamera::getInstance()->setDefaultFOV(m_fFOV * DEG_TO_RAD); -+ -+ // // Determine maximum FOV and aspect ratio values -+ // // Assume left eye and right are sufficiently similar to use left -+ // // Not important for correct 3D, but an ideal value is convenient -+ // // UI issues make FOV adjustability still useful. -+ // F32 tanLeft; -+ // F32 tanRight; -+ // F32 tanUp; -+ // F32 tanDown; -+ // gHMD->GetProjectionRaw(vr::Eye_Left, &tanLeft, &tanRight, &tanDown, &tanUp); -+ // // Maximize instead of add so full view is covered -+ // F32 maxTanWidth = 2.0 * std::max(tanRight, -tanLeft); -+ // F32 maxTanHeight = 2.0 * std::max(tanUp, -tanDown); -+ // m_fFOV = 2 * atan(maxTanHeight/2.0) * RAD_TO_DEG; -+ // LLViewerCamera::getInstance()->setDefaultFOV(m_fFOV * DEG_TO_RAD); -+ // LLViewerCamera::getInstance()->setAspect(maxTanWidth/maxTanHeight); -+ -+ gHMD->ResetSeatedZeroPose(); -+ -+ -+ -+ /*LLCoordWindow cpos; -+ cpos.mX = m_nRenderWidth / 2; -+ cpos.mY = m_nRenderHeight / 2; -+ LLWindow * WI; -+ WI = gViewerWindow->getWindow(); -+ //WI->setCursorPosition(cpos); -+ -+ INPUT Inputs[1] ; -+ Inputs[0].mi.dx = m_nRenderWidth / 2; -+ Inputs[0].mi.dy = m_nRenderHeight / 2; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE; -+ -+ SendInput(1, Inputs, sizeof(INPUT));*/ -+ -+ } -+ else -+ { -+ m_strHudText = ""; -+ hud_textp->setString(m_strHudText); -+ hud_textp->setDoFade(FALSE); -+ hud_textp->setHidden(TRUE); -+ } -+ -+ } -+ -+ if (gHMD == NULL) -+ return; -+ if (gKeyboard->getKeyDown(m_kEditKey) && !m_bEditKeyDown) -+ { -+ m_bEditKeyDown = TRUE; -+ //m_iClockCount2 = m_tTimer1.getCurrentClockCount(); -+ } -+ else if (!gKeyboard->getKeyDown(m_kEditKey) && m_bEditKeyDown) -+ { -+ m_bEditKeyDown = FALSE; -+ //m_iClockCount = m_tTimer1.getCurrentClockCount() - m_iClockCount2; -+ /*if (m_iClockCount > 5000000) -+ { -+ m_iZoomIndex++; -+ if (m_iZoomIndex > 5) -+ m_iZoomIndex = 0; -+ } -+ else*/ -+ if (!m_bEditActive) -+ m_bEditActive = TRUE; -+ else -+ m_bEditActive = FALSE; -+ } -+ -+ if (gKeyboard->getKeyDown(m_kDebugKey) && !m_bDebugKeyDown) -+ { -+ m_bDebugKeyDown = TRUE; -+ } -+ else if (!gKeyboard->getKeyDown(m_kDebugKey) && m_bDebugKeyDown) -+ { -+ m_bDebugKeyDown = FALSE; -+ //m_iZoomIndex++; -+ if (m_iZoomIndex > 7) -+ m_iZoomIndex = 0; -+ } -+ -+ if (gKeyboard->getKeyDown(m_kMenuKey) && !m_bMenuKeyDown) -+ { -+ m_bMenuKeyDown = TRUE; -+ } -+ else if (!gKeyboard->getKeyDown(m_kMenuKey) && m_bMenuKeyDown) -+ { -+ m_bMenuKeyDown = FALSE; -+ if (m_iMenuIndex == 5) -+ INISaveRead(true); -+ -+ m_iMenuIndex++; -+ if (m_iMenuIndex > 5) -+ m_iMenuIndex = 0; -+ } -+} -+ -+void llviewerVR::DrawCursors() -+{ -+ if (!m_bVrActive) -+ return; -+ gUIProgram.bind(); -+ //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -+ //gViewerWindow->setup2DRender(); -+ gGL.pushMatrix(); -+ S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2); -+ S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2); -+ -+ S32 wwidth = gViewerWindow->getWindowWidthScaled(); -+ S32 wheight = gViewerWindow->getWindowHeightScaled(); -+ -+ //translatef moves 0 vector to the pos you specified so oyu can draw fron zero vector there -+ gGL.translatef((F32)half_width, (F32)half_height, 0.f); -+ gGL.color4fv(LLColor4::white.mV); -+ //glClear(GL_DEPTH_BUFFER_BIT); -+ //glDisable(GL_DEPTH_TEST); -+ LLWindow * WI; -+ WI = gViewerWindow->getWindow(); -+ LLCoordWindow mcpos; -+ WI->getCursorPosition(&mcpos); -+ LLCoordGL mpos = gViewerWindow->getCurrentMouse(); -+ -+ for (vr::TrackedDeviceIndex_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; ++unTrackedDevice) -+ { -+ if (gCtrlscreen[unTrackedDevice].mX > -1) -+ { -+ -+ gl_circle_2d(gCtrlscreen[unTrackedDevice].mX - half_width, gCtrlscreen[unTrackedDevice].mY - half_height + gCursorDiff, half_width / 200, 8, TRUE); -+ } -+ -+ } -+ -+ if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) -+ { -+ LLColor4 cl; -+ cl = LLColor4::black.mV; -+ -+ S32 mx = mpos.mX - half_width; -+ S32 my = mpos.mY - (half_height); -+ if (mpos.mX < 0 || mpos.mX > wwidth) -+ mx = half_width; -+ if (mpos.mY < 0 || mpos.mY > wheight) -+ my = half_height; -+ -+ gl_triangle_2d(mx, my, mx + 8, my - 15, mx + 15, my - 8, cl, TRUE); -+ cl = LLColor4::white.mV; -+ gl_triangle_2d(mx+2, my-2, mx + 9, my - 13, mx + 12, my - 8, cl, TRUE); -+ } -+ -+ //gl_circle_2d(mpos.mX - half_width, mpos.mY - (half_height) /*+ gVR.gCursorDiff)*/, half_width / 200, 8, TRUE); -+ -+ //glEnable(GL_DEPTH_TEST); -+ gGL.popMatrix(); -+ gUIProgram.unbind(); -+ stop_glerror(); -+} -+ -+void llviewerVR::RenderControllerAxes() -+{ -+ // Don't attempt to update controllers if input is not available -+ //gCtrlNum = 0; -+ -+ HandleKeyboard(); -+ -+ if (gHMD == NULL) -+ return; -+ HandleInput(); -+ if (!gHMD->IsInputAvailable() || !m_bVrActive) -+ return; -+ -+ //std::vector vertdataarray; -+ //m_uiControllerVertcount = 0; -+ //m_iTrackedControllerCount = 0; -+ -+ -+ for (vr::TrackedDeviceIndex_t unTrackedDevice = vr::k_unTrackedDeviceIndex_Hmd + 1; unTrackedDevice < vr::k_unMaxTrackedDeviceCount; ++unTrackedDevice) -+ { -+ gCtrlscreen[unTrackedDevice].set(-1, -1); -+ if (!gHMD->IsTrackedDeviceConnected(unTrackedDevice)) -+ continue; -+ -+ if (gHMD->GetTrackedDeviceClass(unTrackedDevice) != vr::TrackedDeviceClass_Controller) -+ continue; -+ -+ m_iTrackedControllerCount += 1; -+ -+ if (!gTrackedDevicePose[unTrackedDevice].bPoseIsValid) -+ continue; -+ -+ //Count the controllers -+ -+ glh::matrix4f mat = m_rmat4DevicePose[unTrackedDevice]; -+ -+ //glh::vec4f center; -+ //mat.mult_matrix_vec(glh::vec4f(0, 0, 0, 1),center) ; -+ -+ LLVector3 pos = m_vpos; // LLViewerCamera::getInstance()->getOrigin(); -+ LLVector3 dir; -+ LLVector3 up; -+ LLVector3 left; -+ -+ dir.setVec(mat.element(0, 2), mat.element(1, 2), mat.element(2, 2)); -+ -+ up.setVec(mat.element(0, 1), mat.element(1, 1), mat.element(2, 1)); -+ -+ left.setVec(mat.element(0, 0), mat.element(1, 0), mat.element(2, 0)); -+ -+ gCtrlOrigin[unTrackedDevice].setVec(mat.element(0, 3), mat.element(1, 3), mat.element(2, 3)); -+ -+ LLQuaternion q1(dir, left, up); -+ -+ //get modified camera rot in euler angles -+ float r2; -+ float p2; -+ float y2; -+ q1.getEulerAngles(&r2, &p2, &y2); -+ -+ LLQuaternion qCameraOrig(m_vdir_orig, m_vleft_orig, m_vup_orig); -+ float r3; -+ float p3; -+ float y3; -+ qCameraOrig.getEulerAngles(&r3, &p3, &y3); -+ -+ -+ //make a quat of yaw rot of the HMD camera -+ //LLQuaternion q2; -+ //q2.setEulerAngles(0, p2, y2 + (m_fCamRotOffset * DEG_TO_RAD)); -+ LLQuaternion q3; -+ q3.setEulerAngles(0, 0, y3 - (m_fCamRotOffset * DEG_TO_RAD)); -+ -+ //change the controller rotation according to the HMD facing direction -+ q1 = (q1)*q3; -+ -+ //grab the forward vector from the quat matrix -+ LLMatrix3 m3 = q1.getMatrix3(); -+ dir = m3.getFwdRow(); -+ -+ //up = m3.getUpRow(); -+ //left = m3.getLeftRow(); -+ dir.normalize(); -+ //up.normalize(); -+ //left.normalize(); -+ //get position of the controller -+ gCtrlOrigin[unTrackedDevice] -= gHmdPos; -+ gCtrlOrigin[unTrackedDevice] = m_vpos + gCtrlOrigin[unTrackedDevice] * q3; -+ //project 10 meter line in the direction the controller is facing -+ gCtrlPos[unTrackedDevice] = gCtrlOrigin[unTrackedDevice] - (dir * 10.0f); -+ -+ //translate the fwd vector line to screen coords -+ posToScreen(gCtrlPos[unTrackedDevice], gCtrlscreen[unTrackedDevice], FALSE); -+ -+ //adjust the pos so it fits with the actual mouse cursor pos -+ S32 height = gViewerWindow->getWorldViewHeightScaled(); -+ gCursorDiff= gViewerWindow->getWindowHeightScaled(); -+ gCursorDiff = gCursorDiff - height; -+ gCtrlscreen[unTrackedDevice].mY -= gCursorDiff; -+ -+ -+ -+ -+ -+ //draw the controller lines in world ( make tham nicer ;>) -+ LLGLSUIDefault gls_ui; -+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -+ LLVector3 v = gCurrentCameraPos; -+ // Some coordinate axes -+ glClear(GL_DEPTH_BUFFER_BIT); -+ glDisable(GL_DEPTH_TEST); -+ gGL.pushMatrix(); -+ gGL.translatef(v.mV[VX], v.mV[VY], v.mV[VZ]); -+ gGL.begin(LLRender::LINES); -+ gGL.color3f(1.0f, 0.0f, 0.0f); // i direction = X-Axis = red -+ gGL.vertex3f(gCtrlOrigin[unTrackedDevice].mV[VX], gCtrlOrigin[unTrackedDevice].mV[VY], gCtrlOrigin[unTrackedDevice].mV[VZ]); -+ gGL.vertex3f(gCtrlPos[unTrackedDevice].mV[VX], gCtrlPos[unTrackedDevice].mV[VY], gCtrlPos[unTrackedDevice].mV[VZ]); -+ gGL.end(); -+ gGL.popMatrix(); -+ glEnable(GL_DEPTH_TEST); -+ -+ //EVRControllerAxisType -+ //read the input from the available controllers -+ vr::VRControllerState_t state; -+ if (gHMD->GetControllerState(unTrackedDevice, &state, sizeof(state))) -+ { -+ m_rbShowTrackedDevice[unTrackedDevice] = state.ulButtonPressed == 0; -+ if (1)// state.unPacketNum != gPacketNum) -+ { -+ //if(LLFloaterCamera::inFreeCameraMode()) -+ gPacketNum = state.unPacketNum; -+ //Get the joystick hat state of the controller and move the avatar.. (Figure out how to map it tpo vive and oculus) -+ //add movement intensity slider here. -+ if (fabs(state.rAxis[2].x) > 0.5 && gHMD->GetControllerRoleForTrackedDeviceIndex(unTrackedDevice))// +x rechts +y fwd -+ { -+ if (LLFloaterCamera::inFreeCameraMode()) -+ { -+ m_fCamRotOffset += 0.5; -+ if (m_fCamRotOffset > 360) -+ m_fCamRotOffset = 0; -+ -+ } -+ else -+ { -+ m_fCamRotOffset = 90; -+ agentYaw(state.rAxis[2].x / 40); -+ -+ } -+ -+ } -+ else if (state.rAxis[2].y > 0.5)// +y forward -+ { -+ if (LLFloaterCamera::inFreeCameraMode()) -+ { -+ -+ m_fCamPosOffset += 0.2; -+ } -+ else -+ { -+ gAgent.moveAt(1, false); -+ m_fCamPosOffset = 0; -+ } -+ -+ } -+ -+ else if (state.rAxis[2].y < -0.5)// -y back -+ { -+ if (LLFloaterCamera::inFreeCameraMode()) -+ { -+ -+ m_fCamPosOffset -= 0.2; -+ } -+ else -+ { -+ gAgent.moveAt(-1, false); -+ m_fCamPosOffset = 0; -+ } -+ -+ } -+ -+ -+ -+ gButton = state.ulButtonPressed; -+ LLWindow * WI; -+ WI = gViewerWindow->getWindow(); -+ //MASK mask = gKeyboard->currentMask(TRUE); -+ -+ -+ S32 width = gViewerWindow->getWorldViewWidthScaled(); -+ //S32 height = gViewerWindow->getWindowHeightScaled(); -+ S32 height = gViewerWindow->getWorldViewHeightScaled(); -+ LLCoordWindow cpos; -+ cpos.mX = gCtrlscreen[unTrackedDevice].mX; -+ //size.mY = gCtrlscreen[unDevice].mY; -+ cpos.mY = height - gCtrlscreen[unTrackedDevice].mY; -+ //gCtrlscreen[unDevice].mY = height - gCtrlscreen[unDevice].mY; -+ -+ //LLCoordWindow * mcpos; -+ //WI->getCursorPosition(mcpos); -+ -+ //Emulate mouse clicks with the controllers trigger and grip buttons -+ -+ if ((state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) && !gRightClick[unTrackedDevice]) -+ { -+ -+ gRightClick[unTrackedDevice] = TRUE; -+ if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) -+ { -+ -+ WI->setCursorPosition(cpos); -+ } -+ -+ //LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr(mAppWindowHandle, GWLP_USERDATA); -+ -+ //gViewerWindow->handleAnyMouseClick(WI, gCtrlscreen[unTrackedDevice], mask, LLMouseHandler::CLICK_RIGHT, TRUE); -+ -+ -+#ifdef _WIN32 -+ INPUT Inputs[1] { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_RIGHTDOWN; -+ SendInput(1, Inputs, sizeof(INPUT)); -+#else -+#endif -+ } -+ else if (gRightClick[unTrackedDevice] && !(state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip))) -+ { -+ gRightClick[unTrackedDevice] = FALSE; -+ -+ //gViewerWindow->handleAnyMouseClick(WI, gCtrlscreen[unTrackedDevice], mask, LLMouseHandler::CLICK_RIGHT, FALSE); -+#ifdef _WIN32 -+ INPUT Inputs[1] = { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_RIGHTUP; -+ SendInput(1, Inputs, sizeof(INPUT)); -+#else -+#endif -+ } -+ -+ -+ if ((state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger)) && !gLeftClick[unTrackedDevice]) -+ { -+ gLeftClick[unTrackedDevice] = TRUE; -+ if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) -+ { -+ -+ //LLWindow * WI; -+ //WI = gViewerWindow->getWindow(); -+ //S32 width = gViewerWindow->getWorldViewWidthScaled(); -+ //S32 height = gViewerWindow->getWorldViewHeightScaled(); -+ //LLCoordWindow size; -+ //size.mX = gCtrlscreen[0].mX; -+ //size.mY = height - gCtrlscreen[0].mY; -+ WI->setCursorPosition(cpos); -+ } -+#ifdef _WIN32 -+ INPUT Inputs[1] = { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; -+ SendInput(1, Inputs, sizeof(INPUT)); -+#else -+#endif -+ } -+ else if (gLeftClick[unTrackedDevice] && !(state.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger))) -+ { -+ gLeftClick[unTrackedDevice] = FALSE; -+#ifdef _WIN32 -+ INPUT Inputs[1] = { 0 }; -+ Inputs[0].type = INPUT_MOUSE; -+ Inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTUP; -+ SendInput(1, Inputs, sizeof(INPUT)); -+#else -+#endif -+ } -+ -+ if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK && gLeftClick[unTrackedDevice] && cpos.mX>-1 && cpos.mX < width && cpos.mY >-1 && cpos.mY < height) -+ { -+ -+ WI->setCursorPosition(cpos); -+ } -+ -+ } -+ -+ } -+ } -+ -+} -+ -+BOOL llviewerVR::posToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const -+{ -+ //BOOL in_front = TRUE; -+ GLdouble x, y, z; // object's window coords, GL-style -+ -+ /*LLVector3 dir_to_point = pos_agent - LLViewerCamera::getInstance()->getOrigin(); -+ dir_to_point /= dir_to_point.magVec(); -+ -+ if (dir_to_point * LLCoordFrame::getAtAxis() < 0.f) -+ { -+ if (clamp) -+ { -+ return FALSE; -+ } -+ else -+ { -+ in_front = FALSE; -+ } -+ } -+ */ -+ LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw(); -+ -+ //LLRect world_view_rect = gViewerWindow->handleAnyMouseClick; -+ -+ S32 viewport[4]; -+ viewport[0] = world_view_rect.mLeft; -+ viewport[1] = world_view_rect.mBottom; -+ viewport[2] = world_view_rect.getWidth(); -+ viewport[3] = world_view_rect.getHeight(); -+ -+ F64 mdlv[16]; -+ F64 proj[16]; -+ -+ for (U32 i = 0; i < 16; i++) -+ { -+ mdlv[i] = (F64)gGLModelView[i]; -+ proj[i] = (F64)gGLProjection[i]; -+ } -+ -+ if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ], -+ mdlv, proj, (GLint*)viewport, -+ &x, &y, &z)) -+ { -+ // convert screen coordinates to virtual UI coordinates -+ x /= gViewerWindow->getDisplayScale().mV[VX]; -+ y /= gViewerWindow->getDisplayScale().mV[VY]; -+ -+ // should now have the x,y coords of grab_point in screen space -+ LLRect world_rect = gViewerWindow->getWorldViewRectScaled(); -+ -+ // convert to pixel coordinates -+ S32 int_x = lltrunc(x); -+ S32 int_y = lltrunc(y); -+ -+ out_point.mX = int_x; -+ out_point.mY = int_y; -+ -+ BOOL valid = TRUE; -+ return valid; -+ /* -+ if (clamp) -+ { -+ if (int_x < world_rect.mLeft) -+ { -+ out_point.mX = world_rect.mLeft; -+ valid = FALSE; -+ } -+ else if (int_x > world_rect.mRight) -+ { -+ out_point.mX = world_rect.mRight; -+ valid = FALSE; -+ } -+ else -+ { -+ out_point.mX = int_x; -+ } -+ -+ if (int_y < world_rect.mBottom) -+ { -+ out_point.mY = world_rect.mBottom; -+ valid = FALSE; -+ } -+ else if (int_y > world_rect.mTop) -+ { -+ out_point.mY = world_rect.mTop; -+ valid = FALSE; -+ } -+ else -+ { -+ out_point.mY = int_y; -+ } -+ return valid; -+ } -+ else -+ { -+ out_point.mX = int_x; -+ out_point.mY = int_y; -+ -+ if (int_x < world_rect.mLeft) -+ { -+ valid = FALSE; -+ } -+ else if (int_x > world_rect.mRight) -+ { -+ valid = FALSE; -+ } -+ if (int_y < world_rect.mBottom) -+ { -+ valid = FALSE; -+ } -+ else if (int_y > world_rect.mTop) -+ { -+ valid = FALSE; -+ } -+ -+ return in_front && valid; -+ }*/ -+ } -+ else -+ { -+ return FALSE; -+ } -+} -+ -+void llviewerVR::buttonCallbackLeft() -+{ -+ if (m_pCamStack) -+ { -+ -+ m_fCamRotOffset -= 5; -+ if (m_fCamRotOffset > 360) -+ m_fCamRotOffset = 0; -+ -+ } -+} -+ -+void llviewerVR::buttonCallbackRight() -+{ -+ if (m_pCamStack) -+ { -+ m_fCamRotOffset += 5; -+ if (m_fCamRotOffset > 360) -+ m_fCamRotOffset = 0; -+ -+ LLRect rc; -+ rc.setCenterAndSize(80, 80, 160, 80); -+ m_pCamStack->setRect(rc); -+ if (m_pCamera_floater) -+ { -+ rc = m_pCamera_floater->getRect(); -+ rc.setCenterAndSize(rc.getCenterX(), rc.getCenterY(), 200, 120); -+ //m_pCamera_floater->setRect(rc); -+ m_pCamera_floater->handleReshape(rc, TRUE); -+ } -+ -+ -+ } -+} -+ -+std::string llviewerVR::Settings() -+{ -+ std::string str; -+ std::wstring wstr; -+ std::string sep1 = "\n\xe2\x96\x88\xe2\x96\x88\xe2\x96\x88 "; -+ std::string sep2 = " \xe2\x96\x88\xe2\x96\x88\xe2\x96\x88"; -+ -+ -+ //str = INISaveRead(false); -+ //str.append("\n"); -+ if (m_iMenuIndex == 1) -+ { -+ m_fEyeDistance=Modify(m_fEyeDistance, 1.0, 0, 200); -+ str.append(sep1); -+ str.append("IPD = "); -+ str.append(std::to_string(m_fEyeDistance)); -+ str.append(sep2); -+ str.append("\nFocus Distance = "); -+ str.append(std::to_string(m_fFocusDistance)); -+ str.append("\nTexture Shift = "); -+ str.append(std::to_string(m_fTextureShift)); -+ str.append("\nTexture Zoom = "); -+ str.append(std::to_string(m_fTextureZoom)); -+ str.append("\nFOV = "); -+ str.append(std::to_string(m_fFOV)); -+ str.append("\n \nDoes nothing. Used to represent the distance between eyes, but that is currently incorporated already. Replace with scale adjustment?"); -+ } -+ else if (m_iMenuIndex == 2) -+ { -+ m_fFocusDistance=Modify(m_fFocusDistance, 0.25, 0.5, 10); -+ str.append("IPD = "); -+ str.append(std::to_string(m_fEyeDistance)); -+ str.append(sep1); -+ str.append("Focus Distance = "); -+ str.append(std::to_string(m_fFocusDistance)); -+ str.append(sep2); -+ str.append("\nTexture shift = "); -+ str.append(std::to_string(m_fTextureShift)); -+ str.append("\nTexture Zoom = "); -+ str.append(std::to_string(m_fTextureZoom)); -+ str.append("\nFOV = "); -+ str.append(std::to_string(m_fFOV)); -+ -+ str.append("\n \nDoes nothing."); -+ } -+ else if (m_iMenuIndex == 3) -+ { -+ m_fTextureShift = Modify(m_fTextureShift, 0.5, -100, 100); -+ str.append("IPD = "); -+ str.append(std::to_string(m_fEyeDistance)); -+ str.append("\nFocus Distance = "); -+ str.append(std::to_string(m_fFocusDistance)); -+ str.append(sep1); -+ str.append("Texture shift = "); -+ str.append(std::to_string(m_fTextureShift)); -+ str.append(sep2); -+ str.append("\nTexture Zoom = "); -+ str.append(std::to_string(m_fTextureZoom)); -+ str.append("\nFOV = "); -+ str.append(std::to_string(m_fFOV)); -+ str.append("\n \nDoes nothing."); -+ } -+ else if (m_iMenuIndex == 4) -+ { -+ m_fTextureZoom = Modify(m_fTextureZoom, 1, -200, 200); -+ str.append("IPD = "); -+ str.append(std::to_string(m_fEyeDistance)); -+ str.append("\nFocus Distance = "); -+ str.append(std::to_string(m_fFocusDistance)); -+ str.append("\nTexture shift = "); -+ str.append(std::to_string(m_fTextureShift)); -+ str.append(sep1); -+ str.append("Texture Zoom = "); -+ str.append(std::to_string(m_fTextureZoom)); -+ str.append(sep2); -+ str.append("\nFOV = "); -+ str.append(std::to_string(m_fFOV)); -+ str.append("\n \nZooms the view in or out. It may help with wide FOV HMD's like Pimax.\n Zoom in reduces quality. Zoom out increases quality\nWhen this value is changed FOV must also be adjusted."); -+ } -+ else if (m_iMenuIndex == 5) -+ { -+ m_fFOV = Modify(m_fFOV, 0.5, 50, 175); -+ //LLViewerCamera::getInstance()->setDefaultFOV(m_fFOV * DEG_TO_RAD); -+ str.append("IPD = "); -+ str.append(std::to_string(m_fEyeDistance)); -+ str.append("\nFocus Distance = "); -+ str.append(std::to_string(m_fFocusDistance)); -+ str.append("\nTexture shift = "); -+ str.append(std::to_string(m_fTextureShift)); -+ str.append("\nTexture Zoom = "); -+ str.append(std::to_string(m_fTextureZoom)); -+ str.append(sep1); -+ str.append("FOV = "); -+ str.append(std::to_string(m_fFOV)); -+ str.append(sep2); -+ str.append("\n \nField of view in degree adjustment. Does nothing."); -+ } -+ return str; -+} -+ -+F32 llviewerVR::Modify(F32 val, F32 step, F32 min, F32 max) -+{ -+ if (gKeyboard->getKeyDown(m_kPlusKey) && (!m_bPlusKeyDown || gKeyboard->getKeyElapsedTime(m_kPlusKey) >1)) -+ { -+ m_bPlusKeyDown = TRUE; -+ val += step; -+ if (val > max) -+ val = max; -+ return val; -+ } -+ else if (!gKeyboard->getKeyDown(m_kPlusKey) && m_bPlusKeyDown) -+ { -+ m_bPlusKeyDown = FALSE; -+ /*val += step; -+ if (val > max) -+ val = max; -+ return val;*/ -+ -+ } -+ if (gKeyboard->getKeyDown(m_kMinusKey) && !m_bMinusKeyDown) -+ { -+ m_bMinusKeyDown = TRUE; -+ } -+ else if (!gKeyboard->getKeyDown(m_kMinusKey) && m_bMinusKeyDown) -+ { -+ m_bMinusKeyDown = FALSE; -+ val -= step; -+ if (val < min) -+ val = min; -+ return val; -+ } -+ return val; -+} -+ -+std::string llviewerVR::INISaveRead(bool save) -+{ -+ std::string path = getenv("APPDATA"); -+ path.append("\\FirestormVR_x64\\vrconfig.ini"); -+ std::string ret; -+ ret.append(path); -+ ret.append("\n"); -+ std::string line; -+ std::fstream file; -+ if (!save) -+ { -+ file.open(path, std::ios_base::in); -+ -+ if (file.is_open()) -+ { -+ while (getline(file, line, ',')) -+ { -+ if (line == "EyeDistance") -+ { -+ //ret.append(line.append("|")); -+ getline(file, line, ','); -+ m_fEyeDistance = std::stof(line); -+ } -+ else if (line == "FocusDistance") -+ { -+ //ret.append(line.append("|")); -+ getline(file, line, ','); -+ m_fFocusDistance = std::stof(line); -+ } -+ else if (line == "TextureShift") -+ { -+ //ret.append(line.append("|")); -+ getline(file, line, ','); -+ m_fTextureShift = std::stof(line); -+ } -+ else if (line == "TextureZoom") -+ { -+ //ret.append(line.append("|")); -+ getline(file, line, ','); -+ m_fTextureZoom = std::stof(line); -+ } -+ else if (line == "FieldOfView") -+ { -+ //ret.append(line.append("|")); -+ getline(file, line, ','); -+ m_fFOV = std::stof(line); -+ } -+ -+ } -+ file.close(); -+ } -+ else -+ ret.append("\n file not open!!!\n"); -+ } -+ else -+ { -+ file.open(path, std::ios_base::out); -+ std::string s; -+ s.append("EyeDistance"); -+ s.append(","); -+ s.append(std::to_string(m_fEyeDistance)); -+ s.append(","); -+ -+ s.append("FocusDistance"); -+ s.append(","); -+ s.append(std::to_string(m_fFocusDistance)); -+ s.append(","); -+ -+ s.append("TextureShift"); -+ s.append(","); -+ s.append(std::to_string(m_fTextureShift)); -+ s.append(","); -+ -+ s.append("TextureZoom"); -+ s.append(","); -+ s.append(std::to_string(m_fTextureZoom)); -+ s.append(","); -+ -+ s.append("FieldOfView"); -+ s.append(","); -+ s.append(std::to_string(m_fFOV)); -+ -+ if (file.is_open()) -+ { -+ file << s.c_str(); -+ file.close(); -+ } -+ -+ } -+ return ret; -+ -+} -+ -+void llviewerVR::Debug() -+{ -+ LLWindow * WI; -+ WI = gViewerWindow->getWindow(); -+ LLCoordWindow mpos; -+ WI->getCursorPosition(&mpos); -+ LLCoordGL mcpos = gViewerWindow->getCurrentMouse(); -+ LLVector3 voffset = gHmdPos - gHmdOffsetPos; -+ std::string str; -+ str.append(" Cam Pos \n< "); -+ str.append(std::to_string(m_vpos.mV[VX])); -+ str.append(" , "); -+ str.append(std::to_string(m_vpos.mV[VY])); -+ str.append(" , "); -+ str.append(std::to_string(m_vpos.mV[VZ])); -+ str.append(" > "); -+ str.append("\n HMD Pos offset - hmd \n< "); -+ str.append(std::to_string(voffset.mV[VX])); -+ str.append(" , "); -+ str.append(std::to_string(voffset.mV[VY])); -+ str.append(" , "); -+ str.append(std::to_string(voffset.mV[VZ])); -+ str.append(" > "); -+ str.append("\n HMD Pos offset \n< "); -+ str.append(std::to_string(gHmdOffsetPos.mV[VX])); -+ str.append(" , "); -+ str.append(std::to_string(gHmdOffsetPos.mV[VY])); -+ str.append(" , "); -+ str.append(std::to_string(gHmdOffsetPos.mV[VZ])); -+ str.append(" > "); -+ str.append("\n HMD Pos \n< "); -+ str.append(std::to_string(gHmdPos.mV[VX])); -+ str.append(" , "); -+ str.append(std::to_string(gHmdPos.mV[VY])); -+ str.append(" , "); -+ str.append(std::to_string(gHmdPos.mV[VZ])); -+ str.append(" > "); -+ /* -+ str.append("\nPointe Pos\n< "); -+ str.append(std::to_string(gCtrlPos[0].mV[VX])); -+ str.append(" , "); -+ str.append(std::to_string(gCtrlPos[0].mV[VY])); -+ str.append(" , "); -+ str.append(std::to_string(gCtrlPos[0].mV[VZ])); -+ str.append(" > "); -+ -+ str.append("\nPoint Origin\n< "); -+ str.append(std::to_string(gCtrlOrigin[0].mV[VX])); -+ str.append(" , "); -+ str.append(std::to_string(gCtrlOrigin[0].mV[VY])); -+ str.append(" , "); -+ str.append(std::to_string(gCtrlOrigin[0].mV[VZ])); -+ str.append(" > ");*/ -+ -+ str.append("\n Zoom Index"); -+ str.append(std::to_string(m_iZoomIndex)); -+ -+ str.append("\n MCoord X="); -+ str.append(std::to_string(mpos.mX)); -+ str.append(" Y="); -+ str.append(std::to_string(mpos.mY)); -+ -+ str.append("\n MCoord X="); -+ str.append(std::to_string(mcpos.mX)); -+ str.append(" Y="); -+ str.append(std::to_string(mcpos.mY)); -+ str.append("\n Mview X="); -+ str.append(std::to_string(m_MousePos.mX)); -+ str.append(" Y="); -+ str.append(std::to_string(m_MousePos.mY)); -+ -+ str.append("\n Coord1 X="); -+ str.append(std::to_string(gCtrlscreen[1].mX)); -+ str.append(" Y="); -+ str.append(std::to_string(gCtrlscreen[1].mY)); -+ str.append("\n Rheight="); -+ str.append(std::to_string(m_nRenderHeight)); -+ str.append("\n Rwidth="); -+ str.append(std::to_string(m_nRenderWidth)); -+ str.append("\n Button="); -+ str.append(std::to_string(gButton)); -+ -+ str.append("\n Cam Rot Offset in DEG ="); -+ str.append(std::to_string(m_fCamRotOffset)); -+ -+ str.append("\nL+R Camera Distance in mm\n"); -+ str.append(std::to_string(m_fEyeDistance)); -+ str.append("\nCurrent FOV \n"); -+ str.append(std::to_string(LLViewerCamera::getInstance()->getDefaultFOV())); -+ //str.append("\n LastGL ERR="); -+ //str.append(std::to_string(err)); -+ -+ -+ hud_textp->setString(str); -+ LLVector3 end = m_vpos + (m_vdir)* 1.0f; -+ hud_textp->setPositionAgent(end); -+ hud_textp->setDoFade(FALSE); -+ hud_textp->setHidden(FALSE); -+} -+ -+void llviewerVR::InitUI() -+{ -+ if (!m_pCamButtonLeft) -+ { -+ /*LLPanel* panelp = NULL; -+ panelp=LLPanel::createFactoryPanel("vr_controlls"); -+ -+ panelp->setRect(rc); -+ LLColor4 color(1, 1, 1); -+ panelp->setOrigin(700, 700); -+ panelp->setColor(color); -+ panelp->setVisible(TRUE); -+ panelp->setEnabled(TRUE);*/ -+ LLRect rc; -+ rc.setCenterAndSize(500, 500, 200, 200); -+ -+ -+ m_pCamera_floater = LLFloaterReg::findTypedInstance("camera"); -+ if (m_pCamera_floater) -+ { -+ LLStringExplicit lb("keks"); -+ //LLRect rc; -+ //LLButton *m_pButton1; -+ LLButton *m_pButton; -+ for (int i = 0; i < 2; i++) -+ { -+ -+ LLButton::Params p; -+ if (i == 0) -+ { -+ p.name("rot_left"); -+ p.label("<<"); -+ } -+ else -+ { -+ p.name("rot_right"); -+ p.label(">>"); -+ } -+ -+ -+ m_pButton = LLUICtrlFactory::create(p); -+ -+ -+ m_pCamera_floater->addChild(m_pButton); -+ //panelp->addChild(m_pButton); -+ if (i == 0) -+ rc.setCenterAndSize(20, 20, 30, 20); -+ else -+ rc.setCenterAndSize(50, 20, 30, 20); -+ m_pButton->setRect(rc); -+ m_pButton->setVisible(TRUE); -+ m_pButton->setEnabled(TRUE); -+ if (i == 0) -+ m_pCamButtonLeft = m_pButton; -+ else -+ m_pCamButtonRight = m_pButton; -+ } -+ m_pCamButtonLeft->setCommitCallback(boost::bind(&llviewerVR::buttonCallbackLeft, this)); -+ m_pCamButtonRight->setCommitCallback(boost::bind(&llviewerVR::buttonCallbackRight, this)); -+ -+ /*m_pButton1 = m_pCamera_floater->findChild("rot_left"); -+ //lb.assign("<"); -+ if (m_pButton1) -+ { -+ m_pButton1->setLabel(LLStringExplicit("<")); -+ m_pButton1->setCommitCallback(boost::bind(&llviewerVR::buttonsCallback, this)); -+ }*/ -+ -+ -+ m_pCamStack = m_pCamera_floater->findChild("camera_view_layout_stack"); -+ -+ -+ //m_pCamera_floater->getChildList(); -+ //m_pButton1-> -+ } -+ } -+} -diff --git a/indra/newview/llviewerVR.h b/indra/newview/llviewerVR.h -new file mode 100644 -index 000000000..fd2aa7880 ---- /dev/null -+++ b/indra/newview/llviewerVR.h -@@ -0,0 +1,236 @@ -+#pragma once -+ -+#include "../../../openvr/headers/openvr.h" -+#pragma comment(lib, "../../../openvr/lib/win64/openvr_api.lib") -+#include "llhudtext.h" -+#include "llgl.h" -+#include "string.h" -+#include "llfloater.h" -+#include "llfloatercamera.h" -+#include "llrendertarget.h" -+//#include "control.h" -+//#include "llviewercamera.h" -+//#include "llagentcamera.h" -+//#include "pipeline.h" -+//#include "llagent.h" -+//#include "llviewerwindow.h" -+ -+ -+class llviewerVR -+{ -+public: -+ vr::IVRSystem *gHMD = 0; -+ vr::IVRCompositor* gCompositor = 0; -+ vr::IVRRenderModels * gRenderModels = 0; -+ std::string gStrDriver; -+ std::string gStrDisplay; -+ vr::TrackedDevicePose_t gTrackedDevicePose[vr::k_unMaxTrackedDeviceCount]; -+ vr::VRCompositorError eError = vr::VRCompositorError_None; -+ vr::Texture_t lEyeTexture; -+ vr::Texture_t rEyeTexture; -+ LLRenderTarget lEyeRenderTarget; -+ LLRenderTarget rEyeRenderTarget; -+ LLRenderTarget uiRenderTarget; -+ int screenState = 0; // 0 = gPipeline.mScreen is real screen. 1 = gPipeline.mScreen is lEye, 2 = gPipeline.mScreen is right eye. -+ vr::Texture_t uiTexture; -+ vr::VROverlayHandle_t vrUiOverlay; -+ -+ U32 bx = 0; -+ U32 by = 0; -+ U32 tx = 0; -+ U32 ty = 0; -+ -+ KEY m_kEditKey; -+ KEY m_kDebugKey; -+ KEY m_kMenuKey; -+ KEY m_kPlusKey; -+ KEY m_kMinusKey; -+ -+ bool m_bVrEnabled = 0; -+ -+ bool m_bVrActive = 0; -+ bool m_bVrKeyDown = 0; -+ -+ bool m_bEditKeyDown = 0; -+ bool m_bEditActive = 0; -+ -+ bool m_bDebugKeyDown = 0; -+ -+ bool m_bMenuKeyDown = 0; -+ bool m_bPlusKeyDown = 0; -+ bool m_bMinusKeyDown = 0; -+ -+ -+ bool isRenderingLeftEye = 0; -+ bool gVRInitComplete = 0; -+ -+ -+ S32 m_iTextureShift = 0; -+ -+ struct FramebufferDesc -+ { -+ GLuint m_nDepthBufferId; -+ GLuint m_nRenderTextureId; -+ GLuint m_nRenderFramebufferId; -+ GLuint m_nResolveTextureId; -+ GLuint mFBO; -+ GLuint IsReady; -+ }; -+ FramebufferDesc leftEyeDesc; -+ FramebufferDesc rightEyeDesc; -+ FramebufferDesc uiDesc; -+ U32 m_nRenderWidth; -+ U32 m_nRenderHeight; -+ S32 m_iTrackedControllerCount; -+ S32 m_iTrackedControllerCount_Last; -+ S32 m_iValidPoseCount; -+ S32 m_iValidPoseCount_Last; -+ S32 m_iZoomIndex = 0; -+ U64 m_iClockCount; -+ U64 m_iClockCount2; -+ LLTimer m_tTimer1; -+ F32 m_fCamRotOffset = 90; -+ F32 m_fCamPosOffset = 0; -+ -+ LLVector3 m_vdir_orig; -+ LLVector3 m_vup_orig; -+ LLVector3 m_vleft_orig; -+ LLVector3 m_vpos_orig; -+ -+ LLVector3 m_vdir; -+ LLVector3 m_vup; -+ LLVector3 m_vleft; -+ LLVector3 m_vpos; -+ LLButton *m_pCamButtonLeft = 0; -+ LLButton *m_pCamButtonRight = 0; -+ LLButton *m_pCamButtonChat = 0; -+ LLButton *m_pCamButtonPref = 0; -+ LLFloaterCamera *m_pCamera_floater = 0; -+ LLView *m_pCamStack = 0; -+ -+ -+ -+ LLCoordWindow m_MousePos; -+ LLCoordWindow m_ScrSize; -+ S32 m_iHalfWidth; -+ S32 m_iHalfHeight; -+ S32 m_iThirdWidth; -+ S32 m_iThirdHeight; -+ -+ S32 m_iMenuIndex; -+ F32 m_fEyeDistance; -+ F32 m_fWorldScale; -+ F32 m_fFocusDistance; -+ F32 m_fTextureShift; -+ F32 m_fFOV; -+ F32 m_fTextureZoom; -+ -+ //controller axes -+// int m_iTrackedControllerCount; -+// int m_iTrackedControllerCount_Last; -+ unsigned int m_uiControllerVertcount; -+ //vr::TrackedDevicePose_t m_rTrackedDevicePose[vr::k_unMaxTrackedDeviceCount]; -+ -+ float m_fNearClip; -+ float m_fFarClip; -+ -+ std::string m_strPoseClasses; -+ std::string m_strDriver; -+ std::string m_strDisplay; -+ -+ glh::matrix4f m_mat4HMDPose; -+ glh::matrix4f m_rmat4DevicePose[vr::k_unMaxTrackedDeviceCount]; -+ glh::matrix4f m_mat4eyePosLeft; -+ glh::matrix4f m_mat4eyePosRight; -+ -+ glh::matrix4f m_mat4ProjectionCenter; -+ glh::matrix4f m_mat4ProjectionLeft; -+ glh::matrix4f m_mat4ProjectionRight; -+ char m_rDevClassChar[vr::k_unMaxTrackedDeviceCount]; -+ -+ -+ glh::matrix4f ConvertSteamVRMatrixToMatrix4(const vr::HmdMatrix34_t &matPose); -+ LLVector3 llviewerVR::TransformLLVector(glh::matrix4f transform, LLVector3 vector, F32 w); -+ glh::matrix4f GetHMDMatrixProjectionEye(vr::Hmd_Eye nEye); -+ glh::matrix4f GetHMDMatrixPoseEye(vr::Hmd_Eye nEye); -+ glh::matrix4f GetCurrentViewProjectionMatrix(vr::Hmd_Eye nEye); -+ -+ glh::matrix4f ConvertSteamVRMatrixToMatrix42(const vr::HmdMatrix34_t &matPose); -+ -+ vr::HmdQuaternion_t GetRotation(vr::HmdMatrix34_t matrix); -+ LLMatrix4 ConvertGLHMatrix4ToLLMatrix4(glh::matrix4f m); -+ -+ -+ std::string MatrixToStr(glh::matrix4f mat, std::string name); -+ std::string MatrixToStrLL(glh::matrix4f mat, std::string name); -+ bool gluInvertMatrix(const float m[16], float invOut[16]); -+ glh::ns_float::vec3 m_nPos; -+ -+ -+ LLVector3 gHMDAxes; -+ LLVector3 gCurrentCameraPos; -+ vr::HmdVector3_t gHMDFwd; -+ LLQuaternion gHMDQuat; -+ LLQuaternion gCtrlQuat[2]; -+ LLVector3 gHmdPos; -+ LLVector3 gHmdOffsetPos; -+ -+ LLVector3 gCtrlPos[vr::k_unMaxTrackedDeviceCount]; -+ LLVector3 gCtrlOrigin[vr::k_unMaxTrackedDeviceCount]; -+ //uint32_t gCtrlNum; -+ LLCoordGL gCtrlscreen[vr::k_unMaxTrackedDeviceCount]; -+ -+ LLMatrix4 gM4HMDPose; -+ LLMatrix4 gM4eyePosLeft; -+ LLMatrix4 gM4eyeProjectionLeft; -+ LLMatrix4 gM4eyePosRight; -+ LLMatrix4 gM4eyeProjectionRight; -+ LLHUDText *hud_textp; -+ std::string m_strHudText; -+ bool m_bHudTextUpdated=FALSE; -+ -+ bool gRightClick[vr::k_unMaxTrackedDeviceCount]; -+ bool gLeftClick[vr::k_unMaxTrackedDeviceCount]; -+ bool gLeftTouchpad = FALSE; -+ S32 gCursorDiff; -+ uint64_t gPreviousButtonMask; -+ -+ uint64_t gButton; -+ -+ bool m_rbShowTrackedDevice[vr::k_unMaxTrackedDeviceCount]; -+ uint32_t gPacketNum = 0; -+ -+ void UpdateHMDMatrixPose(); -+ //std::string GetTrackedDeviceString(vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL); -+ void SetupCameras(); -+ bool CreateFrameBuffer(LLRenderTarget &renderTarget, int nWidth, int nHeight, FramebufferDesc &framebufferDesc); -+ void vrStartup(bool is_shutdown); -+ void vrDisplay(); -+ void vrCaptureUI(); -+ bool HandleInput(); -+ void DrawCursors(); -+ void ProcessVREvent(const vr::VREvent_t & event); -+ void agentYaw(F32 yaw_inc); -+ bool ProcessVRCamera(); -+ std::string GetTrackedDeviceString(vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL); -+ void RenderControllerAxes(); -+ BOOL posToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const; -+ void buttonCallbackLeft(); -+ void buttonCallbackRight(); -+ std::string Settings(); -+ F32 Modify(F32 val, F32 step, F32 min, F32 max); -+ std::string INISaveRead(bool save = false); -+ void HandleKeyboard(); -+ void Debug(); -+ void InitUI(); -+ -+ void calcUVBounds(vr::EVREye eye, F32 *uMin, F32 *uMax, F32 *vMin, F32 *vMax); -+ -+ void swapScreenAndEye(int mode); -+ -+ -+ llviewerVR(); -+ -+ ~llviewerVR(); -+}; -+ -diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp -index 14e8b6bad..6ae43daff 100644 ---- a/indra/newview/llviewercamera.cpp -+++ b/indra/newview/llviewercamera.cpp -@@ -96,6 +96,10 @@ LLViewerCamera::LLViewerCamera() : LLCamera() - mZoomSubregion = 1; - mAverageSpeed = 0.f; - mAverageAngularSpeed = 0.f; -+ // P373R Sgeo -+ mHorizontalOffset = 0.f; -+ mVerticalOffset = 0.f; -+ // END P373R Sgeo - gSavedSettings.getControl("CameraAngle")->getCommitSignal()->connect(boost::bind(&LLViewerCamera::updateCameraAngle, this, _2)); - } - -@@ -184,6 +188,11 @@ void LLViewerCamera::calcProjection(const F32 far_distance) const - mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far); - mProjectionMatrix.mMatrix[2][3] = -1; -+ -+ // P373R Sgeo -+ mProjectionMatrix.mMatrix[2][0] = getHorizontalOffset(); -+ mProjectionMatrix.mMatrix[2][1] = getVerticalOffset(); -+ // END P373R Sgeo - } - - // Sets up opengl state for 3D drawing. If for selection, also -@@ -371,7 +380,9 @@ void LLViewerCamera::setPerspective(BOOL for_selection, - - calcProjection(z_far); // Update the projection matrix cache - -- proj_mat *= gl_perspective(fov_y,aspect,z_near,z_far); -+ // P373R Sgeo, replaces non-VR version -+ proj_mat *= gl_perspective_vr(fov_y,aspect,z_near,z_far, getHorizontalOffset(), getVerticalOffset()); -+ // END P373R Sgeo - - gGL.loadMatrix(proj_mat.m); - -@@ -878,6 +889,20 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) - mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f); - } - -+// P373R Sgeo -+// Takes tan angles. Provided directly from OpenVR -+// OpenXR provides angles instead. Convert to tan at callsite or here? -+void LLViewerCamera::setVRFov(F32 left, F32 right, F32 top, F32 bottom) -+{ -+ setView(2 * std::atanf((top-bottom)/2.0)); -+ setAspect((right-left)/(top-bottom)); -+ setHorizontalOffset((right+left)/(right-left)); -+ setVerticalOffset((top+bottom)/(top-bottom)); -+ // Provide accurate frustum planes -+ calculateFrustumPlanes(left * getFar(), right * getFar(), top * getFar(), bottom * getFar()); -+} -+// END P373R Sgeo -+ - BOOL LLViewerCamera::isDefaultFOVChanged() - { - if(mPrevCameraFOVDefault != mCameraFOVDefault) -diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h -index 78ca2b307..972121c6c 100644 ---- a/indra/newview/llviewercamera.h -+++ b/indra/newview/llviewercamera.h -@@ -91,6 +91,13 @@ public: - void setViewNoBroadcast(F32 vertical_fov_rads); // set FOV without broadcasting to simulator (for temporary local cameras) - void setDefaultFOV(F32 fov) ; - F32 getDefaultFOV() { return mCameraFOVDefault; } -+ // P373R Sgeo -+ void setVRFov(F32 left, F32 right, F32 top, F32 bottom); -+ F32 getHorizontalOffset() const { return mHorizontalOffset; } -+ F32 getVerticalOffset() const { return mVerticalOffset; } -+ void setHorizontalOffset(F32 offset) { mHorizontalOffset = offset; } -+ void setVerticalOffset(F32 offset) { mVerticalOffset = offset; } -+ // END P373R Sgeo - - BOOL isDefaultFOVChanged(); - -@@ -125,7 +132,14 @@ protected: - F32 mZoomFactor; - S16 mZoomSubregion; - -+// P373R Sgeo -+private: -+ F32 mHorizontalOffset; -+ F32 mVerticalOffset; -+// END P373R Sgeo -+ - public: -+ - }; - - -diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp -index c82dff4ce..a6647aee7 100644 ---- a/indra/newview/llviewerdisplay.cpp -+++ b/indra/newview/llviewerdisplay.cpp -@@ -88,6 +88,11 @@ - #include "llpresetsmanager.h" - #include "fsdata.h" - -+//################################### P373R ###################################### -+#include "llviewerVR.cpp" -+llviewerVR gVR; -+//################################### END P373R ################################## -+ - extern LLPointer gStartTexture; - extern bool gShiftFrame; - -@@ -783,6 +788,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); - } - -+ //################################### P373R ###################################### -+ gVR.swapScreenAndEye(1); -+ sec: -+ gVR.ProcessVRCamera(); -+ //################################### END P373R ################################## -+ - stop_glerror(); - display_update_camera(); - stop_glerror(); -@@ -1118,7 +1129,29 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) - if (!for_snapshot) - { - render_ui(); -- swap(); -+ //################################### P373R ###################################### -+ -+ gVR.swapScreenAndEye(0); -+ gVR.vrDisplay(); -+ //swap(); -+ if (gVR.leftEyeDesc.IsReady && !gVR.rightEyeDesc.IsReady) -+ { -+ gVR.swapScreenAndEye(2); -+ goto sec; -+ -+ -+ } -+ -+ if (!gVR.leftEyeDesc.IsReady && !gVR.rightEyeDesc.IsReady) -+ { -+ //gVR.HandleInput(); -+ -+ -+ } -+ if (!gVR.m_bVrActive) -+ swap(); -+ -+ //################################### END P373R ################################## - } - - -@@ -1661,6 +1694,9 @@ void render_ui_3d() - stop_glerror(); - - gUIProgram.bind(); -+ //################################### P373R ###################################### -+ gVR.RenderControllerAxes(); -+ //################################### END P373R ################################## - gGL.color4f(1, 1, 1, 1); - - // Coordinate axes -@@ -1688,6 +1724,18 @@ void render_ui_3d() - - void render_ui_2d() - { -+ // P373R Sgeo -+ // LLRenderTarget *priorTarget = NULL; -+ // if (gVR.m_bVrActive) -+ // { -+ // //return; -+ // priorTarget = LLRenderTarget::getCurrentBoundTarget(); -+ // if(priorTarget) priorTarget->flush(); -+ // gPipeline.mUIScreen.bindTarget(); -+ // gGL.setColorMask(true, true); -+ // glClear(GL_COLOR_BUFFER_BIT); -+ // } -+ // /P373R Sgeo - LLGLSUIDefault gls_ui; - - ///////////////////////////////////////////////////////////// -@@ -1813,6 +1861,37 @@ void render_ui_2d() - gViewerWindow->draw(); - } - -+ //################################### P373R ###################################### -+ gVR.DrawCursors(); -+ if(gVR.m_bVrActive) { -+ gPipeline.mRT->uiScreen.flush(); -+ -+ gPipeline.mRT->screen.bindTarget(); -+ // gSplatTextureRectProgram.bind(); -+ // gGL.getTexUnit(0)->bind(&gPipeline.mUIScreen); -+ -+ // // S32 uiDepth = LLAppViewer::instance()->getRiftUIDepth(); -+ // // S32 offset = (gRiftCurrentEye == 0) ? uiDepth + gRiftLensOffset : -uiDepth - gRiftLensOffset; -+ // S32 offset = 0; -+ // S32 width = gViewerWindow->getWindowWidthScaled();; -+ // S32 height = gViewerWindow->getWindowHeightScaled(); -+ // LLGLEnable blend(GL_BLEND); -+ // gGL.setColorMask(true, false); -+ // gGL.color4f(1,1,1,1); -+ // gGL.begin(7); -+ // gGL.texCoord2f(0, height); gGL.vertex2i(offset, height); -+ // gGL.texCoord2f(0, 0); gGL.vertex2i(offset, 0); -+ // gGL.texCoord2f(width, 0); gGL.vertex2i(offset + width, 0); -+ // gGL.texCoord2f(width, height); gGL.vertex2i(offset + width, height); -+ // gGL.end(); -+ // gGL.flush(); -+ -+ //gSplatTextureRectProgram.unbind(); -+ gPipeline.mRT->screen.flush(); -+ -+ } -+ //################################### END P373R ################################## -+ - - - // reset current origin for font rendering, in case of tiling render -@@ -1898,6 +1977,9 @@ void render_disconnected_background() - - void display_cleanup() - { -+ //################################### P373R ###################################### -+ gVR.vrStartup(TRUE); -+ //################################### END P373R ###################################### - gDisconnectedImagep = NULL; - } - -diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp -index 83e822a9a..c90a50b7a 100644 ---- a/indra/newview/pipeline.cpp -+++ b/indra/newview/pipeline.cpp -@@ -876,7 +876,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) - mWaterDis.allocate(resX, resY, GL_RGBA, true); - } - -- if (RenderUIBuffer) -+ if (true || RenderUIBuffer) // P373R Sgeo - { - if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA)) - { --- -2.46.2.windows.1 - - -From 1152acc56c9b8de09a831a9935598457998cf496 Mon Sep 17 00:00:00 2001 -From: Sgeo -Date: Sun, 28 Jan 2024 01:32:03 -0500 -Subject: [PATCH 2/3] Switch back to prior rendering approach. Mysteriously - fixes camera issue. - ---- - indra/newview/llviewerVR.cpp | 4 ++-- - indra/newview/llviewerdisplay.cpp | 3 --- - 2 files changed, 2 insertions(+), 5 deletions(-) - -diff --git a/indra/newview/llviewerVR.cpp b/indra/newview/llviewerVR.cpp -index ce7172233..2ed2b11b0 100644 ---- a/indra/newview/llviewerVR.cpp -+++ b/indra/newview/llviewerVR.cpp -@@ -1182,12 +1182,13 @@ void llviewerVR::vrDisplay() - // tx += thirdx; - // } - } -+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); -+ glReadBuffer(GL_BACK); - - - //if left camera was active bind left eye buffer for drawing in to - if (!leftEyeDesc.IsReady) - { -- glBindFramebuffer(GL_READ_FRAMEBUFFER, lEyeRenderTarget.getFBO()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, leftEyeDesc.mFBO); - if (m_iZoomIndex) - glClear(GL_COLOR_BUFFER_BIT); -@@ -1207,7 +1208,6 @@ void llviewerVR::vrDisplay() - } - if ((leftEyeDesc.IsReady && !rightEyeDesc.IsReady))//if right camera was active bind left eye buffer for drawing in to - { -- glBindFramebuffer(GL_READ_FRAMEBUFFER, rEyeRenderTarget.getFBO()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rightEyeDesc.mFBO); - if (m_iZoomIndex) - glClear(GL_COLOR_BUFFER_BIT); -diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp -index a6647aee7..244957906 100644 ---- a/indra/newview/llviewerdisplay.cpp -+++ b/indra/newview/llviewerdisplay.cpp -@@ -789,7 +789,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) - } - - //################################### P373R ###################################### -- gVR.swapScreenAndEye(1); - sec: - gVR.ProcessVRCamera(); - //################################### END P373R ################################## -@@ -1131,12 +1130,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) - render_ui(); - //################################### P373R ###################################### - -- gVR.swapScreenAndEye(0); - gVR.vrDisplay(); - //swap(); - if (gVR.leftEyeDesc.IsReady && !gVR.rightEyeDesc.IsReady) - { -- gVR.swapScreenAndEye(2); - goto sec; - - --- -2.46.2.windows.1 - - -From 54909beeda0d710dad1493d80e80adf3bf1545d2 Mon Sep 17 00:00:00 2001 -From: CITEST -Date: Sat, 12 Oct 2024 22:28:40 +0000 -Subject: [PATCH 3/3] patch openvr.h and pragma - ---- - indra/newview/llviewerVR.h | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/indra/newview/llviewerVR.h b/indra/newview/llviewerVR.h -index fd2aa7880..89804262b 100644 ---- a/indra/newview/llviewerVR.h -+++ b/indra/newview/llviewerVR.h -@@ -1,7 +1,6 @@ - #pragma once - --#include "../../../openvr/headers/openvr.h" --#pragma comment(lib, "../../../openvr/lib/win64/openvr_api.lib") -+#include - #include "llhudtext.h" - #include "llgl.h" - #include "string.h" --- -2.46.2.windows.1 -