mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Oculus VR (Rift) support
Input device and shaders for supporting the Oculus Rift.
This commit is contained in:
parent
2123365d4d
commit
de7a72d82a
|
|
@ -0,0 +1,188 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/input/oculusVR/barrelDistortionPostEffect.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "platform/input/oculusVR/oculusVRDevice.h"
|
||||
|
||||
extern bool gEditingMission;
|
||||
|
||||
ConsoleDocClass( BarrelDistortionPostEffect,
|
||||
"@brief A fullscreen shader effect used with the Oculus Rift.\n\n"
|
||||
|
||||
"@section PFXTextureIdentifiers\n\n"
|
||||
|
||||
"@ingroup Rendering\n"
|
||||
);
|
||||
|
||||
IMPLEMENT_CONOBJECT(BarrelDistortionPostEffect);
|
||||
|
||||
BarrelDistortionPostEffect::BarrelDistortionPostEffect()
|
||||
: PostEffect(),
|
||||
mHmdWarpParamSC(NULL),
|
||||
mScaleSC(NULL),
|
||||
mScaleInSC(NULL),
|
||||
mLensCenterSC(NULL),
|
||||
mScreenCenterSC(NULL)
|
||||
{
|
||||
mHMDIndex = 0;
|
||||
mSensorIndex = 0;
|
||||
mScaleOutput = 1.0f;
|
||||
}
|
||||
|
||||
BarrelDistortionPostEffect::~BarrelDistortionPostEffect()
|
||||
{
|
||||
}
|
||||
|
||||
void BarrelDistortionPostEffect::initPersistFields()
|
||||
{
|
||||
addField( "hmdIndex", TypeS32, Offset( mHMDIndex, BarrelDistortionPostEffect ),
|
||||
"Oculus VR HMD index to reference." );
|
||||
|
||||
addField( "sensorIndex", TypeS32, Offset( mSensorIndex, BarrelDistortionPostEffect ),
|
||||
"Oculus VR sensor index to reference." );
|
||||
|
||||
addField( "scaleOutput", TypeF32, Offset( mScaleOutput, BarrelDistortionPostEffect ),
|
||||
"Used to increase the size of the window into the world at the expense of apparent resolution." );
|
||||
|
||||
Parent::initPersistFields();
|
||||
}
|
||||
|
||||
bool BarrelDistortionPostEffect::onAdd()
|
||||
{
|
||||
if( !Parent::onAdd() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BarrelDistortionPostEffect::onRemove()
|
||||
{
|
||||
Parent::onRemove();
|
||||
}
|
||||
|
||||
void BarrelDistortionPostEffect::_setupConstants( const SceneRenderState *state )
|
||||
{
|
||||
Parent::_setupConstants(state);
|
||||
|
||||
// Define the shader constants
|
||||
if(!mHmdWarpParamSC)
|
||||
mHmdWarpParamSC = mShader->getShaderConstHandle( "$HmdWarpParam" );
|
||||
|
||||
if(!mScaleSC)
|
||||
mScaleSC = mShader->getShaderConstHandle( "$Scale" );
|
||||
|
||||
if(!mScaleInSC)
|
||||
mScaleInSC = mShader->getShaderConstHandle( "$ScaleIn" );
|
||||
|
||||
if(!mLensCenterSC)
|
||||
mLensCenterSC = mShader->getShaderConstHandle( "$LensCenter" );
|
||||
|
||||
if(!mScreenCenterSC)
|
||||
mScreenCenterSC = mShader->getShaderConstHandle( "$ScreenCenter" );
|
||||
|
||||
const Point2I &resolution = GFX->getActiveRenderTarget()->getSize();
|
||||
F32 widthScale = 0.5f;
|
||||
F32 heightScale = 1.0f;
|
||||
F32 aspectRatio = (resolution.x * 0.5f) / resolution.y;
|
||||
|
||||
// Set up the HMD dependant shader constants
|
||||
if(ManagedSingleton<OculusVRDevice>::instanceOrNull() && OCULUSVRDEV->getHMDDevice(mHMDIndex))
|
||||
{
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(mHMDIndex);
|
||||
|
||||
if(mHmdWarpParamSC->isValid())
|
||||
{
|
||||
const Point4F& distortion = hmd->getKDistortion();
|
||||
mShaderConsts->set( mHmdWarpParamSC, distortion );
|
||||
}
|
||||
|
||||
if(mScaleSC->isValid())
|
||||
{
|
||||
F32 scaleFactor = hmd->getDistortionScale();
|
||||
if(!mIsZero(mScaleOutput))
|
||||
{
|
||||
scaleFactor /= mScaleOutput;
|
||||
}
|
||||
Point2F scale;
|
||||
scale.x = widthScale * 0.5f * scaleFactor;
|
||||
scale.y = heightScale * 0.5f * scaleFactor * aspectRatio;
|
||||
mShaderConsts->set( mScaleSC, scale );
|
||||
}
|
||||
|
||||
if(mLensCenterSC->isValid())
|
||||
{
|
||||
F32 xCenterOffset = hmd->getCenterOffset();
|
||||
Point3F lensCenter;
|
||||
lensCenter.x = (widthScale + xCenterOffset * 0.5f) * 0.5f;
|
||||
lensCenter.y = (widthScale - xCenterOffset * 0.5f) * 0.5f;
|
||||
lensCenter.z = heightScale * 0.5f;
|
||||
mShaderConsts->set( mLensCenterSC, lensCenter );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mHmdWarpParamSC->isValid())
|
||||
{
|
||||
mShaderConsts->set( mHmdWarpParamSC, Point4F(0.0f, 0.0f, 0.0f, 0.0f) );
|
||||
}
|
||||
|
||||
if(mScaleSC->isValid())
|
||||
{
|
||||
mShaderConsts->set( mScaleSC, Point2F(1.0f, 1.0f) );
|
||||
}
|
||||
|
||||
if(mLensCenterSC->isValid())
|
||||
{
|
||||
Point3F lensCenter;
|
||||
lensCenter.x = widthScale * 0.5f;
|
||||
lensCenter.y = widthScale * 0.5f;
|
||||
lensCenter.z = heightScale * 0.5f;
|
||||
mShaderConsts->set( mLensCenterSC, lensCenter );
|
||||
}
|
||||
}
|
||||
|
||||
if(mScaleInSC->isValid())
|
||||
{
|
||||
Point2F scaleIn;
|
||||
scaleIn.x = 2.0f / widthScale;
|
||||
scaleIn.y = 2.0f / heightScale / aspectRatio;
|
||||
mShaderConsts->set( mScaleInSC, scaleIn );
|
||||
}
|
||||
|
||||
if(mScreenCenterSC->isValid())
|
||||
{
|
||||
mShaderConsts->set( mScreenCenterSC, Point2F(widthScale * 0.5f, heightScale * 0.5f) );
|
||||
}
|
||||
}
|
||||
|
||||
void BarrelDistortionPostEffect::process(const SceneRenderState *state, GFXTexHandle &inOutTex, const RectI *inTexViewport)
|
||||
{
|
||||
// Don't draw the post effect if the editor is active
|
||||
if(gEditingMission)
|
||||
return;
|
||||
|
||||
Parent::process(state, inOutTex, inTexViewport);
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _BARRELDISTORTIONPOSTEFFECT_H_
|
||||
#define _BARRELDISTORTIONPOSTEFFECT_H_
|
||||
|
||||
#include "postFx/postEffect.h"
|
||||
|
||||
class BarrelDistortionPostEffect : public PostEffect
|
||||
{
|
||||
typedef PostEffect Parent;
|
||||
|
||||
protected:
|
||||
GFXShaderConstHandle *mHmdWarpParamSC;
|
||||
GFXShaderConstHandle *mScaleSC;
|
||||
GFXShaderConstHandle *mScaleInSC;
|
||||
GFXShaderConstHandle *mLensCenterSC;
|
||||
GFXShaderConstHandle *mScreenCenterSC;
|
||||
|
||||
// Oculus VR HMD index to reference
|
||||
S32 mHMDIndex;
|
||||
|
||||
// Oculus VR sensor index to reference
|
||||
S32 mSensorIndex;
|
||||
|
||||
// Used to increase the size of the window into the world at the
|
||||
// expense of apparent resolution.
|
||||
F32 mScaleOutput;
|
||||
|
||||
protected:
|
||||
virtual void _setupConstants( const SceneRenderState *state );
|
||||
|
||||
public:
|
||||
BarrelDistortionPostEffect();
|
||||
virtual ~BarrelDistortionPostEffect();
|
||||
|
||||
DECLARE_CONOBJECT(BarrelDistortionPostEffect);
|
||||
|
||||
// SimObject
|
||||
virtual bool onAdd();
|
||||
virtual void onRemove();
|
||||
static void initPersistFields();
|
||||
|
||||
virtual void process( const SceneRenderState *state,
|
||||
GFXTexHandle &inOutTex,
|
||||
const RectI *inTexViewport = NULL );
|
||||
};
|
||||
|
||||
#endif // _BARRELDISTORTIONPOSTEFFECT_H_
|
||||
34
Engine/source/platform/input/oculusVR/oculusVRConstants.h
Normal file
34
Engine/source/platform/input/oculusVR/oculusVRConstants.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _OCULUSVRCONSTANTS_H_
|
||||
#define _OCULUSVRCONSTANTS_H_
|
||||
|
||||
namespace OculusVRConstants
|
||||
{
|
||||
enum Constants {
|
||||
DefaultOVRBase = 0,
|
||||
MaxSensors = 1,
|
||||
};
|
||||
}
|
||||
|
||||
#endif // _OCULUSVRCONSTANTS_H_
|
||||
844
Engine/source/platform/input/oculusVR/oculusVRDevice.cpp
Normal file
844
Engine/source/platform/input/oculusVR/oculusVRDevice.cpp
Normal file
|
|
@ -0,0 +1,844 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/input/oculusVR/oculusVRDevice.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "core/module.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
|
||||
MODULE_BEGIN( OculusVRDevice )
|
||||
|
||||
MODULE_INIT_AFTER( InputEventManager )
|
||||
MODULE_SHUTDOWN_BEFORE( InputEventManager )
|
||||
|
||||
MODULE_INIT
|
||||
{
|
||||
OculusVRDevice::staticInit();
|
||||
ManagedSingleton< OculusVRDevice >::createSingleton();
|
||||
if(OculusVRDevice::smEnableDevice)
|
||||
{
|
||||
OCULUSVRDEV->enable();
|
||||
}
|
||||
|
||||
// Register the device with the Input Event Manager
|
||||
INPUTMGR->registerDevice(OCULUSVRDEV);
|
||||
}
|
||||
|
||||
MODULE_SHUTDOWN
|
||||
{
|
||||
INPUTMGR->unregisterDevice(OCULUSVRDEV);
|
||||
ManagedSingleton< OculusVRDevice >::deleteSingleton();
|
||||
}
|
||||
|
||||
MODULE_END;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// OculusVRDevice
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool OculusVRDevice::smEnableDevice = true;
|
||||
|
||||
bool OculusVRDevice::smSimulateHMD = true;
|
||||
|
||||
bool OculusVRDevice::smGenerateAngleAxisRotationEvents = true;
|
||||
bool OculusVRDevice::smGenerateEulerRotationEvents = false;
|
||||
|
||||
bool OculusVRDevice::smGenerateRotationAsAxisEvents = false;
|
||||
F32 OculusVRDevice::smMaximumAxisAngle = 25.0f;
|
||||
|
||||
bool OculusVRDevice::smGenerateWholeFrameEvents = false;
|
||||
|
||||
OculusVRDevice::OculusVRDevice()
|
||||
{
|
||||
// From IInputDevice
|
||||
dStrcpy(mName, "oculusvr");
|
||||
mDeviceType = INPUTMGR->getNextDeviceType();
|
||||
|
||||
//
|
||||
mEnabled = false;
|
||||
mActive = false;
|
||||
|
||||
// We don't current support scaling of the input texture. The graphics pipeline will
|
||||
// need to be modified for this.
|
||||
mScaleInputTexture = false;
|
||||
|
||||
mDeviceManager = NULL;
|
||||
mListener = NULL;
|
||||
|
||||
buildCodeTable();
|
||||
}
|
||||
|
||||
OculusVRDevice::~OculusVRDevice()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
void OculusVRDevice::staticInit()
|
||||
{
|
||||
Con::addVariable("pref::OculusVR::EnableDevice", TypeBool, &smEnableDevice,
|
||||
"@brief If true, the Oculus VR device will be enabled, if present.\n\n"
|
||||
"@ingroup Game");
|
||||
|
||||
Con::addVariable("OculusVR::GenerateAngleAxisRotationEvents", TypeBool, &smGenerateAngleAxisRotationEvents,
|
||||
"@brief If true, broadcast sensor rotation events as angled axis.\n\n"
|
||||
"@ingroup Game");
|
||||
Con::addVariable("OculusVR::GenerateEulerRotationEvents", TypeBool, &smGenerateEulerRotationEvents,
|
||||
"@brief If true, broadcast sensor rotation events as Euler angles about the X, Y and Z axis.\n\n"
|
||||
"@ingroup Game");
|
||||
|
||||
Con::addVariable("OculusVR::GenerateRotationAsAxisEvents", TypeBool, &smGenerateRotationAsAxisEvents,
|
||||
"@brief If true, broadcast sensor rotation as axis events.\n\n"
|
||||
"@ingroup Game");
|
||||
Con::addVariable("OculusVR::MaximumAxisAngle", TypeF32, &smMaximumAxisAngle,
|
||||
"@brief The maximum sensor angle when used as an axis event as measured from a vector pointing straight up (in degrees).\n\n"
|
||||
"Should range from 0 to 90 degrees.\n\n"
|
||||
"@ingroup Game");
|
||||
|
||||
Con::addVariable("OculusVR::GenerateWholeFrameEvents", TypeBool, &smGenerateWholeFrameEvents,
|
||||
"@brief Indicates that a whole frame event should be generated and frames should be buffered.\n\n"
|
||||
"@ingroup Game");
|
||||
}
|
||||
|
||||
void OculusVRDevice::cleanUp()
|
||||
{
|
||||
disable();
|
||||
}
|
||||
|
||||
void OculusVRDevice::buildCodeTable()
|
||||
{
|
||||
// Build the sensor device code table
|
||||
OculusVRSensorDevice::buildCodeTable();
|
||||
}
|
||||
|
||||
void OculusVRDevice::addHMDDevice(OVR::HMDDevice* hmd)
|
||||
{
|
||||
if(!hmd)
|
||||
return;
|
||||
|
||||
OVR::HMDInfo hmdInfo;
|
||||
if(!hmd->GetDeviceInfo(&hmdInfo))
|
||||
return;
|
||||
|
||||
OculusVRHMDDevice* hmdd = new OculusVRHMDDevice();
|
||||
hmdd->set(hmd, hmdInfo, mScaleInputTexture);
|
||||
mHMDDevices.push_back(hmdd);
|
||||
|
||||
Con::printf(" HMD found: %s by %s [v%d]", hmdInfo.ProductName, hmdInfo.Manufacturer, hmdInfo.Version);
|
||||
}
|
||||
|
||||
void OculusVRDevice::createSimulatedHMD()
|
||||
{
|
||||
OculusVRHMDDevice* hmdd = new OculusVRHMDDevice();
|
||||
hmdd->createSimulation(OculusVRHMDDevice::ST_RIFT_PREVIEW, mScaleInputTexture);
|
||||
mHMDDevices.push_back(hmdd);
|
||||
|
||||
Con::printf(" HMD simulated: %s by %s [v%d]", hmdd->getProductName(), hmdd->getManufacturer(), hmdd->getVersion());
|
||||
}
|
||||
|
||||
void OculusVRDevice::addSensorDevice(OVR::SensorDevice* sensor)
|
||||
{
|
||||
if(!sensor)
|
||||
return;
|
||||
|
||||
OVR::SensorInfo sensorInfo;
|
||||
if(!sensor->GetDeviceInfo(&sensorInfo))
|
||||
return;
|
||||
|
||||
OculusVRSensorDevice* sensord = new OculusVRSensorDevice();
|
||||
sensord->set(sensor, sensorInfo, mSensorDevices.size());
|
||||
mSensorDevices.push_back(sensord);
|
||||
|
||||
Con::printf(" Sensor found: %s by %s [v%d] %s", sensorInfo.ProductName, sensorInfo.Manufacturer, sensorInfo.Version, sensorInfo.SerialNumber);
|
||||
}
|
||||
|
||||
void OculusVRDevice::createSimulatedSensor()
|
||||
{
|
||||
OculusVRSensorDevice* sensord = new OculusVRSensorDevice();
|
||||
sensord->createSimulation(OculusVRSensorDevice::ST_RIFT_PREVIEW, mSensorDevices.size());
|
||||
mSensorDevices.push_back(sensord);
|
||||
|
||||
Con::printf(" Sensor simulated: %s by %s [v%d] %s", sensord->getProductName(), sensord->getManufacturer(), sensord->getVersion(), sensord->getSerialNumber());
|
||||
}
|
||||
|
||||
bool OculusVRDevice::enable()
|
||||
{
|
||||
// Start off with disabling the device if it is already enabled
|
||||
disable();
|
||||
|
||||
Con::printf("Oculus VR Device Init:");
|
||||
|
||||
OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All));
|
||||
if(OVR::System::IsInitialized())
|
||||
{
|
||||
mEnabled = true;
|
||||
|
||||
// Create the OVR device manager
|
||||
mDeviceManager = OVR::DeviceManager::Create();
|
||||
if(!mDeviceManager)
|
||||
{
|
||||
if(smSimulateHMD)
|
||||
{
|
||||
Con::printf(" Could not create a HMD device manager. Simulating a HMD.");
|
||||
Con::printf(" ");
|
||||
|
||||
createSimulatedHMD();
|
||||
createSimulatedSensor();
|
||||
setActive(true);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::printf(" Could not create a HMD device manager.");
|
||||
Con::printf(" ");
|
||||
|
||||
mEnabled = false;
|
||||
OVR::System::Destroy();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Provide a message listener
|
||||
// NOTE: Commented out as non-functional in 0.1.2
|
||||
//mListener = new DeviceListener(this);
|
||||
//mDeviceManager->SetMessageHandler(mListener);
|
||||
|
||||
// Enumerate HMDs and pick the first one
|
||||
OVR::HMDDevice* hmd = mDeviceManager->EnumerateDevices<OVR::HMDDevice>().CreateDevice();
|
||||
if(hmd)
|
||||
{
|
||||
// Add the HMD to our list
|
||||
addHMDDevice(hmd);
|
||||
|
||||
// Detect and add any sensor on the HMD
|
||||
OVR::SensorDevice* sensor = hmd->GetSensor();
|
||||
if(sensor)
|
||||
{
|
||||
addSensorDevice(sensor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::printf(" No sensor device on HMD.");
|
||||
}
|
||||
|
||||
setActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(smSimulateHMD)
|
||||
{
|
||||
Con::printf(" Could not enumerate a HMD device. Simulating a HMD.");
|
||||
createSimulatedHMD();
|
||||
createSimulatedSensor();
|
||||
setActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::printf(" Could not enumerate a HMD device.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Con::printf(" ");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OculusVRDevice::disable()
|
||||
{
|
||||
for(U32 i=0; i<mSensorDevices.size(); ++i)
|
||||
{
|
||||
delete mSensorDevices[i];
|
||||
}
|
||||
mSensorDevices.clear();
|
||||
|
||||
for(U32 i=0; i<mHMDDevices.size(); ++i)
|
||||
{
|
||||
delete mHMDDevices[i];
|
||||
}
|
||||
mHMDDevices.clear();
|
||||
|
||||
if(mDeviceManager)
|
||||
{
|
||||
mDeviceManager->Release();
|
||||
mDeviceManager = NULL;
|
||||
}
|
||||
|
||||
if(mEnabled)
|
||||
{
|
||||
OVR::System::Destroy();
|
||||
}
|
||||
|
||||
if(mListener)
|
||||
{
|
||||
delete mListener;
|
||||
mListener = NULL;
|
||||
}
|
||||
|
||||
setActive(false);
|
||||
mEnabled = false;
|
||||
}
|
||||
|
||||
bool OculusVRDevice::process()
|
||||
{
|
||||
if(!mEnabled)
|
||||
return false;
|
||||
|
||||
if(!getActive())
|
||||
return false;
|
||||
|
||||
//Build the maximum axis angle to be passed into the sensor process()
|
||||
F32 maxAxisRadius = mSin(mDegToRad(smMaximumAxisAngle));
|
||||
|
||||
// Process each sensor
|
||||
for(U32 i=0; i<mSensorDevices.size(); ++i)
|
||||
{
|
||||
mSensorDevices[i]->process(mDeviceType, smGenerateAngleAxisRotationEvents, smGenerateEulerRotationEvents, smGenerateRotationAsAxisEvents, maxAxisRadius);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool OculusVRDevice::providesYFOV() const
|
||||
{
|
||||
if(!mHMDDevices.size())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
F32 OculusVRDevice::getYFOV() const
|
||||
{
|
||||
if(!mHMDDevices.size())
|
||||
return 0.0f;
|
||||
|
||||
const OculusVRHMDDevice* hmd = getHMDDevice(0);
|
||||
if(!hmd)
|
||||
return 0.0f;
|
||||
|
||||
return hmd->getYFOV();
|
||||
}
|
||||
|
||||
bool OculusVRDevice::providesEyeOffset() const
|
||||
{
|
||||
if(!mHMDDevices.size())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const Point3F& OculusVRDevice::getEyeOffset() const
|
||||
{
|
||||
if(!mHMDDevices.size())
|
||||
return Point3F::Zero;
|
||||
|
||||
const OculusVRHMDDevice* hmd = getHMDDevice(0);
|
||||
if(!hmd)
|
||||
return Point3F::Zero;
|
||||
|
||||
return hmd->getEyeWorldOffset();
|
||||
}
|
||||
|
||||
bool OculusVRDevice::providesProjectionOffset() const
|
||||
{
|
||||
if(!mHMDDevices.size())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const Point2F& OculusVRDevice::getProjectionOffset() const
|
||||
{
|
||||
if(!mHMDDevices.size())
|
||||
return Point2F::Zero;
|
||||
|
||||
const OculusVRHMDDevice* hmd = getHMDDevice(0);
|
||||
if(!hmd)
|
||||
return Point2F::Zero;
|
||||
|
||||
return hmd->getProjectionCenterOffset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const OculusVRHMDDevice* OculusVRDevice::getHMDDevice(U32 index) const
|
||||
{
|
||||
if(index >= mHMDDevices.size())
|
||||
return NULL;
|
||||
|
||||
return mHMDDevices[index];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const OculusVRSensorDevice* OculusVRDevice::getSensorDevice(U32 index) const
|
||||
{
|
||||
if(index >= mSensorDevices.size())
|
||||
return NULL;
|
||||
|
||||
return mSensorDevices[index];
|
||||
}
|
||||
|
||||
EulerF OculusVRDevice::getSensorEulerRotation(U32 index)
|
||||
{
|
||||
if(index >= mSensorDevices.size())
|
||||
return Point3F::Zero;
|
||||
|
||||
return mSensorDevices[index]->getEulerRotation();
|
||||
}
|
||||
|
||||
F32 OculusVRDevice::getSensorPredictionTime(U32 index)
|
||||
{
|
||||
const OculusVRSensorDevice* sensor = getSensorDevice(index);
|
||||
if(!sensor || !sensor->isValid())
|
||||
return 0.0f;
|
||||
|
||||
return sensor->getPredictionTime();
|
||||
}
|
||||
|
||||
void OculusVRDevice::setSensorPredictionTime(U32 index, F32 dt)
|
||||
{
|
||||
if(index >= mSensorDevices.size())
|
||||
return;
|
||||
|
||||
OculusVRSensorDevice* sensor = mSensorDevices[index];
|
||||
if(!sensor->isValid())
|
||||
return;
|
||||
|
||||
sensor->setPredictionTime(dt);
|
||||
}
|
||||
|
||||
void OculusVRDevice::setAllSensorPredictionTime(F32 dt)
|
||||
{
|
||||
for(U32 i=0; i<mSensorDevices.size(); ++i)
|
||||
{
|
||||
mSensorDevices[i]->setPredictionTime(dt);
|
||||
}
|
||||
}
|
||||
|
||||
void OculusVRDevice::resetAllSensors()
|
||||
{
|
||||
// Reset each sensor
|
||||
for(U32 i=0; i<mSensorDevices.size(); ++i)
|
||||
{
|
||||
mSensorDevices[i]->reset();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void OculusVRDevice::DeviceListener::OnMessage(const OVR::Message& msg)
|
||||
{
|
||||
switch(msg.Type)
|
||||
{
|
||||
case OVR::Message_DeviceAdded:
|
||||
{
|
||||
const OVR::MessageDeviceStatus* status = static_cast<const OVR::MessageDeviceStatus*>(&msg);
|
||||
Con::printf("OVR: Device added of type: %d", status->Handle.GetType());
|
||||
}
|
||||
break;
|
||||
|
||||
case OVR::Message_DeviceRemoved:
|
||||
Con::printf("OVR: Device removed of type: %d", msg.pDevice->GetType());
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineFunction(isOculusVRDeviceActive, bool, (),,
|
||||
"@brief Used to determine if the Oculus VR input device is active\n\n"
|
||||
|
||||
"The Oculus VR device is considered active when the library has been "
|
||||
"initialized and either a real of simulated HMD is present.\n\n"
|
||||
|
||||
"@return True if the Oculus VR input device is active.\n"
|
||||
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return OCULUSVRDEV->getActive();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineFunction(setOVRHMDAsGameConnectionDisplayDevice, bool, (GameConnection* conn),,
|
||||
"@brief Sets the first HMD to be a GameConnection's display device\n\n"
|
||||
"@param conn The GameConnection to set.\n"
|
||||
"@return True if the GameConnection display device was set.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
Con::errorf("setOVRHMDAsGameConnectionDisplayDevice(): No Oculus VR Device present.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!conn)
|
||||
{
|
||||
Con::errorf("setOVRHMDAsGameConnectionDisplayDevice(): Invalid GameConnection.");
|
||||
return false;
|
||||
}
|
||||
|
||||
conn->setDisplayDevice(OCULUSVRDEV);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineFunction(getOVRHMDCount, S32, (),,
|
||||
"@brief Get the number of HMD devices that are currently connected.\n\n"
|
||||
"@return The number of Oculus VR HMD devices that are currently connected.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return OCULUSVRDEV->getHMDCount();
|
||||
}
|
||||
|
||||
DefineEngineFunction(isOVRHMDSimulated, bool, (S32 index),,
|
||||
"@brief Determines if the requested OVR HMD is simulated or real.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return True if the HMD is simulated.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return hmd->isSimulated();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDProductName, const char*, (S32 index),,
|
||||
"@brief Retrieves the HMD product name.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The name of the HMD product.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return hmd->getProductName();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDManufacturer, const char*, (S32 index),,
|
||||
"@brief Retrieves the HMD manufacturer name.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The manufacturer of the HMD product.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return hmd->getManufacturer();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDVersion, S32, (S32 index),,
|
||||
"@brief Retrieves the HMD version number.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The version number of the HMD product.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hmd->getVersion();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDDisplayDeviceName, const char*, (S32 index),,
|
||||
"@brief Windows display device name used in EnumDisplaySettings/CreateDC.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The name of the HMD display device, if any.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return hmd->getDisplayDeviceName();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDResolution, Point2I, (S32 index),,
|
||||
"@brief Provides the OVR HMD screen resolution.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return A two component string with the screen's resolution.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return Point2I(1280, 800);
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return Point2I(1280, 800);
|
||||
}
|
||||
|
||||
return hmd->getResolution();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDDistortionCoefficients, String, (S32 index),,
|
||||
"@brief Provides the OVR HMD distortion coefficients.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return A four component string with the distortion coefficients.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return "0 0 0 0";
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return "0 0 0 0";
|
||||
}
|
||||
|
||||
const Point4F& k = hmd->getKDistortion();
|
||||
char buf[256];
|
||||
dSprintf(buf, 256, "%g %g %g %g", k.x, k.y, k.z, k.w);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDEyeXOffsets, Point2F, (S32 index),,
|
||||
"@brief Provides the OVR HMD eye x offsets in uv coordinates.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return A two component string with the left and right eye x offsets.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return Point2F(0.5, 0.5);
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return Point2F(0.5, 0.5);
|
||||
}
|
||||
|
||||
// X component is left, Y component is right
|
||||
const Point2F& offset = hmd->getEyeUVOffset();
|
||||
return offset;
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDXCenterOffset, F32, (S32 index),,
|
||||
"@brief Provides the OVR HMD calculated XCenterOffset.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The calculated XCenterOffset.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
F32 offset = hmd->getCenterOffset();
|
||||
return offset;
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDDistortionScale, F32, (S32 index),,
|
||||
"@brief Provides the OVR HMD calculated distortion scale.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The calculated distortion scale.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
F32 scale = hmd->getDistortionScale();
|
||||
return scale;
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRHMDYFOV, F32, (S32 index),,
|
||||
"@brief Provides the OVR HMD calculated Y FOV.\n\n"
|
||||
"@param index The HMD index.\n"
|
||||
"@return The calculated Y FOV.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
const OculusVRHMDDevice* hmd = OCULUSVRDEV->getHMDDevice(index);
|
||||
if(!hmd)
|
||||
{
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
F32 fov = hmd->getYFOV();
|
||||
return mRadToDeg(fov);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineFunction(getOVRSensorCount, S32, (),,
|
||||
"@brief Get the number of sensor devices that are currently connected.\n\n"
|
||||
"@return The number of Oculus VR sensor devices that are currently connected.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return OCULUSVRDEV->getSensorCount();
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRSensorEulerRotation, Point3F, (S32 index),,
|
||||
"@brief Get the Euler rotation values for the given sensor index.\n\n"
|
||||
"@param index The sensor index.\n"
|
||||
"@return The Euler rotation values of the Oculus VR sensor, in degrees.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return Point3F::Zero;
|
||||
}
|
||||
|
||||
EulerF rot = OCULUSVRDEV->getSensorEulerRotation(index);
|
||||
return Point3F(mRadToDeg(rot.x), mRadToDeg(rot.y), mRadToDeg(rot.z));
|
||||
}
|
||||
|
||||
DefineEngineFunction(getOVRSensorPredictionTime, F32, (S32 index),,
|
||||
"@brief Get the prediction time set for the given sensor index.\n\n"
|
||||
"@param index The sensor index.\n"
|
||||
"@return The prediction time of the Oculus VR sensor, given in seconds.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return OCULUSVRDEV->getSensorPredictionTime(index);
|
||||
}
|
||||
|
||||
DefineEngineFunction(setSensorPredictionTime, void, (S32 index, F32 dt),,
|
||||
"@brief Set the prediction time set for the given sensor index.\n\n"
|
||||
"@param index The sensor index.\n"
|
||||
"@param dt The prediction time to set given in seconds. Setting to 0 disables prediction.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OCULUSVRDEV->setSensorPredictionTime(index, dt);
|
||||
}
|
||||
|
||||
DefineEngineFunction(setAllSensorPredictionTime, void, (F32 dt),,
|
||||
"@brief Set the prediction time set for all sensors.\n\n"
|
||||
"@param dt The prediction time to set given in seconds. Setting to 0 disables prediction.\n"
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OCULUSVRDEV->setAllSensorPredictionTime(dt);
|
||||
}
|
||||
|
||||
DefineEngineFunction(ovrResetAllSensors, void, (),,
|
||||
"@brief Resets all Oculus VR sensors.\n\n"
|
||||
"This resets all sensor orientations such that their 'normal' rotation "
|
||||
"is defined when this function is called. This defines an HMD's forwards "
|
||||
"and up direction, for example."
|
||||
"@ingroup Game")
|
||||
{
|
||||
if(!ManagedSingleton<OculusVRDevice>::instanceOrNull())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
OCULUSVRDEV->resetAllSensors();
|
||||
}
|
||||
152
Engine/source/platform/input/oculusVR/oculusVRDevice.h
Normal file
152
Engine/source/platform/input/oculusVR/oculusVRDevice.h
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _OCULUSVRDEVICE_H_
|
||||
#define _OCULUSVRDEVICE_H_
|
||||
|
||||
#include "platform/input/oculusVR/oculusVRConstants.h"
|
||||
#include "platform/input/oculusVR/oculusVRHMDDevice.h"
|
||||
#include "platform/input/oculusVR/oculusVRSensorDevice.h"
|
||||
#include "platform/input/IInputDevice.h"
|
||||
#include "platform/input/event.h"
|
||||
#include "platform/output/IDisplayDevice.h"
|
||||
#include "core/util/tSingleton.h"
|
||||
#include "math/mQuat.h"
|
||||
#include "math/mPoint4.h"
|
||||
#include "OVR.h"
|
||||
|
||||
#define DEFAULT_RIFT_UNIT 0
|
||||
|
||||
class OculusVRDevice : public IInputDevice, public IDisplayDevice
|
||||
{
|
||||
public:
|
||||
static bool smEnableDevice;
|
||||
|
||||
// If no HMD is present simulate it being available
|
||||
static bool smSimulateHMD;
|
||||
|
||||
// Type of rotation events to broadcast
|
||||
static bool smGenerateAngleAxisRotationEvents;
|
||||
static bool smGenerateEulerRotationEvents;
|
||||
|
||||
// Broadcast sensor rotation as axis
|
||||
static bool smGenerateRotationAsAxisEvents;
|
||||
|
||||
// The maximum sensor angle when used as an axis event
|
||||
// as measured from a vector pointing straight up (in degrees)
|
||||
static F32 smMaximumAxisAngle;
|
||||
|
||||
// Indicates that a whole frame event should be generated and frames
|
||||
// should be buffered.
|
||||
static bool smGenerateWholeFrameEvents;
|
||||
|
||||
protected:
|
||||
class DeviceListener : public OVR::MessageHandler
|
||||
{
|
||||
protected:
|
||||
OculusVRDevice* mOwner;
|
||||
|
||||
public:
|
||||
DeviceListener(OculusVRDevice* owner) { mOwner = owner; }
|
||||
virtual ~DeviceListener() { mOwner = NULL; }
|
||||
|
||||
virtual void OnMessage(const OVR::Message&);
|
||||
};
|
||||
|
||||
// Our OVR SDK device listener class
|
||||
DeviceListener* mListener;
|
||||
|
||||
// The OVR SDK device manager
|
||||
OVR::DeviceManager* mDeviceManager;
|
||||
|
||||
// Discovered HMD devices
|
||||
Vector<OculusVRHMDDevice*> mHMDDevices;
|
||||
|
||||
// Discovered sensor devices
|
||||
Vector<OculusVRSensorDevice*> mSensorDevices;
|
||||
|
||||
/// Is the device active
|
||||
bool mActive;
|
||||
|
||||
// Should the input texture into the HMD (the render target that the scene has been
|
||||
// rendered to) be scaled according to the HMD's distortion calculation?
|
||||
bool mScaleInputTexture;
|
||||
|
||||
protected:
|
||||
void cleanUp();
|
||||
|
||||
/// Build out the codes used for controller actions with the
|
||||
/// Input Event Manager
|
||||
void buildCodeTable();
|
||||
|
||||
void addHMDDevice(OVR::HMDDevice* hmd);
|
||||
|
||||
void createSimulatedHMD();
|
||||
|
||||
void addSensorDevice(OVR::SensorDevice* sensor);
|
||||
|
||||
void createSimulatedSensor();
|
||||
|
||||
public:
|
||||
OculusVRDevice();
|
||||
~OculusVRDevice();
|
||||
|
||||
static void staticInit();
|
||||
|
||||
bool enable();
|
||||
void disable();
|
||||
|
||||
bool getActive() { return mActive; }
|
||||
void setActive(bool state) { mActive = state; }
|
||||
|
||||
bool process();
|
||||
|
||||
// IDisplayDevice
|
||||
virtual bool providesYFOV() const;
|
||||
virtual F32 getYFOV() const;
|
||||
virtual bool providesEyeOffset() const;
|
||||
virtual const Point3F& getEyeOffset() const;
|
||||
virtual bool providesProjectionOffset() const;
|
||||
virtual const Point2F& getProjectionOffset() const;
|
||||
|
||||
// HMDs
|
||||
U32 getHMDCount() const { return mHMDDevices.size(); }
|
||||
const OculusVRHMDDevice* getHMDDevice(U32 index) const;
|
||||
|
||||
// Sensors
|
||||
U32 getSensorCount() const { return mSensorDevices.size(); }
|
||||
const OculusVRSensorDevice* getSensorDevice(U32 index) const;
|
||||
EulerF getSensorEulerRotation(U32 index);
|
||||
F32 getSensorPredictionTime(U32 index);
|
||||
void setSensorPredictionTime(U32 index, F32 dt);
|
||||
void setAllSensorPredictionTime(F32 dt);
|
||||
void resetAllSensors();
|
||||
|
||||
public:
|
||||
// For ManagedSingleton.
|
||||
static const char* getSingletonName() { return "OculusVRDevice"; }
|
||||
};
|
||||
|
||||
/// Returns the OculusVRDevice singleton.
|
||||
#define OCULUSVRDEV ManagedSingleton<OculusVRDevice>::instance()
|
||||
|
||||
#endif // _OCULUSVRDEVICE_H_
|
||||
208
Engine/source/platform/input/oculusVR/oculusVRHMDDevice.cpp
Normal file
208
Engine/source/platform/input/oculusVR/oculusVRHMDDevice.cpp
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/input/oculusVR/oculusVRHMDDevice.h"
|
||||
|
||||
OculusVRHMDDevice::OculusVRHMDDevice()
|
||||
{
|
||||
mIsValid = false;
|
||||
mIsSimulation = false;
|
||||
mDevice = NULL;
|
||||
}
|
||||
|
||||
OculusVRHMDDevice::~OculusVRHMDDevice()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
|
||||
void OculusVRHMDDevice::cleanUp()
|
||||
{
|
||||
if(mDevice)
|
||||
{
|
||||
mDevice->Release();
|
||||
mDevice = NULL;
|
||||
}
|
||||
|
||||
mIsValid = false;
|
||||
}
|
||||
|
||||
void OculusVRHMDDevice::set(OVR::HMDDevice* hmd, OVR::HMDInfo& info, bool calculateDistortionScale)
|
||||
{
|
||||
mIsValid = false;
|
||||
mIsSimulation = false;
|
||||
|
||||
mDevice = hmd;
|
||||
|
||||
// DeviceInfo
|
||||
mProductName = info.ProductName;
|
||||
mManufacturer = info.Manufacturer;
|
||||
mVersion = info.Version;
|
||||
|
||||
mDisplayDeviceName = info.DisplayDeviceName;
|
||||
|
||||
mResolution.x = info.HResolution;
|
||||
mResolution.y = info.VResolution;
|
||||
|
||||
mScreenSize.x = info.HScreenSize;
|
||||
mScreenSize.y = info.VScreenSize;
|
||||
|
||||
mVerticalEyeCenter = info.VScreenCenter;
|
||||
mEyeToScreen = info.EyeToScreenDistance;
|
||||
mLensSeparation = info.LensSeparationDistance;
|
||||
mInterpupillaryDistance = info.InterpupillaryDistance;
|
||||
|
||||
mKDistortion.x = info.DistortionK[0];
|
||||
mKDistortion.y = info.DistortionK[1];
|
||||
mKDistortion.z = info.DistortionK[2];
|
||||
mKDistortion.w = info.DistortionK[3];
|
||||
|
||||
// Calculated values
|
||||
calculateValues(calculateDistortionScale);
|
||||
|
||||
mIsValid = true;
|
||||
}
|
||||
|
||||
void OculusVRHMDDevice::createSimulation(SimulationTypes simulationType, bool calculateDistortionScale)
|
||||
{
|
||||
if(simulationType == ST_RIFT_PREVIEW)
|
||||
{
|
||||
createSimulatedPreviewRift(calculateDistortionScale);
|
||||
}
|
||||
}
|
||||
|
||||
void OculusVRHMDDevice::createSimulatedPreviewRift(bool calculateDistortionScale)
|
||||
{
|
||||
mIsValid = true;
|
||||
mIsSimulation = true;
|
||||
|
||||
mProductName = "Oculus Rift DK1-SLA1";
|
||||
mManufacturer = "Oculus VR";
|
||||
mVersion = 0;
|
||||
|
||||
mDisplayDeviceName = "";
|
||||
|
||||
mResolution.x = 1280;
|
||||
mResolution.y = 800;
|
||||
|
||||
mScreenSize.x = 0.14975999f;
|
||||
mScreenSize.y = 0.093599997f;
|
||||
|
||||
mVerticalEyeCenter = 0.046799999f;
|
||||
mEyeToScreen = 0.041000001f;
|
||||
mLensSeparation = 0.064000003f;
|
||||
mInterpupillaryDistance = 0.064000003f;
|
||||
|
||||
mKDistortion.x = 1.0000000f;
|
||||
mKDistortion.y = 0.22000000f;
|
||||
mKDistortion.z = 0.23999999f;
|
||||
mKDistortion.w = 0.00000000f;
|
||||
|
||||
calculateValues(calculateDistortionScale);
|
||||
}
|
||||
|
||||
// Computes scale that should be applied to the input render texture
|
||||
// before distortion to fit the result in the same screen size.
|
||||
// The 'fitRadius' parameter specifies the distance away from distortion center at
|
||||
// which the input and output coordinates will match, assuming [-1,1] range.
|
||||
F32 OculusVRHMDDevice::calcScale(F32 fitRadius)
|
||||
{
|
||||
F32 s = fitRadius;
|
||||
|
||||
// This should match distortion equation used in shader.
|
||||
F32 ssq = s * s;
|
||||
F32 scale = s * (mKDistortion.x + mKDistortion.y * ssq + mKDistortion.z * ssq * ssq + mKDistortion.w * ssq * ssq * ssq);
|
||||
return scale;
|
||||
}
|
||||
|
||||
void OculusVRHMDDevice::calculateValues(bool calculateDistortionScale)
|
||||
{
|
||||
F32 halfScreenX = mScreenSize.x * 0.5f;
|
||||
if(halfScreenX > 0)
|
||||
{
|
||||
F32 halfLensSeparation = mLensSeparation * 0.5;
|
||||
F32 offset = halfLensSeparation / halfScreenX;
|
||||
mEyeUVOffset.x = offset - 0.5;
|
||||
mEyeUVOffset.y = 1.0f - offset - 0.5;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEyeUVOffset.x = 0.5f;
|
||||
mEyeUVOffset.y = 0.5f;
|
||||
}
|
||||
|
||||
F32 lensOffset = mLensSeparation * 0.5f;
|
||||
F32 lensShift = mScreenSize.x * 0.25f - lensOffset;
|
||||
F32 lensViewportShift = 4.0f * lensShift / mScreenSize.x;
|
||||
mXCenterOffset= lensViewportShift;
|
||||
|
||||
// Determine how the input texture should be scaled relative to the back buffer
|
||||
// so that we fit the distorted view to the backbuffer after calculating the
|
||||
// distortion. In reference to section 5.6.3 Distortion Scale and FOV in the
|
||||
// SDK docs.
|
||||
if(!calculateDistortionScale)
|
||||
{
|
||||
// Do not calculate a distortion scale for the input texture. This means that the input
|
||||
// texture and the backbuffer will be the same resolution.
|
||||
mDistortionFit.x = 0.0f;
|
||||
mDistortionFit.y = 0.0f;
|
||||
}
|
||||
else if (mScreenSize.x > 0.140f) // 7"
|
||||
{
|
||||
mDistortionFit.x = -1.0f;
|
||||
mDistortionFit.y = 0.0f;
|
||||
}
|
||||
else // 5"
|
||||
{
|
||||
mDistortionFit.x = 0.0f;
|
||||
mDistortionFit.y = 1.0f;
|
||||
}
|
||||
|
||||
// Compute distortion scale from DistortionFitX & DistortionFitY.
|
||||
// Fit value of 0.0 means "no fit".
|
||||
if (mIsZero(mDistortionFit.x) && mIsZero(mDistortionFit.y))
|
||||
{
|
||||
mDistortionScale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert fit value to distortion-centered coordinates before fit radius
|
||||
// calculation.
|
||||
// NOTE: For now just assume a full view the same size as the HMD supports. It is
|
||||
// possible that this full view is smaller or larger.
|
||||
F32 stereoAspect = 0.5f * mResolution.x / mResolution.y;
|
||||
F32 dx = mDistortionFit.x - mXCenterOffset;
|
||||
F32 dy = mDistortionFit.y / stereoAspect;
|
||||
F32 fitRadius = sqrt(dx * dx + dy * dy);
|
||||
mDistortionScale = calcScale(fitRadius)/fitRadius;
|
||||
}
|
||||
|
||||
// Calculate the vertical FOV for a single eye
|
||||
mAspectRatio = F32(mResolution.x * 0.5f) / F32(mResolution.y);
|
||||
F32 halfScreenDistance = mScreenSize.y * 0.5f * mDistortionScale;
|
||||
mYFOV = 2.0f * mAtan(halfScreenDistance / mEyeToScreen);
|
||||
|
||||
F32 viewCenter = mScreenSize.x * 0.25f;
|
||||
F32 eyeProjectionShift = viewCenter - (mInterpupillaryDistance * 0.5f);
|
||||
mProjectionCenterOffset.set(4.0f * eyeProjectionShift / mScreenSize.x, 0.0f);
|
||||
|
||||
mEyeWorldOffset.set(mInterpupillaryDistance * 0.5f, 0.0f, 0.0f);
|
||||
}
|
||||
187
Engine/source/platform/input/oculusVR/oculusVRHMDDevice.h
Normal file
187
Engine/source/platform/input/oculusVR/oculusVRHMDDevice.h
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _OCULUSVRHMDDEVICE_H_
|
||||
#define _OCULUSVRHMDDEVICE_H_
|
||||
|
||||
#include "core/util/str.h"
|
||||
#include "math/mQuat.h"
|
||||
#include "math/mPoint2.h"
|
||||
#include "math/mPoint3.h"
|
||||
#include "math/mPoint4.h"
|
||||
#include "platform/input/oculusVR/oculusVRConstants.h"
|
||||
#include "platform/types.h"
|
||||
#include "OVR.h"
|
||||
|
||||
class OculusVRHMDDevice
|
||||
{
|
||||
public:
|
||||
enum SimulationTypes {
|
||||
ST_RIFT_PREVIEW,
|
||||
};
|
||||
|
||||
protected:
|
||||
bool mIsValid;
|
||||
|
||||
bool mIsSimulation;
|
||||
|
||||
OVR::HMDDevice* mDevice;
|
||||
|
||||
// From OVR::DeviceInfo
|
||||
String mProductName;
|
||||
String mManufacturer;
|
||||
U32 mVersion;
|
||||
|
||||
// Windows display device name used in EnumDisplaySettings/CreateDC
|
||||
String mDisplayDeviceName;
|
||||
|
||||
// Whole screen resolution
|
||||
Point2I mResolution;
|
||||
|
||||
// Physical screen size in meters
|
||||
Point2F mScreenSize;
|
||||
|
||||
// Physical offset from the top of the screen to the center of the
|
||||
// eye, in meters. Usually half of the vertical physical screen size
|
||||
F32 mVerticalEyeCenter;
|
||||
|
||||
// Physical distance from the eye to the screen
|
||||
F32 mEyeToScreen;
|
||||
|
||||
// Physical distance between lens centers, in meters
|
||||
F32 mLensSeparation;
|
||||
|
||||
// Physical distance between the user's eye centers
|
||||
F32 mInterpupillaryDistance;
|
||||
|
||||
// The eye IPD as a Point3F
|
||||
Point3F mEyeWorldOffset;
|
||||
|
||||
// Radial distortion correction coefficients used by the barrel distortion shader
|
||||
Point4F mKDistortion;
|
||||
|
||||
// Calculated values of eye x offset from center in normalized (uv) coordinates
|
||||
// where each eye is 0..1. Used for the mono to stereo postFX to simulate an
|
||||
// eye offset of the camera. The x component is the left eye, the y component
|
||||
// is the right eye.
|
||||
Point2F mEyeUVOffset;
|
||||
|
||||
// Used to adjust where an eye's view is rendered to account for the lenses not
|
||||
// being in the center of the physical screen half.
|
||||
F32 mXCenterOffset;
|
||||
|
||||
// When calculating the distortion scale to use to increase the size of the input texture
|
||||
// this determines how we should attempt to fit the distorted view into the backbuffer.
|
||||
Point2F mDistortionFit;
|
||||
|
||||
// Is the factor by which the input texture size is increased to make post-distortion
|
||||
// result distortion fit the viewport. If the input texture is the same size as the
|
||||
// backbuffer, then this should be 1.0.
|
||||
F32 mDistortionScale;
|
||||
|
||||
// Aspect ratio for a single eye
|
||||
F32 mAspectRatio;
|
||||
|
||||
// Vertical field of view
|
||||
F32 mYFOV;
|
||||
|
||||
// The amount to offset the projection matrix to account for the eye not being in the
|
||||
// center of the screen.
|
||||
Point2F mProjectionCenterOffset;
|
||||
|
||||
protected:
|
||||
F32 calcScale(F32 fitRadius);
|
||||
|
||||
void calculateValues(bool calculateDistortionScale);
|
||||
|
||||
void createSimulatedPreviewRift(bool calculateDistortionScale);
|
||||
|
||||
public:
|
||||
OculusVRHMDDevice();
|
||||
~OculusVRHMDDevice();
|
||||
|
||||
void cleanUp();
|
||||
|
||||
// Set the HMD properties based on information from the OVR device
|
||||
void set(OVR::HMDDevice* hmd, OVR::HMDInfo& info, bool calculateDistortionScale);
|
||||
|
||||
// Set the HMD properties based on a simulation of the given type
|
||||
void createSimulation(SimulationTypes simulationType, bool calculateDistortionScale);
|
||||
|
||||
bool isValid() const {return mIsValid;}
|
||||
bool isSimulated() const {return mIsSimulation;}
|
||||
|
||||
const char* getProductName() const { return mProductName.c_str(); }
|
||||
const char* getManufacturer() const { return mManufacturer.c_str(); }
|
||||
U32 getVersion() const { return mVersion; }
|
||||
|
||||
// Windows display device name used in EnumDisplaySettings/CreateDC
|
||||
const char* getDisplayDeviceName() const { return mDisplayDeviceName.c_str(); }
|
||||
|
||||
// Whole screen resolution
|
||||
const Point2I& getResolution() const { return mResolution; }
|
||||
|
||||
// Physical screen size in meters
|
||||
const Point2F& getScreenSize() const { return mScreenSize; }
|
||||
|
||||
// Physical offset from the top of the screen to the center of the
|
||||
// eye, in meters. Usually half of the vertical physical screen size
|
||||
F32 getVerticalEyeCenter() const { return mVerticalEyeCenter; }
|
||||
|
||||
// Physical distance from the eye to the screen
|
||||
F32 getEyeToScreen() const { return mEyeToScreen; }
|
||||
|
||||
// Physical distance between lens centers, in meters
|
||||
F32 getLensSeparation() const { return mLensSeparation; }
|
||||
|
||||
// Physical distance between the user's eye centers
|
||||
F32 getIPD() const { return mInterpupillaryDistance; }
|
||||
|
||||
// Provides the IPD of one eye as a Point3F
|
||||
const Point3F& getEyeWorldOffset() const { return mEyeWorldOffset; }
|
||||
|
||||
// Radial distortion correction coefficients used by the barrel distortion shader
|
||||
const Point4F& getKDistortion() const { return mKDistortion; }
|
||||
|
||||
// Calculated values of eye x offset from center in normalized (uv) coordinates.
|
||||
const Point2F& getEyeUVOffset() const { return mEyeUVOffset; }
|
||||
|
||||
// Used to adjust where an eye's view is rendered to account for the lenses not
|
||||
// being in the center of the physical screen half.
|
||||
F32 getCenterOffset() const { return mXCenterOffset; }
|
||||
|
||||
// Is the factor by which the input texture size is increased to make post-distortion
|
||||
// result distortion fit the viewport.
|
||||
F32 getDistortionScale() const { return mDistortionScale; }
|
||||
|
||||
// Aspect ration for a single eye
|
||||
F32 getAspectRation() const { return mAspectRatio; }
|
||||
|
||||
// Vertical field of view
|
||||
F32 getYFOV() const { return mYFOV; }
|
||||
|
||||
// The amount to offset the projection matrix to account for the eye not being in the
|
||||
// center of the screen.
|
||||
const Point2F& getProjectionCenterOffset() const { return mProjectionCenterOffset; }
|
||||
};
|
||||
|
||||
#endif // _OCULUSVRHMDDEVICE_H_
|
||||
96
Engine/source/platform/input/oculusVR/oculusVRSensorData.cpp
Normal file
96
Engine/source/platform/input/oculusVR/oculusVRSensorData.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/input/oculusVR/oculusVRSensorData.h"
|
||||
#include "platform/input/oculusVR/oculusVRUtil.h"
|
||||
#include "console/console.h"
|
||||
|
||||
OculusVRSensorData::OculusVRSensorData()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void OculusVRSensorData::reset()
|
||||
{
|
||||
mDataSet = false;
|
||||
}
|
||||
|
||||
void OculusVRSensorData::setData(const OVR::SensorFusion& data, const F32& maxAxisRadius)
|
||||
{
|
||||
// Sensor rotation
|
||||
OVR::Quatf orientation;
|
||||
if(data.GetPredictionDelta() > 0)
|
||||
{
|
||||
orientation = data.GetPredictedOrientation();
|
||||
}
|
||||
else
|
||||
{
|
||||
orientation = data.GetOrientation();
|
||||
}
|
||||
OVR::Matrix4f orientMat(orientation);
|
||||
OculusVRUtil::convertRotation(orientMat.M, mRot);
|
||||
mRotQuat.set(mRot);
|
||||
|
||||
// Sensor rotation in Euler format
|
||||
OculusVRUtil::convertRotation(orientation, mRotEuler);
|
||||
|
||||
// Sensor rotation as axis
|
||||
OculusVRUtil::calculateAxisRotation(mRot, maxAxisRadius, mRotAxis);
|
||||
|
||||
mDataSet = true;
|
||||
}
|
||||
|
||||
void OculusVRSensorData::simulateData(const F32& maxAxisRadius)
|
||||
{
|
||||
// Sensor rotation
|
||||
mRot.identity();
|
||||
mRotQuat.identity();
|
||||
mRotEuler.zero();
|
||||
|
||||
// Sensor rotation as axis
|
||||
OculusVRUtil::calculateAxisRotation(mRot, maxAxisRadius, mRotAxis);
|
||||
|
||||
mDataSet = true;
|
||||
}
|
||||
|
||||
U32 OculusVRSensorData::compare(OculusVRSensorData* other)
|
||||
{
|
||||
S32 result = DIFF_NONE;
|
||||
|
||||
// Check rotation
|
||||
if(mRotEuler.x != other->mRotEuler.x || mRotEuler.y != other->mRotEuler.y || mRotEuler.z != other->mRotEuler.z || !mDataSet)
|
||||
{
|
||||
result |= DIFF_ROT;
|
||||
}
|
||||
|
||||
// Check rotation as axis
|
||||
if(mRotAxis.x != other->mRotAxis.x || !mDataSet)
|
||||
{
|
||||
result |= DIFF_ROTAXISX;
|
||||
}
|
||||
if(mRotAxis.y != other->mRotAxis.y || !mDataSet)
|
||||
{
|
||||
result |= DIFF_ROTAXISY;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
68
Engine/source/platform/input/oculusVR/oculusVRSensorData.h
Normal file
68
Engine/source/platform/input/oculusVR/oculusVRSensorData.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _OCULUSVRSENSORDATA_H_
|
||||
#define _OCULUSVRSENSORDATA_H_
|
||||
|
||||
#include "platform/types.h"
|
||||
#include "math/mMatrix.h"
|
||||
#include "math/mQuat.h"
|
||||
#include "math/mPoint2.h"
|
||||
#include "OVR.h"
|
||||
|
||||
struct OculusVRSensorData
|
||||
{
|
||||
enum DataDifferences {
|
||||
DIFF_NONE = 0,
|
||||
DIFF_ROT = (1<<0),
|
||||
DIFF_ROTAXISX = (1<<1),
|
||||
DIFF_ROTAXISY = (1<<2),
|
||||
|
||||
DIFF_ROTAXIS = (DIFF_ROTAXISX | DIFF_ROTAXISY),
|
||||
};
|
||||
|
||||
bool mDataSet;
|
||||
|
||||
// Rotation
|
||||
MatrixF mRot;
|
||||
QuatF mRotQuat;
|
||||
EulerF mRotEuler;
|
||||
|
||||
// Controller rotation as axis x, y
|
||||
Point2F mRotAxis;
|
||||
|
||||
OculusVRSensorData();
|
||||
|
||||
/// Reset the data
|
||||
void reset();
|
||||
|
||||
/// Set data based on given sensor fusion
|
||||
void setData(const OVR::SensorFusion& data, const F32& maxAxisRadius);
|
||||
|
||||
/// Simulate valid data
|
||||
void simulateData(const F32& maxAxisRadius);
|
||||
|
||||
/// Compare this data and given and return differences
|
||||
U32 compare(OculusVRSensorData* other);
|
||||
};
|
||||
|
||||
#endif // _OCULUSVRSENSORDATA_H_
|
||||
265
Engine/source/platform/input/oculusVR/oculusVRSensorDevice.cpp
Normal file
265
Engine/source/platform/input/oculusVR/oculusVRSensorDevice.cpp
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/input/oculusVR/oculusVRSensorDevice.h"
|
||||
#include "platform/input/oculusVR/oculusVRSensorData.h"
|
||||
#include "platform/input/oculusVR/oculusVRUtil.h"
|
||||
#include "platform/platformInput.h"
|
||||
|
||||
U32 OculusVRSensorDevice::OVR_SENSORROT[OculusVRConstants::MaxSensors] = {0};
|
||||
U32 OculusVRSensorDevice::OVR_SENSORROTANG[OculusVRConstants::MaxSensors] = {0};
|
||||
U32 OculusVRSensorDevice::OVR_SENSORROTAXISX[OculusVRConstants::MaxSensors] = {0};
|
||||
U32 OculusVRSensorDevice::OVR_SENSORROTAXISY[OculusVRConstants::MaxSensors] = {0};
|
||||
|
||||
OculusVRSensorDevice::OculusVRSensorDevice()
|
||||
{
|
||||
mIsValid = false;
|
||||
mIsSimulation = false;
|
||||
mDevice = NULL;
|
||||
|
||||
for(U32 i=0; i<2; ++i)
|
||||
{
|
||||
mDataBuffer[i] = new OculusVRSensorData();
|
||||
}
|
||||
mPrevData = mDataBuffer[0];
|
||||
}
|
||||
|
||||
OculusVRSensorDevice::~OculusVRSensorDevice()
|
||||
{
|
||||
cleanUp();
|
||||
|
||||
for(U32 i=0; i<2; ++i)
|
||||
{
|
||||
delete mDataBuffer[i];
|
||||
mDataBuffer[i] = NULL;
|
||||
}
|
||||
mPrevData = NULL;
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::cleanUp()
|
||||
{
|
||||
mSensorFusion.AttachToSensor(NULL);
|
||||
|
||||
if(mDevice)
|
||||
{
|
||||
mDevice->Release();
|
||||
mDevice = NULL;
|
||||
}
|
||||
|
||||
mIsValid = false;
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::set(OVR::SensorDevice* sensor, OVR::SensorInfo& info, S32 actionCodeIndex)
|
||||
{
|
||||
mIsValid = false;
|
||||
|
||||
mDevice = sensor;
|
||||
mSensorFusion.AttachToSensor(sensor);
|
||||
|
||||
// DeviceInfo
|
||||
mProductName = info.ProductName;
|
||||
mManufacturer = info.Manufacturer;
|
||||
mVersion = info.Version;
|
||||
|
||||
// SensorInfo
|
||||
mVendorId = info.VendorId;
|
||||
mProductId = info.ProductId;
|
||||
mSerialNumber = info.SerialNumber;
|
||||
|
||||
mActionCodeIndex = actionCodeIndex;
|
||||
|
||||
if(mActionCodeIndex >= OculusVRConstants::MaxSensors)
|
||||
{
|
||||
// Cannot declare more sensors than we are able to handle
|
||||
mIsValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::createSimulation(SimulationTypes simulationType, S32 actionCodeIndex)
|
||||
{
|
||||
if(simulationType == ST_RIFT_PREVIEW)
|
||||
{
|
||||
createSimulatedPreviewRift(actionCodeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::createSimulatedPreviewRift(S32 actionCodeIndex)
|
||||
{
|
||||
mIsValid = false;
|
||||
mIsSimulation = true;
|
||||
|
||||
// DeviceInfo
|
||||
mProductName = "Tracker DK";
|
||||
mManufacturer = "Oculus VR, Inc.";
|
||||
mVersion = 0;
|
||||
|
||||
// SensorInfo
|
||||
mVendorId = 10291;
|
||||
mProductId = 1;
|
||||
mSerialNumber = "000000000000";
|
||||
|
||||
mActionCodeIndex = actionCodeIndex;
|
||||
|
||||
if(mActionCodeIndex >= OculusVRConstants::MaxSensors)
|
||||
{
|
||||
// Cannot declare more sensors than we are able to handle
|
||||
mIsValid = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::buildCodeTable()
|
||||
{
|
||||
// Obtain all of the device codes
|
||||
for(U32 i=0; i<OculusVRConstants::MaxSensors; ++i)
|
||||
{
|
||||
OVR_SENSORROT[i] = INPUTMGR->getNextDeviceCode();
|
||||
|
||||
OVR_SENSORROTANG[i] = INPUTMGR->getNextDeviceCode();
|
||||
|
||||
OVR_SENSORROTAXISX[i] = INPUTMGR->getNextDeviceCode();
|
||||
OVR_SENSORROTAXISY[i] = INPUTMGR->getNextDeviceCode();
|
||||
}
|
||||
|
||||
// Build out the virtual map
|
||||
char buffer[64];
|
||||
for(U32 i=0; i<OculusVRConstants::MaxSensors; ++i)
|
||||
{
|
||||
dSprintf(buffer, 64, "ovr_sensorrot%d", i);
|
||||
INPUTMGR->addVirtualMap( buffer, SI_ROT, OVR_SENSORROT[i] );
|
||||
|
||||
dSprintf(buffer, 64, "ovr_sensorrotang%d", i);
|
||||
INPUTMGR->addVirtualMap( buffer, SI_ROT, OVR_SENSORROTANG[i] );
|
||||
|
||||
dSprintf(buffer, 64, "ovr_sensorrotaxisx%d", i);
|
||||
INPUTMGR->addVirtualMap( buffer, SI_AXIS, OVR_SENSORROTAXISX[i] );
|
||||
dSprintf(buffer, 64, "ovr_sensorrotaxisy%d", i);
|
||||
INPUTMGR->addVirtualMap( buffer, SI_AXIS, OVR_SENSORROTAXISY[i] );
|
||||
}
|
||||
}
|
||||
|
||||
bool OculusVRSensorDevice::process(U32 deviceType, bool generateRotAsAngAxis, bool generateRotAsEuler, bool generateRotationAsAxisEvents, F32 maxAxisRadius)
|
||||
{
|
||||
if(!mIsValid)
|
||||
return false;
|
||||
|
||||
// Store the current data from the sensor and compare with previous data
|
||||
U32 diff;
|
||||
OculusVRSensorData* currentBuffer = (mPrevData == mDataBuffer[0]) ? mDataBuffer[1] : mDataBuffer[0];
|
||||
if(!mIsSimulation)
|
||||
{
|
||||
currentBuffer->setData(mSensorFusion, maxAxisRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
currentBuffer->simulateData(maxAxisRadius);
|
||||
}
|
||||
diff = mPrevData->compare(currentBuffer);
|
||||
|
||||
// Update the previous data pointer. We do this here in case someone calls our
|
||||
// console functions during one of the input events below.
|
||||
mPrevData = currentBuffer;
|
||||
|
||||
// Rotation event
|
||||
if(diff & OculusVRSensorData::DIFF_ROT)
|
||||
{
|
||||
if(generateRotAsAngAxis)
|
||||
{
|
||||
INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_ROT, OVR_SENSORROT[mActionCodeIndex], SI_MOVE, currentBuffer->mRotQuat);
|
||||
}
|
||||
|
||||
if(generateRotAsEuler)
|
||||
{
|
||||
// Convert angles to degrees
|
||||
VectorF angles;
|
||||
for(U32 i=0; i<3; ++i)
|
||||
{
|
||||
angles[i] = mRadToDeg(currentBuffer->mRotEuler[i]);
|
||||
}
|
||||
INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_POS, OVR_SENSORROTANG[mActionCodeIndex], SI_MOVE, angles);
|
||||
}
|
||||
}
|
||||
|
||||
// Rotation as axis event
|
||||
if(generateRotationAsAxisEvents && diff & OculusVRSensorData::DIFF_ROTAXIS)
|
||||
{
|
||||
if(diff & OculusVRSensorData::DIFF_ROTAXISX)
|
||||
INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISX[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.x);
|
||||
if(diff & OculusVRSensorData::DIFF_ROTAXISY)
|
||||
INPUTMGR->buildInputEvent(deviceType, OculusVRConstants::DefaultOVRBase, SI_AXIS, OVR_SENSORROTAXISY[mActionCodeIndex], SI_MOVE, currentBuffer->mRotAxis.y);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::reset()
|
||||
{
|
||||
if(!mIsValid)
|
||||
return;
|
||||
|
||||
mSensorFusion.Reset();
|
||||
}
|
||||
|
||||
F32 OculusVRSensorDevice::getPredictionTime() const
|
||||
{
|
||||
if(!mIsValid)
|
||||
return 0.0f;
|
||||
|
||||
return mSensorFusion.GetPredictionDelta();
|
||||
}
|
||||
|
||||
void OculusVRSensorDevice::setPredictionTime(F32 dt)
|
||||
{
|
||||
if(!mIsValid)
|
||||
return;
|
||||
|
||||
mSensorFusion.SetPrediction(dt);
|
||||
}
|
||||
|
||||
EulerF OculusVRSensorDevice::getEulerRotation()
|
||||
{
|
||||
if(!mIsValid)
|
||||
return Point3F::Zero;
|
||||
|
||||
OVR::Quatf orientation;
|
||||
if(mSensorFusion.GetPredictionDelta() > 0)
|
||||
{
|
||||
orientation = mSensorFusion.GetPredictedOrientation();
|
||||
}
|
||||
else
|
||||
{
|
||||
orientation = mSensorFusion.GetOrientation();
|
||||
}
|
||||
|
||||
// Sensor rotation in Euler format
|
||||
EulerF rot;
|
||||
OculusVRUtil::convertRotation(orientation, rot);
|
||||
|
||||
return rot;
|
||||
}
|
||||
122
Engine/source/platform/input/oculusVR/oculusVRSensorDevice.h
Normal file
122
Engine/source/platform/input/oculusVR/oculusVRSensorDevice.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _OCULUSVRSENSORDEVICE_H_
|
||||
#define _OCULUSVRSENSORDEVICE_H_
|
||||
|
||||
#include "core/util/str.h"
|
||||
#include "math/mQuat.h"
|
||||
#include "math/mPoint2.h"
|
||||
#include "math/mPoint3.h"
|
||||
#include "math/mPoint4.h"
|
||||
#include "platform/input/oculusVR/oculusVRConstants.h"
|
||||
#include "platform/types.h"
|
||||
#include "OVR.h"
|
||||
|
||||
struct OculusVRSensorData;
|
||||
|
||||
class OculusVRSensorDevice
|
||||
{
|
||||
public:
|
||||
enum SimulationTypes {
|
||||
ST_RIFT_PREVIEW,
|
||||
};
|
||||
|
||||
public:
|
||||
// Action codes
|
||||
static U32 OVR_SENSORROT[OculusVRConstants::MaxSensors]; // SI_ROT
|
||||
|
||||
static U32 OVR_SENSORROTANG[OculusVRConstants::MaxSensors]; // SI_POS but is EulerF
|
||||
|
||||
static U32 OVR_SENSORROTAXISX[OculusVRConstants::MaxSensors]; // SI_AXIS
|
||||
static U32 OVR_SENSORROTAXISY[OculusVRConstants::MaxSensors];
|
||||
|
||||
protected:
|
||||
bool mIsValid;
|
||||
|
||||
bool mIsSimulation;
|
||||
|
||||
OVR::SensorDevice* mDevice;
|
||||
|
||||
OVR::SensorFusion mSensorFusion;
|
||||
|
||||
// From OVR::DeviceInfo
|
||||
String mProductName;
|
||||
String mManufacturer;
|
||||
U32 mVersion;
|
||||
|
||||
// From OVR::SensorInfo
|
||||
U16 mVendorId;
|
||||
U16 mProductId;
|
||||
String mSerialNumber;
|
||||
|
||||
// Assigned by the OculusVRDevice
|
||||
S32 mActionCodeIndex;
|
||||
|
||||
// Buffers to store data for sensor
|
||||
OculusVRSensorData* mDataBuffer[2];
|
||||
|
||||
// Points to the buffer that holds the previously collected data
|
||||
// for the sensor
|
||||
OculusVRSensorData* mPrevData;
|
||||
|
||||
protected:
|
||||
void createSimulatedPreviewRift(S32 actionCodeIndex);
|
||||
|
||||
public:
|
||||
OculusVRSensorDevice();
|
||||
virtual ~OculusVRSensorDevice();
|
||||
|
||||
static void buildCodeTable();
|
||||
|
||||
void cleanUp();
|
||||
|
||||
// Set the sensor properties based on information from the OVR device
|
||||
void set(OVR::SensorDevice* sensor, OVR::SensorInfo& info, S32 actionCodeIndex);
|
||||
|
||||
// Set the sensor properties based on a simulation of the given type
|
||||
void createSimulation(SimulationTypes simulationType, S32 actionCodeIndex);
|
||||
|
||||
bool isValid() const {return mIsValid;}
|
||||
bool isSimulated() {return mIsSimulation;}
|
||||
|
||||
bool process(U32 deviceType, bool generateRotAsAngAxis, bool generateRotAsEuler, bool generateRotationAsAxisEvents, F32 maxAxisRadius);
|
||||
|
||||
void reset();
|
||||
|
||||
// Get the prediction time for the sensor fusion. The time is in seconds.
|
||||
F32 getPredictionTime() const;
|
||||
|
||||
// Set the prediction time for the sensor fusion. The time is in seconds.
|
||||
void setPredictionTime(F32 dt);
|
||||
|
||||
const char* getProductName() { return mProductName.c_str(); }
|
||||
const char* getManufacturer() { return mManufacturer.c_str(); }
|
||||
U32 getVersion() { return mVersion; }
|
||||
U16 getVendorId() { return mVendorId; }
|
||||
U16 getProductId() { return mProductId; }
|
||||
const char* getSerialNumber() { return mSerialNumber; }
|
||||
|
||||
EulerF getEulerRotation();
|
||||
};
|
||||
|
||||
#endif // _OCULUSVRSENSORDEVICE_H_
|
||||
76
Engine/source/platform/input/oculusVR/oculusVRUtil.cpp
Normal file
76
Engine/source/platform/input/oculusVR/oculusVRUtil.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/input/oculusVR/oculusVRUtil.h"
|
||||
|
||||
namespace OculusVRUtil
|
||||
{
|
||||
|
||||
void convertRotation(const F32 inRotMat[4][4], MatrixF& outRotation)
|
||||
{
|
||||
// Set rotation. We need to convert from sensor coordinates to
|
||||
// Torque coordinates. The sensor matrix is stored row-major.
|
||||
// The conversion is:
|
||||
//
|
||||
// Sensor Torque
|
||||
// a b c a b c a -c b
|
||||
// d e f --> -g -h -i --> -g i -h
|
||||
// g h i d e f d -f e
|
||||
outRotation.setColumn(0, Point4F( inRotMat[0][0], -inRotMat[2][0], inRotMat[1][0], 0.0f));
|
||||
outRotation.setColumn(1, Point4F(-inRotMat[0][2], inRotMat[2][2], -inRotMat[1][2], 0.0f));
|
||||
outRotation.setColumn(2, Point4F( inRotMat[0][1], -inRotMat[2][1], inRotMat[1][1], 0.0f));
|
||||
outRotation.setPosition(Point3F::Zero);
|
||||
}
|
||||
|
||||
void convertRotation(OVR::Quatf& inRotation, EulerF& outRotation)
|
||||
{
|
||||
F32 yaw, pitch, roll;
|
||||
inRotation.GetEulerAngles<OVR::Axis_Y, OVR::Axis_X, OVR::Axis_Z>(&yaw, &pitch, &roll);
|
||||
outRotation.x = -pitch;
|
||||
outRotation.y = roll;
|
||||
outRotation.z = -yaw;
|
||||
}
|
||||
|
||||
void calculateAxisRotation(const MatrixF& inRotation, const F32& maxAxisRadius, Point2F& outRotation)
|
||||
{
|
||||
const VectorF& controllerUp = inRotation.getUpVector();
|
||||
Point2F axis(0,0);
|
||||
axis.x = controllerUp.x;
|
||||
axis.y = controllerUp.y;
|
||||
|
||||
// Limit the axis angle to that given to us
|
||||
if(axis.len() > maxAxisRadius)
|
||||
{
|
||||
axis.normalize(maxAxisRadius);
|
||||
}
|
||||
|
||||
// Renormalize to the range of 0..1
|
||||
if(maxAxisRadius != 0.0f)
|
||||
{
|
||||
axis /= maxAxisRadius;
|
||||
}
|
||||
|
||||
outRotation.x = axis.x;
|
||||
outRotation.y = axis.y;
|
||||
}
|
||||
|
||||
}
|
||||
42
Engine/source/platform/input/oculusVR/oculusVRUtil.h
Normal file
42
Engine/source/platform/input/oculusVR/oculusVRUtil.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _OCULUSVRUTIL_H_
|
||||
#define _OCULUSVRUTIL_H_
|
||||
|
||||
#include "math/mPoint2.h"
|
||||
#include "math/mMatrix.h"
|
||||
#include "OVR.h"
|
||||
|
||||
namespace OculusVRUtil
|
||||
{
|
||||
/// Convert an OVR sensor's rotation to a Torque 3D matrix
|
||||
void convertRotation(const F32 inRotMat[4][4], MatrixF& outRotation);
|
||||
|
||||
/// Convert an OVR sensor's rotation to Torque 3D Euler angles (in radians)
|
||||
void convertRotation(OVR::Quatf& inRotation, EulerF& outRotation);
|
||||
|
||||
/// Calcualte a sensor's rotation as if it were a thumb stick axis
|
||||
void calculateAxisRotation(const MatrixF& inRotation, const F32& maxAxisRadius, Point2F& outRotation);
|
||||
}
|
||||
|
||||
#endif // _OCULUSVRUTIL_H_
|
||||
|
|
@ -54,6 +54,9 @@ function initializeCore()
|
|||
exec( "./audioStates.cs" );
|
||||
exec( "./audioAmbiences.cs" );
|
||||
|
||||
// Input devices
|
||||
exec("~/scripts/client/oculusVR.cs");
|
||||
|
||||
// Seed the random number generator.
|
||||
setRandomSeed();
|
||||
|
||||
|
|
|
|||
125
Templates/Empty/game/core/scripts/client/oculusVR.cs
Normal file
125
Templates/Empty/game/core/scripts/client/oculusVR.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Only load these functions if an Oculus VR device is present
|
||||
if(!isFunction(isOculusVRDeviceActive))
|
||||
return;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function oculusSensorMetricsCallback()
|
||||
{
|
||||
return " | OVR Sensor 0 |" @
|
||||
" rot: " @ getOVRSensorEulerRotation(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Call this function from createCanvas() to have the Canvas attach itself
|
||||
// to the Rift's display. The Canvas' window will still open on the primary
|
||||
// display if that is different from the Rift, but it will move to the Rift
|
||||
// when it goes full screen. If the Rift is not connected then nothing
|
||||
// will happen.
|
||||
function pointCanvasToOculusVRDisplay()
|
||||
{
|
||||
$pref::Video::displayOutputDevice = getOVRHMDDisplayDeviceName(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Call this function from GameConnection::initialControlSet() just before
|
||||
// your "Canvas.setContent(PlayGui);" call, or at any time you wish to switch
|
||||
// to a side-by-side rendering and the appropriate barrel distortion. This
|
||||
// will turn on side-by-side rendering and tell the GameConnection to use the
|
||||
// Rift as its display device.
|
||||
// Parameters:
|
||||
// %gameConnection - The client GameConnection instance
|
||||
// %trueStereoRendering - If true will enable stereo rendering with an eye
|
||||
// offset for each viewport. This will render each frame twice. If false
|
||||
// then a pseudo stereo rendering is done with only a single render per frame.
|
||||
function enableOculusVRDisplay(%gameConnection, %trueStereoRendering)
|
||||
{
|
||||
setOVRHMDAsGameConnectionDisplayDevice(%gameConnection);
|
||||
PlayGui.renderStyle = "stereo side by side";
|
||||
|
||||
if(%trueStereoRendering)
|
||||
{
|
||||
OVRBarrelDistortionPostFX.isEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBarrelDistortionMonoPostFX.isEnabled = true;
|
||||
}
|
||||
|
||||
// Reset all sensors
|
||||
ovrResetAllSensors();
|
||||
}
|
||||
|
||||
// Call this function when ever you wish to turn off the stereo rendering
|
||||
// and barrel distortion for the Rift.
|
||||
function disableOculusVRDisplay(%gameConnection)
|
||||
{
|
||||
%gameConnection.clearDisplayDevice();
|
||||
PlayGui.renderStyle = "standard";
|
||||
OVRBarrelDistortionPostFX.isEnabled = false;
|
||||
OVRBarrelDistortionMonoPostFX.isEnabled = false;
|
||||
}
|
||||
|
||||
// Helper function to set the standard Rift control scheme. You could place
|
||||
// this function in GameConnection::initialControlSet() at the same time
|
||||
// you call enableOculusVRDisplay().
|
||||
function setStandardOculusVRControlScheme(%gameConnection)
|
||||
{
|
||||
if(isOVRHMDSimulated(0))
|
||||
{
|
||||
// We are simulating a HMD so allow the mouse and gamepad to control
|
||||
// both yaw and pitch.
|
||||
%gameConnection.setControlSchemeParameters(true, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// A HMD is connected so have the mouse and gamepad only add to yaw
|
||||
%gameConnection.setControlSchemeParameters(true, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helper function to set the resolution for the Rift.
|
||||
// Parameters:
|
||||
// %fullscreen - If true then the display will be forced to full screen. If
|
||||
// pointCanvasToOculusVRDisplay() was called before the Canvas was created, then
|
||||
// the full screen display will appear on the Rift.
|
||||
function setVideoModeForOculusVRDisplay(%fullscreen)
|
||||
{
|
||||
%res = getOVRHMDResolution(0);
|
||||
Canvas.setVideoMode(%res.x, %res.y, %fullscreen, 32, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Reset all Oculus Rift sensors. This will make the Rift's current heading
|
||||
// be considered the origin.
|
||||
function resetOculusVRSensors()
|
||||
{
|
||||
ovrResetAllSensors();
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Only load these shaders if an Oculus VR device is present
|
||||
if(!isFunction(isOculusVRDeviceActive))
|
||||
return;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shader data
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
singleton ShaderData( OVRMonoToStereoShader )
|
||||
{
|
||||
DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl";
|
||||
DXPixelShaderFile = "shaders/common/postFx/oculusvr/monoToStereoP.hlsl";
|
||||
|
||||
pixVersion = 2.0;
|
||||
};
|
||||
|
||||
singleton ShaderData( OVRBarrelDistortionShader )
|
||||
{
|
||||
DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl";
|
||||
DXPixelShaderFile = "shaders/common/postFx/oculusvr/barrelDistortionP.hlsl";
|
||||
|
||||
pixVersion = 2.0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GFX state blocks
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
singleton GFXStateBlockData( OVRBarrelDistortionStateBlock : PFX_DefaultStateBlock )
|
||||
{
|
||||
samplersDefined = true;
|
||||
samplerStates[0] = SamplerClampLinear;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Barrel Distortion PostFx
|
||||
//
|
||||
// To be used with the Oculus Rift.
|
||||
// Expects a stereo pair to exist on the back buffer and then applies the
|
||||
// appropriate barrel distortion.
|
||||
//-----------------------------------------------------------------------------
|
||||
singleton BarrelDistortionPostEffect( OVRBarrelDistortionPostFX )
|
||||
{
|
||||
isEnabled = false;
|
||||
allowReflectPass = false;
|
||||
|
||||
renderTime = "PFXAfterDiffuse";
|
||||
renderPriority = 100;
|
||||
|
||||
// The barrel distortion
|
||||
shader = OVRBarrelDistortionShader;
|
||||
stateBlock = OVRBarrelDistortionStateBlock;
|
||||
|
||||
texture[0] = "$backBuffer";
|
||||
|
||||
scaleOutput = 1.25;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Barrel Distortion Mono PostFx
|
||||
//
|
||||
// To be used with the Oculus Rift.
|
||||
// Takes a non-stereo image and turns it into a stereo pair with barrel
|
||||
// distortion applied. Only a vertical slice around the center of the back
|
||||
// buffer is used to generate the pseudo stereo pair.
|
||||
//-----------------------------------------------------------------------------
|
||||
singleton PostEffect( OVRBarrelDistortionMonoPostFX )
|
||||
{
|
||||
isEnabled = false;
|
||||
allowReflectPass = false;
|
||||
|
||||
renderTime = "PFXAfterDiffuse";
|
||||
renderPriority = 100;
|
||||
|
||||
// Converts the mono display to a stereo one
|
||||
shader = OVRMonoToStereoShader;
|
||||
stateBlock = OVRBarrelDistortionStateBlock;
|
||||
|
||||
texture[0] = "$backBuffer";
|
||||
target = "$outTex";
|
||||
|
||||
// The actual barrel distortion
|
||||
new BarrelDistortionPostEffect(OVRBarrelDistortionMonoStage2PostFX)
|
||||
{
|
||||
shader = OVRBarrelDistortionShader;
|
||||
stateBlock = OVRBarrelDistortionStateBlock;
|
||||
texture[0] = "$inTex";
|
||||
target = "$backBuffer";
|
||||
|
||||
scaleOutput = 1.25;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
function OVRBarrelDistortionMonoPostFX::setShaderConsts( %this )
|
||||
{
|
||||
%HMDIndex = 0;
|
||||
|
||||
%xOffsets = getOVRHMDEyeXOffsets(%HMDIndex);
|
||||
%this.setShaderConst( "$LensXOffsets", %xOffsets );
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "shadergen:/autogenConditioners.h"
|
||||
#include "../postFx.hlsl"
|
||||
#include "../../torque.hlsl"
|
||||
|
||||
uniform sampler2D backBuffer : register(S0);
|
||||
|
||||
uniform float3 LensCenter; // x=Left X, y=Right X, z=Y
|
||||
uniform float2 ScreenCenter;
|
||||
uniform float2 Scale;
|
||||
uniform float2 ScaleIn;
|
||||
uniform float4 HmdWarpParam;
|
||||
|
||||
// Scales input texture coordinates for distortion.
|
||||
// ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
|
||||
// larger due to aspect ratio.
|
||||
float2 HmdWarp(float2 in01, float2 lensCenter)
|
||||
{
|
||||
float2 theta = (in01 - lensCenter) * ScaleIn; // Scales to [-1, 1]
|
||||
float rSq = theta.x * theta.x + theta.y * theta.y;
|
||||
float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);
|
||||
return lensCenter + Scale * theta1;
|
||||
}
|
||||
|
||||
float4 main( PFXVertToPix IN ) : COLOR0
|
||||
{
|
||||
float2 texCoord;
|
||||
float xOffset;
|
||||
float2 lensCenter;
|
||||
lensCenter.y = LensCenter.z;
|
||||
if(IN.uv0.x < 0.5)
|
||||
{
|
||||
texCoord.x = IN.uv0.x;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.0;
|
||||
lensCenter.x = LensCenter.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
texCoord.x = IN.uv0.x - 0.5;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.5;
|
||||
lensCenter.x = LensCenter.y;
|
||||
}
|
||||
|
||||
float2 tc = HmdWarp(texCoord, lensCenter);
|
||||
|
||||
float4 color;
|
||||
if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))
|
||||
{
|
||||
color = float4(0,0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tc.x += xOffset;
|
||||
color = tex2D(backBuffer, tc);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "shadergen:/autogenConditioners.h"
|
||||
#include "../postFx.hlsl"
|
||||
#include "../../torque.hlsl"
|
||||
|
||||
uniform sampler2D backBuffer : register(S0);
|
||||
|
||||
uniform float2 LensXOffsets;
|
||||
|
||||
float4 main( PFXVertToPix IN ) : COLOR0
|
||||
{
|
||||
float2 texCoord;
|
||||
float xOffset;
|
||||
float2 lensCenter;
|
||||
lensCenter.y = 0.5;
|
||||
if(IN.uv0.x < 0.5)
|
||||
{
|
||||
texCoord.x = IN.uv0.x;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.0;
|
||||
lensCenter.x = LensXOffsets.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
texCoord.x = IN.uv0.x - 0.5;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.5;
|
||||
lensCenter.x = LensXOffsets.y;
|
||||
}
|
||||
|
||||
texCoord.x *= 2.0;
|
||||
texCoord.x += lensCenter.x;
|
||||
texCoord.x *= 0.5;
|
||||
texCoord.x += 0.25;
|
||||
|
||||
float4 color = tex2D(backBuffer, texCoord);
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
@ -54,6 +54,9 @@ function initializeCore()
|
|||
exec( "./audioStates.cs" );
|
||||
exec( "./audioAmbiences.cs" );
|
||||
|
||||
// Input devices
|
||||
exec("~/scripts/client/oculusVR.cs");
|
||||
|
||||
// Seed the random number generator.
|
||||
setRandomSeed();
|
||||
|
||||
|
|
|
|||
125
Templates/Full/game/core/scripts/client/oculusVR.cs
Normal file
125
Templates/Full/game/core/scripts/client/oculusVR.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Only load these functions if an Oculus VR device is present
|
||||
if(!isFunction(isOculusVRDeviceActive))
|
||||
return;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function oculusSensorMetricsCallback()
|
||||
{
|
||||
return " | OVR Sensor 0 |" @
|
||||
" rot: " @ getOVRSensorEulerRotation(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Call this function from createCanvas() to have the Canvas attach itself
|
||||
// to the Rift's display. The Canvas' window will still open on the primary
|
||||
// display if that is different from the Rift, but it will move to the Rift
|
||||
// when it goes full screen. If the Rift is not connected then nothing
|
||||
// will happen.
|
||||
function pointCanvasToOculusVRDisplay()
|
||||
{
|
||||
$pref::Video::displayOutputDevice = getOVRHMDDisplayDeviceName(0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Call this function from GameConnection::initialControlSet() just before
|
||||
// your "Canvas.setContent(PlayGui);" call, or at any time you wish to switch
|
||||
// to a side-by-side rendering and the appropriate barrel distortion. This
|
||||
// will turn on side-by-side rendering and tell the GameConnection to use the
|
||||
// Rift as its display device.
|
||||
// Parameters:
|
||||
// %gameConnection - The client GameConnection instance
|
||||
// %trueStereoRendering - If true will enable stereo rendering with an eye
|
||||
// offset for each viewport. This will render each frame twice. If false
|
||||
// then a pseudo stereo rendering is done with only a single render per frame.
|
||||
function enableOculusVRDisplay(%gameConnection, %trueStereoRendering)
|
||||
{
|
||||
setOVRHMDAsGameConnectionDisplayDevice(%gameConnection);
|
||||
PlayGui.renderStyle = "stereo side by side";
|
||||
|
||||
if(%trueStereoRendering)
|
||||
{
|
||||
OVRBarrelDistortionPostFX.isEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OVRBarrelDistortionMonoPostFX.isEnabled = true;
|
||||
}
|
||||
|
||||
// Reset all sensors
|
||||
ovrResetAllSensors();
|
||||
}
|
||||
|
||||
// Call this function when ever you wish to turn off the stereo rendering
|
||||
// and barrel distortion for the Rift.
|
||||
function disableOculusVRDisplay(%gameConnection)
|
||||
{
|
||||
%gameConnection.clearDisplayDevice();
|
||||
PlayGui.renderStyle = "standard";
|
||||
OVRBarrelDistortionPostFX.isEnabled = false;
|
||||
OVRBarrelDistortionMonoPostFX.isEnabled = false;
|
||||
}
|
||||
|
||||
// Helper function to set the standard Rift control scheme. You could place
|
||||
// this function in GameConnection::initialControlSet() at the same time
|
||||
// you call enableOculusVRDisplay().
|
||||
function setStandardOculusVRControlScheme(%gameConnection)
|
||||
{
|
||||
if(isOVRHMDSimulated(0))
|
||||
{
|
||||
// We are simulating a HMD so allow the mouse and gamepad to control
|
||||
// both yaw and pitch.
|
||||
%gameConnection.setControlSchemeParameters(true, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// A HMD is connected so have the mouse and gamepad only add to yaw
|
||||
%gameConnection.setControlSchemeParameters(true, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helper function to set the resolution for the Rift.
|
||||
// Parameters:
|
||||
// %fullscreen - If true then the display will be forced to full screen. If
|
||||
// pointCanvasToOculusVRDisplay() was called before the Canvas was created, then
|
||||
// the full screen display will appear on the Rift.
|
||||
function setVideoModeForOculusVRDisplay(%fullscreen)
|
||||
{
|
||||
%res = getOVRHMDResolution(0);
|
||||
Canvas.setVideoMode(%res.x, %res.y, %fullscreen, 32, 0);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Reset all Oculus Rift sensors. This will make the Rift's current heading
|
||||
// be considered the origin.
|
||||
function resetOculusVRSensors()
|
||||
{
|
||||
ovrResetAllSensors();
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Only load these shaders if an Oculus VR device is present
|
||||
if(!isFunction(isOculusVRDeviceActive))
|
||||
return;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Shader data
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
singleton ShaderData( OVRMonoToStereoShader )
|
||||
{
|
||||
DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl";
|
||||
DXPixelShaderFile = "shaders/common/postFx/oculusvr/monoToStereoP.hlsl";
|
||||
|
||||
pixVersion = 2.0;
|
||||
};
|
||||
|
||||
singleton ShaderData( OVRBarrelDistortionShader )
|
||||
{
|
||||
DXVertexShaderFile = "shaders/common/postFx/postFxV.hlsl";
|
||||
DXPixelShaderFile = "shaders/common/postFx/oculusvr/barrelDistortionP.hlsl";
|
||||
|
||||
pixVersion = 2.0;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GFX state blocks
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
singleton GFXStateBlockData( OVRBarrelDistortionStateBlock : PFX_DefaultStateBlock )
|
||||
{
|
||||
samplersDefined = true;
|
||||
samplerStates[0] = SamplerClampLinear;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Barrel Distortion PostFx
|
||||
//
|
||||
// To be used with the Oculus Rift.
|
||||
// Expects a stereo pair to exist on the back buffer and then applies the
|
||||
// appropriate barrel distortion.
|
||||
//-----------------------------------------------------------------------------
|
||||
singleton BarrelDistortionPostEffect( OVRBarrelDistortionPostFX )
|
||||
{
|
||||
isEnabled = false;
|
||||
allowReflectPass = false;
|
||||
|
||||
renderTime = "PFXAfterDiffuse";
|
||||
renderPriority = 100;
|
||||
|
||||
// The barrel distortion
|
||||
shader = OVRBarrelDistortionShader;
|
||||
stateBlock = OVRBarrelDistortionStateBlock;
|
||||
|
||||
texture[0] = "$backBuffer";
|
||||
|
||||
scaleOutput = 1.25;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Barrel Distortion Mono PostFx
|
||||
//
|
||||
// To be used with the Oculus Rift.
|
||||
// Takes a non-stereo image and turns it into a stereo pair with barrel
|
||||
// distortion applied. Only a vertical slice around the center of the back
|
||||
// buffer is used to generate the pseudo stereo pair.
|
||||
//-----------------------------------------------------------------------------
|
||||
singleton PostEffect( OVRBarrelDistortionMonoPostFX )
|
||||
{
|
||||
isEnabled = false;
|
||||
allowReflectPass = false;
|
||||
|
||||
renderTime = "PFXAfterDiffuse";
|
||||
renderPriority = 100;
|
||||
|
||||
// Converts the mono display to a stereo one
|
||||
shader = OVRMonoToStereoShader;
|
||||
stateBlock = OVRBarrelDistortionStateBlock;
|
||||
|
||||
texture[0] = "$backBuffer";
|
||||
target = "$outTex";
|
||||
|
||||
// The actual barrel distortion
|
||||
new BarrelDistortionPostEffect(OVRBarrelDistortionMonoStage2PostFX)
|
||||
{
|
||||
shader = OVRBarrelDistortionShader;
|
||||
stateBlock = OVRBarrelDistortionStateBlock;
|
||||
texture[0] = "$inTex";
|
||||
target = "$backBuffer";
|
||||
|
||||
scaleOutput = 1.25;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
function OVRBarrelDistortionMonoPostFX::setShaderConsts( %this )
|
||||
{
|
||||
%HMDIndex = 0;
|
||||
|
||||
%xOffsets = getOVRHMDEyeXOffsets(%HMDIndex);
|
||||
%this.setShaderConst( "$LensXOffsets", %xOffsets );
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "shadergen:/autogenConditioners.h"
|
||||
#include "../postFx.hlsl"
|
||||
#include "../../torque.hlsl"
|
||||
|
||||
uniform sampler2D backBuffer : register(S0);
|
||||
|
||||
uniform float3 LensCenter; // x=Left X, y=Right X, z=Y
|
||||
uniform float2 ScreenCenter;
|
||||
uniform float2 Scale;
|
||||
uniform float2 ScaleIn;
|
||||
uniform float4 HmdWarpParam;
|
||||
|
||||
// Scales input texture coordinates for distortion.
|
||||
// ScaleIn maps texture coordinates to Scales to ([-1, 1]), although top/bottom will be
|
||||
// larger due to aspect ratio.
|
||||
float2 HmdWarp(float2 in01, float2 lensCenter)
|
||||
{
|
||||
float2 theta = (in01 - lensCenter) * ScaleIn; // Scales to [-1, 1]
|
||||
float rSq = theta.x * theta.x + theta.y * theta.y;
|
||||
float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);
|
||||
return lensCenter + Scale * theta1;
|
||||
}
|
||||
|
||||
float4 main( PFXVertToPix IN ) : COLOR0
|
||||
{
|
||||
float2 texCoord;
|
||||
float xOffset;
|
||||
float2 lensCenter;
|
||||
lensCenter.y = LensCenter.z;
|
||||
if(IN.uv0.x < 0.5)
|
||||
{
|
||||
texCoord.x = IN.uv0.x;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.0;
|
||||
lensCenter.x = LensCenter.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
texCoord.x = IN.uv0.x - 0.5;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.5;
|
||||
lensCenter.x = LensCenter.y;
|
||||
}
|
||||
|
||||
float2 tc = HmdWarp(texCoord, lensCenter);
|
||||
|
||||
float4 color;
|
||||
if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))
|
||||
{
|
||||
color = float4(0,0,0,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
tc.x += xOffset;
|
||||
color = tex2D(backBuffer, tc);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "shadergen:/autogenConditioners.h"
|
||||
#include "../postFx.hlsl"
|
||||
#include "../../torque.hlsl"
|
||||
|
||||
uniform sampler2D backBuffer : register(S0);
|
||||
|
||||
uniform float2 LensXOffsets;
|
||||
|
||||
float4 main( PFXVertToPix IN ) : COLOR0
|
||||
{
|
||||
float2 texCoord;
|
||||
float xOffset;
|
||||
float2 lensCenter;
|
||||
lensCenter.y = 0.5;
|
||||
if(IN.uv0.x < 0.5)
|
||||
{
|
||||
texCoord.x = IN.uv0.x;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.0;
|
||||
lensCenter.x = LensXOffsets.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
texCoord.x = IN.uv0.x - 0.5;
|
||||
texCoord.y = IN.uv0.y;
|
||||
xOffset = 0.5;
|
||||
lensCenter.x = LensXOffsets.y;
|
||||
}
|
||||
|
||||
texCoord.x *= 2.0;
|
||||
texCoord.x += lensCenter.x;
|
||||
texCoord.x *= 0.5;
|
||||
texCoord.x += 0.25;
|
||||
|
||||
float4 color = tex2D(backBuffer, texCoord);
|
||||
|
||||
return color;
|
||||
}
|
||||
80
Tools/projectGenerator/modules/oculusVR.inc
Normal file
80
Tools/projectGenerator/modules/oculusVR.inc
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (c) 2012 GarageGames, LLC
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
beginModule( 'oculusVR' );
|
||||
|
||||
// Look for the optional global from the project.conf.
|
||||
global $OCULUSVR_SDK_PATH;
|
||||
if (!$OCULUSVR_SDK_PATH)
|
||||
{
|
||||
// First look for an environment var.
|
||||
$OCULUSVR_SDK_PATH = getenv( "TORQUE_OCULUSVR_PATH" );
|
||||
|
||||
if (strlen($OCULUSVR_SDK_PATH) == 0 || !file_exists($OCULUSVR_SDK_PATH))
|
||||
{
|
||||
// Sometimes users get confused and use this var.
|
||||
$OCULUSVR_SDK_PATH = getenv( "OCULUSVR_SDK_PATH" );
|
||||
}
|
||||
|
||||
// We need forward slashes for paths.
|
||||
$OCULUSVR_SDK_PATH = str_replace( "\\", "/", $OCULUSVR_SDK_PATH);
|
||||
|
||||
// Remove trailing slashes.
|
||||
$OCULUSVR_SDK_PATH = rtrim($OCULUSVR_SDK_PATH, " /");
|
||||
}
|
||||
|
||||
// If we still don't have the SDK path then let the user know.
|
||||
if (!file_exists($OCULUSVR_SDK_PATH))
|
||||
{
|
||||
trigger_error(
|
||||
"\n*******************************************************************".
|
||||
"\n".
|
||||
"\n We were not able to find a valid path to the Oculus Rift SDK!".
|
||||
"\n".
|
||||
"\n You must install the latest Oculus VR SDK and set the path via a".
|
||||
"\n \$OCULUSVR_SDK_PATH variable in your buildFiles/project.conf file".
|
||||
"\n or by setting the TORQUE_OCULUSVR_PATH system environment variable".
|
||||
"\n (may require a reboot).".
|
||||
"\n".
|
||||
"\n*******************************************************************".
|
||||
"\n", E_USER_ERROR );
|
||||
}
|
||||
|
||||
// Only Windows is supported at this time
|
||||
if ( Generator::$platform == "win32" )
|
||||
{
|
||||
// Source
|
||||
addEngineSrcDir( "platform/input/oculusVR" );
|
||||
|
||||
// Includes
|
||||
addIncludePath( $OCULUSVR_SDK_PATH . "/LibOVR/Include" );
|
||||
addIncludePath( $OCULUSVR_SDK_PATH . "/LibOVR/Src" );
|
||||
|
||||
// Libs
|
||||
addProjectLibDir( $OCULUSVR_SDK_PATH . "/LibOVR/Lib/Win32" );
|
||||
addProjectLibInput( "libovr.lib", "libovrd.lib" );
|
||||
}
|
||||
|
||||
endModule();
|
||||
|
||||
?>
|
||||
Loading…
Reference in a new issue