This commit is contained in:
Stephen Birarda 2015-09-17 14:15:05 -07:00
commit 320429fd1e
9 changed files with 340 additions and 314 deletions

View file

@ -1,7 +1,8 @@
(function() {
// Script.include("../libraries/utils.js");
//Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge
Script.include("https://hifi-public.s3.amazonaws.com/scripts/libraries/utils.js");
Script.include("../libraries/utils.js");
GRAB_FRAME_USER_DATA_KEY = "grabFrame";
this.userData = {};
@ -56,26 +57,21 @@
timeSinceLastMoved = 0;
}
if (self.userData.grabKey && self.userData.grabKey.activated === true) {
//Only activate for the user who grabbed the object
if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) {
if (self.activated !== true) {
//We were just grabbed, so create a particle system
self.grab();
Entities.editEntity(self.paintStream, {
animationSettings: startSetting
});
}
//Move emitter to where entity is always when its activated
self.sprayStream();
} else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) {
Entities.editEntity(self.paintStream, {
animationSettings: stopSetting
});
self.activated = false;
self.letGo();
}
}
this.grab = function() {
self.activated = true;
this.activated = true;
var animationSettings = JSON.stringify({
fps: 30,
loop: true,
@ -92,9 +88,9 @@
emitVelocity: ZERO_VEC,
emitAcceleration: ZERO_VEC,
velocitySpread: {
x: .02,
y: .02,
z: 0.02
x: .1,
y: .1,
z: 0.1
},
emitRate: 100,
particleRadius: 0.01,
@ -103,14 +99,14 @@
green: 20,
blue: 150
},
lifetime: 500, //probably wont be holding longer than this straight
lifetime: 50, //probably wont be holding longer than this straight
});
}
this.letGo = function() {
self.activated = false;
this.activated = false;
Entities.deleteEntity(this.paintStream);
this.paintStream = null;
}
this.reset = function() {
@ -123,8 +119,7 @@
}
this.sprayStream = function() {
var forwardVec = Quat.getFront(self.properties.rotation);
forwardVec = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, 90, 0), forwardVec);
var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0)));
forwardVec = Vec3.normalize(forwardVec);
var upVec = Quat.getUp(self.properties.rotation);
@ -132,11 +127,10 @@
position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y))
Entities.editEntity(self.paintStream, {
position: position,
emitVelocity: Vec3.multiply(forwardVec, 4)
emitVelocity: Vec3.multiply(5, forwardVec)
});
//Now check for an intersection with an entity
//move forward so ray doesnt intersect with gun
var origin = Vec3.sum(position, forwardVec);
var pickRay = {
@ -216,6 +210,8 @@
this.entityId = entityId;
this.properties = Entities.getEntityProperties(self.entityId);
this.getUserData();
//Only activate for the avatar who is grabbing the can!
if (this.userData.grabKey && this.userData.grabKey.activated) {
this.activated = true;
}
@ -235,7 +231,9 @@
this.unload = function() {
Script.update.disconnect(this.update);
Entities.deleteEntity(this.paintStream);
if(this.paintStream) {
Entities.deleteEntity(this.paintStream);
}
this.strokes.forEach(function(stroke) {
Entities.deleteEntity(stroke);
});
@ -244,6 +242,7 @@
});
function randFloat(min, max) {
return Math.random() * (max - min) + min;
}

View file

