Bug fix for head trackers in desktop mode

Sitting and standing modes work even in desktop mode.
We were inadvertently checking for HMD Mode instead of if the head was valid.
* A change was made to the ViveControllerManager to return head poses in the correct standing universe when in desktop mode.
* The default sensorToWorld matrix in desktop mode is similar to the one returned by the system for Vive and Oculus sensor frame; y = 0 is at floor level.
* Sitting mode, walking mode and recentering flags are now visible in the AnimStats.
This commit is contained in:
Anthony Thibault 2018-11-05 16:21:19 -08:00
parent d0181283dd
commit ac8869eb61
8 changed files with 68 additions and 20 deletions

View file

@ -50,6 +50,9 @@ Item {
StatText { StatText {
text: root.positionText text: root.positionText
} }
StatText {
text: root.recenterText
}
StatText { StatText {
text: "Anim Vars:--------------------------------------------------------------------------------" text: "Anim Vars:--------------------------------------------------------------------------------"
} }
@ -92,6 +95,9 @@ Item {
StatText { StatText {
text: root.rotationText text: root.rotationText
} }
StatText {
text: root.sittingText
}
StatText { StatText {
text: "State Machines:---------------------------------------------------------------------------" text: "State Machines:---------------------------------------------------------------------------"
} }
@ -122,6 +128,9 @@ Item {
StatText { StatText {
text: root.velocityText text: root.velocityText
} }
StatText {
text: root.walkingText
}
StatText { StatText {
text: "Alpha Values:--------------------------------------------------------------------------" text: "Alpha Values:--------------------------------------------------------------------------"
} }

View file

@ -6471,7 +6471,7 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const {
void Application::resetSensors(bool andReload) { void Application::resetSensors(bool andReload) {
DependencyManager::get<DdeFaceTracker>()->reset(); DependencyManager::get<DdeFaceTracker>()->reset();
DependencyManager::get<EyeTracker>()->reset(); DependencyManager::get<EyeTracker>()->reset();
getActiveDisplayPlugin()->resetSensors(); //getActiveDisplayPlugin()->resetSensors();
_overlayConductor.centerUI(); _overlayConductor.centerUI();
getMyAvatar()->reset(true, andReload); getMyAvatar()->reset(true, andReload);
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection); QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);

View file

@ -471,7 +471,7 @@ void MyAvatar::updateSitStandState(float newHeightReading, float dt) {
const float STANDING_TIMEOUT = 0.3333f; // 1/3 second const float STANDING_TIMEOUT = 0.3333f; // 1/3 second
const float SITTING_UPPER_BOUND = 1.52f; const float SITTING_UPPER_BOUND = 1.52f;
if (!getIsSitStandStateLocked()) { if (!getIsSitStandStateLocked()) {
if (!getIsAway() && qApp->isHMDMode()) { if (!getIsAway() && getControllerPoseInAvatarFrame(controller::Action::HEAD).isValid()) {
if (getIsInSittingState()) { if (getIsInSittingState()) {
if (newHeightReading > (STANDING_HEIGHT_MULTIPLE * _tippingPoint)) { if (newHeightReading > (STANDING_HEIGHT_MULTIPLE * _tippingPoint)) {
// if we recenter upwards then no longer in sitting state // if we recenter upwards then no longer in sitting state
@ -720,6 +720,10 @@ void MyAvatar::recalculateChildCauterization() const {
_cauterizationNeedsUpdate = true; _cauterizationNeedsUpdate = true;
} }
bool MyAvatar::isFollowActive(FollowHelper::FollowType followType) const {
return _follow.isActive(followType);
}
void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object, bool cauterize) { void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object, bool cauterize) {
if (object->getNestableType() == NestableType::Entity) { if (object->getNestableType() == NestableType::Entity) {
EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object); EntityItemPointer entity = std::static_pointer_cast<EntityItem>(object);
@ -1067,9 +1071,9 @@ void MyAvatar::updateSensorToWorldMatrix() {
void MyAvatar::updateFromTrackers(float deltaTime) { void MyAvatar::updateFromTrackers(float deltaTime) {
glm::vec3 estimatedRotation; glm::vec3 estimatedRotation;
bool inHmd = qApp->isHMDMode(); bool hasHead = getControllerPoseInAvatarFrame(controller::Action::HEAD).isValid();
bool playing = DependencyManager::get<recording::Deck>()->isPlaying(); bool playing = DependencyManager::get<recording::Deck>()->isPlaying();
if (inHmd && playing) { if (hasHead && playing) {
return; return;
} }
@ -1103,7 +1107,7 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
Head* head = getHead(); Head* head = getHead();
if (inHmd || playing) { if (hasHead || playing) {
head->setDeltaPitch(estimatedRotation.x); head->setDeltaPitch(estimatedRotation.x);
head->setDeltaYaw(estimatedRotation.y); head->setDeltaYaw(estimatedRotation.y);
head->setDeltaRoll(estimatedRotation.z); head->setDeltaRoll(estimatedRotation.z);
@ -3480,7 +3484,7 @@ void MyAvatar::triggerRotationRecenter() {
// old school meat hook style // old school meat hook style
glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const {
glm::vec3 headPosition; glm::vec3 headPosition(0.0f, _userHeight.get(), 0.0f);
glm::quat headOrientation; glm::quat headOrientation;
auto headPose = getControllerPoseInSensorFrame(controller::Action::HEAD); auto headPose = getControllerPoseInSensorFrame(controller::Action::HEAD);
if (headPose.isValid()) { if (headPose.isValid()) {
@ -3799,7 +3803,7 @@ float MyAvatar::computeStandingHeightMode(const controller::Pose& head) {
modeInMeters = ((float)mode) / CENTIMETERS_PER_METER; modeInMeters = ((float)mode) / CENTIMETERS_PER_METER;
if (!(modeInMeters > getCurrentStandingHeight())) { if (!(modeInMeters > getCurrentStandingHeight())) {
// if not greater check for a reset // if not greater check for a reset
if (getResetMode() && qApp->isHMDMode()) { if (getResetMode() && getControllerPoseInAvatarFrame(controller::Action::HEAD).isValid()) {
setResetMode(false); setResetMode(false);
float resetModeInCentimeters = glm::floor((head.getTranslation().y - MODE_CORRECTION_FACTOR)*CENTIMETERS_PER_METER); float resetModeInCentimeters = glm::floor((head.getTranslation().y - MODE_CORRECTION_FACTOR)*CENTIMETERS_PER_METER);
modeInMeters = (resetModeInCentimeters / CENTIMETERS_PER_METER); modeInMeters = (resetModeInCentimeters / CENTIMETERS_PER_METER);

View file

@ -54,6 +54,7 @@ Q_DECLARE_METATYPE(AudioListenerMode);
class MyAvatar : public Avatar { class MyAvatar : public Avatar {
Q_OBJECT Q_OBJECT
friend class AnimStats;
/**jsdoc /**jsdoc
* Your avatar is your in-world representation of you. The <code>MyAvatar</code> API is used to manipulate the avatar. * Your avatar is your in-world representation of you. The <code>MyAvatar</code> API is used to manipulate the avatar.
@ -1163,7 +1164,7 @@ public:
virtual QVariantList getAttachmentsVariant() const override; virtual QVariantList getAttachmentsVariant() const override;
virtual void setAttachmentsVariant(const QVariantList& variant) override; virtual void setAttachmentsVariant(const QVariantList& variant) override;
glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); }; glm::vec3 getNextPosition() { return _goToPending ? _goToPosition : getWorldPosition(); }
public slots: public slots:
@ -1780,8 +1781,11 @@ private:
std::atomic<bool> _forceActivateHorizontal { false }; std::atomic<bool> _forceActivateHorizontal { false };
std::atomic<bool> _toggleHipsFollowing { true }; std::atomic<bool> _toggleHipsFollowing { true };
}; };
FollowHelper _follow; FollowHelper _follow;
bool isFollowActive(FollowHelper::FollowType followType) const;
bool _goToPending { false }; bool _goToPending { false };
bool _physicsSafetyPending { false }; bool _physicsSafetyPending { false };
bool _goToSafe { true }; bool _goToSafe { true };

View file

@ -65,6 +65,35 @@ void AnimStats::updateStats(bool force) {
arg(QString::number(localVelocity.z, 'f', 2)); arg(QString::number(localVelocity.z, 'f', 2));
emit velocityTextChanged(); emit velocityTextChanged();
// print if we are recentering or not.
_recenterText = "Recenter: ";
if (myAvatar->isFollowActive(MyAvatar::FollowHelper::Rotation)) {
_recenterText += "Rotation ";
}
if (myAvatar->isFollowActive(MyAvatar::FollowHelper::Horizontal)) {
_recenterText += "Horizontal ";
}
if (myAvatar->isFollowActive(MyAvatar::FollowHelper::Vertical)) {
_recenterText += "Vertical ";
}
emit recenterTextChanged();
// print current standing vs sitting state.
if (myAvatar->getIsInSittingState()) {
_sittingText = "SittingState: Sit";
} else {
_sittingText = "SittingState: Stand";
}
emit sittingTextChanged();
// print current walking vs leaning state.
if (myAvatar->getIsInWalkingState()) {
_walkingText = "WalkingState: Walk";
} else {
_walkingText = "WalkingState: Lean";
}
emit walkingTextChanged();
// update animation debug alpha values // update animation debug alpha values
QStringList newAnimAlphaValues; QStringList newAnimAlphaValues;
qint64 now = usecTimestampNow(); qint64 now = usecTimestampNow();

View file

@ -22,6 +22,9 @@ class AnimStats : public QQuickItem {
Q_PROPERTY(QString positionText READ positionText NOTIFY positionTextChanged) Q_PROPERTY(QString positionText READ positionText NOTIFY positionTextChanged)
Q_PROPERTY(QString rotationText READ rotationText NOTIFY rotationTextChanged) Q_PROPERTY(QString rotationText READ rotationText NOTIFY rotationTextChanged)
Q_PROPERTY(QString velocityText READ velocityText NOTIFY velocityTextChanged) Q_PROPERTY(QString velocityText READ velocityText NOTIFY velocityTextChanged)
Q_PROPERTY(QString recenterText READ recenterText NOTIFY recenterTextChanged)
Q_PROPERTY(QString sittingText READ sittingText NOTIFY sittingTextChanged)
Q_PROPERTY(QString walkingText READ walkingText NOTIFY walkingTextChanged)
public: public:
static AnimStats* getInstance(); static AnimStats* getInstance();
@ -37,6 +40,9 @@ public:
QString positionText() const { return _positionText; } QString positionText() const { return _positionText; }
QString rotationText() const { return _rotationText; } QString rotationText() const { return _rotationText; }
QString velocityText() const { return _velocityText; } QString velocityText() const { return _velocityText; }
QString recenterText() const { return _recenterText; }
QString sittingText() const { return _sittingText; }
QString walkingText() const { return _walkingText; }
public slots: public slots:
void forceUpdateStats() { updateStats(true); } void forceUpdateStats() { updateStats(true); }
@ -49,6 +55,9 @@ signals:
void positionTextChanged(); void positionTextChanged();
void rotationTextChanged(); void rotationTextChanged();
void velocityTextChanged(); void velocityTextChanged();
void recenterTextChanged();
void sittingTextChanged();
void walkingTextChanged();
private: private:
QStringList _animAlphaValues; QStringList _animAlphaValues;
@ -64,6 +73,9 @@ private:
QString _positionText; QString _positionText;
QString _rotationText; QString _rotationText;
QString _velocityText; QString _velocityText;
QString _recenterText;
QString _sittingText;
QString _walkingText;
}; };
#endif // hifi_AnimStats_h #endif // hifi_AnimStats_h

View file

@ -180,9 +180,6 @@ void ViveControllerManager::setConfigurationSettings(const QJsonObject configura
if (isSupported()) { if (isSupported()) {
if (configurationSettings.contains("desktopMode")) { if (configurationSettings.contains("desktopMode")) {
_desktopMode = configurationSettings["desktopMode"].toBool(); _desktopMode = configurationSettings["desktopMode"].toBool();
if (!_desktopMode) {
_resetMatCalculated = false;
}
} }
if (configurationSettings.contains("hmdDesktopTracking")) { if (configurationSettings.contains("hmdDesktopTracking")) {
@ -267,13 +264,8 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
} }
if (isDesktopMode() && _desktopMode) { if (isDesktopMode() && _desktopMode) {
if (!_resetMatCalculated) {
_resetMat = calculateResetMat();
_resetMatCalculated = true;
}
_system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, _nextSimPoseData.vrPoses, vr::k_unMaxTrackedDeviceCount); _system->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, _nextSimPoseData.vrPoses, vr::k_unMaxTrackedDeviceCount);
_nextSimPoseData.update(_resetMat); _nextSimPoseData.update(Matrices::IDENTITY);
} else if (isDesktopMode()) { } else if (isDesktopMode()) {
_nextSimPoseData.resetToInvalid(); _nextSimPoseData.resetToInvalid();
} }

View file

@ -213,12 +213,10 @@ private:
bool isDesktopMode(); bool isDesktopMode();
bool _registeredWithInputMapper { false }; bool _registeredWithInputMapper { false };
bool _modelLoaded { false }; bool _modelLoaded { false };
bool _resetMatCalculated { false };
bool _desktopMode { false }; bool _desktopMode { false };
bool _hmdDesktopTracking { false }; bool _hmdDesktopTracking { false };
glm::mat4 _resetMat { glm::mat4() };
graphics::Geometry _modelGeometry; graphics::Geometry _modelGeometry;
gpu::TexturePointer _texture; gpu::TexturePointer _texture;