diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index bb85438ad..552995457 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -72,6 +72,8 @@ public: class CStereoOVRDevicePtr; +#define NL_STEREO_MAX_USER_CAMERAS 8 + /** * \brief CStereoOVR * \date 2013-06-25 22:22GMT @@ -88,18 +90,18 @@ public: /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height); /// Set latest camera position etcetera - virtual void updateCamera(const NL3D::UCamera *camera); + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); /// Is there a next pass virtual bool nextPass(); /// Gets the current viewport virtual const NL3D::CViewport &getCurrentViewport() const; /// Gets the current camera frustum - virtual const NL3D::CFrustum &getCurrentFrustum() const; + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; /// Gets the current camera frustum - virtual void getCurrentFrustum(NL3D::UCamera *camera) const; + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; /// Gets the current camera matrix - virtual void getCurrentMatrix(NL3D::UCamera *camera) const; + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; /// At the start of a new render target virtual bool beginClear(); @@ -122,7 +124,7 @@ public: /// Get the HMD orientation virtual NLMISC::CQuat getOrientation() const; /// Get GUI center (1 = width, 1 = height, 0 = center) - virtual void getInterface2DShift(float &x, float &y, float distance); + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance); static void listDevices(std::vector &devicesOut); @@ -132,7 +134,7 @@ public: /// Calculates internal camera information based on the reference camera - void initCamera(const NL3D::UCamera *camera); + void initCamera(uint cid, const NL3D::UCamera *camera); bool isDeviceCreated(); @@ -141,9 +143,9 @@ private: int m_Stage; CViewport m_LeftViewport; CViewport m_RightViewport; - CFrustum m_LeftFrustum; - CFrustum m_RightFrustum; - CMatrix m_CameraMatrix; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; mutable bool m_OrientationCached; mutable NLMISC::CQuat m_OrientationCache; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 5ef7f9933..4b2417571 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -204,29 +204,29 @@ void CStereoOVR::getScreenResolution(uint &width, uint &height) height = m_DevicePtr->HMDInfo.VResolution; } -void CStereoOVR::initCamera(const NL3D::UCamera *camera) +void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) { float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.VScreenSize / 2.0f) / m_DevicePtr->HMDInfo.EyeToScreenDistance); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); - m_LeftFrustum.initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); - m_RightFrustum = m_LeftFrustum; + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; float projectionCenterOffset = 4.0f * eyeProjectionShift / m_DevicePtr->HMDInfo.HScreenSize; nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); - projectionCenterOffset *= (m_LeftFrustum.Left - m_LeftFrustum.Right) * 0.5f; // made this up ... - m_LeftFrustum.Left += projectionCenterOffset; - m_LeftFrustum.Right += projectionCenterOffset; - m_RightFrustum.Left -= projectionCenterOffset; - m_RightFrustum.Right -= projectionCenterOffset; + projectionCenterOffset *= (m_LeftFrustum[cid].Left - m_LeftFrustum[cid].Right) * 0.5f; // made this up ... + m_LeftFrustum[cid].Left += projectionCenterOffset; + m_LeftFrustum[cid].Right += projectionCenterOffset; + m_RightFrustum[cid].Left -= projectionCenterOffset; + m_RightFrustum[cid].Right -= projectionCenterOffset; } -void CStereoOVR::updateCamera(const NL3D::UCamera *camera) +void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) { - if (camera->getFrustum().Near != m_LeftFrustum.Near - || camera->getFrustum().Far != m_LeftFrustum.Far) - CStereoOVR::initCamera(camera); - m_CameraMatrix = camera->getMatrix(); + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoOVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); } bool CStereoOVR::nextPass() @@ -285,25 +285,25 @@ const NL3D::CViewport &CStereoOVR::getCurrentViewport() const else return m_RightViewport; } -const NL3D::CFrustum &CStereoOVR::getCurrentFrustum() const +const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const { - if (m_Stage % 2) return m_LeftFrustum; - else return m_RightFrustum; + if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; } -void CStereoOVR::getCurrentFrustum(NL3D::UCamera *camera) const +void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const { - if (m_Stage % 2) camera->setFrustum(m_LeftFrustum); - else camera->setFrustum(m_RightFrustum); + if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); } -void CStereoOVR::getCurrentMatrix(NL3D::UCamera *camera) const +void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const { CMatrix translate; if (m_Stage % 2) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); else translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f)); camera->setTransformMode(NL3D::UTransformable::DirectMatrix); - camera->setMatrix(m_CameraMatrix * translate); + camera->setMatrix(m_CameraMatrix[cid] * translate); } bool CStereoOVR::beginClear() @@ -395,7 +395,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const } /// Get GUI shift -void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) +void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) { #if 0 @@ -437,7 +437,7 @@ void CStereoOVR::getInterface2DShift(float &x, float &y, float distance) CVector rotshift = CVector(p, 0.f, t) * -distance; - CVector proj = CStereoOVR::getCurrentFrustum().project(vec + ipd + rotshift); + CVector proj = CStereoOVR::getCurrentFrustum(cid).project(vec + ipd + rotshift); x = (proj.x - 0.5f); y = (proj.y - 0.5f); diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index 030ebe0d9..ef65a7a9f 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -131,7 +131,7 @@ void initCamera() if (StereoHMD) { - StereoHMD->initCamera(&Camera); + StereoHMD->initCamera(0, &Camera); } // Create the snowing particle system diff --git a/code/snowballs2/client/src/commands.cpp b/code/snowballs2/client/src/commands.cpp index bd44411e1..e6e7a0086 100644 --- a/code/snowballs2/client/src/commands.cpp +++ b/code/snowballs2/client/src/commands.cpp @@ -388,7 +388,7 @@ void updateCommands() if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 1.f); + StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f); // snap to pixels xshift = ((float)(sint32)(xshift * width)) / width; yshift = ((float)(sint32)(yshift * height)) / height; diff --git a/code/snowballs2/client/src/compass.cpp b/code/snowballs2/client/src/compass.cpp index 285ba3bdc..e01173f66 100644 --- a/code/snowballs2/client/src/compass.cpp +++ b/code/snowballs2/client/src/compass.cpp @@ -98,7 +98,7 @@ void updateCompass () if (StereoHMD) { float xshift, yshift; - StereoHMD->getInterface2DShift(xshift, yshift, 1.f); + StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f); x += xshift; y += yshift; } diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 9563ad774..292465266 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -710,7 +710,7 @@ void loopIngame() // 09. Update Camera (depends on entities) updateCamera(); - if (StereoHMD) StereoHMD->updateCamera(&Camera); + if (StereoHMD) StereoHMD->updateCamera(0, &Camera); // 10. Update Interface (login, ui, etc) // ... @@ -741,9 +741,9 @@ void loopIngame() Driver->setViewport(vp); Scene->setViewport(vp); SkyScene->setViewport(vp); - StereoHMD->getCurrentFrustum(&Camera); - StereoHMD->getCurrentFrustum(&SkyCamera); - StereoHMD->getCurrentMatrix(&Camera); + StereoHMD->getCurrentFrustum(0, &Camera); + StereoHMD->getCurrentFrustum(0, &SkyCamera); + StereoHMD->getCurrentMatrix(0, &Camera); } if (!StereoHMD || StereoHMD->beginClear())