@ -9,9 +9,9 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//Just temporarily using my own bucket here so others can test the entity. Once PR is tested and merged, then the entity script will appear in its proper place in S3, and I wil switch it
var scriptURL = "https://hifi-public.s3.amazonaws.com/eric/scripts/sprayPaintCan.js?=v1";
// var scriptURL = "https://hifi-public.s3.amazonaws.com/eric/scripts/sprayPaintCan.js?=v6 ";
var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js?v2");
var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx";
var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1, Quat.getFront(Camera.getOrientation())));
var sprayCan = Entities.addEntity({
type: "Model",
@ -32,7 +32,10 @@ var sprayCan = Entities.addEntity({
});
function cleanup() {
Entities.deleteEntity(sprayCan);
// Uncomment the below line to delete sprayCan on script reload- for faster iteration during development
// Entities.deleteEntity(sprayCan);
}
Script.scriptEnding.connect(cleanup);

View file

@ -16,6 +16,7 @@
#include "openvr/OpenVrDisplayPlugin.h"
#include "oculus/OculusDisplayPlugin.h"
#include "oculus/OculusDebugDisplayPlugin.h"
#include "oculus/OculusLegacyDisplayPlugin.h"
const QString& DisplayPlugin::MENU_PATH() {
@ -42,6 +43,10 @@ DisplayPluginList getDisplayPlugins() {
// Windows Oculus SDK
new OculusDisplayPlugin(),
// Windows Oculus Simulator... uses head tracking and the same rendering
// as the connected hardware, but without using the SDK to display to the
// Rift. Useful for debugging Rift performance with nSight.
new OculusDebugDisplayPlugin(),
// Mac/Linux Oculus SDK (0.5)
new OculusLegacyDisplayPlugin(),
#ifdef Q_OS_WIN

View file

@ -0,0 +1,151 @@
//
// Created by Bradley Austin Davis on 2014/04/13.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "OculusBaseDisplayPlugin.h"
#include <ViewFrustum.h>
#include "OculusHelpers.h"
uvec2 OculusBaseDisplayPlugin::getRecommendedRenderSize() const {
return _desiredFramebufferSize;
}
void OculusBaseDisplayPlugin::preRender() {
#if (OVR_MAJOR_VERSION >= 6)
ovrFrameTiming ftiming = ovr_GetFrameTiming(_hmd, _frameIndex);
_trackingState = ovr_GetTrackingState(_hmd, ftiming.DisplayMidpointSeconds);
ovr_CalcEyePoses(_trackingState.HeadPose.ThePose, _eyeOffsets, _eyePoses);
#endif
}
glm::mat4 OculusBaseDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const {
return _eyeProjections[eye];
}
void OculusBaseDisplayPlugin::resetSensors() {
#if (OVR_MAJOR_VERSION >= 6)
ovr_RecenterPose(_hmd);
#endif
}
glm::mat4 OculusBaseDisplayPlugin::getEyePose(Eye eye) const {
return toGlm(_eyePoses[eye]);
}
glm::mat4 OculusBaseDisplayPlugin::getHeadPose() const {
return toGlm(_trackingState.HeadPose.ThePose);
}
bool OculusBaseDisplayPlugin::isSupported() const {
#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
return false;
}
bool result = false;
if (ovrHmd_Detect() > 0) {
result = true;
}
ovr_Shutdown();
return result;
#else
return false;
#endif
}
void OculusBaseDisplayPlugin::init() {
}
void OculusBaseDisplayPlugin::deinit() {
}
void OculusBaseDisplayPlugin::activate() {
#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
qFatal("Could not init OVR");
}
#if (OVR_MAJOR_VERSION == 6)
if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) {
#elif (OVR_MAJOR_VERSION == 7)
if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) {
#endif
Q_ASSERT(false);
qFatal("Failed to acquire HMD");
}
_hmdDesc = ovr_GetHmdDesc(_hmd);
_ipd = ovr_GetFloat(_hmd, OVR_KEY_IPD, _ipd);
glm::uvec2 eyeSizes[2];
ovr_for_each_eye([&](ovrEyeType eye) {
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]);
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, 0.001f, 10.0f, ovrProjection_RightHanded);
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
});
ovrFovPort combined = _eyeFovs[Left];
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
combined.RightTan = std::max(_eyeFovs[Left].RightTan, _eyeFovs[Right].RightTan);
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(combined, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[Mono] = toGlm(ovrPerspectiveProjection);
_desiredFramebufferSize = uvec2(
eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y));
_frameIndex = 0;
if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device");
}
// Parent class relies on our _hmd intialization, so it must come after that.
memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
_sceneLayer.Header.Type = ovrLayerType_EyeFov;
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
ovr_for_each_eye([&](ovrEyeType eye) {
ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov;
ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_hmd, eye, fov, 1.0f);
_sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
});
if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device");
}
#endif
WindowOpenGLDisplayPlugin::activate();
}
void OculusBaseDisplayPlugin::deactivate() {
WindowOpenGLDisplayPlugin::deactivate();
#if (OVR_MAJOR_VERSION >= 6)
ovr_Destroy(_hmd);
_hmd = nullptr;
ovr_Shutdown();
#endif
}
void OculusBaseDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
++_frameIndex;
}

