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;
#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;

View file

@ -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);

View file

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

View file

@ -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;

View file

@ -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;
}

View file

@ -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())