mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:41:20 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into atp-client
This commit is contained in:
commit
645cfce828
20 changed files with 509 additions and 267 deletions
|
@ -34,36 +34,32 @@
|
||||||
{ "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" },
|
{ "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" },
|
||||||
{ "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" },
|
{ "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" },
|
||||||
|
|
||||||
{ "from": "Vive.LeftHand", "to": "Standard.LeftHand", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.LeftHand", "to": "Standard.LeftHand"},
|
||||||
{ "from": "Vive.RightHand", "to": "Standard.RightHand", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.RightHand", "to": "Standard.RightHand"},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.LeftFoot", "to" : "Standard.LeftFoot",
|
"from": "Vive.LeftFoot", "to" : "Standard.LeftFoot",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.RightFoot", "to" : "Standard.RightFoot",
|
"from": "Vive.RightFoot", "to" : "Standard.RightFoot",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.Hips", "to" : "Standard.Hips",
|
"from": "Vive.Hips", "to" : "Standard.Hips",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"from": "Vive.Spine2", "to" : "Standard.Spine2",
|
"from": "Vive.Spine2", "to" : "Standard.Spine2",
|
||||||
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}],
|
"filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}]
|
||||||
"when": [ "Application.InHMD" ]
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "from": "Vive.Head", "to" : "Standard.Head", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.Head", "to" : "Standard.Head"},
|
||||||
|
|
||||||
{ "from": "Vive.RightArm", "to" : "Standard.RightArm", "when": [ "Application.InHMD" ] },
|
{ "from": "Vive.RightArm", "to" : "Standard.RightArm"},
|
||||||
{ "from": "Vive.LeftArm", "to" : "Standard.LeftArm", "when": [ "Application.InHMD" ] }
|
{ "from": "Vive.LeftArm", "to" : "Standard.LeftArm"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -642,6 +642,57 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Separator {
|
||||||
|
id: advanceSeperator
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: timeToCalibrate.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayBold {
|
||||||
|
id: advanceSettings
|
||||||
|
|
||||||
|
text: "Advance Settings"
|
||||||
|
size: 12
|
||||||
|
|
||||||
|
color: hifi.colors.white
|
||||||
|
|
||||||
|
anchors.top: advanceSeperator.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: leftMargin
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HifiControls.CheckBox {
|
||||||
|
id: viveInDesktop
|
||||||
|
width: 15
|
||||||
|
height: 15
|
||||||
|
boxRadius: 7
|
||||||
|
|
||||||
|
anchors.top: advanceSettings.bottom
|
||||||
|
anchors.topMargin: 5
|
||||||
|
anchors.left: openVrConfiguration.left
|
||||||
|
anchors.leftMargin: leftMargin + 10
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
sendConfigurationSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayBold {
|
||||||
|
id: viveDesktopText
|
||||||
|
size: 10
|
||||||
|
text: "Use vive devices in desktop mode"
|
||||||
|
color: hifi.colors.white
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: viveInDesktop.right
|
||||||
|
leftMargin: 5
|
||||||
|
verticalCenter: viveInDesktop.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
id: numberAnimation
|
id: numberAnimation
|
||||||
target: openVrConfiguration
|
target: openVrConfiguration
|
||||||
|
@ -728,6 +779,7 @@ Rectangle {
|
||||||
|
|
||||||
var HmdHead = settings["HMDHead"];
|
var HmdHead = settings["HMDHead"];
|
||||||
var viveController = settings["handController"];
|
var viveController = settings["handController"];
|
||||||
|
var desktopMode = settings["desktopMode"];
|
||||||
|
|
||||||
if (HmdHead) {
|
if (HmdHead) {
|
||||||
headBox.checked = true;
|
headBox.checked = true;
|
||||||
|
@ -745,6 +797,8 @@ Rectangle {
|
||||||
handBox.checked = false;
|
handBox.checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viveInDesktop.checked = desktopMode;
|
||||||
|
|
||||||
initializeButtonState();
|
initializeButtonState();
|
||||||
updateCalibrationText();
|
updateCalibrationText();
|
||||||
|
|
||||||
|
@ -901,7 +955,8 @@ Rectangle {
|
||||||
var settingsObject = {
|
var settingsObject = {
|
||||||
"bodyConfiguration": trackerConfiguration,
|
"bodyConfiguration": trackerConfiguration,
|
||||||
"headConfiguration": headObject,
|
"headConfiguration": headObject,
|
||||||
"handConfiguration": handObject
|
"handConfiguration": handObject,
|
||||||
|
"desktopMode": viveInDesktop.checked
|
||||||
}
|
}
|
||||||
|
|
||||||
return settingsObject;
|
return settingsObject;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <QtCore/QCommandLineParser>
|
#include <QtCore/QCommandLineParser>
|
||||||
#include <QtCore/QMimeData>
|
#include <QtCore/QMimeData>
|
||||||
#include <QtCore/QThreadPool>
|
#include <QtCore/QThreadPool>
|
||||||
|
#include <QtConcurrent/QtConcurrentRun>
|
||||||
|
|
||||||
#include <QtGui/QScreen>
|
#include <QtGui/QScreen>
|
||||||
#include <QtGui/QWindow>
|
#include <QtGui/QWindow>
|
||||||
|
@ -480,6 +481,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset";
|
static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset";
|
||||||
bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET);
|
bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET);
|
||||||
bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt);
|
bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt);
|
||||||
|
// get dir to use for cache
|
||||||
|
static const auto CACHE_SWITCH = "--cache";
|
||||||
|
QString cacheDir = getCmdOption(argc, const_cast<const char**>(argv), CACHE_SWITCH);
|
||||||
|
if (!cacheDir.isEmpty()) {
|
||||||
|
qApp->setProperty(hifi::properties::APP_LOCAL_DATA_PATH, cacheDir);
|
||||||
|
}
|
||||||
|
|
||||||
Setting::init();
|
Setting::init();
|
||||||
|
|
||||||
|
@ -1218,8 +1225,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
settingsTimer->stop();
|
settingsTimer->stop();
|
||||||
// Delete it (this will trigger the thread destruction
|
// Delete it (this will trigger the thread destruction
|
||||||
settingsTimer->deleteLater();
|
settingsTimer->deleteLater();
|
||||||
// Mark the settings thread as finished, so we know we can safely save in the main application
|
// Mark the settings thread as finished, so we know we can safely save in the main application
|
||||||
// shutdown code
|
// shutdown code
|
||||||
_settingsGuard.trigger();
|
_settingsGuard.trigger();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2164,48 +2171,74 @@ void Application::paintGL() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto displayPlugin = getActiveDisplayPlugin();
|
DisplayPluginPointer displayPlugin;
|
||||||
// FIXME not needed anymore?
|
{
|
||||||
_offscreenContext->makeCurrent();
|
PROFILE_RANGE(render, "/getActiveDisplayPlugin");
|
||||||
|
displayPlugin = getActiveDisplayPlugin();
|
||||||
|
}
|
||||||
|
|
||||||
// If a display plugin loses it's underlying support, it
|
{
|
||||||
// needs to be able to signal us to not use it
|
PROFILE_RANGE(render, "/offscreenMakeCurrent");
|
||||||
if (!displayPlugin->beginFrameRender(_frameCount)) {
|
// FIXME not needed anymore?
|
||||||
_inPaint = false;
|
_offscreenContext->makeCurrent();
|
||||||
updateDisplayMode();
|
}
|
||||||
return;
|
|
||||||
|
{
|
||||||
|
PROFILE_RANGE(render, "/pluginBeginFrameRender");
|
||||||
|
// If a display plugin loses it's underlying support, it
|
||||||
|
// needs to be able to signal us to not use it
|
||||||
|
if (!displayPlugin->beginFrameRender(_frameCount)) {
|
||||||
|
_inPaint = false;
|
||||||
|
updateDisplayMode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the avatar with a fresh HMD pose
|
// update the avatar with a fresh HMD pose
|
||||||
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
|
{
|
||||||
|
PROFILE_RANGE(render, "/updateAvatar");
|
||||||
|
getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
|
||||||
|
}
|
||||||
|
|
||||||
auto lodManager = DependencyManager::get<LODManager>();
|
auto lodManager = DependencyManager::get<LODManager>();
|
||||||
|
|
||||||
|
RenderArgs renderArgs;
|
||||||
{
|
{
|
||||||
QMutexLocker viewLocker(&_viewMutex);
|
PROFILE_RANGE(render, "/buildFrustrumAndArgs");
|
||||||
_viewFrustum.calculate();
|
{
|
||||||
}
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
RenderArgs renderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
|
_viewFrustum.calculate();
|
||||||
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
}
|
||||||
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
renderArgs = RenderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
|
||||||
{
|
lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
|
||||||
QMutexLocker viewLocker(&_viewMutex);
|
RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
|
||||||
renderArgs.setViewFrustum(_viewFrustum);
|
{
|
||||||
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
|
renderArgs.setViewFrustum(_viewFrustum);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
{
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
PROFILE_RANGE(render, "/resizeGL");
|
||||||
PerformanceWarning warn(showWarnings, "Application::paintGL()");
|
PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
|
||||||
resizeGL();
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
|
PerformanceWarning warn(showWarnings, "Application::paintGL()");
|
||||||
_gpuContext->beginFrame(getHMDSensorPose());
|
resizeGL();
|
||||||
// Reset the gpu::Context Stages
|
}
|
||||||
// Back to the default framebuffer;
|
|
||||||
gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) {
|
|
||||||
batch.resetStages();
|
|
||||||
});
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE(render, "/gpuContextReset");
|
||||||
|
_gpuContext->beginFrame(getHMDSensorPose());
|
||||||
|
// Reset the gpu::Context Stages
|
||||||
|
// Back to the default framebuffer;
|
||||||
|
gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) {
|
||||||
|
batch.resetStages();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
PROFILE_RANGE(render, "/renderOverlay");
|
||||||
PerformanceTimer perfTimer("renderOverlay");
|
PerformanceTimer perfTimer("renderOverlay");
|
||||||
// NOTE: There is no batch associated with this renderArgs
|
// NOTE: There is no batch associated with this renderArgs
|
||||||
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
// the ApplicationOverlay class assumes it's viewport is setup to be the device size
|
||||||
|
@ -2216,114 +2249,127 @@ void Application::paintGL() {
|
||||||
|
|
||||||
glm::vec3 boomOffset;
|
glm::vec3 boomOffset;
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("CameraUpdates");
|
PROFILE_RANGE(render, "/updateCamera");
|
||||||
|
{
|
||||||
|
PerformanceTimer perfTimer("CameraUpdates");
|
||||||
|
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
|
boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
|
||||||
|
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
|
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
|
||||||
cameraMenuChanged();
|
cameraMenuChanged();
|
||||||
}
|
|
||||||
|
|
||||||
// The render mode is default or mirror if the camera is in mirror mode, assigned further below
|
|
||||||
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
|
||||||
|
|
||||||
// Always use the default eye position, not the actual head eye position.
|
|
||||||
// Using the latter will cause the camera to wobble with idle animations,
|
|
||||||
// or with changes from the face tracker
|
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
|
||||||
if (isHMDMode()) {
|
|
||||||
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
|
||||||
_myCamera.setPosition(extractTranslation(camMat));
|
|
||||||
_myCamera.setOrientation(glm::quat_cast(camMat));
|
|
||||||
} else {
|
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition());
|
|
||||||
_myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
|
|
||||||
}
|
}
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
|
||||||
if (isHMDMode()) {
|
|
||||||
auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
|
||||||
_myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat)));
|
|
||||||
_myCamera.setPosition(extractTranslation(hmdWorldMat) +
|
|
||||||
myAvatar->getOrientation() * boomOffset);
|
|
||||||
} else {
|
|
||||||
_myCamera.setOrientation(myAvatar->getHead()->getOrientation());
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
|
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
|
||||||
+ _myCamera.getOrientation() * boomOffset);
|
|
||||||
} else {
|
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
|
||||||
+ myAvatar->getOrientation() * boomOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
|
||||||
if (isHMDMode()) {
|
|
||||||
auto mirrorBodyOrientation = myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
|
|
||||||
|
|
||||||
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
|
// The render mode is default or mirror if the camera is in mirror mode, assigned further below
|
||||||
// Mirror HMD yaw and roll
|
renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
|
||||||
glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation);
|
|
||||||
mirrorHmdEulers.y = -mirrorHmdEulers.y;
|
|
||||||
mirrorHmdEulers.z = -mirrorHmdEulers.z;
|
|
||||||
glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers);
|
|
||||||
|
|
||||||
glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation;
|
// Always use the default eye position, not the actual head eye position.
|
||||||
|
// Using the latter will cause the camera to wobble with idle animations,
|
||||||
_myCamera.setOrientation(worldMirrorRotation);
|
// or with changes from the face tracker
|
||||||
|
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||||
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
|
||||||
// Mirror HMD lateral offsets
|
|
||||||
hmdOffset.x = -hmdOffset.x;
|
|
||||||
|
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
|
||||||
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
|
||||||
+ mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
|
||||||
+ mirrorBodyOrientation * hmdOffset);
|
|
||||||
} else {
|
|
||||||
_myCamera.setOrientation(myAvatar->getWorldAlignedOrientation()
|
|
||||||
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
|
||||||
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
|
||||||
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
|
||||||
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
|
||||||
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
|
||||||
}
|
|
||||||
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
|
|
||||||
EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
|
|
||||||
if (cameraEntity != nullptr) {
|
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
|
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
||||||
_myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation);
|
_myCamera.setPosition(extractTranslation(camMat));
|
||||||
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
_myCamera.setOrientation(glm::quat_cast(camMat));
|
||||||
_myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset));
|
|
||||||
} else {
|
} else {
|
||||||
_myCamera.setOrientation(cameraEntity->getRotation());
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition());
|
||||||
_myCamera.setPosition(cameraEntity->getPosition());
|
_myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
|
||||||
|
}
|
||||||
|
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||||
|
if (isHMDMode()) {
|
||||||
|
auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
||||||
|
_myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat)));
|
||||||
|
_myCamera.setPosition(extractTranslation(hmdWorldMat) +
|
||||||
|
myAvatar->getOrientation() * boomOffset);
|
||||||
|
} else {
|
||||||
|
_myCamera.setOrientation(myAvatar->getHead()->getOrientation());
|
||||||
|
if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
|
||||||
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
|
+ _myCamera.getOrientation() * boomOffset);
|
||||||
|
} else {
|
||||||
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
|
+ myAvatar->getOrientation() * boomOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
|
if (isHMDMode()) {
|
||||||
|
auto mirrorBodyOrientation = myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
|
||||||
|
|
||||||
|
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
|
||||||
|
// Mirror HMD yaw and roll
|
||||||
|
glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation);
|
||||||
|
mirrorHmdEulers.y = -mirrorHmdEulers.y;
|
||||||
|
mirrorHmdEulers.z = -mirrorHmdEulers.z;
|
||||||
|
glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers);
|
||||||
|
|
||||||
|
glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation;
|
||||||
|
|
||||||
|
_myCamera.setOrientation(worldMirrorRotation);
|
||||||
|
|
||||||
|
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
||||||
|
// Mirror HMD lateral offsets
|
||||||
|
hmdOffset.x = -hmdOffset.x;
|
||||||
|
|
||||||
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
|
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
||||||
|
+ mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
|
||||||
|
+ mirrorBodyOrientation * hmdOffset);
|
||||||
|
} else {
|
||||||
|
_myCamera.setOrientation(myAvatar->getWorldAlignedOrientation()
|
||||||
|
* glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
|
||||||
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition()
|
||||||
|
+ glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
|
||||||
|
+ (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
|
||||||
|
glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
|
||||||
|
}
|
||||||
|
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
|
||||||
|
} else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
|
||||||
|
EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
|
||||||
|
if (cameraEntity != nullptr) {
|
||||||
|
if (isHMDMode()) {
|
||||||
|
glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
|
||||||
|
_myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation);
|
||||||
|
glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
|
||||||
|
_myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset));
|
||||||
|
} else {
|
||||||
|
_myCamera.setOrientation(cameraEntity->getRotation());
|
||||||
|
_myCamera.setPosition(cameraEntity->getPosition());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// Update camera position
|
||||||
// Update camera position
|
if (!isHMDMode()) {
|
||||||
if (!isHMDMode()) {
|
_myCamera.update(1.0f / _frameCounter.rate());
|
||||||
_myCamera.update(1.0f / _frameCounter.rate());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform());
|
{
|
||||||
|
PROFILE_RANGE(render, "/updateCompositor");
|
||||||
|
getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform());
|
||||||
|
}
|
||||||
|
|
||||||
// Primary rendering pass
|
gpu::FramebufferPointer finalFramebuffer;
|
||||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
QSize finalFramebufferSize;
|
||||||
const QSize size = framebufferCache->getFrameBufferSize();
|
{
|
||||||
// Final framebuffer that will be handled to the display-plugin
|
PROFILE_RANGE(render, "/getOutputFramebuffer");
|
||||||
auto finalFramebuffer = framebufferCache->getFramebuffer();
|
// Primary rendering pass
|
||||||
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
|
finalFramebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
|
// Final framebuffer that will be handled to the display-plugin
|
||||||
|
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(render, "/mainRender");
|
PROFILE_RANGE(render, "/mainRender");
|
||||||
PerformanceTimer perfTimer("mainRender");
|
PerformanceTimer perfTimer("mainRender");
|
||||||
renderArgs._boomOffset = boomOffset;
|
renderArgs._boomOffset = boomOffset;
|
||||||
|
// FIXME is this ever going to be different from the size previously set in the render args
|
||||||
|
// in the overlay render?
|
||||||
// Viewport is assigned to the size of the framebuffer
|
// Viewport is assigned to the size of the framebuffer
|
||||||
renderArgs._viewport = ivec4(0, 0, size.width(), size.height());
|
renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height());
|
||||||
if (displayPlugin->isStereo()) {
|
if (displayPlugin->isStereo()) {
|
||||||
// Stereo modes will typically have a larger projection matrix overall,
|
// Stereo modes will typically have a larger projection matrix overall,
|
||||||
// so we ask for the 'mono' projection matrix, which for stereo and HMD
|
// so we ask for the 'mono' projection matrix, which for stereo and HMD
|
||||||
|
@ -3623,6 +3669,133 @@ bool Application::shouldPaint(float nsecsElapsed) {
|
||||||
#include <TCHAR.h>
|
#include <TCHAR.h>
|
||||||
#include <pdh.h>
|
#include <pdh.h>
|
||||||
#pragma comment(lib, "pdh.lib")
|
#pragma comment(lib, "pdh.lib")
|
||||||
|
#pragma comment(lib, "ntdll.lib")
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
enum SYSTEM_INFORMATION_CLASS {
|
||||||
|
SystemBasicInformation = 0,
|
||||||
|
SystemProcessorPerformanceInformation = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
|
||||||
|
LARGE_INTEGER IdleTime;
|
||||||
|
LARGE_INTEGER KernelTime;
|
||||||
|
LARGE_INTEGER UserTime;
|
||||||
|
LARGE_INTEGER DpcTime;
|
||||||
|
LARGE_INTEGER InterruptTime;
|
||||||
|
ULONG InterruptCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SYSTEM_BASIC_INFORMATION {
|
||||||
|
ULONG Reserved;
|
||||||
|
ULONG TimerResolution;
|
||||||
|
ULONG PageSize;
|
||||||
|
ULONG NumberOfPhysicalPages;
|
||||||
|
ULONG LowestPhysicalPageNumber;
|
||||||
|
ULONG HighestPhysicalPageNumber;
|
||||||
|
ULONG AllocationGranularity;
|
||||||
|
ULONG_PTR MinimumUserModeAddress;
|
||||||
|
ULONG_PTR MaximumUserModeAddress;
|
||||||
|
ULONG_PTR ActiveProcessorsAffinityMask;
|
||||||
|
CCHAR NumberOfProcessors;
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformation(
|
||||||
|
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
|
||||||
|
_Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
|
||||||
|
_In_ ULONG SystemInformationLength,
|
||||||
|
_Out_opt_ PULONG ReturnLength
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, T& t) {
|
||||||
|
return NtQuerySystemInformation(SystemInformationClass, &t, (ULONG)sizeof(T), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, std::vector<T>& t) {
|
||||||
|
return NtQuerySystemInformation(SystemInformationClass, t.data(), (ULONG)(sizeof(T) * t.size()), nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void updateValueAndDelta(std::pair<T, T>& pair, T newValue) {
|
||||||
|
auto& value = pair.first;
|
||||||
|
auto& delta = pair.second;
|
||||||
|
delta = (value != 0) ? newValue - value : 0;
|
||||||
|
value = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MyCpuInfo {
|
||||||
|
using ValueAndDelta = std::pair<LONGLONG, LONGLONG>;
|
||||||
|
std::string name;
|
||||||
|
ValueAndDelta kernel { 0, 0 };
|
||||||
|
ValueAndDelta user { 0, 0 };
|
||||||
|
ValueAndDelta idle { 0, 0 };
|
||||||
|
float kernelUsage { 0.0f };
|
||||||
|
float userUsage { 0.0f };
|
||||||
|
|
||||||
|
void update(const SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION& cpuInfo) {
|
||||||
|
updateValueAndDelta(kernel, cpuInfo.KernelTime.QuadPart);
|
||||||
|
updateValueAndDelta(user, cpuInfo.UserTime.QuadPart);
|
||||||
|
updateValueAndDelta(idle, cpuInfo.IdleTime.QuadPart);
|
||||||
|
auto totalTime = kernel.second + user.second + idle.second;
|
||||||
|
if (totalTime != 0) {
|
||||||
|
kernelUsage = (FLOAT)kernel.second / totalTime;
|
||||||
|
userUsage = (FLOAT)user.second / totalTime;
|
||||||
|
} else {
|
||||||
|
kernelUsage = userUsage = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void updateCpuInformation() {
|
||||||
|
static std::once_flag once;
|
||||||
|
static SYSTEM_BASIC_INFORMATION systemInfo {};
|
||||||
|
static SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION cpuTotals;
|
||||||
|
static std::vector<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION> cpuInfos;
|
||||||
|
static std::vector<MyCpuInfo> myCpuInfos;
|
||||||
|
static MyCpuInfo myCpuTotals;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
NtQuerySystemInformation( SystemBasicInformation, systemInfo);
|
||||||
|
cpuInfos.resize(systemInfo.NumberOfProcessors);
|
||||||
|
myCpuInfos.resize(systemInfo.NumberOfProcessors);
|
||||||
|
for (size_t i = 0; i < systemInfo.NumberOfProcessors; ++i) {
|
||||||
|
myCpuInfos[i].name = "cpu." + std::to_string(i);
|
||||||
|
}
|
||||||
|
myCpuTotals.name = "cpu.total";
|
||||||
|
});
|
||||||
|
NtQuerySystemInformation(SystemProcessorPerformanceInformation, cpuInfos);
|
||||||
|
|
||||||
|
// Zero the CPU totals.
|
||||||
|
memset(&cpuTotals, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
|
||||||
|
for (size_t i = 0; i < systemInfo.NumberOfProcessors; ++i) {
|
||||||
|
auto& cpuInfo = cpuInfos[i];
|
||||||
|
// KernelTime includes IdleTime.
|
||||||
|
cpuInfo.KernelTime.QuadPart -= cpuInfo.IdleTime.QuadPart;
|
||||||
|
|
||||||
|
// Update totals
|
||||||
|
cpuTotals.IdleTime.QuadPart += cpuInfo.IdleTime.QuadPart;
|
||||||
|
cpuTotals.KernelTime.QuadPart += cpuInfo.KernelTime.QuadPart;
|
||||||
|
cpuTotals.UserTime.QuadPart += cpuInfo.UserTime.QuadPart;
|
||||||
|
|
||||||
|
// Update friendly structure
|
||||||
|
auto& myCpuInfo = myCpuInfos[i];
|
||||||
|
myCpuInfo.update(cpuInfo);
|
||||||
|
PROFILE_COUNTER(app, myCpuInfo.name.c_str(), {
|
||||||
|
{ "kernel", myCpuInfo.kernelUsage },
|
||||||
|
{ "user", myCpuInfo.userUsage }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
myCpuTotals.update(cpuTotals);
|
||||||
|
PROFILE_COUNTER(app, myCpuTotals.name.c_str(), {
|
||||||
|
{ "kernel", myCpuTotals.kernelUsage },
|
||||||
|
{ "user", myCpuTotals.userUsage }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
|
static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
|
||||||
static int numProcessors;
|
static int numProcessors;
|
||||||
|
@ -3675,6 +3848,26 @@ void getCpuUsage(vec3& systemAndUser) {
|
||||||
systemAndUser.z = (float)counterVal.doubleValue;
|
systemAndUser.z = (float)counterVal.doubleValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setupCpuMonitorThread() {
|
||||||
|
initCpuUsage();
|
||||||
|
auto cpuMonitorThread = QThread::currentThread();
|
||||||
|
|
||||||
|
QTimer* timer = new QTimer();
|
||||||
|
timer->setInterval(50);
|
||||||
|
QObject::connect(timer, &QTimer::timeout, [] {
|
||||||
|
updateCpuInformation();
|
||||||
|
vec3 kernelUserAndSystem;
|
||||||
|
getCpuUsage(kernelUserAndSystem);
|
||||||
|
PROFILE_COUNTER(app, "cpuProcess", { { "system", kernelUserAndSystem.x }, { "user", kernelUserAndSystem.y } });
|
||||||
|
PROFILE_COUNTER(app, "cpuSystem", { { "system", kernelUserAndSystem.z } });
|
||||||
|
});
|
||||||
|
QObject::connect(cpuMonitorThread, &QThread::finished, [=] {
|
||||||
|
timer->deleteLater();
|
||||||
|
cpuMonitorThread->deleteLater();
|
||||||
|
});
|
||||||
|
timer->start();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -3695,15 +3888,17 @@ void Application::idle(float nsecsElapsed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
// If tracing is enabled then monitor the CPU in a separate thread
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [] {
|
std::call_once(once, [&] {
|
||||||
initCpuUsage();
|
if (trace_app().isDebugEnabled()) {
|
||||||
|
QThread* cpuMonitorThread = new QThread(qApp);
|
||||||
|
cpuMonitorThread->setObjectName("cpuMonitorThread");
|
||||||
|
QObject::connect(cpuMonitorThread, &QThread::started, [this] { setupCpuMonitorThread(); });
|
||||||
|
QObject::connect(qApp, &QCoreApplication::aboutToQuit, cpuMonitorThread, &QThread::quit);
|
||||||
|
cpuMonitorThread->start();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
vec3 kernelUserAndSystem;
|
|
||||||
getCpuUsage(kernelUserAndSystem);
|
|
||||||
PROFILE_COUNTER(app, "cpuProcess", { { "system", kernelUserAndSystem.x }, { "user", kernelUserAndSystem.y } });
|
|
||||||
PROFILE_COUNTER(app, "cpuSystem", { { "system", kernelUserAndSystem.z } });
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,6 @@ public:
|
||||||
void setAvatarOverrideUrl(const QUrl& url, bool save);
|
void setAvatarOverrideUrl(const QUrl& url, bool save);
|
||||||
QUrl getAvatarOverrideUrl() { return _avatarOverrideUrl; }
|
QUrl getAvatarOverrideUrl() { return _avatarOverrideUrl; }
|
||||||
bool getSaveAvatarOverrideUrl() { return _saveAvatarOverrideUrl; }
|
bool getSaveAvatarOverrideUrl() { return _saveAvatarOverrideUrl; }
|
||||||
void setCacheOverrideDir(const QString& dirName) { _cacheDir = dirName; }
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void svoImportRequested(const QString& url);
|
void svoImportRequested(const QString& url);
|
||||||
|
@ -691,6 +690,5 @@ private:
|
||||||
QUrl _avatarOverrideUrl;
|
QUrl _avatarOverrideUrl;
|
||||||
bool _saveAvatarOverrideUrl { false };
|
bool _saveAvatarOverrideUrl { false };
|
||||||
|
|
||||||
QString _cacheDir;
|
|
||||||
};
|
};
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -1634,7 +1634,8 @@ void MyAvatar::prepareForPhysicsSimulation() {
|
||||||
_characterController.setParentVelocity(parentVelocity);
|
_characterController.setParentVelocity(parentVelocity);
|
||||||
|
|
||||||
_characterController.setPositionAndOrientation(getPosition(), getOrientation());
|
_characterController.setPositionAndOrientation(getPosition(), getOrientation());
|
||||||
if (qApp->isHMDMode()) {
|
auto headPose = getHeadControllerPoseInAvatarFrame();
|
||||||
|
if (headPose.isValid()) {
|
||||||
_follow.prePhysicsUpdate(*this, deriveBodyFromHMDSensor(), _bodySensorMatrix, hasDriveInput());
|
_follow.prePhysicsUpdate(*this, deriveBodyFromHMDSensor(), _bodySensorMatrix, hasDriveInput());
|
||||||
} else {
|
} else {
|
||||||
_follow.deactivate();
|
_follow.deactivate();
|
||||||
|
|
|
@ -101,7 +101,7 @@ int main(int argc, const char* argv[]) {
|
||||||
if (allowMultipleInstances) {
|
if (allowMultipleInstances) {
|
||||||
instanceMightBeRunning = false;
|
instanceMightBeRunning = false;
|
||||||
}
|
}
|
||||||
// this needs to be done here in main, as the mechanism for setting the
|
// this needs to be done here in main, as the mechanism for setting the
|
||||||
// scripts directory appears not to work. See the bug report
|
// scripts directory appears not to work. See the bug report
|
||||||
// https://highfidelity.fogbugz.com/f/cases/5759/Issues-changing-scripts-directory-in-ScriptsEngine
|
// https://highfidelity.fogbugz.com/f/cases/5759/Issues-changing-scripts-directory-in-ScriptsEngine
|
||||||
if (parser.isSet(overrideScriptsPathOption)) {
|
if (parser.isSet(overrideScriptsPathOption)) {
|
||||||
|
@ -111,20 +111,6 @@ int main(int argc, const char* argv[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parser.isSet(overrideAppLocalDataPathOption)) {
|
|
||||||
// get dir to use for cache
|
|
||||||
QString cacheDir = parser.value(overrideAppLocalDataPathOption);
|
|
||||||
if (!cacheDir.isEmpty()) {
|
|
||||||
// tell everyone to use the right cache location
|
|
||||||
//
|
|
||||||
// this handles data8 and prepared
|
|
||||||
DependencyManager::get<ResourceManager>()->setCacheDir(cacheDir);
|
|
||||||
|
|
||||||
// this does the ktx_cache
|
|
||||||
PathUtils::getAppLocalDataPath(cacheDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceMightBeRunning) {
|
if (instanceMightBeRunning) {
|
||||||
// Try to connect and send message to existing interface instance
|
// Try to connect and send message to existing interface instance
|
||||||
QLocalSocket socket;
|
QLocalSocket socket;
|
||||||
|
|
|
@ -67,19 +67,14 @@ void Overlays::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::update(float deltatime) {
|
void Overlays::update(float deltatime) {
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&_mutex);
|
QMutexLocker locker(&_mutex);
|
||||||
overlaysHUD = _overlaysHUD;
|
foreach(const auto& thisOverlay, _overlaysHUD) {
|
||||||
overlaysWorld = _overlaysWorld;
|
thisOverlay->update(deltatime);
|
||||||
}
|
}
|
||||||
|
foreach(const auto& thisOverlay, _overlaysWorld) {
|
||||||
foreach(const auto& thisOverlay, overlaysHUD) {
|
thisOverlay->update(deltatime);
|
||||||
thisOverlay->update(deltatime);
|
}
|
||||||
}
|
|
||||||
foreach(const auto& thisOverlay, overlaysWorld) {
|
|
||||||
thisOverlay->update(deltatime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanupOverlaysToDelete();
|
cleanupOverlaysToDelete();
|
||||||
|
@ -119,14 +114,8 @@ void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||||
int height = size.y;
|
int height = size.y;
|
||||||
mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000);
|
mat4 legacyProjection = glm::ortho<float>(0, width, height, 0, -1000, 1000);
|
||||||
|
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
QMutexLocker locker(&_mutex);
|
||||||
{
|
foreach(Overlay::Pointer thisOverlay, _overlaysHUD) {
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
overlaysHUD = _overlaysHUD;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
foreach(Overlay::Pointer thisOverlay, overlaysHUD) {
|
|
||||||
|
|
||||||
// Reset all batch pipeline settings between overlay
|
// Reset all batch pipeline settings between overlay
|
||||||
geometryCache->useSimpleDrawPipeline(batch);
|
geometryCache->useSimpleDrawPipeline(batch);
|
||||||
|
@ -400,36 +389,22 @@ OverlayID Overlays::getOverlayAtPoint(const glm::vec2& point) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 pointCopy = point;
|
|
||||||
if (!_enabled) {
|
if (!_enabled) {
|
||||||
return UNKNOWN_OVERLAY_ID;
|
return UNKNOWN_OVERLAY_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysHUD;
|
QMutexLocker locker(&_mutex);
|
||||||
{
|
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysHUD);
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
overlaysHUD = _overlaysHUD;
|
|
||||||
}
|
|
||||||
QMapIterator<OverlayID, Overlay::Pointer> i(overlaysHUD);
|
|
||||||
|
|
||||||
const float LARGE_NEGATIVE_FLOAT = -9999999;
|
|
||||||
glm::vec3 origin(pointCopy.x, pointCopy.y, LARGE_NEGATIVE_FLOAT);
|
|
||||||
glm::vec3 direction(0, 0, 1);
|
|
||||||
glm::vec3 thisSurfaceNormal;
|
|
||||||
unsigned int bestStackOrder = 0;
|
unsigned int bestStackOrder = 0;
|
||||||
OverlayID bestOverlayID = UNKNOWN_OVERLAY_ID;
|
OverlayID bestOverlayID = UNKNOWN_OVERLAY_ID;
|
||||||
|
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
OverlayID thisID = i.key();
|
auto thisOverlay = std::dynamic_pointer_cast<Overlay2D>(i.value());
|
||||||
if (!i.value()->is3D()) {
|
if (thisOverlay && thisOverlay->getVisible() && thisOverlay->isLoaded() &&
|
||||||
auto thisOverlay = std::dynamic_pointer_cast<Overlay2D>(i.value());
|
thisOverlay->getBoundingRect().contains(point.x, point.y, false)) {
|
||||||
if (thisOverlay && thisOverlay->getVisible() && thisOverlay->isLoaded() &&
|
if (thisOverlay->getStackOrder() > bestStackOrder) {
|
||||||
thisOverlay->getBoundingRect().contains(pointCopy.x, pointCopy.y, false)) {
|
bestOverlayID = i.key();
|
||||||
if (thisOverlay->getStackOrder() > bestStackOrder) {
|
bestStackOrder = thisOverlay->getStackOrder();
|
||||||
bestOverlayID = thisID;
|
|
||||||
bestStackOrder = thisOverlay->getStackOrder();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,14 +473,9 @@ RayToOverlayIntersectionResult Overlays::findRayIntersectionInternal(const PickR
|
||||||
float bestDistance = std::numeric_limits<float>::max();
|
float bestDistance = std::numeric_limits<float>::max();
|
||||||
bool bestIsFront = false;
|
bool bestIsFront = false;
|
||||||
|
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
QMutexLocker locker(&_mutex);
|
||||||
{
|
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
overlaysWorld = _overlaysWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
RayToOverlayIntersectionResult result;
|
RayToOverlayIntersectionResult result;
|
||||||
QMapIterator<OverlayID, Overlay::Pointer> i(overlaysWorld);
|
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysWorld);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
OverlayID thisID = i.key();
|
OverlayID thisID = i.key();
|
||||||
|
@ -995,13 +965,8 @@ QVector<QUuid> Overlays::findOverlays(const glm::vec3& center, float radius) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<OverlayID, Overlay::Pointer> overlaysWorld;
|
QMutexLocker locker(&_mutex);
|
||||||
{
|
QMapIterator<OverlayID, Overlay::Pointer> i(_overlaysWorld);
|
||||||
QMutexLocker locker(&_mutex);
|
|
||||||
overlaysWorld = _overlaysWorld;
|
|
||||||
}
|
|
||||||
|
|
||||||
QMapIterator<OverlayID, Overlay::Pointer> i(overlaysWorld);
|
|
||||||
int checked = 0;
|
int checked = 0;
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
checked++;
|
checked++;
|
||||||
|
|
|
@ -198,11 +198,7 @@ gpu::TexturePointer TextureCache::getTextureByHash(const std::string& hash) {
|
||||||
std::unique_lock<std::mutex> lock(_texturesByHashesMutex);
|
std::unique_lock<std::mutex> lock(_texturesByHashesMutex);
|
||||||
weakPointer = _texturesByHashes[hash];
|
weakPointer = _texturesByHashes[hash];
|
||||||
}
|
}
|
||||||
auto result = weakPointer.lock();
|
return weakPointer.lock();
|
||||||
if (result) {
|
|
||||||
qCWarning(modelnetworking) << "QQQ Returning live texture for hash " << hash.c_str();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::TexturePointer TextureCache::cacheTextureByHash(const std::string& hash, const gpu::TexturePointer& texture) {
|
gpu::TexturePointer TextureCache::cacheTextureByHash(const std::string& hash, const gpu::TexturePointer& texture) {
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include <QtScript/QScriptEngine>
|
#include <QtScript/QScriptEngine>
|
||||||
#include <QtNetwork/QNetworkDiskCache>
|
#include <QtNetwork/QNetworkDiskCache>
|
||||||
|
|
||||||
|
#include <shared/GlobalAppProperties.h>
|
||||||
|
|
||||||
#include "AssetRequest.h"
|
#include "AssetRequest.h"
|
||||||
#include "AssetUpload.h"
|
#include "AssetUpload.h"
|
||||||
#include "AssetUtils.h"
|
#include "AssetUtils.h"
|
||||||
|
@ -31,11 +33,12 @@
|
||||||
|
|
||||||
MessageID AssetClient::_currentID = 0;
|
MessageID AssetClient::_currentID = 0;
|
||||||
|
|
||||||
AssetClient::AssetClient(const QString& cacheDir) : _cacheDir(cacheDir) {
|
AssetClient::AssetClient() {
|
||||||
|
_cacheDir = qApp->property(hifi::properties::APP_LOCAL_DATA_PATH).toString();
|
||||||
setCustomDeleter([](Dependency* dependency){
|
setCustomDeleter([](Dependency* dependency){
|
||||||
static_cast<AssetClient*>(dependency)->deleteLater();
|
static_cast<AssetClient*>(dependency)->deleteLater();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ void AssetClient::handleAssetMappingOperationReply(QSharedPointer<ReceivedMessag
|
||||||
|
|
||||||
MessageID messageID;
|
MessageID messageID;
|
||||||
message->readPrimitive(&messageID);
|
message->readPrimitive(&messageID);
|
||||||
|
|
||||||
AssetServerError error;
|
AssetServerError error;
|
||||||
message->readPrimitive(&error);
|
message->readPrimitive(&error);
|
||||||
|
|
||||||
|
@ -132,13 +135,13 @@ void AssetClient::handleAssetMappingOperationReply(QSharedPointer<ReceivedMessag
|
||||||
bool haveAssetServer() {
|
bool haveAssetServer() {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
if (!assetServer) {
|
if (!assetServer) {
|
||||||
qCWarning(asset_client) << "Could not complete AssetClient operation "
|
qCWarning(asset_client) << "Could not complete AssetClient operation "
|
||||||
<< "since you are not currently connected to an asset-server.";
|
<< "since you are not currently connected to an asset-server.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,14 +223,14 @@ MessageID AssetClient::getAsset(const QString& hash, DataOffset start, DataOffse
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
if (assetServer) {
|
if (assetServer) {
|
||||||
|
|
||||||
auto messageID = ++_currentID;
|
auto messageID = ++_currentID;
|
||||||
|
|
||||||
auto payloadSize = sizeof(messageID) + SHA256_HASH_LENGTH + sizeof(start) + sizeof(end);
|
auto payloadSize = sizeof(messageID) + SHA256_HASH_LENGTH + sizeof(start) + sizeof(end);
|
||||||
auto packet = NLPacket::create(PacketType::AssetGet, payloadSize, true);
|
auto packet = NLPacket::create(PacketType::AssetGet, payloadSize, true);
|
||||||
|
|
||||||
qCDebug(asset_client) << "Requesting data from" << start << "to" << end << "of" << hash << "from asset-server.";
|
qCDebug(asset_client) << "Requesting data from" << start << "to" << end << "of" << hash << "from asset-server.";
|
||||||
|
|
||||||
packet->writePrimitive(messageID);
|
packet->writePrimitive(messageID);
|
||||||
|
|
||||||
packet->write(QByteArray::fromHex(hash.toLatin1()));
|
packet->write(QByteArray::fromHex(hash.toLatin1()));
|
||||||
|
@ -254,10 +257,10 @@ MessageID AssetClient::getAssetInfo(const QString& hash, GetInfoCallback callbac
|
||||||
|
|
||||||
if (assetServer) {
|
if (assetServer) {
|
||||||
auto messageID = ++_currentID;
|
auto messageID = ++_currentID;
|
||||||
|
|
||||||
auto payloadSize = sizeof(messageID) + SHA256_HASH_LENGTH;
|
auto payloadSize = sizeof(messageID) + SHA256_HASH_LENGTH;
|
||||||
auto packet = NLPacket::create(PacketType::AssetGetInfo, payloadSize, true);
|
auto packet = NLPacket::create(PacketType::AssetGetInfo, payloadSize, true);
|
||||||
|
|
||||||
packet->writePrimitive(messageID);
|
packet->writePrimitive(messageID);
|
||||||
packet->write(QByteArray::fromHex(hash.toLatin1()));
|
packet->write(QByteArray::fromHex(hash.toLatin1()));
|
||||||
|
|
||||||
|
@ -278,7 +281,7 @@ void AssetClient::handleAssetGetInfoReply(QSharedPointer<ReceivedMessage> messag
|
||||||
MessageID messageID;
|
MessageID messageID;
|
||||||
message->readPrimitive(&messageID);
|
message->readPrimitive(&messageID);
|
||||||
auto assetHash = message->read(SHA256_HASH_LENGTH);
|
auto assetHash = message->read(SHA256_HASH_LENGTH);
|
||||||
|
|
||||||
AssetServerError error;
|
AssetServerError error;
|
||||||
message->readPrimitive(&error);
|
message->readPrimitive(&error);
|
||||||
|
|
||||||
|
@ -367,7 +370,7 @@ void AssetClient::handleAssetGetReply(QSharedPointer<ReceivedMessage> message, S
|
||||||
callbacks.completeCallback(true, error, message->readAll());
|
callbacks.completeCallback(true, error, message->readAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
messageCallbackMap.erase(requestIt);
|
messageCallbackMap.erase(requestIt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,7 +481,7 @@ MessageID AssetClient::getAllAssetMappings(MappingOperationCallback callback) {
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
if (assetServer) {
|
if (assetServer) {
|
||||||
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
||||||
|
|
||||||
|
@ -501,7 +504,7 @@ MessageID AssetClient::getAllAssetMappings(MappingOperationCallback callback) {
|
||||||
MessageID AssetClient::deleteAssetMappings(const AssetPathList& paths, MappingOperationCallback callback) {
|
MessageID AssetClient::deleteAssetMappings(const AssetPathList& paths, MappingOperationCallback callback) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
if (assetServer) {
|
if (assetServer) {
|
||||||
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
||||||
|
|
||||||
|
@ -532,7 +535,7 @@ MessageID AssetClient::setAssetMapping(const QString& path, const AssetHash& has
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
if (assetServer) {
|
if (assetServer) {
|
||||||
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
||||||
|
|
||||||
|
@ -644,7 +647,7 @@ MessageID AssetClient::uploadAsset(const QByteArray& data, UploadResultCallback
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
if (assetServer) {
|
if (assetServer) {
|
||||||
auto packetList = NLPacketList::create(PacketType::AssetUpload, QByteArray(), true, true);
|
auto packetList = NLPacketList::create(PacketType::AssetUpload, QByteArray(), true, true);
|
||||||
|
|
||||||
|
@ -682,7 +685,7 @@ void AssetClient::handleAssetUploadReply(QSharedPointer<ReceivedMessage> message
|
||||||
} else {
|
} else {
|
||||||
auto hash = message->read(SHA256_HASH_LENGTH);
|
auto hash = message->read(SHA256_HASH_LENGTH);
|
||||||
hashString = hash.toHex();
|
hashString = hash.toHex();
|
||||||
|
|
||||||
qCDebug(asset_client) << "Successfully uploaded asset to asset-server - SHA256 hash is " << hashString;
|
qCDebug(asset_client) << "Successfully uploaded asset to asset-server - SHA256 hash is " << hashString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ using ProgressCallback = std::function<void(qint64 totalReceived, qint64 total)>
|
||||||
class AssetClient : public QObject, public Dependency {
|
class AssetClient : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AssetClient(const QString& cacheDir="");
|
AssetClient();
|
||||||
|
|
||||||
Q_INVOKABLE GetMappingRequest* createGetMappingRequest(const AssetPath& path);
|
Q_INVOKABLE GetMappingRequest* createGetMappingRequest(const AssetPath& path);
|
||||||
Q_INVOKABLE GetAllMappingsRequest* createGetAllMappingsRequest();
|
Q_INVOKABLE GetAllMappingsRequest* createGetAllMappingsRequest();
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
ResourceManager::ResourceManager() {
|
ResourceManager::ResourceManager() {
|
||||||
_thread.setObjectName("Resource Manager Thread");
|
_thread.setObjectName("Resource Manager Thread");
|
||||||
|
|
||||||
auto assetClient = DependencyManager::set<AssetClient>(_cacheDir);
|
auto assetClient = DependencyManager::set<AssetClient>();
|
||||||
assetClient->moveToThread(&_thread);
|
assetClient->moveToThread(&_thread);
|
||||||
QObject::connect(&_thread, &QThread::started, assetClient.data(), &AssetClient::init);
|
QObject::connect(&_thread, &QThread::started, assetClient.data(), &AssetClient::init);
|
||||||
|
|
||||||
|
@ -160,7 +160,3 @@ bool ResourceManager::resourceExists(const QUrl& url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceManager::setCacheDir(const QString& cacheDir) {
|
|
||||||
// TODO: check for existence?
|
|
||||||
_cacheDir = cacheDir;
|
|
||||||
}
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ private:
|
||||||
PrefixMap _prefixMap;
|
PrefixMap _prefixMap;
|
||||||
QMutex _prefixMapLock;
|
QMutex _prefixMapLock;
|
||||||
|
|
||||||
QString _cacheDir;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1821,7 +1821,7 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac
|
||||||
clearExceptions();
|
clearExceptions();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
scriptWarningMessage("Script.include() skipping evaluation of previously included url:" + url.toString());
|
scriptPrintedMessage("Script.include() skipping evaluation of previously included url:" + url.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "PathUtils.h"
|
#include "PathUtils.h"
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
#include <mutex> // std::once
|
#include <mutex> // std::once
|
||||||
|
#include "shared/GlobalAppProperties.h"
|
||||||
|
|
||||||
const QString& PathUtils::resourcesPath() {
|
const QString& PathUtils::resourcesPath() {
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
@ -34,12 +35,8 @@ QString PathUtils::getAppDataPath() {
|
||||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/";
|
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PathUtils::getAppLocalDataPath(const QString& overridePath /* = "" */) {
|
QString PathUtils::getAppLocalDataPath() {
|
||||||
static QString overriddenPath = "";
|
QString overriddenPath = qApp->property(hifi::properties::APP_LOCAL_DATA_PATH).toString();
|
||||||
// set the overridden path if one was passed in
|
|
||||||
if (!overridePath.isEmpty()) {
|
|
||||||
overriddenPath = overridePath;
|
|
||||||
}
|
|
||||||
// return overridden path if set
|
// return overridden path if set
|
||||||
if (!overriddenPath.isEmpty()) {
|
if (!overriddenPath.isEmpty()) {
|
||||||
return overriddenPath;
|
return overriddenPath;
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
static const QString& resourcesPath();
|
static const QString& resourcesPath();
|
||||||
|
|
||||||
static QString getAppDataPath();
|
static QString getAppDataPath();
|
||||||
static QString getAppLocalDataPath(const QString& overridePath = "");
|
static QString getAppLocalDataPath();
|
||||||
|
|
||||||
static QString getAppDataFilePath(const QString& filename);
|
static QString getAppDataFilePath(const QString& filename);
|
||||||
static QString getAppLocalDataFilePath(const QString& filename);
|
static QString getAppLocalDataFilePath(const QString& filename);
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace hifi { namespace properties {
|
||||||
const char* TEST = "com.highfidelity.test";
|
const char* TEST = "com.highfidelity.test";
|
||||||
const char* TRACING = "com.highfidelity.tracing";
|
const char* TRACING = "com.highfidelity.tracing";
|
||||||
const char* HMD = "com.highfidelity.hmd";
|
const char* HMD = "com.highfidelity.hmd";
|
||||||
|
const char* APP_LOCAL_DATA_PATH = "com.highfidelity.appLocalDataPath";
|
||||||
|
|
||||||
namespace gl {
|
namespace gl {
|
||||||
const char* BACKEND = "com.highfidelity.gl.backend";
|
const char* BACKEND = "com.highfidelity.gl.backend";
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace hifi { namespace properties {
|
||||||
extern const char* TEST;
|
extern const char* TEST;
|
||||||
extern const char* TRACING;
|
extern const char* TRACING;
|
||||||
extern const char* HMD;
|
extern const char* HMD;
|
||||||
|
extern const char* APP_LOCAL_DATA_PATH;
|
||||||
|
|
||||||
namespace gl {
|
namespace gl {
|
||||||
extern const char* BACKEND;
|
extern const char* BACKEND;
|
||||||
|
|
|
@ -82,6 +82,12 @@ struct PoseData {
|
||||||
angularVelocities[i] = transformVectorFast(resetMat, toGlm(vrPoses[i].vAngularVelocity));
|
angularVelocities[i] = transformVectorFast(resetMat, toGlm(vrPoses[i].vAngularVelocity));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void resetToInvalid() {
|
||||||
|
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||||
|
vrPoses[i].bPoseIsValid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME remove once OpenVR header is updated
|
// FIXME remove once OpenVR header is updated
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <glm/ext.hpp>
|
#include <glm/ext.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
#include <ui-plugins/PluginContainer.h>
|
||||||
|
#include <plugins/DisplayPlugin.h>
|
||||||
|
|
||||||
#include <controllers/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
#include <Plugins/InputConfiguration.h>
|
#include <Plugins/InputConfiguration.h>
|
||||||
|
@ -60,11 +62,6 @@ static const int SECOND_FOOT = 1;
|
||||||
static const int HIP = 2;
|
static const int HIP = 2;
|
||||||
static const int CHEST = 3;
|
static const int CHEST = 3;
|
||||||
|
|
||||||
static float HEAD_PUCK_Y_OFFSET = -0.0254f;
|
|
||||||
static float HEAD_PUCK_Z_OFFSET = -0.152f;
|
|
||||||
static float HAND_PUCK_Y_OFFSET = -0.0508f;
|
|
||||||
static float HAND_PUCK_Z_OFFSET = 0.0254f;
|
|
||||||
|
|
||||||
const char* ViveControllerManager::NAME { "OpenVR" };
|
const char* ViveControllerManager::NAME { "OpenVR" };
|
||||||
|
|
||||||
const std::map<vr::ETrackingResult, QString> TRACKING_RESULT_TO_STRING = {
|
const std::map<vr::ETrackingResult, QString> TRACKING_RESULT_TO_STRING = {
|
||||||
|
@ -121,6 +118,29 @@ static QString deviceTrackingResultToString(vr::ETrackingResult trackingResult)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static glm::mat4 calculateResetMat() {
|
||||||
|
auto chaperone = vr::VRChaperone();
|
||||||
|
if (chaperone) {
|
||||||
|
float const UI_RADIUS = 1.0f;
|
||||||
|
float const UI_HEIGHT = 1.6f;
|
||||||
|
float const UI_Z_OFFSET = 0.5;
|
||||||
|
|
||||||
|
float xSize, zSize;
|
||||||
|
chaperone->GetPlayAreaSize(&xSize, &zSize);
|
||||||
|
glm::vec3 uiPos(0.0f, UI_HEIGHT, UI_RADIUS - (0.5f * zSize) - UI_Z_OFFSET);
|
||||||
|
|
||||||
|
return glm::inverse(createMatFromQuatAndPos(glm::quat(), uiPos));
|
||||||
|
}
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViveControllerManager::isDesktopMode() {
|
||||||
|
if (_container) {
|
||||||
|
return !_container->getActiveDisplayPlugin()->isHmd();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ViveControllerManager::calibrate() {
|
void ViveControllerManager::calibrate() {
|
||||||
if (isSupported()) {
|
if (isSupported()) {
|
||||||
_inputDevice->calibrateNextFrame();
|
_inputDevice->calibrateNextFrame();
|
||||||
|
@ -141,13 +161,21 @@ bool ViveControllerManager::isSupported() const {
|
||||||
|
|
||||||
void ViveControllerManager::setConfigurationSettings(const QJsonObject configurationSettings) {
|
void ViveControllerManager::setConfigurationSettings(const QJsonObject configurationSettings) {
|
||||||
if (isSupported()) {
|
if (isSupported()) {
|
||||||
|
if (configurationSettings.contains("desktopMode")) {
|
||||||
|
_desktopMode = configurationSettings["desktopMode"].toBool();
|
||||||
|
if (!_desktopMode) {
|
||||||
|
_resetMatCalculated = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
_inputDevice->configureCalibrationSettings(configurationSettings);
|
_inputDevice->configureCalibrationSettings(configurationSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject ViveControllerManager::configurationSettings() {
|
QJsonObject ViveControllerManager::configurationSettings() {
|
||||||
if (isSupported()) {
|
if (isSupported()) {
|
||||||
return _inputDevice->configurationSettings();
|
QJsonObject configurationSettings = _inputDevice->configurationSettings();
|
||||||
|
configurationSettings["desktopMode"] = _desktopMode;
|
||||||
|
return configurationSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QJsonObject();
|
return QJsonObject();
|
||||||
|
@ -218,6 +246,18 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDesktopMode() && _desktopMode) {
|
||||||
|
if (!_resetMatCalculated) {
|
||||||
|
_resetMat = calculateResetMat();
|
||||||
|
_resetMatCalculated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, _nextSimPoseData.vrPoses, vr::k_unMaxTrackedDeviceCount);
|
||||||
|
_nextSimPoseData.update(_resetMat);
|
||||||
|
} else if (isDesktopMode()) {
|
||||||
|
_nextSimPoseData.resetToInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
handleOpenVrEvents();
|
handleOpenVrEvents();
|
||||||
if (openVrQuitRequested()) {
|
if (openVrQuitRequested()) {
|
||||||
|
@ -344,8 +384,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
bool overrideHead = headObject["override"].toBool();
|
bool overrideHead = headObject["override"].toBool();
|
||||||
if (overrideHead) {
|
if (overrideHead) {
|
||||||
_headConfig = HeadConfig::Puck;
|
_headConfig = HeadConfig::Puck;
|
||||||
HEAD_PUCK_Y_OFFSET = headObject["Y"].toDouble();
|
_headPuckYOffset = headObject["Y"].toDouble();
|
||||||
HEAD_PUCK_Z_OFFSET = headObject["Z"].toDouble();
|
_headPuckZOffset = headObject["Z"].toDouble();
|
||||||
} else {
|
} else {
|
||||||
_headConfig = HeadConfig::HMD;
|
_headConfig = HeadConfig::HMD;
|
||||||
}
|
}
|
||||||
|
@ -354,8 +394,8 @@ void ViveControllerManager::InputDevice::configureCalibrationSettings(const QJso
|
||||||
bool overrideHands = handsObject["override"].toBool();
|
bool overrideHands = handsObject["override"].toBool();
|
||||||
if (overrideHands) {
|
if (overrideHands) {
|
||||||
_handConfig = HandConfig::Pucks;
|
_handConfig = HandConfig::Pucks;
|
||||||
HAND_PUCK_Y_OFFSET = handsObject["Y"].toDouble();
|
_handPuckYOffset = handsObject["Y"].toDouble();
|
||||||
HAND_PUCK_Z_OFFSET = handsObject["Z"].toDouble();
|
_handPuckZOffset = handsObject["Z"].toDouble();
|
||||||
} else {
|
} else {
|
||||||
_handConfig = HandConfig::HandController;
|
_handConfig = HandConfig::HandController;
|
||||||
}
|
}
|
||||||
|
@ -714,7 +754,7 @@ glm::mat4 ViveControllerManager::InputDevice::calculateDefaultToReferenceForHead
|
||||||
glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f));
|
glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f));
|
||||||
|
|
||||||
glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f),
|
glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f),
|
||||||
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, HEAD_PUCK_Y_OFFSET, HEAD_PUCK_Z_OFFSET, 1.0f));
|
glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, _headPuckYOffset, _headPuckZOffset, 1.0f));
|
||||||
|
|
||||||
glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset;
|
glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset;
|
||||||
|
|
||||||
|
@ -914,7 +954,7 @@ void ViveControllerManager::InputDevice::calibrateLeftHand(glm::mat4& defaultToR
|
||||||
glm::vec4(zPrime, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
glm::vec4(zPrime, 0.0f), glm::vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 translationOffset = glm::vec3(0.0f, HAND_PUCK_Y_OFFSET, HAND_PUCK_Z_OFFSET);
|
glm::vec3 translationOffset = glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset);
|
||||||
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
||||||
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
||||||
|
|
||||||
|
@ -945,7 +985,7 @@ void ViveControllerManager::InputDevice::calibrateRightHand(glm::mat4& defaultTo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 translationOffset = glm::vec3(0.0f, HAND_PUCK_Y_OFFSET, HAND_PUCK_Z_OFFSET);
|
glm::vec3 translationOffset = glm::vec3(0.0f, _handPuckYOffset, _handPuckZOffset);
|
||||||
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
glm::quat initialRotation = glmExtractRotation(handPoseAvatarMat);
|
||||||
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
glm::quat finalRotation = glmExtractRotation(newHandMat);
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,10 @@ private:
|
||||||
float _leftHapticDuration { 0.0f };
|
float _leftHapticDuration { 0.0f };
|
||||||
float _rightHapticStrength { 0.0f };
|
float _rightHapticStrength { 0.0f };
|
||||||
float _rightHapticDuration { 0.0f };
|
float _rightHapticDuration { 0.0f };
|
||||||
|
float _headPuckYOffset { 0.0f };
|
||||||
|
float _headPuckZOffset { 0.0f };
|
||||||
|
float _handPuckYOffset { 0.0f };
|
||||||
|
float _handPuckZOffset { 0.0f };
|
||||||
bool _triggersPressedHandled { false };
|
bool _triggersPressedHandled { false };
|
||||||
bool _calibrated { false };
|
bool _calibrated { false };
|
||||||
bool _timeTilCalibrationSet { false };
|
bool _timeTilCalibrationSet { false };
|
||||||
|
@ -190,9 +194,12 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign);
|
void renderHand(const controller::Pose& pose, gpu::Batch& batch, int sign);
|
||||||
|
bool isDesktopMode();
|
||||||
bool _registeredWithInputMapper { false };
|
bool _registeredWithInputMapper { false };
|
||||||
bool _modelLoaded { false };
|
bool _modelLoaded { false };
|
||||||
|
bool _resetMatCalculated { false };
|
||||||
|
bool _desktopMode { false };
|
||||||
|
glm::mat4 _resetMat { glm::mat4() };
|
||||||
model::Geometry _modelGeometry;
|
model::Geometry _modelGeometry;
|
||||||
gpu::TexturePointer _texture;
|
gpu::TexturePointer _texture;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue