Merge pull request #838 from ctrlaltdavid/fix/hud-recentering

HUD overlay fixes and improvements
This commit is contained in:
Kalila 2020-12-14 20:46:02 -05:00 committed by GitHub
commit 0f87e4cd86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 30 additions and 30 deletions

View file

@ -309,8 +309,8 @@ FocusScope {
if (child.hasOwnProperty("modality")) { if (child.hasOwnProperty("modality")) {
var mappedPoint = mapToItem(child, point.x, point.y); var mappedPoint = mapToItem(child, point.x, point.y);
if (child.hasOwnProperty("frame")) { if (child.hasOwnProperty("frame")) {
var outLine = child.frame.children[2]; var outLine = child.frame.children[2]; // sizeOutline
var framePoint = outLine.mapFromGlobal(point.x, point.y); var framePoint = mapToItem(outLine, point.x, point.y);
if (outLine.contains(framePoint)) { if (outLine.contains(framePoint)) {
return true; return true;
} }

View file

@ -27,7 +27,6 @@ Item {
readonly property int frameMarginRight: frame.decoration ? frame.decoration.frameMarginRight : 0 readonly property int frameMarginRight: frame.decoration ? frame.decoration.frameMarginRight : 0
readonly property int frameMarginTop: frame.decoration ? frame.decoration.frameMarginTop : 0 readonly property int frameMarginTop: frame.decoration ? frame.decoration.frameMarginTop : 0
readonly property int frameMarginBottom: frame.decoration ? frame.decoration.frameMarginBottom : 0 readonly property int frameMarginBottom: frame.decoration ? frame.decoration.frameMarginBottom : 0
readonly property int offsetCorrection: 20
// Frames always fill their parents, but their decorations may extend // Frames always fill their parents, but their decorations may extend
// beyond the window via negative margin sizes // beyond the window via negative margin sizes
@ -76,7 +75,7 @@ Item {
Rectangle { Rectangle {
id: sizeOutline id: sizeOutline
x: -frameMarginLeft x: -frameMarginLeft
y: -frameMarginTop - offsetCorrection y: -frameMarginTop
width: window ? window.width + frameMarginLeft + frameMarginRight + 2 : 0 width: window ? window.width + frameMarginLeft + frameMarginRight + 2 : 0
height: window ? window.height + frameMarginTop + frameMarginBottom + 2 : 0 height: window ? window.height + frameMarginTop + frameMarginBottom + 2 : 0
color: hifi.colors.baseGrayHighlight15 color: hifi.colors.baseGrayHighlight15

View file

@ -23,7 +23,7 @@ OverlayConductor::OverlayConductor() {
OverlayConductor::~OverlayConductor() { OverlayConductor::~OverlayConductor() {
} }
bool OverlayConductor::headOutsideOverlay() const { bool OverlayConductor::headNotCenteredInOverlay() const {
glm::mat4 hmdMat = qApp->getHMDSensorPose(); glm::mat4 hmdMat = qApp->getHMDSensorPose();
glm::vec3 hmdPos = extractTranslation(hmdMat); glm::vec3 hmdPos = extractTranslation(hmdMat);
glm::vec3 hmdForward = transformVectorFast(hmdMat, glm::vec3(0.0f, 0.0f, -1.0f)); glm::vec3 hmdForward = transformVectorFast(hmdMat, glm::vec3(0.0f, 0.0f, -1.0f));
@ -32,8 +32,8 @@ bool OverlayConductor::headOutsideOverlay() const {
glm::vec3 uiPos = uiTransform.getTranslation(); glm::vec3 uiPos = uiTransform.getTranslation();
glm::vec3 uiForward = uiTransform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 uiForward = uiTransform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f);
const float MAX_COMPOSITOR_DISTANCE = 0.99f; // If you're 1m from center of ui sphere, you're at the surface. const float MAX_COMPOSITOR_DISTANCE = 0.33f;
const float MAX_COMPOSITOR_ANGLE = 180.0f; // rotation check is effectively disabled const float MAX_COMPOSITOR_ANGLE = 90.0f;
if (glm::distance(uiPos, hmdPos) > MAX_COMPOSITOR_DISTANCE || if (glm::distance(uiPos, hmdPos) > MAX_COMPOSITOR_DISTANCE ||
glm::dot(uiForward, hmdForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE))) { glm::dot(uiForward, hmdForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE))) {
return true; return true;
@ -70,6 +70,8 @@ bool OverlayConductor::updateAvatarIsAtRest() {
void OverlayConductor::centerUI() { void OverlayConductor::centerUI() {
// place the overlay at the current hmd position in sensor space // place the overlay at the current hmd position in sensor space
auto camMat = cancelOutRollAndPitch(qApp->getHMDSensorPose()); auto camMat = cancelOutRollAndPitch(qApp->getHMDSensorPose());
// Set its radius.
camMat = glm::scale(camMat, glm::vec3(HUD_RADIUS));
qApp->getApplicationCompositor().setModelTransform(Transform(camMat)); qApp->getApplicationCompositor().setModelTransform(Transform(camMat));
} }
@ -83,7 +85,6 @@ void OverlayConductor::update(float dt) {
if (!desktop) { if (!desktop) {
return; return;
} }
bool currentVisible = !desktop->property("pinned").toBool();
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
// centerUI when hmd mode is first enabled and mounted // centerUI when hmd mode is first enabled and mounted
@ -96,24 +97,24 @@ void OverlayConductor::update(float dt) {
_hmdMode = false; _hmdMode = false;
} }
bool shouldRecenter = false; bool initiateRecenter = false;
if (_hmdMode && headNotCenteredInOverlay()) {
if (_suppressedByHead) { initiateRecenter = true;
if (updateAvatarIsAtRest()) {
_suppressedByHead = false;
shouldRecenter = true;
}
} else {
if (_hmdMode && headOutsideOverlay()) {
_suppressedByHead = true;
}
} }
bool shouldRecenter = false;
if (initiateRecenter || _suppressedByHead) {
_suppressedByHead = !updateAvatarIsAtRest();
shouldRecenter = !_suppressedByHead;
}
bool currentVisible = !desktop->property("pinned").toBool();
bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && !_suppressedByHead; bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && !_suppressedByHead;
if (targetVisible != currentVisible) { if (targetVisible != currentVisible) {
offscreenUi->setPinned(!targetVisible); offscreenUi->setPinned(!targetVisible);
} }
if (shouldRecenter && !_suppressedByHead) {
if (shouldRecenter) {
centerUI(); centerUI();
} }
#endif #endif

View file

@ -22,7 +22,7 @@ public:
void centerUI(); void centerUI();
private: private:
bool headOutsideOverlay() const; bool headNotCenteredInOverlay() const;
bool updateAvatarIsAtRest(); bool updateAvatarIsAtRest();
#if !defined(DISABLE_QML) #if !defined(DISABLE_QML)

View file

@ -41,10 +41,10 @@ static const float reticleSize = TWO_PI / 100.0f;
//EntityItemID CompositorHelper::_noItemId; //EntityItemID CompositorHelper::_noItemId;
static QString _tooltipId; static QString _tooltipId;
const uvec2 CompositorHelper::VIRTUAL_SCREEN_SIZE = uvec2(3960, 1188); // ~10% more pixel density than old version, 72dx240d FOV const uvec2 CompositorHelper::VIRTUAL_SCREEN_SIZE = uvec2(2640, 1188);
const QRect CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT = QRect(956, 0, 2048, 1188); // don't include entire width only center 2048 const QRect CompositorHelper::VIRTUAL_SCREEN_RECOMMENDED_OVERLAY_RECT = QRect(296, 0, 2048, 1188); // Center 2048 pixels.
const float CompositorHelper::VIRTUAL_UI_ASPECT_RATIO = (float)VIRTUAL_SCREEN_SIZE.x / (float)VIRTUAL_SCREEN_SIZE.y; const float CompositorHelper::VIRTUAL_UI_ASPECT_RATIO = (float)VIRTUAL_SCREEN_SIZE.x / (float)VIRTUAL_SCREEN_SIZE.y;
const vec2 CompositorHelper::VIRTUAL_UI_TARGET_FOV = vec2(PI * 3.0f / 2.0f, PI * 3.0f / 2.0f / VIRTUAL_UI_ASPECT_RATIO); const vec2 CompositorHelper::VIRTUAL_UI_TARGET_FOV = vec2(PI, PI / VIRTUAL_UI_ASPECT_RATIO);
const vec2 CompositorHelper::MOUSE_EXTENTS_ANGULAR_SIZE = vec2(PI * 2.0f, PI * 0.95f); // horizontal: full sphere, vertical: ~5deg from poles const vec2 CompositorHelper::MOUSE_EXTENTS_ANGULAR_SIZE = vec2(PI * 2.0f, PI * 0.95f); // horizontal: full sphere, vertical: ~5deg from poles
const vec2 CompositorHelper::MOUSE_EXTENTS_PIXELS = vec2(VIRTUAL_SCREEN_SIZE) * (MOUSE_EXTENTS_ANGULAR_SIZE / VIRTUAL_UI_TARGET_FOV); const vec2 CompositorHelper::MOUSE_EXTENTS_PIXELS = vec2(VIRTUAL_SCREEN_SIZE) * (MOUSE_EXTENTS_ANGULAR_SIZE / VIRTUAL_UI_TARGET_FOV);
@ -384,9 +384,9 @@ bool CompositorHelper::calculateRayUICollisionPoint(const glm::vec3& position, c
glm::vec3 localPosition = transformPoint(worldToUi, position); glm::vec3 localPosition = transformPoint(worldToUi, position);
glm::vec3 localDirection = glm::normalize(transformVectorFast(worldToUi, direction)); glm::vec3 localDirection = glm::normalize(transformVectorFast(worldToUi, direction));
const float UI_RADIUS = 1.0f; const float UNIT_RADIUS = 1.0f;
float intersectionDistance; float intersectionDistance;
if (raySphereIntersect(localDirection, localPosition, UI_RADIUS, &intersectionDistance)) { if (raySphereIntersect(localDirection, localPosition, UNIT_RADIUS, &intersectionDistance)) {
result = transformPoint(uiToWorld, localPosition + localDirection * intersectionDistance); result = transformPoint(uiToWorld, localPosition + localDirection * intersectionDistance);
#ifdef WANT_DEBUG #ifdef WANT_DEBUG
DebugDraw::getInstance().drawRay(position, result, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(position, result, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
@ -407,9 +407,8 @@ bool CompositorHelper::calculateParabolaUICollisionPoint(const glm::vec3& origin
glm::vec3 localVelocity = glm::normalize(transformVectorFast(worldToUi, velocity)); glm::vec3 localVelocity = glm::normalize(transformVectorFast(worldToUi, velocity));
glm::vec3 localAcceleration = glm::normalize(transformVectorFast(worldToUi, acceleration)); glm::vec3 localAcceleration = glm::normalize(transformVectorFast(worldToUi, acceleration));
const float UI_RADIUS = 1.0f;
float intersectionDistance; float intersectionDistance;
if (findParabolaSphereIntersection(localOrigin, localVelocity, localAcceleration, glm::vec3(0.0f), UI_RADIUS, intersectionDistance)) { if (findParabolaSphereIntersection(localOrigin, localVelocity, localAcceleration, glm::vec3(0.0f), HUD_RADIUS, intersectionDistance)) {
result = origin + velocity * intersectionDistance + 0.5f * acceleration * intersectionDistance * intersectionDistance; result = origin + velocity * intersectionDistance + 0.5f * acceleration * intersectionDistance * intersectionDistance;
parabolicDistance = intersectionDistance; parabolicDistance = intersectionDistance;
return true; return true;

View file

@ -27,7 +27,8 @@
class ReticleInterface; class ReticleInterface;
const float DEFAULT_RETICLE_DEPTH = 1.0f; // FIXME - probably should be based on UI radius const float HUD_RADIUS = 1.5f;
const float DEFAULT_RETICLE_DEPTH = HUD_RADIUS;
const float MAGNIFY_WIDTH = 220.0f; const float MAGNIFY_WIDTH = 220.0f;
const float MAGNIFY_HEIGHT = 100.0f; const float MAGNIFY_HEIGHT = 100.0f;
@ -154,7 +155,7 @@ private:
std::unique_ptr<QPropertyAnimation> _alphaPropertyAnimation; std::unique_ptr<QPropertyAnimation> _alphaPropertyAnimation;
std::atomic<bool> _reticleVisible { true }; std::atomic<bool> _reticleVisible { true };
std::atomic<float> _reticleDepth { 1.0f }; std::atomic<float> _reticleDepth { DEFAULT_RETICLE_DEPTH };
// NOTE: when the compositor is running in HMD mode, it will control the reticle position as a custom // NOTE: when the compositor is running in HMD mode, it will control the reticle position as a custom
// application specific position, when it's in desktop mode, the reticle position will simply move // application specific position, when it's in desktop mode, the reticle position will simply move