View file

@ -0,0 +1,79 @@
//
// Created by Bradley Austin Davis on 2015/05/29
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#include "../WindowOpenGLDisplayPlugin.h"
#include <QTimer>
#include <OVR_CAPI_GL.h>
class OculusBaseDisplayPlugin : public WindowOpenGLDisplayPlugin {
public:
virtual bool isSupported() const override;
virtual void init() override final;
virtual void deinit() override final;
virtual void activate() override;
virtual void deactivate() override;
// Stereo specific methods
virtual bool isHmd() const override final { return true; }
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override;
virtual glm::uvec2 getRecommendedRenderSize() const override final;
virtual glm::uvec2 getRecommendedUiSize() const override final { return uvec2(1920, 1080); }
virtual void resetSensors() override final;
virtual glm::mat4 getEyePose(Eye eye) const override final;
virtual glm::mat4 getHeadPose() const override final;
protected:
virtual void preRender() override final;
virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
protected:
ovrPosef _eyePoses[2];
mat4 _eyeProjections[3];
mat4 _compositeEyeProjections[2];
uvec2 _desiredFramebufferSize;
ovrTrackingState _trackingState;
unsigned int _frameIndex{ 0 };
#if (OVR_MAJOR_VERSION >= 6)
ovrHmd _hmd;
float _ipd{ OVR_DEFAULT_IPD };
ovrEyeRenderDesc _eyeRenderDescs[2];
ovrVector3f _eyeOffsets[2];
ovrFovPort _eyeFovs[2];
ovrHmdDesc _hmdDesc;
ovrLayerEyeFov _sceneLayer;
#endif
#if (OVR_MAJOR_VERSION == 7)
ovrGraphicsLuid _luid;
#endif
};
#if (OVR_MAJOR_VERSION == 6)
#define ovr_Create ovrHmd_Create
#define ovr_CreateSwapTextureSetGL ovrHmd_CreateSwapTextureSetGL
#define ovr_CreateMirrorTextureGL ovrHmd_CreateMirrorTextureGL
#define ovr_Destroy ovrHmd_Destroy
#define ovr_DestroySwapTextureSet ovrHmd_DestroySwapTextureSet
#define ovr_DestroyMirrorTexture ovrHmd_DestroyMirrorTexture
#define ovr_GetFloat ovrHmd_GetFloat
#define ovr_GetFovTextureSize ovrHmd_GetFovTextureSize
#define ovr_GetFrameTiming ovrHmd_GetFrameTiming
#define ovr_GetTrackingState ovrHmd_GetTrackingState
#define ovr_GetRenderDesc ovrHmd_GetRenderDesc
#define ovr_RecenterPose ovrHmd_RecenterPose
#define ovr_SubmitFrame ovrHmd_SubmitFrame
#define ovr_ConfigureTracking ovrHmd_ConfigureTracking
#define ovr_GetHmdDesc(X) *X
#endif

View file

@ -0,0 +1,40 @@
//
// Created by Bradley Austin Davis on 2014/04/13.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "OculusDebugDisplayPlugin.h"
#include <QtCore/QProcessEnvironment>
const QString OculusDebugDisplayPlugin::NAME("Oculus Rift (Simulator)");
const QString & OculusDebugDisplayPlugin::getName() const {
return NAME;
}
static const QString DEBUG_FLAG("HIFI_DEBUG_OCULUS");
static bool enableDebugOculus = QProcessEnvironment::systemEnvironment().contains("HIFI_DEBUG_OCULUS");
bool OculusDebugDisplayPlugin::isSupported() const {
if (!enableDebugOculus) {
return false;
}
return OculusBaseDisplayPlugin::isSupported();
}
void OculusDebugDisplayPlugin::customizeContext() {
WindowOpenGLDisplayPlugin::customizeContext();
enableVsync(false);
}
void OculusDebugDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
WindowOpenGLDisplayPlugin::display(finalTexture, sceneSize);
OculusBaseDisplayPlugin::display(finalTexture, sceneSize);
}
void OculusDebugDisplayPlugin::finishFrame() {
swapBuffers();
doneCurrent();
};

