RiftSdk.cc 3.58 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#include <ACGL/HardwareSupport/RiftSdk.hh>
#include <ACGL/OpenGL/Creator/ShaderProgramCreator.hh>

#include <iostream>

#include <ACGL/Utils/Log.hh>

#ifdef ACGL_USE_OCULUS_RIFT
#if ACGL_RIFT_SDK_VERSION >= 32

namespace ACGL{
namespace HardwareSupport{

	using namespace std;
	using namespace ACGL::Utils;

	// C API helpers:

	static bool ACGL_RiftSDKInitialized = false;

	bool initRiftSDK()
	{
		if (ACGL_RiftSDKInitialized) return true; // don't init twice

		ovrBool ok = ovr_Initialize();
		if (!ok) {
			error() << "could not initialize Oculus Rift library" << endl;
		}
		else {
			ACGL_RiftSDKInitialized = true;
		}
		return ACGL_RiftSDKInitialized;
	}

	void shutdownRiftSDK()
	{
		ovr_Shutdown();
	}

	// For more sophisticated use cases build your own Rift for your needs based on the Rift SDK instead of using this default Rift.
	//
	// _headTrackingIsRequired           = if false, the call will create a dummy device that won't generate any data in case no real Rift is connected
	//                                     (for developing without an actual device).
	// _headTranslationTrackingIsAllowed = if true the Tracking of DK2 will get supported, if false even a DK2 will behave like a DK1
	ovrHmd createRift(bool _headTrackingIsRequired, bool _headTranslationTrackingIsAllowed)
	{
		if (!ACGL_RiftSDKInitialized) {
			error() << "Rift SDK not initialized correctly - did you call/check initRiftSDK()?" << endl;
		}

		ovrHmd mHmd = ovrHmd_Create(0);
		if (!mHmd && _headTrackingIsRequired) {
			error() << "could not connect to an Oculus Rift HMD" << endl;
			return NULL;
		}
		else if (!mHmd && !_headTrackingIsRequired) {
57 58 59 60 61 62 63 64 65 66

#if ACGL_RIFT_USE_DUMMY
            warning() << "could not connect to a real Oculus Rift HMD - generating sensorless dummy" << endl;
            mHmd = ovrHmd_CreateDebug(ovrHmd_DK1);
#else
            debug() << "could not connect to a real Oculus Rift HMD" << endl;
            mHmd = NULL;
#endif

            return mHmd;
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
		}

		ovrHmdDesc mHmdDesc;
		ovrHmd_GetDesc(mHmd, &mHmdDesc);

		// debug output:
		debug() << "Connected to: " << mHmdDesc.ProductName << endl;

		// start the tracking:
		// what the application supports:
		unsigned int supportedCaps = ovrSensorCap_Orientation | ovrSensorCap_YawCorrection | ovrHmdCap_LowPersistence | ovrHmdCap_LatencyTest | ovrHmdCap_DynamicPrediction;
		if (_headTranslationTrackingIsAllowed) supportedCaps |= ovrSensorCap_Position;

		// what the device must deliver as a bare minimum:
		unsigned int requiredCaps = 0;
		if (_headTrackingIsRequired) requiredCaps |= ovrSensorCap_Orientation;
		ovrBool ok = ovrHmd_StartSensor(mHmd, supportedCaps, requiredCaps);
		if (!ok) {
			error() << "could not get connected to a Rift tracker - only rendering is supported" << endl;
		}

		return mHmd;
	}

	void destroyRift(ovrHmd _hmd)
	{
		ovrHmd_Destroy(_hmd);
	}


	glm::uvec2 getOptimalRenderSizePerEye(ovrHmd _hmd)
	{
		if (_hmd == NULL) return glm::uvec2(640, 800);
		ovrHmdDesc hmdDesc;
		ovrHmd_GetDesc(_hmd, &hmdDesc);
		ovrSizei optimalLeft = ovrHmd_GetFovTextureSize(_hmd, ovrEye_Left, hmdDesc.DefaultEyeFov[0], 1.0f);
		ovrSizei optimalRight = ovrHmd_GetFovTextureSize(_hmd, ovrEye_Right, hmdDesc.DefaultEyeFov[1], 1.0f);

		debug() << "optimalLeft  " << optimalLeft.w << " " << optimalLeft.h << endl;
		debug() << "optimalRight " << optimalRight.w << " " << optimalRight.h << endl;

		debug() << "hmd: " << hmdDesc.ProductName << endl;
		debug() << "hmd WindowsPos: " << hmdDesc.WindowsPos.x << " " << hmdDesc.WindowsPos.y << endl;

		return glm::uvec2(glm::max(optimalLeft.w, optimalRight.w), glm::max(optimalLeft.h, optimalRight.h));
	}
}
}

#endif
117
#endif