Commit fdc6494d authored by Robert Menzel's avatar Robert Menzel

added SimpleRiftController

parent c8d60cf8
/**
*
* Includes the Oculus Rift LibOVR but tries to suppress as much compiler warnings
* as possible.
*
*/
#ifdef ACGL_USE_OCULUS_RIFT
/////////////////////////////////////////////////////////////////////////////////////
// ignore compiler warnings from LibOVR:
//
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning ( disable : 4201 )
#pragma warning ( disable : 4100 )
#pragma warning ( disable : 4996 )
#pragma warning ( disable : 4244 )
#endif
#if (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4))
#define COMPILER_IS_GCC_4_6_OR_NEWER
#endif
#ifdef __clang__
// clang/llvm:
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wuninitialized"
# pragma clang diagnostic ignored "-Wunused-parameter"
#elif defined __GNUC__
# ifdef COMPILER_IS_GCC_4_6_OR_NEWER
// gcc >= 4.6:
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wtype-limits"
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
# pragma GCC diagnostic ignored "-Wattributes"
# pragma GCC diagnostic ignored "-Wreorder"
# endif
// gcc:
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
//
/////////////////////////////////////////////////////////////////////////////////////
#include <OVR.h>
#include <OVRVersion.h>
/////////////////////////////////////////////////////////////////////////////////////
// reactivate compiler warnings:
//
#ifdef __clang__
// clang/llvm:
# pragma clang diagnostic pop
#elif defined COMPILER_IS_GCC_4_6_OR_NEWER
// gcc >= 4.6:
# pragma GCC diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning( pop )
#endif
//
/////////////////////////////////////////////////////////////////////////////////////
#endif // ACGL_USE_OCULUS_RIFT
#pragma once
/**
* IMPORTANT:
*
* This class needs the LibOVR version 0.2.4 or higher to work.
* Headers of this lib need to be placed in the search path.
*
* In addition ACGL_USE_OCULUS_RIFT has to be defined.
*
*/
#include <ACGL/ACGL.hh>
#ifdef ACGL_USE_OCULUS_RIFT
#include <ACGL/Math/Math.hh>
#include <ACGL/Scene/HMDCamera.hh>
#include <ACGL/OpenGL/Objects/Texture.hh>
#include <ACGL/OpenGL/Managers.hh>
#include <ACGL/HardwareSupport/OVRWrapper.hh>
namespace ACGL{
namespace HardwareSupport{
/**
* This class provides access to the Oculus Rift. It can read out the orientation and control a HMDCamera
* based on this.
* Distorted rendering is provided in two ways:
* * renderDistorted( texture ) if the input is one side-by-side rendered image
* * renderDistorted( texture, texture ) if the input are two seperate textures for the both eyes
*
* Alternatively the application can implement the distortion on its own (e.g. to add other effects in the
* same pass). For this the needed parameters are provided.
*
* Use the camera provided by this class (getCamera) or provide your own (attachCamera).
* This class needs to use a HMDCamera which is derived from GenericCamera!
*/
class SimpleRiftController
{
public:
/**
* _riftnumber: which device to use in case multiple are attached
* _performAutomaticMagneticCalibration: try to calibrate the magetometer to reduce drift
* the user has to look into at least four very different directions
* for this to work.
*/
SimpleRiftController( uint32_t _riftnumber = 0, bool _performAutomaticMagneticCalibration = true );
~SimpleRiftController();
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Camera and sensor handling:
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! attach an external camera to manipulate (see updateCamera)
//! per default the SimpleRiftController already has a camera which can be used as well
//! only one camera can be attached at all times
void attachCamera( ACGL::Scene::SharedHMDCamera _camera );
ACGL::Scene::SharedHMDCamera getCamera() { return mCamera; }
//! Query the orientation of the Rift and set it as the cameras orientation.
//! This will do nothing if no Rift is attached (so the camera can get controlled
//! e.g. by a mouse)!
void updateCamera();
//! returns the current orientation as a rotation matrix from the device.
//! this can be used as an alternative to updateCamera if the attached camera should not be used.
glm::mat3 getCurrentRotation();
//! start the automatic calibration process, by default this is done in the constructor
void startMagneticCalibration();
//! delete the calibration data and work uncalibrated. A new calibration can be started if wanted
void deactivateMagneticDriftCorrection();
//! check if the calibration worked
bool magneticCalibrationDone();
//! sets the amound of seconds to predict the headmovements into the future
//! default is 0.03f, should be no more than the rendering latency!
void setPrediction( float _seconds );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// RAW parameters for distortion rendering:
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! Default is 1.0, larger values result in higher FoVs and larger areas of the Rift being used.
//! Note that - depending on the lenses used - the user will not be able to see the whole screen.
//! Often 1.75 is enough.
//! Increase the offscreen rendering viewport accordingly to counter the decreased image quality.
void setDistortionScaleFactor( float _f );
float getDistortionScaleFactor() { return mDistortionScaleFactor; }
//! x,y are the values for the left eye. z,w the values for the right eye
glm::vec4 getLensCenter();
//! x,y are the values for the left eye. z,w the values for the right eye
glm::vec4 getScreenCenter();
//! x,y are the values for both eyes, ignore z,w
glm::vec4 getScale();
//! x,y are the values for both eyes, ignore z,w
glm::vec4 getScaleIn();
//! the four distortion parameters are the same for both eyes
glm::vec4 getHmdWarpParam();
//! the four chromatic aberation parameters are the same for both eyes
glm::vec4 getChromAbParam();
//! the full physical screen resolution, offscreen rendering should get performed at a higher resolution!
//! 'full' means it's the size used fpr both eyes!
glm::uvec2 getPhysicalScreenResolution();
//! returns the stereo projection from the stored camera adjusted for the rift
//! returns nonsens in case no camera was set
glm::mat4 getProjectionMatrixFromCamera();
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Optional integrated distortion rendering:
//
// If it's activated and used, make sure the RiftDistort* shader files are located where the
// ShaderProgramFileManager can find them.
// They may set texture units 0..3 and render to Framebuffer 0 (which will get bound) using the viewport of the
// physical dimensions of the rift!
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void renderDistorted( ACGL::OpenGL::ConstSharedTexture2D _sideBySideTexture );
void renderDistorted( ACGL::OpenGL::ConstSharedTexture2D _leftTexture, ACGL::OpenGL::ConstSharedTexture2D _rightTexture );
void renderDistorted( ACGL::OpenGL::ConstSharedShaderProgram _program );
bool getSuccessfulConnected() { return mSuccessfulConnected; }
//! activate and deactivate the distortion, only works if the renderers above are used, does not change the raw
//! distortion parameters!
void setDistortion( bool _value ) { mUseDistortion = _value; }
bool getDistortion() { return mUseDistortion; }
//! activate and deactivate the chromatic aberation correction (true to correct the aberation), only works if the renderers
//! above are used, does not change the raw distortion parameters!
void setChromaticAberation( bool _value ) { mUseChromaticAberation = _value; }
bool getChromaticAberation() { return mUseChromaticAberation; }
//! Sets the size of the final rendering. This should be the size of the window to render into.
void setOutputViewportSize( glm::uvec2 _size ) { mOutputViewport = _size; }
//! Defines that the current HMD orientations should be defined as "no rotation"
//! Can be used to "reset" the orientation.
//! Note: if the user is just looking in the wrong direction, use setNeutralYaw(), if e.g. looking up should be
//! neutral (laying on the ground), this is the way to go.
void setNeutralPosition();
//! Will define the current view direction as the neutral direction but only takes yaw into account.
//! Will also reset the neutral position.
//! Basically works as if the Rift was started in the current orientation
void setNeutralYaw();
private:
ACGL::OpenGL::ConstSharedShaderProgram mDistortShaderSideBySide;
ACGL::OpenGL::ConstSharedShaderProgram mDistortShaderTwoTextures;
bool mUseDistortion;
bool mUseChromaticAberation;
glm::uvec2 mOutputViewport; // if it's 0,0 -> use the Rifts screen dimensions!
private:
glm::vec4 getShaderValue( int v );
void updateCameraFoV();
bool mSuccessfulConnected;
ACGL::Scene::SharedHMDCamera mCamera;
float mDistortionScaleFactor;
// handles to the rift:
OVR::Ptr<OVR::DeviceManager> mORManager;
OVR::Ptr<OVR::HMDDevice> mORDevice;
OVR::Ptr<OVR::SensorDevice> mORSensor;
OVR::SensorFusion mORSensorFusion;
OVR::HMDInfo mORHMDInfo;
OVR::Util::MagCalibration mMagneticCalibration;
// all rotations are relative to the one the Rift started with:
OVR::Quatf mInverseNeutralRotation; // as quaternion
float mPredictionTime;
};
}
}
#endif // ACGL_USE_OCULUS_RIFT
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment