mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-30 01:48:11 +02:00
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.
193 lines
6.5 KiB
C++
193 lines
6.5 KiB
C++
//
|
|
// Created by Anthony J. Thibault 2018/08/06
|
|
// Copyright 2018 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "AnimStats.h"
|
|
|
|
#include <avatar/AvatarManager.h>
|
|
#include <OffscreenUi.h>
|
|
#include "Menu.h"
|
|
|
|
HIFI_QML_DEF(AnimStats)
|
|
|
|
static AnimStats* INSTANCE{ nullptr };
|
|
|
|
AnimStats* AnimStats::getInstance() {
|
|
Q_ASSERT(INSTANCE);
|
|
return INSTANCE;
|
|
}
|
|
|
|
AnimStats::AnimStats(QQuickItem* parent) : QQuickItem(parent) {
|
|
INSTANCE = this;
|
|
}
|
|
|
|
void AnimStats::updateStats(bool force) {
|
|
QQuickItem* parent = parentItem();
|
|
if (!force) {
|
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::AnimStats)) {
|
|
if (parent->isVisible()) {
|
|
parent->setVisible(false);
|
|
}
|
|
return;
|
|
} else if (!parent->isVisible()) {
|
|
parent->setVisible(true);
|
|
}
|
|
}
|
|
|
|
auto avatarManager = DependencyManager::get<AvatarManager>();
|
|
auto myAvatar = avatarManager->getMyAvatar();
|
|
auto debugAlphaMap = myAvatar->getSkeletonModel()->getRig().getDebugAlphaMap();
|
|
|
|
glm::vec3 position = myAvatar->getWorldPosition();
|
|
glm::quat rotation = myAvatar->getWorldOrientation();
|
|
glm::vec3 velocity = myAvatar->getWorldVelocity();
|
|
|
|
_positionText = QString("Position: (%1, %2, %3)").
|
|
arg(QString::number(position.x, 'f', 2)).
|
|
arg(QString::number(position.y, 'f', 2)).
|
|
arg(QString::number(position.z, 'f', 2));
|
|
emit positionTextChanged();
|
|
|
|
glm::vec3 eulerRotation = safeEulerAngles(rotation);
|
|
_rotationText = QString("Heading: %1").
|
|
arg(QString::number(glm::degrees(eulerRotation.y), 'f', 2));
|
|
emit rotationTextChanged();
|
|
|
|
// transform velocity into rig coordinate frame. z forward.
|
|
glm::vec3 localVelocity = Quaternions::Y_180 * glm::inverse(rotation) * velocity;
|
|
_velocityText = QString("Local Vel: (%1, %2, %3)").
|
|
arg(QString::number(localVelocity.x, 'f', 2)).
|
|
arg(QString::number(localVelocity.y, 'f', 2)).
|
|
arg(QString::number(localVelocity.z, 'f', 2));
|
|
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
|
|
QStringList newAnimAlphaValues;
|
|
qint64 now = usecTimestampNow();
|
|
for (auto& iter : debugAlphaMap) {
|
|
QString key = iter.first;
|
|
float alpha = std::get<0>(iter.second);
|
|
|
|
auto prevIter = _prevDebugAlphaMap.find(key);
|
|
if (prevIter != _prevDebugAlphaMap.end()) {
|
|
float prevAlpha = std::get<0>(iter.second);
|
|
if (prevAlpha != alpha) {
|
|
// change detected: reset timer
|
|
_animAlphaValueChangedTimers[key] = now;
|
|
}
|
|
} else {
|
|
// new value: start timer
|
|
_animAlphaValueChangedTimers[key] = now;
|
|
}
|
|
|
|
AnimNodeType type = std::get<1>(iter.second);
|
|
if (type == AnimNodeType::Clip) {
|
|
|
|
// figure out the grayScale color of this line.
|
|
const float LIT_TIME = 2.0f;
|
|
const float FADE_OUT_TIME = 1.0f;
|
|
float grayScale = 0.0f;
|
|
float secondsElapsed = (float)(now - _animAlphaValueChangedTimers[key]) / (float)USECS_PER_SECOND;
|
|
if (secondsElapsed < LIT_TIME) {
|
|
grayScale = 1.0f;
|
|
} else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) {
|
|
grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME;
|
|
} else {
|
|
grayScale = 0.0f;
|
|
}
|
|
|
|
if (grayScale > 0.0f) {
|
|
// append grayScaleColor to start of debug string
|
|
newAnimAlphaValues << QString::number(grayScale, 'f', 2) + "|" + key + ": " + QString::number(alpha, 'f', 3);
|
|
}
|
|
}
|
|
}
|
|
|
|
_animAlphaValues = newAnimAlphaValues;
|
|
_prevDebugAlphaMap = debugAlphaMap;
|
|
|
|
emit animAlphaValuesChanged();
|
|
|
|
// update animation anim vars
|
|
_animVarsList.clear();
|
|
auto animVars = myAvatar->getSkeletonModel()->getRig().getAnimVars().toDebugMap();
|
|
for (auto& iter : animVars) {
|
|
QString key = iter.first;
|
|
QString value = iter.second;
|
|
|
|
auto prevIter = _prevAnimVars.find(key);
|
|
if (prevIter != _prevAnimVars.end()) {
|
|
QString prevValue = prevIter->second;
|
|
if (value != prevValue) {
|
|
// change detected: reset timer
|
|
_animVarChangedTimers[key] = now;
|
|
}
|
|
} else {
|
|
// new value: start timer
|
|
_animVarChangedTimers[key] = now;
|
|
}
|
|
|
|
// figure out the grayScale color of this line.
|
|
const float LIT_TIME = 2.0f;
|
|
const float FADE_OUT_TIME = 0.5f;
|
|
float grayScale = 0.0f;
|
|
float secondsElapsed = (float)(now - _animVarChangedTimers[key]) / (float)USECS_PER_SECOND;
|
|
if (secondsElapsed < LIT_TIME) {
|
|
grayScale = 1.0f;
|
|
} else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) {
|
|
grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME;
|
|
} else {
|
|
grayScale = 0.0f;
|
|
}
|
|
|
|
if (grayScale > 0.0f) {
|
|
// append grayScaleColor to start of debug string
|
|
_animVarsList << QString::number(grayScale, 'f', 2) + "|" + key + ": " + value;
|
|
}
|
|
}
|
|
_prevAnimVars = animVars;
|
|
emit animVarsChanged();
|
|
|
|
// animation state machines
|
|
_animStateMachines.clear();
|
|
auto stateMachineMap = myAvatar->getSkeletonModel()->getRig().getStateMachineMap();
|
|
for (auto& iter : stateMachineMap) {
|
|
_animStateMachines << iter.second;
|
|
}
|
|
emit animStateMachinesChanged();
|
|
}
|
|
|
|
|