mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 06:44:06 +02:00
Merge remote-tracking branch 'tony/ajt/overlay-fade' into plugins
This commit is contained in:
commit
975c95eded
11 changed files with 296 additions and 14 deletions
|
@ -970,13 +970,15 @@ void Application::paintGL() {
|
|||
// or with changes from the face tracker
|
||||
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||
|
||||
_myCamera.setPosition(_myAvatar->getDefaultEyePosition());
|
||||
if (!getActiveDisplayPlugin()->isHmd()) {
|
||||
_myCamera.setPosition(_myAvatar->getDefaultEyePosition());
|
||||
_myCamera.setRotation(_myAvatar->getHead()->getCameraOrientation());
|
||||
} else {
|
||||
// The plugin getModelview() call below will compose the base
|
||||
// avatar transform with the HMD pose.
|
||||
_myCamera.setRotation(_myAvatar->getOrientation());
|
||||
// sensor to world transform with the HMD pose.
|
||||
mat4 sensorToWorldMat = _myAvatar->getSensorToWorldMatrix();
|
||||
_myCamera.setPosition(extractTranslation(sensorToWorldMat));
|
||||
_myCamera.setRotation(glm::quat_cast(sensorToWorldMat));
|
||||
}
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
if (isHMDMode()) {
|
||||
|
@ -1143,6 +1145,7 @@ void Application::audioMuteToggled() {
|
|||
}
|
||||
|
||||
void Application::faceTrackerMuteToggled() {
|
||||
|
||||
QAction* muteAction = Menu::getInstance()->getActionForOption(MenuOption::MuteFaceTracking);
|
||||
Q_CHECK_PTR(muteAction);
|
||||
bool isMuted = getSelectedFaceTracker()->isMuted();
|
||||
|
@ -1703,6 +1706,9 @@ void Application::mousePressEvent(QMouseEvent* event, unsigned int deviceID) {
|
|||
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
// right click items here
|
||||
} else if (event->button() == Qt::MiddleButton) {
|
||||
// toggle the overlay
|
||||
_overlayConductor.setEnabled(!_overlayConductor.getEnabled());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1988,6 +1994,9 @@ void Application::idle() {
|
|||
}
|
||||
}
|
||||
|
||||
float secondsSinceLastUpdate = (float)timeSinceLastUpdate / 1000.0f;
|
||||
_overlayConductor.update(secondsSinceLastUpdate);
|
||||
|
||||
// depending on whether we're throttling or not.
|
||||
// Once rendering is off on another thread we should be able to have Application::idle run at start(0) in
|
||||
// perpetuity and not expect events to get backed up.
|
||||
|
@ -4892,6 +4901,15 @@ mat4 Application::getEyePose(int eye) const {
|
|||
return mat4();
|
||||
}
|
||||
|
||||
mat4 Application::getEyeOffset(int eye) const {
|
||||
if (isHMDMode()) {
|
||||
mat4 identity;
|
||||
return getActiveDisplayPlugin()->getModelview((Eye)eye, identity);
|
||||
}
|
||||
|
||||
return mat4();
|
||||
}
|
||||
|
||||
mat4 Application::getHMDSensorPose() const {
|
||||
if (isHMDMode()) {
|
||||
return getActiveDisplayPlugin()->getHeadPose();
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "ui/overlays/Overlays.h"
|
||||
#include "ui/ApplicationOverlay.h"
|
||||
#include "ui/ApplicationCompositor.h"
|
||||
#include "ui/OverlayConductor.h"
|
||||
#include "ui/RunningScriptsWidget.h"
|
||||
#include "ui/ToolWindow.h"
|
||||
#include "octree/OctreePacketProcessor.h"
|
||||
|
@ -317,6 +318,7 @@ public:
|
|||
bool isHMDMode() const;
|
||||
glm::mat4 getHMDSensorPose() const;
|
||||
glm::mat4 getEyePose(int eye) const;
|
||||
glm::mat4 getEyeOffset(int eye) const;
|
||||
glm::mat4 getEyeProjection(int eye) const;
|
||||
|
||||
QRect getDesirableApplicationGeometry();
|
||||
|
@ -654,12 +656,15 @@ private:
|
|||
Overlays _overlays;
|
||||
ApplicationOverlay _applicationOverlay;
|
||||
ApplicationCompositor _compositor;
|
||||
OverlayConductor _overlayConductor;
|
||||
|
||||
int _oldHandMouseX[2];
|
||||
int _oldHandMouseY[2];
|
||||
bool _oldHandLeftClick[2];
|
||||
bool _oldHandRightClick[2];
|
||||
int _numFramesSinceLastResize = 0;
|
||||
|
||||
bool _overlayEnabled = true;
|
||||
};
|
||||
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -278,7 +278,7 @@ void AvatarManager::handleCollisionEvents(CollisionEvents& collisionEvents) {
|
|||
const QString& collisionSoundURL = myAvatar->getCollisionSoundURL();
|
||||
if (!collisionSoundURL.isEmpty()) {
|
||||
const float velocityChange = glm::length(collision.velocityChange);
|
||||
const float MIN_AVATAR_COLLISION_ACCELERATION = 0.01;
|
||||
const float MIN_AVATAR_COLLISION_ACCELERATION = 0.01f;
|
||||
const bool isSound = (collision.type == CONTACT_EVENT_TYPE_START) && (velocityChange > MIN_AVATAR_COLLISION_ACCELERATION);
|
||||
|
||||
if (!isSound) {
|
||||
|
|
|
@ -1345,7 +1345,6 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
|||
|
||||
void MyAvatar::updateOrientation(float deltaTime) {
|
||||
// Smoothly rotate body with arrow keys
|
||||
float driveLeft = _driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT];
|
||||
float targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED;
|
||||
if (targetSpeed != 0.0f) {
|
||||
const float ROTATION_RAMP_TIMESCALE = 0.1f;
|
||||
|
|
|
@ -186,7 +186,8 @@ void ApplicationCompositor::bindCursorTexture(gpu::Batch& batch, uint8_t cursorI
|
|||
// Draws the FBO texture for the screen
|
||||
void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
if (_alpha == 0.0f) {
|
||||
|
||||
if (_alpha <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -253,7 +254,8 @@ vec2 getPolarCoordinates(const PalmData& palm) {
|
|||
// Draws the FBO texture for Oculus rift.
|
||||
void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int eye) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
if (_alpha == 0.0f) {
|
||||
|
||||
if (_alpha <= 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -280,11 +282,12 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
|
|||
|
||||
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
|
||||
|
||||
batch.setViewTransform(Transform());
|
||||
batch.setProjectionTransform(qApp->getEyeProjection(eye));
|
||||
mat4 camMat;
|
||||
_cameraBaseTransform.getMatrix(camMat);
|
||||
camMat = camMat * qApp->getEyePose(eye);
|
||||
batch.setViewTransform(camMat);
|
||||
|
||||
mat4 eyePose = qApp->getEyePose(eye);
|
||||
glm::mat4 overlayXfm = glm::inverse(eyePose);
|
||||
batch.setProjectionTransform(qApp->getEyeProjection(eye));
|
||||
|
||||
#ifdef DEBUG_OVERLAY
|
||||
{
|
||||
|
@ -293,7 +296,9 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
|
|||
}
|
||||
#else
|
||||
{
|
||||
batch.setModelTransform(overlayXfm);
|
||||
//batch.setModelTransform(overlayXfm);
|
||||
|
||||
batch.setModelTransform(_modelTransform);
|
||||
drawSphereSection(batch);
|
||||
}
|
||||
#endif
|
||||
|
@ -304,8 +309,11 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
|
|||
|
||||
bindCursorTexture(batch);
|
||||
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
//Controller Pointers
|
||||
glm::mat4 overlayXfm;
|
||||
_modelTransform.getMatrix(overlayXfm);
|
||||
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
||||
PalmData& palm = myAvatar->getHand()->getPalms()[i];
|
||||
if (palm.isActive()) {
|
||||
|
@ -619,6 +627,19 @@ void ApplicationCompositor::drawSphereSection(gpu::Batch& batch) {
|
|||
batch.setInputFormat(streamFormat);
|
||||
|
||||
static const int VERTEX_STRIDE = sizeof(vec3) + sizeof(vec2) + sizeof(vec4);
|
||||
|
||||
if (_prevAlpha != _alpha) {
|
||||
// adjust alpha by munging vertex color alpha.
|
||||
// FIXME we should probably just use a uniform for this.
|
||||
float* floatPtr = reinterpret_cast<float*>(_hemiVertices->editData());
|
||||
const auto ALPHA_FLOAT_OFFSET = (sizeof(vec3) + sizeof(vec2) + sizeof(vec3)) / sizeof(float);
|
||||
const auto VERTEX_FLOAT_STRIDE = (sizeof(vec3) + sizeof(vec2) + sizeof(vec4)) / sizeof(float);
|
||||
const auto NUM_VERTS = _hemiVertices->getSize() / VERTEX_STRIDE;
|
||||
for (size_t i = 0; i < NUM_VERTS; i++) {
|
||||
floatPtr[i * VERTEX_FLOAT_STRIDE + ALPHA_FLOAT_OFFSET] = _alpha;
|
||||
}
|
||||
}
|
||||
|
||||
gpu::BufferView posView(_hemiVertices, 0, _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::POSITION)._element);
|
||||
gpu::BufferView uvView(_hemiVertices, sizeof(vec3), _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::TEXCOORD)._element);
|
||||
gpu::BufferView colView(_hemiVertices, sizeof(vec3) + sizeof(vec2), _hemiVertices->getSize(), VERTEX_STRIDE, streamFormat->getAttributes().at(gpu::Stream::COLOR)._element);
|
||||
|
@ -708,3 +729,13 @@ void ApplicationCompositor::updateTooltips() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationCompositor::update(float dt) {
|
||||
const int ALPHA_FADE_RATE = 2.0f;
|
||||
_prevAlpha = _alpha;
|
||||
if (_fadeInAlpha && _alpha < 1.0f) {
|
||||
_alpha = std::min(_alpha + ALPHA_FADE_RATE * dt, 1.0f);
|
||||
} else if (!_fadeInAlpha && _alpha > 0.0f) {
|
||||
_alpha = std::max(_alpha - ALPHA_FADE_RATE * dt, 0.0f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,17 @@ public:
|
|||
void computeHmdPickRay(glm::vec2 cursorPos, glm::vec3& origin, glm::vec3& direction) const;
|
||||
uint32_t getOverlayTexture() const;
|
||||
|
||||
void setCameraBaseTransform(const Transform& transform) { _cameraBaseTransform = transform; }
|
||||
const Transform& getCameraBaseTransform() const { return _cameraBaseTransform; }
|
||||
|
||||
void setModelTransform(const Transform& transform) { _modelTransform = transform; }
|
||||
const Transform& getModelTransform() const { return _modelTransform; }
|
||||
|
||||
void fadeIn() { _fadeInAlpha = true; }
|
||||
void fadeOut() { _fadeInAlpha = false; }
|
||||
void toggle() { _fadeInAlpha = !_fadeInAlpha; }
|
||||
void update(float dt);
|
||||
|
||||
static glm::vec2 directionToSpherical(const glm::vec3 & direction);
|
||||
static glm::vec3 sphericalToDirection(const glm::vec2 & sphericalPos);
|
||||
static glm::vec2 screenToSpherical(const glm::vec2 & screenPos);
|
||||
|
@ -100,6 +111,8 @@ private:
|
|||
bool _magnifier{ true };
|
||||
|
||||
float _alpha{ 1.0f };
|
||||
float _prevAlpha{ 1.0f };
|
||||
float _fadeInAlpha{ true };
|
||||
float _oculusUIRadius{ 1.0f };
|
||||
|
||||
QMap<uint16_t, gpu::TexturePointer> _cursors;
|
||||
|
@ -115,6 +128,9 @@ private:
|
|||
glm::vec3 _previousMagnifierBottomRight;
|
||||
glm::vec3 _previousMagnifierTopLeft;
|
||||
glm::vec3 _previousMagnifierTopRight;
|
||||
|
||||
Transform _modelTransform;
|
||||
Transform _cameraBaseTransform;
|
||||
};
|
||||
|
||||
#endif // hifi_ApplicationCompositor_h
|
||||
|
|
161
interface/src/ui/OverlayConductor.cpp
Normal file
161
interface/src/ui/OverlayConductor.cpp
Normal file
|
@ -0,0 +1,161 @@
|
|||
//
|
||||
// OverlayConductor.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// 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 "Application.h"
|
||||
#include "InterfaceLogging.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
|
||||
#include "OverlayConductor.h"
|
||||
|
||||
OverlayConductor::OverlayConductor() {
|
||||
}
|
||||
|
||||
OverlayConductor::~OverlayConductor() {
|
||||
}
|
||||
|
||||
void OverlayConductor::update(float dt) {
|
||||
|
||||
updateMode();
|
||||
|
||||
switch (_mode) {
|
||||
case SITTING: {
|
||||
// when sitting, the overlay is at the origin, facing down the -z axis.
|
||||
// the camera is taken directly from the HMD.
|
||||
Transform identity;
|
||||
qApp->getApplicationCompositor().setModelTransform(identity);
|
||||
qApp->getApplicationCompositor().setCameraBaseTransform(identity);
|
||||
break;
|
||||
}
|
||||
case STANDING: {
|
||||
// when standing, the overlay is at a reference position, which is set when the overlay is
|
||||
// enabled. The camera is taken directly from the HMD, but in world space.
|
||||
// So the sensorToWorldMatrix must be applied.
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
Transform t;
|
||||
t.evalFromRawMatrix(myAvatar->getSensorToWorldMatrix());
|
||||
qApp->getApplicationCompositor().setCameraBaseTransform(t);
|
||||
|
||||
// detect when head moves out side of sweet spot, or looks away.
|
||||
mat4 headMat = myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose();
|
||||
vec3 headWorldPos = extractTranslation(headMat);
|
||||
vec3 headForward = glm::quat_cast(headMat) * glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
Transform modelXform = qApp->getApplicationCompositor().getModelTransform();
|
||||
vec3 compositorWorldPos = modelXform.getTranslation();
|
||||
vec3 compositorForward = modelXform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
const float MAX_COMPOSITOR_DISTANCE = 0.6f;
|
||||
const float MAX_COMPOSITOR_ANGLE = 110.0f;
|
||||
if (_enabled && (glm::distance(headWorldPos, compositorWorldPos) > MAX_COMPOSITOR_DISTANCE ||
|
||||
glm::dot(headForward, compositorForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE)))) {
|
||||
// fade out the overlay
|
||||
setEnabled(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FLAT:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// process alpha fade animations
|
||||
qApp->getApplicationCompositor().update(dt);
|
||||
}
|
||||
|
||||
void OverlayConductor::updateMode() {
|
||||
|
||||
Mode newMode;
|
||||
if (qApp->isHMDMode()) {
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
if (myAvatar->getStandingHMDSensorMode()) {
|
||||
newMode = STANDING;
|
||||
} else {
|
||||
newMode = SITTING;
|
||||
}
|
||||
} else {
|
||||
newMode = FLAT;
|
||||
}
|
||||
|
||||
if (newMode != _mode) {
|
||||
switch (newMode) {
|
||||
case SITTING: {
|
||||
// enter the SITTING state
|
||||
// place the overlay at origin
|
||||
Transform identity;
|
||||
qApp->getApplicationCompositor().setModelTransform(identity);
|
||||
break;
|
||||
}
|
||||
case STANDING: {
|
||||
// enter the STANDING state
|
||||
// place the overlay at the current hmd position in world space
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
auto camMat = cancelOutRollAndPitch(myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose());
|
||||
Transform t;
|
||||
t.setTranslation(extractTranslation(camMat));
|
||||
t.setRotation(glm::quat_cast(camMat));
|
||||
qApp->getApplicationCompositor().setModelTransform(t);
|
||||
break;
|
||||
}
|
||||
|
||||
case FLAT:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_mode = newMode;
|
||||
}
|
||||
|
||||
void OverlayConductor::setEnabled(bool enabled) {
|
||||
|
||||
if (enabled == _enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_enabled) {
|
||||
// alpha fadeOut the overlay mesh.
|
||||
qApp->getApplicationCompositor().fadeOut();
|
||||
|
||||
// disable mouse clicks from script
|
||||
qApp->getOverlays().disable();
|
||||
|
||||
// disable QML events
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->getRootItem()->setEnabled(false);
|
||||
|
||||
_enabled = false;
|
||||
} else {
|
||||
// alpha fadeIn the overlay mesh.
|
||||
qApp->getApplicationCompositor().fadeIn();
|
||||
|
||||
// enable mouse clicks from script
|
||||
qApp->getOverlays().enable();
|
||||
|
||||
// enable QML events
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
offscreenUi->getRootItem()->setEnabled(true);
|
||||
|
||||
if (_mode == STANDING) {
|
||||
// place the overlay at the current hmd position in world space
|
||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||
auto camMat = cancelOutRollAndPitch(myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose());
|
||||
Transform t;
|
||||
t.setTranslation(extractTranslation(camMat));
|
||||
t.setRotation(glm::quat_cast(camMat));
|
||||
qApp->getApplicationCompositor().setModelTransform(t);
|
||||
}
|
||||
|
||||
_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool OverlayConductor::getEnabled() const {
|
||||
return _enabled;
|
||||
}
|
||||
|
36
interface/src/ui/OverlayConductor.h
Normal file
36
interface/src/ui/OverlayConductor.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// OverlayConductor.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_OverlayConductor_h
|
||||
#define hifi_OverlayConductor_h
|
||||
|
||||
class OverlayConductor {
|
||||
public:
|
||||
OverlayConductor();
|
||||
~OverlayConductor();
|
||||
|
||||
void update(float dt);
|
||||
void setEnabled(bool enable);
|
||||
bool getEnabled() const;
|
||||
|
||||
private:
|
||||
void updateMode();
|
||||
|
||||
enum Mode {
|
||||
FLAT,
|
||||
SITTING,
|
||||
STANDING
|
||||
};
|
||||
|
||||
Mode _mode = FLAT;
|
||||
bool _enabled = true;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -124,6 +124,16 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
|
|||
}
|
||||
}
|
||||
|
||||
void Overlays::disable() {
|
||||
QWriteLocker lock(&_lock);
|
||||
_enabled = false;
|
||||
}
|
||||
|
||||
void Overlays::enable() {
|
||||
QWriteLocker lock(&_lock);
|
||||
_enabled = true;
|
||||
}
|
||||
|
||||
unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) {
|
||||
unsigned int thisID = 0;
|
||||
Overlay* thisOverlay = NULL;
|
||||
|
@ -269,6 +279,9 @@ unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
|||
}
|
||||
|
||||
QReadLocker lock(&_lock);
|
||||
if (!_enabled) {
|
||||
return 0;
|
||||
}
|
||||
QMapIterator<unsigned int, Overlay::Pointer> i(_overlaysHUD);
|
||||
i.toBack();
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
void init();
|
||||
void update(float deltatime);
|
||||
void renderHUD(RenderArgs* renderArgs);
|
||||
void disable();
|
||||
void enable();
|
||||
|
||||
public slots:
|
||||
/// adds an overlay with the specific properties
|
||||
|
@ -99,6 +101,7 @@ private:
|
|||
QReadWriteLock _lock;
|
||||
QReadWriteLock _deleteLock;
|
||||
QScriptEngine* _scriptEngine;
|
||||
bool _enabled = true;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ mat4 OpenVrDisplayPlugin::getProjection(Eye eye, const mat4& baseProjection) con
|
|||
}
|
||||
|
||||
glm::mat4 OpenVrDisplayPlugin::getModelview(Eye eye, const mat4& baseModelview) const {
|
||||
return baseModelview * _eyesData[eye]._eyeOffset;
|
||||
return baseModelview * getEyePose(eye);
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::resetSensors() {
|
||||
|
|
Loading…
Reference in a new issue