Allow multiple user cameras to be calculated separately, useful for sky etc, re #43
This commit is contained in:
parent
4a579d0af2
commit
2f4867ab78
6 changed files with 41 additions and 39 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Reference in a new issue