mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 09:43:25 +02:00
Moved AnimStats into its own qml panels.
Added state machine tracking as well.
This commit is contained in:
parent
3a3ffcc98c
commit
acc7f1f168
13 changed files with 427 additions and 12 deletions
157
interface/resources/qml/AnimStats.qml
Normal file
157
interface/resources/qml/AnimStats.qml
Normal file
|
@ -0,0 +1,157 @@
|
|||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.3
|
||||
import '.'
|
||||
|
||||
Item {
|
||||
id: animStats
|
||||
|
||||
anchors.leftMargin: 300
|
||||
objectName: "StatsItem"
|
||||
property int modality: Qt.NonModal
|
||||
implicitHeight: row.height
|
||||
implicitWidth: row.width
|
||||
|
||||
Component.onCompleted: {
|
||||
animStats.parentChanged.connect(fill);
|
||||
fill();
|
||||
}
|
||||
Component.onDestruction: {
|
||||
animStats.parentChanged.disconnect(fill);
|
||||
}
|
||||
|
||||
function fill() {
|
||||
// This will cause a warning at shutdown, need to find another way to remove
|
||||
// the warning other than filling the anchors to the parent
|
||||
anchors.horizontalCenter = parent.horizontalCenter
|
||||
}
|
||||
|
||||
Hifi.AnimStats {
|
||||
id: root
|
||||
objectName: "AnimStats"
|
||||
implicitHeight: row.height
|
||||
implicitWidth: row.width
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
readonly property string bgColor: "#AA111111"
|
||||
|
||||
Row {
|
||||
id: row
|
||||
spacing: 8
|
||||
|
||||
Rectangle {
|
||||
width: firstCol.width + 8;
|
||||
height: firstCol.height + 8;
|
||||
color: root.bgColor;
|
||||
|
||||
Column {
|
||||
id: firstCol
|
||||
spacing: 4; x: 4; y: 4;
|
||||
|
||||
StatText {
|
||||
text: "State Machines:---------------------------------------------------------------------------"
|
||||
}
|
||||
ListView {
|
||||
width: firstCol.width
|
||||
height: root.animStateMachines.length * 15
|
||||
visible: root.animStateMchines.length > 0;
|
||||
model: root.animStateMachines
|
||||
delegate: StatText {
|
||||
text: {
|
||||
return modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: secondCol.width + 8
|
||||
height: secondCol.height + 8
|
||||
color: root.bgColor;
|
||||
|
||||
Column {
|
||||
id: secondCol
|
||||
spacing: 4; x: 4; y: 4;
|
||||
|
||||
StatText {
|
||||
text: "Anim Vars:--------------------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
ListView {
|
||||
width: secondCol.width
|
||||
height: root.animVars.length * 15
|
||||
visible: root.animVars.length > 0;
|
||||
model: root.animVars
|
||||
delegate: StatText {
|
||||
text: {
|
||||
var actualText = modelData.split("|")[1];
|
||||
if (actualText) {
|
||||
return actualText;
|
||||
} else {
|
||||
return modelData;
|
||||
}
|
||||
}
|
||||
color: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(1.0, 1.0, 1.0, grayScale);
|
||||
}
|
||||
styleColor: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(0.0, 0.0, 0.0, grayScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: thirdCol.width + 8
|
||||
height: thirdCol.height + 8
|
||||
color: root.bgColor;
|
||||
|
||||
Column {
|
||||
id: thirdCol
|
||||
spacing: 4; x: 4; y: 4;
|
||||
|
||||
StatText {
|
||||
text: "Alpha Values:--------------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
ListView {
|
||||
width: thirdCol.width
|
||||
height: root.animAlphaValues.length * 15
|
||||
visible: root.animAlphaValues.length > 0;
|
||||
model: root.animAlphaValues
|
||||
delegate: StatText {
|
||||
text: {
|
||||
var actualText = modelData.split("|")[1];
|
||||
if (actualText) {
|
||||
return actualText;
|
||||
} else {
|
||||
return modelData;
|
||||
}
|
||||
}
|
||||
color: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(1.0, 1.0, 1.0, grayScale);
|
||||
}
|
||||
styleColor: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(0.0, 0.0, 0.0, grayScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.parent
|
||||
onWidthChanged: {
|
||||
root.x = root.parent.width - root.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -192,6 +192,25 @@ Item {
|
|||
StatText {
|
||||
text: "Yaw: " + root.yaw.toFixed(1)
|
||||
}
|
||||
StatText {
|
||||
visible: root.animStateMachines.length > 0;
|
||||
text: "Anim State Machines:"
|
||||
}
|
||||
ListView {
|
||||
width: geoCol.width
|
||||
height: root.animStateMachines.length * 15
|
||||
visible: root.animStateMchines.length > 0;
|
||||
model: root.animStateMachines
|
||||
delegate: StatText {
|
||||
text: {
|
||||
if (modelData.length > 30) {
|
||||
return modelData.substring(0, 5) + "..." + modelData.substring(.length - 22);
|
||||
} else {
|
||||
return modelData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StatText {
|
||||
visible: root.animAlphaValues.length > 0;
|
||||
text: "Anim Alpha Values:"
|
||||
|
@ -216,9 +235,11 @@ Item {
|
|||
}
|
||||
color: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(0.3 * grayScale + 0.7,
|
||||
0.3 * grayScale + 0.7,
|
||||
0.3 * grayScale + 0.7, 1.0);
|
||||
return Qt.rgba(1.0, 1.0, 1.0, grayScale);
|
||||
}
|
||||
styleColor: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(0.0, 0.0, 0.0, grayScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -246,9 +267,11 @@ Item {
|
|||
}
|
||||
color: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(0.3 * grayScale + 0.7,
|
||||
0.3 * grayScale + 0.7,
|
||||
0.3 * grayScale + 0.7, 1.0);
|
||||
return Qt.rgba(1.0, 1.0, 1.0, grayScale);
|
||||
}
|
||||
styleColor: {
|
||||
var grayScale = parseFloat(modelData.split("|")[0]);
|
||||
return Qt.rgba(0.0, 0.0, 0.0, grayScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -195,6 +195,7 @@
|
|||
#include "ui/SnapshotAnimated.h"
|
||||
#include "ui/StandAloneJSConsole.h"
|
||||
#include "ui/Stats.h"
|
||||
#include "ui/AnimStats.h"
|
||||
#include "ui/UpdateDialog.h"
|
||||
#include "ui/overlays/Overlays.h"
|
||||
#include "ui/DomainConnectionModel.h"
|
||||
|
@ -3081,8 +3082,10 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
|||
|
||||
void Application::onDesktopRootItemCreated(QQuickItem* rootItem) {
|
||||
Stats::show();
|
||||
AnimStats::show();
|
||||
auto surfaceContext = DependencyManager::get<OffscreenUi>()->getSurfaceContext();
|
||||
surfaceContext->setContextProperty("Stats", Stats::getInstance());
|
||||
surfaceContext->setContextProperty("AnimStats", AnimStats::getInstance());
|
||||
|
||||
#if !defined(Q_OS_ANDROID)
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
@ -4618,6 +4621,7 @@ void Application::idle() {
|
|||
checkChangeCursor();
|
||||
|
||||
Stats::getInstance()->updateStats();
|
||||
AnimStats::getInstance()->updateStats();
|
||||
|
||||
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
||||
|
|
|
@ -737,6 +737,7 @@ Menu::Menu() {
|
|||
|
||||
// Developer > Stats
|
||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats);
|
||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AnimStats);
|
||||
|
||||
// Settings > Enable Speech Control API
|
||||
#if defined(Q_OS_MAC) || defined(Q_OS_WIN)
|
||||
|
|
|
@ -197,6 +197,7 @@ namespace MenuOption {
|
|||
const QString SMIEyeTracking = "SMI Eye Tracking";
|
||||
const QString SparseTextureManagement = "Enable Sparse Texture Management";
|
||||
const QString Stats = "Show Statistics";
|
||||
const QString AnimStats = "Show Animation Stats";
|
||||
const QString StopAllScripts = "Stop All Scripts";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString ThirdPerson = "Third Person";
|
||||
|
|
141
interface/src/ui/AnimStats.cpp
Normal file
141
interface/src/ui/AnimStats.cpp
Normal file
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// 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();
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
55
interface/src/ui/AnimStats.h
Normal file
55
interface/src/ui/AnimStats.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_AnimStats_h
|
||||
#define hifi_AnimStats_h
|
||||
|
||||
#include <OffscreenQmlElement.h>
|
||||
#include <AnimContext.h>
|
||||
|
||||
class AnimStats : public QQuickItem {
|
||||
Q_OBJECT
|
||||
HIFI_QML_DECL
|
||||
|
||||
Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged)
|
||||
Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged)
|
||||
Q_PROPERTY(QStringList animStateMachines READ animStateMachines NOTIFY animStateMachinesChanged)
|
||||
|
||||
public:
|
||||
static AnimStats* getInstance();
|
||||
|
||||
AnimStats(QQuickItem* parent = nullptr);
|
||||
|
||||
void updateStats(bool force = false);
|
||||
|
||||
QStringList animAlphaValues() { return _animAlphaValues; }
|
||||
QStringList animVars() { return _animVarsList; }
|
||||
QStringList animStateMachines() { return _animStateMachines; }
|
||||
|
||||
public slots:
|
||||
void forceUpdateStats() { updateStats(true); }
|
||||
|
||||
signals:
|
||||
|
||||
void animAlphaValuesChanged();
|
||||
void animVarsChanged();
|
||||
void animStateMachinesChanged();
|
||||
|
||||
private:
|
||||
QStringList _animAlphaValues;
|
||||
AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame
|
||||
std::map<QString, qint64> _animAlphaValueChangedTimers; // last time alpha value has changed
|
||||
|
||||
QStringList _animVarsList;
|
||||
std::map<QString, QString> _prevAnimVars; // anim vars from previous frame
|
||||
std::map<QString, qint64> _animVarChangedTimers; // last time animVar value has changed.
|
||||
|
||||
QStringList _animStateMachines;
|
||||
};
|
||||
|
||||
#endif // hifi_AnimStats_h
|
|
@ -239,7 +239,7 @@ void Stats::updateStats(bool force) {
|
|||
if (secondsElapsed < LIT_TIME) {
|
||||
grayScale = 1.0f;
|
||||
} else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) {
|
||||
grayScale = (LIT_TIME - (secondsElapsed - FADE_OUT_TIME)) / LIT_TIME;
|
||||
grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME;
|
||||
} else {
|
||||
grayScale = 0.0f;
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ void Stats::updateStats(bool force) {
|
|||
if (secondsElapsed < LIT_TIME) {
|
||||
grayScale = 1.0f;
|
||||
} else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) {
|
||||
grayScale = (LIT_TIME - (secondsElapsed - FADE_OUT_TIME)) / LIT_TIME;
|
||||
grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME;
|
||||
} else {
|
||||
grayScale = 0.0f;
|
||||
}
|
||||
|
@ -296,6 +296,14 @@ void Stats::updateStats(bool force) {
|
|||
_prevAnimVars = animVars;
|
||||
emit animVarsChanged();
|
||||
|
||||
// animation state machines
|
||||
_animStateMachines.clear();
|
||||
auto stateMachineMap = myAvatar->getSkeletonModel()->getRig().getStateMachineMap();
|
||||
for (auto& iter : stateMachineMap) {
|
||||
_animStateMachines << iter.second;
|
||||
}
|
||||
emit animStateMachinesChanged();
|
||||
|
||||
glm::vec3 avatarPos = myAvatar->getWorldPosition();
|
||||
STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z));
|
||||
STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f);
|
||||
|
|
|
@ -184,6 +184,7 @@ class Stats : public QQuickItem {
|
|||
HIFI_QML_DECL
|
||||
Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged)
|
||||
Q_PROPERTY(bool timingExpanded READ isTimingExpanded NOTIFY timingExpandedChanged)
|
||||
|
||||
Q_PROPERTY(QString monospaceFont READ monospaceFont CONSTANT)
|
||||
|
||||
STATS_PROPERTY(int, serverCount, 0)
|
||||
|
@ -294,6 +295,7 @@ class Stats : public QQuickItem {
|
|||
STATS_PROPERTY(float, avatarSimulationTime, 0)
|
||||
Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged)
|
||||
Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged)
|
||||
Q_PROPERTY(QStringList animStateMachines READ animStateMachines NOTIFY animStateMachinesChanged)
|
||||
|
||||
STATS_PROPERTY(int, stylusPicksCount, 0)
|
||||
STATS_PROPERTY(int, rayPicksCount, 0)
|
||||
|
@ -329,6 +331,7 @@ public:
|
|||
QStringList downloadUrls () { return _downloadUrls; }
|
||||
QStringList animAlphaValues() { return _animAlphaValues; }
|
||||
QStringList animVars() { return _animVarsList; }
|
||||
QStringList animStateMachines() { return _animStateMachines; }
|
||||
|
||||
public slots:
|
||||
void forceUpdateStats() { updateStats(true); }
|
||||
|
@ -1032,6 +1035,7 @@ signals:
|
|||
|
||||
void animAlphaValuesChanged();
|
||||
void animVarsChanged();
|
||||
void animStateMachinesChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the value of the <code>rectifiedTextureCount</code> property changes.
|
||||
|
@ -1333,15 +1337,17 @@ private:
|
|||
bool _showGameUpdateStats{ false };
|
||||
QString _monospaceFont;
|
||||
const AudioIOStats* _audioStats;
|
||||
QStringList _downloadUrls = QStringList();
|
||||
QStringList _downloadUrls;
|
||||
|
||||
QStringList _animAlphaValues = QStringList();
|
||||
QStringList _animAlphaValues;
|
||||
AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame
|
||||
std::map<QString, qint64> _animAlphaValueChangedTimers; // last time alpha value has changed
|
||||
|
||||
QStringList _animVarsList = QStringList();
|
||||
QStringList _animVarsList;
|
||||
std::map<QString, QString> _prevAnimVars; // anim vars from previous frame
|
||||
std::map<QString, qint64> _animVarChangedTimers; // last time animVar value has changed.
|
||||
|
||||
QStringList _animStateMachines;
|
||||
};
|
||||
|
||||
#endif // hifi_Stats_h
|
||||
|
|
|
@ -64,6 +64,19 @@ public:
|
|||
return _debugAlphaMap;
|
||||
}
|
||||
|
||||
using DebugStateMachineMapValue = QString;
|
||||
using DebugStateMachineMap = std::map<QString, DebugStateMachineMapValue>;
|
||||
|
||||
void addStateMachineInfo(const QString& stateMachineName, const QString& currentState, const QString& previousState, bool duringInterp, float alpha) const {
|
||||
if (duringInterp) {
|
||||
_stateMachineMap[stateMachineName] = QString("%1: %2 -> %3 (%4)").arg(stateMachineName).arg(previousState).arg(currentState).arg(QString::number(alpha, 'f', 2));
|
||||
} else {
|
||||
_stateMachineMap[stateMachineName] = QString("%1: %2").arg(stateMachineName).arg(currentState);
|
||||
}
|
||||
}
|
||||
|
||||
const DebugStateMachineMap& getStateMachineMap() const { return _stateMachineMap; }
|
||||
|
||||
protected:
|
||||
|
||||
bool _enableDebugDrawIKTargets { false };
|
||||
|
@ -74,6 +87,7 @@ protected:
|
|||
|
||||
// used for debugging internal state of animation system.
|
||||
mutable DebugAlphaMap _debugAlphaMap;
|
||||
mutable DebugStateMachineMap _stateMachineMap;
|
||||
};
|
||||
|
||||
#endif // hifi_AnimContext_h
|
||||
|
|
|
@ -87,10 +87,13 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co
|
|||
}
|
||||
processOutputJoints(triggersOut);
|
||||
|
||||
context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha);
|
||||
|
||||
return _poses;
|
||||
}
|
||||
|
||||
void AnimStateMachine::setCurrentState(State::Pointer state) {
|
||||
_previousState = _currentState ? _currentState : state;
|
||||
_currentState = state;
|
||||
}
|
||||
|
||||
|
@ -135,7 +138,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon
|
|||
qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID() << "duration =" << duration << "targetFrame =" << desiredState->_interpTarget << "interpType = " << (int)_interpType;
|
||||
#endif
|
||||
|
||||
_currentState = desiredState;
|
||||
setCurrentState(desiredState);
|
||||
}
|
||||
|
||||
AnimStateMachine::State::Pointer AnimStateMachine::evaluateTransitions(const AnimVariantMap& animVars) const {
|
||||
|
|
|
@ -140,6 +140,7 @@ protected:
|
|||
AnimPoseVec _nextPoses;
|
||||
|
||||
State::Pointer _currentState;
|
||||
State::Pointer _previousState;
|
||||
std::vector<State::Pointer> _states;
|
||||
|
||||
QString _currentStateVar;
|
||||
|
|
|
@ -225,6 +225,7 @@ public:
|
|||
// used to debug animation playback
|
||||
const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); }
|
||||
const AnimVariantMap& getAnimVars() const { return _lastAnimVars; }
|
||||
const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); }
|
||||
|
||||
void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; };
|
||||
signals:
|
||||
|
|
Loading…
Reference in a new issue