View file

@ -0,0 +1,26 @@
//
// Created by Bradley Austin Davis on 2015/05/29
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#include "OculusBaseDisplayPlugin.h"
class OculusDebugDisplayPlugin : public OculusBaseDisplayPlugin {
public:
virtual const QString & getName() const override;
virtual bool isSupported() const override;
protected:
virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
virtual void customizeContext() override;
// Do not perform swap in finish
virtual void finishFrame() override;
private:
static const QString NAME;
};

View file

@ -7,59 +7,10 @@
//
#include "OculusDisplayPlugin.h"
#include <memory>
#include <QMainWindow>
#include <QGLWidget>
#include <GLMHelpers.h>
#include <GlWindow.h>
#include <QEvent>
#include <QResizeEvent>
#include <QThread>
#include <OglplusHelpers.h>
#include <oglplus/opt/list_init.hpp>
#include <oglplus/shapes/vector.hpp>
#include <oglplus/opt/list_init.hpp>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdouble-promotion"
#endif
#include <oglplus/shapes/obj_mesh.hpp>
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
#include <PerfStat.h>
#include <plugins/PluginContainer.h>
#include <ViewFrustum.h>
#include "OculusHelpers.h"
#if (OVR_MAJOR_VERSION == 6)
#define ovr_Create ovrHmd_Create
#define ovr_CreateSwapTextureSetGL ovrHmd_CreateSwapTextureSetGL
#define ovr_CreateMirrorTextureGL ovrHmd_CreateMirrorTextureGL
#define ovr_Destroy ovrHmd_Destroy
#define ovr_DestroySwapTextureSet ovrHmd_DestroySwapTextureSet
#define ovr_DestroyMirrorTexture ovrHmd_DestroyMirrorTexture
#define ovr_GetFloat ovrHmd_GetFloat
#define ovr_GetFovTextureSize ovrHmd_GetFovTextureSize
#define ovr_GetFrameTiming ovrHmd_GetFrameTiming
#define ovr_GetTrackingState ovrHmd_GetTrackingState
#define ovr_GetRenderDesc ovrHmd_GetRenderDesc
#define ovr_RecenterPose ovrHmd_RecenterPose
#define ovr_SubmitFrame ovrHmd_SubmitFrame
#define ovr_ConfigureTracking ovrHmd_ConfigureTracking
#define ovr_GetHmdDesc(X) *X
#endif
#if (OVR_MAJOR_VERSION >= 6)
// A base class for FBO wrappers that need to use the Oculus C
@ -180,160 +131,21 @@ private:
const QString OculusDisplayPlugin::NAME("Oculus Rift");
uvec2 OculusDisplayPlugin::getRecommendedRenderSize() const {
return _desiredFramebufferSize;
}
void OculusDisplayPlugin::preRender() {
#if (OVR_MAJOR_VERSION >= 6)
ovrFrameTiming ftiming = ovr_GetFrameTiming(_hmd, _frameIndex);
_trackingState = ovr_GetTrackingState(_hmd, ftiming.DisplayMidpointSeconds);
ovr_CalcEyePoses(_trackingState.HeadPose.ThePose, _eyeOffsets, _eyePoses);
#endif
}
glm::mat4 OculusDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const {
return _eyeProjections[eye];
}
void OculusDisplayPlugin::resetSensors() {
#if (OVR_MAJOR_VERSION >= 6)
ovr_RecenterPose(_hmd);
#endif
}
glm::mat4 OculusDisplayPlugin::getEyePose(Eye eye) const {
return toGlm(_eyePoses[eye]);
}
glm::mat4 OculusDisplayPlugin::getHeadPose() const {
return toGlm(_trackingState.HeadPose.ThePose);
}
const QString & OculusDisplayPlugin::getName() const {
return NAME;
}
bool OculusDisplayPlugin::isSupported() const {
#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
return false;
}
bool result = false;
if (ovrHmd_Detect() > 0) {
result = true;
}
ovr_Shutdown();
return result;
#else
return false;
#endif
}
void OculusDisplayPlugin::init() {
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
qFatal("Could not init OVR");
}
}
void OculusDisplayPlugin::deinit() {
ovr_Shutdown();
}
#if (OVR_MAJOR_VERSION >= 6)
ovrLayerEyeFov& OculusDisplayPlugin::getSceneLayer() {
return _sceneLayer;
}
#endif
//static gpu::TexturePointer _texture;
void OculusDisplayPlugin::activate() {
#if (OVR_MAJOR_VERSION >= 6)
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
Q_ASSERT(false);
qFatal("Failed to Initialize SDK");
}
// CONTAINER->getPrimarySurface()->makeCurrent();
#if (OVR_MAJOR_VERSION == 6)
if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) {
#elif (OVR_MAJOR_VERSION == 7)
if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) {
#endif
Q_ASSERT(false);
qFatal("Failed to acquire HMD");
}
_hmdDesc = ovr_GetHmdDesc(_hmd);
_ipd = ovr_GetFloat(_hmd, OVR_KEY_IPD, _ipd);
glm::uvec2 eyeSizes[2];
ovr_for_each_eye([&](ovrEyeType eye) {
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]);
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, 0.001f, 10.0f, ovrProjection_RightHanded);
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
});
ovrFovPort combined = _eyeFovs[Left];
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
combined.RightTan = std::max(_eyeFovs[Left].RightTan, _eyeFovs[Right].RightTan);
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(combined, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[Mono] = toGlm(ovrPerspectiveProjection);
_desiredFramebufferSize = uvec2(
eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y));
_frameIndex = 0;
if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device");
}
WindowOpenGLDisplayPlugin::activate();
// Parent class relies on our _hmd intialization, so it must come after that.
ovrLayerEyeFov& sceneLayer = getSceneLayer();
memset(&sceneLayer, 0, sizeof(ovrLayerEyeFov));
sceneLayer.Header.Type = ovrLayerType_EyeFov;
sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
ovr_for_each_eye([&](ovrEyeType eye) {
ovrFovPort & fov = sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov;
ovrSizei & size = sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_hmd, eye, fov, 1.0f);
sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
});
// We're rendering both eyes to the same texture, so only one of the
// pointers is populated
sceneLayer.ColorTexture[0] = _sceneFbo->color;
// not needed since the structure was zeroed on init, but explicit
sceneLayer.ColorTexture[1] = nullptr;
if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
qFatal("Could not attach to sensor device");
}
#endif
}
void OculusDisplayPlugin::customizeContext() {
WindowOpenGLDisplayPlugin::customizeContext();
#if (OVR_MAJOR_VERSION >= 6)
_sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd));
_sceneFbo->Init(getRecommendedRenderSize());
// We're rendering both eyes to the same texture, so only one of the
// pointers is populated
_sceneLayer.ColorTexture[0] = _sceneFbo->color;
// not needed since the structure was zeroed on init, but explicit
_sceneLayer.ColorTexture[1] = nullptr;
#endif
enableVsync(false);
// Only enable mirroring if we know vsync is disabled
@ -345,13 +157,9 @@ void OculusDisplayPlugin::deactivate() {
makeCurrent();
_sceneFbo.reset();
doneCurrent();
WindowOpenGLDisplayPlugin::deactivate();
ovr_Destroy(_hmd);
_hmd = nullptr;
ovr_Shutdown();
#endif
OculusBaseDisplayPlugin::deactivate();
}
void OculusDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
@ -379,9 +187,8 @@ void OculusDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSi
drawUnitQuad();
});
ovrLayerEyeFov& sceneLayer = getSceneLayer();
ovr_for_each_eye([&](ovrEyeType eye) {
sceneLayer.RenderPose[eye] = _eyePoses[eye];
_sceneLayer.RenderPose[eye] = _eyePoses[eye];
});
auto windowSize = toGlm(_window->size());
@ -391,7 +198,7 @@ void OculusDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSi
viewScaleDesc.HmdToEyeViewOffset[0] = _eyeOffsets[0];
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
ovrLayerHeader* layers = &sceneLayer.Header;
ovrLayerHeader* layers = &_sceneLayer.Header;
ovrResult result = ovr_SubmitFrame(_hmd, 0, &viewScaleDesc, &layers, 1);
if (!OVR_SUCCESS(result)) {
qDebug() << result;
@ -403,11 +210,6 @@ void OculusDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSi
#endif
}
// Pass input events on to the application
bool OculusDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
return WindowOpenGLDisplayPlugin::eventFilter(receiver, event);
}
/*
The swapbuffer call here is only required if we want to mirror the content to the screen.
However, it should only be done if we can reliably disable v-sync on the mirror surface,
@ -419,36 +221,3 @@ void OculusDisplayPlugin::finishFrame() {
}
doneCurrent();
};
#if 0
/*
An alternative way to render the UI is to pass it specifically as a composition layer to
the Oculus SDK which should technically result in higher quality. However, the SDK doesn't
have a mechanism to present the image as a sphere section, which is our desired look.
*/
ovrLayerQuad& uiLayer = getUiLayer();
if (nullptr == uiLayer.ColorTexture || overlaySize != _uiFbo->size) {
_uiFbo->Resize(overlaySize);
uiLayer.ColorTexture = _uiFbo->color;
uiLayer.Viewport.Size.w = overlaySize.x;
uiLayer.Viewport.Size.h = overlaySize.y;
float overlayAspect = aspect(overlaySize);
uiLayer.QuadSize.x = 1.0f;
uiLayer.QuadSize.y = 1.0f / overlayAspect;
}
_uiFbo->Bound([&] {
Q_ASSERT(0 == glGetError());
using namespace oglplus;
Context::Viewport(_uiFbo->size.x, _uiFbo->size.y);
glClearColor(0, 0, 0, 0);
Context::Clear().ColorBuffer();
_program->Bind();
glBindTexture(GL_TEXTURE_2D, overlayTexture);
_plane->Use();
_plane->Draw();
Q_ASSERT(0 == glGetError());
});
#endif

