History

HMD re-centering while driving improvements.

Previously the HUD fading in/out would also recenter the hmd sensor and the avatar, which caused many problems including: * The user's view could shift vertically. * Your avatar would briefly go into t-pose * other users would see your avatar go into t-pose. Now we now move the UI sphere instead, which results in a much smoother experience. MyAvatar: added hasDriveInput method. OverlayConductor: * removed avatar and sensor reset, instead the overlay's modelTransform is changed. * revived STANDING mode, which is active if myAvatar->getClearOverlayWhenDriving() is true and you are wearing an HMD. * SITTING & FLAT mode should be unchanged. * Instead of using avatar velocity to fade out/fade in the hud, We use the presense or absanse of avatar drive input. * Additionally, we check distance to the UI sphere, and quickly recenter the hud if the users head is too close to the actual hud sphere. CompositorHelper: * Bug fixes for ray picks not using the modelTransform.

Anthony J. Thibault committed 10 years ago

Commit 5ef68471 parent b21fbe56 files · +65 −63Browse files

Showing the changes to interface/src/ui/OverlayConductor.cpp (1 of 6 files). Show all

Unified · Split

interface/src/ui/OverlayConductor.cpp+52−59
@@ -22,10 +22,31 @@ OverlayConductor::OverlayConductor() { · 21 unmodified lines
2222 OverlayConductor::~OverlayConductor() {
2323 }
2424
25+bool OverlayConductor::shouldCenterUI() const {
26+
27+ glm::mat4 hmdMat = qApp->getHMDSensorPose();
28+ glm::vec3 hmdPos = extractTranslation(hmdMat);
29+ glm::vec3 hmdForward = transformVectorFast(hmdMat, glm::vec3(0.0f, 0.0f, -1.0f));
30+
31+ Transform uiTransform = qApp->getApplicationCompositor().getModelTransform();
32+ glm::vec3 uiPos = uiTransform.getTranslation();
33+ glm::vec3 uiForward = uiTransform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f);
34+
35+ const float MAX_COMPOSITOR_DISTANCE = 0.6f;
36+ const float MAX_COMPOSITOR_ANGLE = 180.0f; // rotation check is effectively disabled
37+ if (glm::distance(uiPos, hmdPos) > MAX_COMPOSITOR_DISTANCE ||
38+ glm::dot(uiForward, hmdForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE))) {
39+ return true;
40+ }
41+ return false;
42+}
43+
2544 void OverlayConductor::update(float dt) {
2645
2746 updateMode();
2847
48+ MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
49+
2950 switch (_mode) {
3051 case SITTING: {
3152 // when sitting, the overlay is at the origin, facing down the -z axis.
@@ -36,75 +57,49 @@ void OverlayConductor::update(float dt) { · 4 unmodified lines
3657 break;
3758 }
3859 case STANDING: {
39− // when standing, the overlay is at a reference position, which is set when the overlay is
40− // enabled. The camera is taken directly from the HMD, but in world space.
41− // So the sensorToWorldMatrix must be applied.
42− MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
43− Transform t;
44− t.evalFromRawMatrix(myAvatar->getSensorToWorldMatrix());
45− qApp->getApplicationCompositor().setCameraBaseTransform(t);
46−
47− // detect when head moves out side of sweet spot, or looks away.
48− mat4 headMat = myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose();
49− vec3 headWorldPos = extractTranslation(headMat);
50− vec3 headForward = glm::quat_cast(headMat) * glm::vec3(0.0f, 0.0f, -1.0f);
51− Transform modelXform = qApp->getApplicationCompositor().getModelTransform();
52− vec3 compositorWorldPos = modelXform.getTranslation();
53− vec3 compositorForward = modelXform.getRotation() * glm::vec3(0.0f, 0.0f, -1.0f);
54− const float MAX_COMPOSITOR_DISTANCE = 0.6f;
55− const float MAX_COMPOSITOR_ANGLE = 110.0f;
56− if (_enabled && (glm::distance(headWorldPos, compositorWorldPos) > MAX_COMPOSITOR_DISTANCE ||
57− glm::dot(headForward, compositorForward) < cosf(glm::radians(MAX_COMPOSITOR_ANGLE)))) {
58− // fade out the overlay
59− setEnabled(false);
60− }
61− break;
62− }
63− case FLAT:
64− // do nothing
65− break;
66− }
67−}
6860
69−void OverlayConductor::updateMode() {
70− MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
71− if (myAvatar->getClearOverlayWhenDriving()) {
72− float speed = glm::length(myAvatar->getVelocity());
73− const float MIN_DRIVING = 0.2f;
74− const float MAX_NOT_DRIVING = 0.01f;
7561 const quint64 REQUIRED_USECS_IN_NEW_MODE_BEFORE_INVISIBLE = 200 * 1000;
7662 const quint64 REQUIRED_USECS_IN_NEW_MODE_BEFORE_VISIBLE = 1000 * 1000;
77− bool nowDriving = _driving; // Assume current _driving mode unless...
78− if (speed > MIN_DRIVING) { // ... we're definitely moving...
79− nowDriving = true;
80− } else if (speed < MAX_NOT_DRIVING) { // ... or definitely not.
81− nowDriving = false;
82− }
63+
64+ // fade in or out the overlay, based on driving.
65+ bool nowDriving = myAvatar->hasDriveInput();
8366 // Check that we're in this new mode for long enough to really trigger a transition.
8467 if (nowDriving == _driving) { // If there's no change in state, clear any attepted timer.
8568 _timeInPotentialMode = 0;
86− } else if (_timeInPotentialMode == 0) { // We've just changed with no timer, so start timing now.
69+ } else if (_timeInPotentialMode == 0) { // We've just changed with no timer, so start timing now.
8770 _timeInPotentialMode = usecTimestampNow();
8871 } else if ((usecTimestampNow() - _timeInPotentialMode) > (nowDriving ? REQUIRED_USECS_IN_NEW_MODE_BEFORE_INVISIBLE : REQUIRED_USECS_IN_NEW_MODE_BEFORE_VISIBLE)) {
8972 _timeInPotentialMode = 0; // a real transition
90− if (nowDriving) {
91− _wantsOverlays = Menu::getInstance()->isOptionChecked(MenuOption::Overlays);
92− } else { // reset when coming out of driving
93− _mode = FLAT; // Seems appropriate to let things reset, below, after the following.
94− // All reset of, e.g., room-scale location as though by apostrophe key, without all the other adjustments.
95− qApp->getActiveDisplayPlugin()->resetSensors();
96− myAvatar->reset(true, false, false);
97− }
98− if (_wantsOverlays) {
73+ bool wantsOverlays = Menu::getInstance()->isOptionChecked(MenuOption::Overlays);
74+ if (wantsOverlays) {
9975 setEnabled(!nowDriving);
10076 }
10177 _driving = nowDriving;
102− } // Else haven't accumulated enough time in new mode, but keep timing.
78+ }
79+
80+ // center the UI
81+ if (shouldCenterUI()) {
82+ Transform hmdTransform(cancelOutRollAndPitch(qApp->getHMDSensorPose()));
83+ qApp->getApplicationCompositor().setModelTransform(hmdTransform);
84+ }
85+ break;
86+ }
87+ case FLAT:
88+ // do nothing
89+ break;
10390 }
91+}
92+
93+void OverlayConductor::updateMode() {
94+ MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
10495
10596 Mode newMode;
10697 if (qApp->isHMDMode()) {
107− newMode = SITTING;
98+ if (myAvatar->getClearOverlayWhenDriving()) {
99+ newMode = STANDING;
100+ } else {
101+ newMode = SITTING;
102+ }
108103 } else {
109104 newMode = FLAT;
110105 }
@@ -117,11 +112,10 @@ void OverlayConductor::updateMode() { · 6 unmodified lines
117112 qApp->getApplicationCompositor().setModelTransform(Transform());
118113 break;
119114 }
120− case STANDING: { // STANDING mode is not currently used.
115+ case STANDING: {
121116 // enter the STANDING state
122− // place the overlay at the current hmd position in world space
123− auto camMat = cancelOutRollAndPitch(myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose());
124− qApp->getApplicationCompositor().setModelTransform(Transform(camMat));
117+ Transform hmdTransform(cancelOutRollAndPitch(qApp->getHMDSensorPose()));
118+ qApp->getApplicationCompositor().setModelTransform(hmdTransform);
125119 break;
126120 }
127121
@@ -132,7 +126,6 @@ void OverlayConductor::updateMode() { · 4 unmodified lines
132126 }
133127
134128 _mode = newMode;
135−
136129 }
137130
138131 void OverlayConductor::setEnabled(bool enabled) {
@@ -149,7 +142,7 @@ void OverlayConductor::setEnabled(bool enabled) { · 10 unmodified lines
149142 MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
150143 auto camMat = cancelOutRollAndPitch(myAvatar->getSensorToWorldMatrix() * qApp->getHMDSensorPose());
151144 qApp->getApplicationCompositor().setModelTransform(Transform(camMat));
152− }
145+ }
153146 }
154147
155148 bool OverlayConductor::getEnabled() const {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t