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;
|
||||
|
||||
#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<CStereoDeviceInfo> &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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -131,7 +131,7 @@ void initCamera()
|
|||
|
||||
if (StereoHMD)
|
||||
{
|
||||
StereoHMD->initCamera(&Camera);
|
||||
StereoHMD->initCamera(0, &Camera);
|
||||
}
|
||||
|
||||
// Create the snowing particle system
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in a new issue