View file

@ -7,43 +7,17 @@
//
#pragma once
#include "../WindowOpenGLDisplayPlugin.h"
#include "OculusBaseDisplayPlugin.h"
#include <QTimer>
#include <OVR_CAPI.h>
class OffscreenGlCanvas;
struct SwapFramebufferWrapper;
struct MirrorFramebufferWrapper;
using SwapFboPtr = QSharedPointer<SwapFramebufferWrapper>;
using MirrorFboPtr = QSharedPointer<MirrorFramebufferWrapper>;
class OculusDisplayPlugin : public WindowOpenGLDisplayPlugin {
class OculusDisplayPlugin : public OculusBaseDisplayPlugin {
public:
virtual bool isSupported() const override;
virtual void deactivate() override;
virtual const QString & getName() const override;
virtual void init() override;
virtual void deinit() override;
virtual void activate() override;
virtual void deactivate() override;
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
// Stereo specific methods
virtual bool isHmd() const override { return true; }
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override;
virtual glm::uvec2 getRecommendedRenderSize() const override;
virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); }
virtual void resetSensors() override;
virtual glm::mat4 getEyePose(Eye eye) const override;
virtual glm::mat4 getHeadPose() const override;
protected:
virtual void preRender() override;
virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
virtual void customizeContext() override;
// Do not perform swap in finish
@ -51,30 +25,10 @@ protected:
private:
static const QString NAME;
ovrPosef _eyePoses[2];
mat4 _eyeProjections[3];
mat4 _compositeEyeProjections[2];
uvec2 _desiredFramebufferSize;
ovrTrackingState _trackingState;
bool _enableMirror{ false };
#if (OVR_MAJOR_VERSION >= 6)
ovrHmd _hmd;
float _ipd{ OVR_DEFAULT_IPD };
unsigned int _frameIndex;
ovrEyeRenderDesc _eyeRenderDescs[2];
ovrVector3f _eyeOffsets[2];
ovrFovPort _eyeFovs[2];
ovrLayerEyeFov& getSceneLayer();
ovrHmdDesc _hmdDesc;
SwapFboPtr _sceneFbo;
ovrLayerEyeFov _sceneLayer;
#endif
#if (OVR_MAJOR_VERSION == 7)
ovrGraphicsLuid _luid;
#endif
};