Allow multiple user cameras to be calculated separately, useful for sky etc, re #43

This commit is contained in:
kaetemi 2013-06-26 20:57:37 +02:00
parent 4a579d0af2
commit 2f4867ab78
6 changed files with 41 additions and 39 deletions

View file

@ -72,6 +72,8 @@ public:
class CStereoOVRDevicePtr; class CStereoOVRDevicePtr;
#define NL_STEREO_MAX_USER_CAMERAS 8
/** /**
* \brief CStereoOVR * \brief CStereoOVR
* \date 2013-06-25 22:22GMT * \date 2013-06-25 22:22GMT
@ -88,18 +90,18 @@ public:
/// Gets the required screen resolution for this device /// Gets the required screen resolution for this device
virtual void getScreenResolution(uint &width, uint &height); virtual void getScreenResolution(uint &width, uint &height);
/// Set latest camera position etcetera /// 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 /// Is there a next pass
virtual bool nextPass(); virtual bool nextPass();
/// Gets the current viewport /// Gets the current viewport
virtual const NL3D::CViewport &getCurrentViewport() const; virtual const NL3D::CViewport &getCurrentViewport() const;
/// Gets the current camera frustum /// Gets the current camera frustum
virtual const NL3D::CFrustum &getCurrentFrustum() const; virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const;
/// Gets the current camera frustum /// 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 /// 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 /// At the start of a new render target
virtual bool beginClear(); virtual bool beginClear();
@ -122,7 +124,7 @@ public:
/// Get the HMD orientation /// Get the HMD orientation
virtual NLMISC::CQuat getOrientation() const; virtual NLMISC::CQuat getOrientation() const;
/// Get GUI center (1 = width, 1 = height, 0 = center) /// 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<CStereoDeviceInfo> &devicesOut); static void listDevices(std::vector<CStereoDeviceInfo> &devicesOut);
@ -132,7 +134,7 @@ public:
/// Calculates internal camera information based on the reference camera /// 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(); bool isDeviceCreated();
@ -141,9 +143,9 @@ private:
int m_Stage; int m_Stage;
CViewport m_LeftViewport; CViewport m_LeftViewport;
CViewport m_RightViewport; CViewport m_RightViewport;
CFrustum m_LeftFrustum; CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS];
CFrustum m_RightFrustum; CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS];
CMatrix m_CameraMatrix; CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS];
mutable bool m_OrientationCached; mutable bool m_OrientationCached;
mutable NLMISC::CQuat m_OrientationCache; mutable NLMISC::CQuat m_OrientationCache;

View file

@ -204,29 +204,29 @@ void CStereoOVR::getScreenResolution(uint &width, uint &height)
height = m_DevicePtr->HMDInfo.VResolution; 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 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); 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_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far);
m_RightFrustum = m_LeftFrustum; m_RightFrustum[cid] = m_LeftFrustum[cid];
float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f;
float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f;
float projectionCenterOffset = 4.0f * eyeProjectionShift / m_DevicePtr->HMDInfo.HScreenSize; float projectionCenterOffset = 4.0f * eyeProjectionShift / m_DevicePtr->HMDInfo.HScreenSize;
nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset);
projectionCenterOffset *= (m_LeftFrustum.Left - m_LeftFrustum.Right) * 0.5f; // made this up ... projectionCenterOffset *= (m_LeftFrustum[cid].Left - m_LeftFrustum[cid].Right) * 0.5f; // made this up ...
m_LeftFrustum.Left += projectionCenterOffset; m_LeftFrustum[cid].Left += projectionCenterOffset;
m_LeftFrustum.Right += projectionCenterOffset; m_LeftFrustum[cid].Right += projectionCenterOffset;
m_RightFrustum.Left -= projectionCenterOffset; m_RightFrustum[cid].Left -= projectionCenterOffset;
m_RightFrustum.Right -= 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 if (camera->getFrustum().Near != m_LeftFrustum[cid].Near
|| camera->getFrustum().Far != m_LeftFrustum.Far) || camera->getFrustum().Far != m_LeftFrustum[cid].Far)
CStereoOVR::initCamera(camera); CStereoOVR::initCamera(cid, camera);
m_CameraMatrix = camera->getMatrix(); m_CameraMatrix[cid] = camera->getMatrix();
} }
bool CStereoOVR::nextPass() bool CStereoOVR::nextPass()
@ -285,25 +285,25 @@ const NL3D::CViewport &CStereoOVR::getCurrentViewport() const
else return m_RightViewport; 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; if (m_Stage % 2) return m_LeftFrustum[cid];
else return m_RightFrustum; 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); if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]);
else camera->setFrustum(m_RightFrustum); else camera->setFrustum(m_RightFrustum[cid]);
} }
void CStereoOVR::getCurrentMatrix(NL3D::UCamera *camera) const void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const
{ {
CMatrix translate; CMatrix translate;
if (m_Stage % 2) translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * -0.5f, 0.f, 0.f)); 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)); else translate.translate(CVector(m_DevicePtr->HMDInfo.InterpupillaryDistance * 0.5f, 0.f, 0.f));
camera->setTransformMode(NL3D::UTransformable::DirectMatrix); camera->setTransformMode(NL3D::UTransformable::DirectMatrix);
camera->setMatrix(m_CameraMatrix * translate); camera->setMatrix(m_CameraMatrix[cid] * translate);
} }
bool CStereoOVR::beginClear() bool CStereoOVR::beginClear()
@ -395,7 +395,7 @@ NLMISC::CQuat CStereoOVR::getOrientation() const
} }
/// Get GUI shift /// 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 #if 0
@ -437,7 +437,7 @@ void CStereoOVR::getInterface2DShift(float &x, float &y, float distance)
CVector rotshift = CVector(p, 0.f, t) * -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); x = (proj.x - 0.5f);
y = (proj.y - 0.5f); y = (proj.y - 0.5f);

View file

@ -131,7 +131,7 @@ void initCamera()
if (StereoHMD) if (StereoHMD)
{ {
StereoHMD->initCamera(&Camera); StereoHMD->initCamera(0, &Camera);
} }
// Create the snowing particle system // Create the snowing particle system

View file

@ -388,7 +388,7 @@ void updateCommands()
if (StereoHMD) if (StereoHMD)
{ {
float xshift, yshift; float xshift, yshift;
StereoHMD->getInterface2DShift(xshift, yshift, 1.f); StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f);
// snap to pixels // snap to pixels
xshift = ((float)(sint32)(xshift * width)) / width; xshift = ((float)(sint32)(xshift * width)) / width;
yshift = ((float)(sint32)(yshift * height)) / height; yshift = ((float)(sint32)(yshift * height)) / height;

View file

@ -98,7 +98,7 @@ void updateCompass ()
if (StereoHMD) if (StereoHMD)
{ {
float xshift, yshift; float xshift, yshift;
StereoHMD->getInterface2DShift(xshift, yshift, 1.f); StereoHMD->getInterface2DShift(0, xshift, yshift, 1.f);
x += xshift; x += xshift;
y += yshift; y += yshift;
} }

View file

@ -710,7 +710,7 @@ void loopIngame()
// 09. Update Camera (depends on entities) // 09. Update Camera (depends on entities)
updateCamera(); updateCamera();
if (StereoHMD) StereoHMD->updateCamera(&Camera); if (StereoHMD) StereoHMD->updateCamera(0, &Camera);
// 10. Update Interface (login, ui, etc) // 10. Update Interface (login, ui, etc)
// ... // ...
@ -741,9 +741,9 @@ void loopIngame()
Driver->setViewport(vp); Driver->setViewport(vp);
Scene->setViewport(vp); Scene->setViewport(vp);
SkyScene->setViewport(vp); SkyScene->setViewport(vp);
StereoHMD->getCurrentFrustum(&Camera); StereoHMD->getCurrentFrustum(0, &Camera);
StereoHMD->getCurrentFrustum(&SkyCamera); StereoHMD->getCurrentFrustum(0, &SkyCamera);
StereoHMD->getCurrentMatrix(&Camera); StereoHMD->getCurrentMatrix(0, &Camera);
} }
if (!StereoHMD || StereoHMD->beginClear()) if (!StereoHMD || StereoHMD->beginClear())