Skip to content

Commit

Permalink
Client|Renderer|Stereo 3D: Remove global VR::mode variable, in favor …
Browse files Browse the repository at this point in the history
…of Con_GetInteger("rend-vr-mode")

Adjust link libraries for Win32 Oculus Rift SDK
Adjust comments in vr.h
  • Loading branch information
cmbruns committed Oct 27, 2013
1 parent 929d325 commit f33ee6a
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 26 deletions.
45 changes: 28 additions & 17 deletions doomsday/client/include/render/vr.h
Expand Up @@ -3,8 +3,10 @@

namespace VR {

// The order shown here determines the integer value in the console.
/// @todo - Should rend-vr-mode console variable be a string instead of an int, for better semantics (but decreased discoverability)?
/// Menu of stereoscopic 3D modes available. Oculus Rift is the star player, but there
/// are many other options.
/// The order shown here determines the integer value in the console.
/// @todo - Add an additional console command to support symbolic versions of these mode settings
enum Stereo3DMode {
MODE_MONO = 0,
MODE_GREEN_MAGENTA,
Expand All @@ -16,23 +18,19 @@ enum Stereo3DMode {
MODE_PARALLEL,
MODE_CROSSEYE,
MODE_OCULUS_RIFT,
MODE_ROW_INTERLEAVED, // 10
MODE_COLUMN_INTERLEAVED,
MODE_CHECKERBOARD,
MODE_ROW_INTERLEAVED, // 10 // NOT IMPLEMENTED YET
MODE_COLUMN_INTERLEAVED, // NOT IMPLEMENTED YET
MODE_CHECKERBOARD, // NOT IMPLEMENTED YET
MODE_QUAD_BUFFERED,
//
MODE_MAX_3D_MODE_PLUS_ONE
};

// Console variables

// Console variables
extern int mode;
// Interpupillary distance in meters
extern float ipd;
extern float playerHeight;
extern float dominantEye;
extern byte swapEyes;
extern float ipd; /// Interpupillary distance in meters
extern float playerHeight; /// Human player's real world height in meters
extern float dominantEye; /// Kludge for aim-down-weapon-sight modes
extern byte swapEyes; /// When true, inverts stereoscopic effect

// Variables below are global, but not user visible //

Expand All @@ -41,17 +39,30 @@ extern byte swapEyes;
extern bool applyFrustumShift;

// local viewpoint relative eye position in map units,
// vr::eyeshift is ordinarily set from vr::setEyeView()
// VR::eyeShift is ordinarily set from VR::getEyeShift()
extern float eyeShift;

extern float hudDistance; // in map units
extern float weaponDistance; // in map units
extern float hudDistance; // Distance from player character to screen, in map units (not used in Rift mode, because it's used by frustum shift)
extern float weaponDistance; // (UNUSED) Distance from player character to weapon sprite, in map units

// -1 means left eye, +1 means right eye
/// @param eye: -1 means left eye, +1 means right eye
/// @return viewpoint eye shift in map units
float getEyeShift(float eye);

// Register console variables
void consoleRegister();

// Head tracking API

// True if Oculus Rift is enabled and can report head orientation.
bool hasHeadOrientation();

// Returns current pitch, roll, yaw angles, in radians, or empty vector if head tracking is not available.
std::vector<float> getHeadOrientation();

// To release memory and resources when done, for tidiness.
void deleteOculusTracker();

} // namespace VR

#endif // CLIENT_RENDER_VR_H
124 changes: 120 additions & 4 deletions doomsday/client/src/render/vr.cpp
Expand Up @@ -3,21 +3,23 @@


// Console variables
int VR::mode = 0;
static int vrMode = 0;
// Interpupillary distance in meters
float VR::ipd = 0.0622f;
float VR::playerHeight = 1.70f;
float VR::dominantEye = 0.0f;
byte VR::swapEyes = 0;


// Global variables
bool VR::applyFrustumShift = true;
float VR::eyeShift = 0;
float VR::hudDistance = 30.0f;
float VR::weaponDistance = 10.0f;

// eye: -1 means left eye, +1 means right eye
// Returns viewpoint eye shift in map units

/// @param eye: -1 means left eye, +1 means right eye
/// @return viewpoint eye shift in map units
float VR::getEyeShift(float eye)
{
// 0.95 because eyes are not at top of head
Expand All @@ -43,5 +45,119 @@ void VR::consoleRegister()
C_VAR_FLOAT ("rend-vr-player-height", & VR::playerHeight, 0, 1.0f, 3.0f);
C_VAR_FLOAT ("rend-vr-dominant-eye", & VR::dominantEye, 0, -1.0f, 1.0f);
C_VAR_BYTE ("rend-vr-swap-eyes", & VR::swapEyes, 0, 0, 1);
C_VAR_INT2 ("rend-vr-mode", & VR::mode, 0, 0, (int)(VR::MODE_MAX_3D_MODE_PLUS_ONE - 1), vrModeChanged);
C_VAR_INT2 ("rend-vr-mode", & vrMode, 0, 0, (int)(VR::MODE_MAX_3D_MODE_PLUS_ONE - 1), vrModeChanged);
}


// Head tracking

#ifdef DENG_HAVE_OCULUS_API
#include "OVR.h"

class OculusTracker {
public:
OculusTracker()
: pitch(0)
, roll(0)
, yaw(0)
{
OVR::System::Init();
pFusionResult = new OVR::SensorFusion();
pManager = *OVR::DeviceManager::Create();
pHMD = *pManager->EnumerateDevices<OVR::HMDDevice>().CreateDevice();
if(pHMD)
{
InfoLoaded = pHMD->GetDeviceInfo(&Info);
pSensor = pHMD->GetSensor();
}
else
{
pSensor = *pManager->EnumerateDevices<OVR::SensorDevice>().CreateDevice();
}

if (pSensor)
{
pFusionResult->AttachToSensor(pSensor);
}
}

~OculusTracker()
{
pSensor.Clear();
pHMD.Clear();
pManager.Clear();
delete pFusionResult;
OVR::System::Destroy();
}

const OVR::HMDInfo& getInfo() const {
return Info;
}

bool isGood() const {
return pSensor.GetPtr() != NULL;
}

void update()
{
OVR::Quatf quaternion = pFusionResult->GetOrientation();
quaternion.GetEulerAngles<OVR::Axis_Y, OVR::Axis_X, OVR::Axis_Z>(&yaw, &pitch, &roll);
}

// Head orientation state, refreshed by call to update();
float pitch, roll, yaw;

private:
OVR::Ptr<OVR::DeviceManager> pManager;
OVR::Ptr<OVR::HMDDevice> pHMD;
OVR::Ptr<OVR::SensorDevice> pSensor;
OVR::SensorFusion* pFusionResult;
OVR::HMDInfo Info;
bool InfoLoaded;
};

static OculusTracker* oculusTracker = NULL;
#endif

// True if Oculus Rift is enabled and can report head orientation.
bool VR::hasHeadOrientation()
{
#ifdef DENG_HAVE_OCULUS_API
if (oculusTracker == NULL)
oculusTracker = new OculusTracker();
return oculusTracker->isGood();
#else
// No API; No head tracking.
return false;
#endif
}

// Returns current pitch, roll, yaw angles, in radians
std::vector<float> VR::getHeadOrientation()
{
std::vector<float> result;
#ifdef DENG_HAVE_OCULUS_API
if (! VR::hasHeadOrientation())
return result; // empty vector
oculusTracker->update();
result.push_back(oculusTracker->pitch);
result.push_back(oculusTracker->roll);
result.push_back(oculusTracker->yaw);
return result;
#else
// No API; Return empty vector. You should have called VR::hasHeadOrientation() first...
return result;
#endif
}

// To release memory and resources when done, for tidiness.
void VR::deleteOculusTracker()
{
#ifdef DENG_HAVE_OCULUS_API
if (oculusTracker != NULL)
{
delete oculusTracker;
oculusTracker = NULL;
}
#endif
}
6 changes: 3 additions & 3 deletions doomsday/client/src/ui/clientwindow.cpp
Expand Up @@ -278,7 +278,7 @@ DENG2_OBSERVES(App, GameChange)
{
MouseEvent ev = event;

switch(VR::mode)
switch(Con_GetInteger("rend-vr-mode"))
{
// Left-right screen split modes
case VR::MODE_SIDE_BY_SIDE:
Expand Down Expand Up @@ -552,7 +552,7 @@ void ClientWindow::canvasGLDraw(Canvas &canvas)
DENG_ASSERT_IN_MAIN_THREAD();
DENG_ASSERT_GL_CONTEXT_ACTIVE();

switch(VR::mode)
switch(Con_GetInteger("rend-vr-mode"))
{
// A) Single view type stereo 3D modes here:
case VR::MODE_MONO:
Expand Down Expand Up @@ -853,7 +853,7 @@ void ClientWindow::updateRootSize()
{
Canvas::Size size = canvas().size();

switch(VR::mode)
switch(Con_GetInteger("rend-vr-mode"))
{
// Left-right screen split modes
case VR::MODE_CROSSEYE:
Expand Down
5 changes: 3 additions & 2 deletions doomsday/dep_rift.pri
Expand Up @@ -4,9 +4,10 @@ exists($${LIBOVR_DIR}/Include/OVR.h) {
INCLUDEPATH += $${LIBOVR_DIR}/Include
# TODO - LIBS statement for Mac, Linux
win32:LIBS += $${LIBOVR_DIR}/Lib/Win32/libovr.lib
DEFINES += HAVE_OCULUS_API
# Additional windows libraries needed to avoid link errors when using Rift
win32:LIBS += shell32.lib winmm.lib
DEFINES += DENG_HAVE_OCULUS_API
# message("Found Oculus Rift SDK")
} else {
# message("Oculus Rift SDK not found")
}

0 comments on commit f33ee6a

Please sign in to comment.