mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Added animation debug draw items to menu.
* Debug Draw Bind Pose - used to display the current avatar's bind pose * Debug Draw Animation - used to display the current avatar's AnimGraph animation. Currently does not work with old animation so it's only valid when Enable Anim Graph is true. * Draw Mesh - used to hide or display the avatar mesh.
This commit is contained in:
parent
471400e595
commit
30264e9c3d
8 changed files with 113 additions and 26 deletions
|
@ -435,6 +435,12 @@ Menu::Menu() {
|
|||
avatar, SLOT(setEnableRigAnimations(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableAnimGraph, 0, false,
|
||||
avatar, SLOT(setEnableAnimGraph(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AnimDebugDrawBindPose, 0, false,
|
||||
avatar, SLOT(setEnableDebugDrawBindPose(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::AnimDebugDrawAnimPose, 0, false,
|
||||
avatar, SLOT(setEnableDebugDrawAnimPose(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::MeshVisible, 0, true,
|
||||
avatar, SLOT(setEnableMeshVisible(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(avatarDebugMenu,
|
||||
MenuOption::Connexion,
|
||||
|
|
|
@ -132,6 +132,8 @@ namespace MenuOption {
|
|||
const QString AddRemoveFriends = "Add/Remove Friends...";
|
||||
const QString AddressBar = "Show Address Bar";
|
||||
const QString Animations = "Animations...";
|
||||
const QString AnimDebugDrawAnimPose = "Debug Draw Animation";
|
||||
const QString AnimDebugDrawBindPose = "Debug Draw Bind Pose";
|
||||
const QString Atmosphere = "Atmosphere";
|
||||
const QString Attachments = "Attachments...";
|
||||
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||
|
@ -215,6 +217,7 @@ namespace MenuOption {
|
|||
const QString Log = "Log";
|
||||
const QString LogExtraTimings = "Log Extra Timing Details";
|
||||
const QString LowVelocityFilter = "Low Velocity Filter";
|
||||
const QString MeshVisible = "Draw Mesh";
|
||||
const QString Mirror = "Mirror";
|
||||
const QString MuteAudio = "Mute Microphone";
|
||||
const QString MuteEnvironment = "Mute Environment";
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <SharedUtil.h>
|
||||
#include <TextRenderer3D.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <AnimDebugDraw.h>
|
||||
|
||||
#include "devices/Faceshift.h"
|
||||
|
||||
|
@ -718,6 +719,27 @@ void MyAvatar::setEnableAnimGraph(bool isEnabled) {
|
|||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setEnableDebugDrawBindPose(bool isEnabled) {
|
||||
_enableDebugDrawBindPose = isEnabled;
|
||||
|
||||
if (!isEnabled) {
|
||||
AnimDebugDraw::getInstance().removeSkeleton("myAvatar");
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
|
||||
_enableDebugDrawAnimPose = isEnabled;
|
||||
|
||||
if (!isEnabled) {
|
||||
AnimDebugDraw::getInstance().removeAnimNode("myAvatar");
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::setEnableMeshVisible(bool isEnabled) {
|
||||
render::ScenePointer scene = Application::getInstance()->getMain3DScene();
|
||||
_skeletonModel.setVisibleInScene(isEnabled, scene);
|
||||
}
|
||||
|
||||
void MyAvatar::loadData() {
|
||||
Settings settings;
|
||||
settings.beginGroup("Avatar");
|
||||
|
@ -1230,6 +1252,27 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
|||
_skeletonModel.initAnimGraph(graphUrl, _skeletonModel.getGeometry()->getFBXGeometry());
|
||||
}
|
||||
|
||||
if (_enableDebugDrawBindPose || _enableDebugDrawAnimPose) {
|
||||
|
||||
AnimSkeleton::ConstPointer animSkeleton = _rig->getAnimSkeleton();
|
||||
AnimNode::ConstPointer animNode = _rig->getAnimNode();
|
||||
|
||||
// bones space is rotated
|
||||
glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
AnimPose xform(glm::vec3(1), rotY180 * getOrientation(), getPosition());
|
||||
|
||||
if (animSkeleton && _enableDebugDrawBindPose) {
|
||||
glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f);
|
||||
AnimDebugDraw::getInstance().addSkeleton("myAvatar", animSkeleton, xform, gray);
|
||||
}
|
||||
|
||||
// This only works for when new anim system is enabled, at the moment.
|
||||
if (animNode && animSkeleton && _enableDebugDrawAnimPose && _rig->getEnableAnimGraph()) {
|
||||
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
|
||||
AnimDebugDraw::getInstance().addAnimNode("myAvatar", animNode, xform, cyan);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||
_skeletonModel.setCauterizeBones(!shouldDrawHead);
|
||||
}
|
||||
|
|
|
@ -190,8 +190,12 @@ public slots:
|
|||
void loadLastRecording();
|
||||
|
||||
virtual void rebuildSkeletonBody();
|
||||
|
||||
void setEnableRigAnimations(bool isEnabled);
|
||||
void setEnableAnimGraph(bool isEnabled);
|
||||
void setEnableDebugDrawBindPose(bool isEnabled);
|
||||
void setEnableDebugDrawAnimPose(bool isEnabled);
|
||||
void setEnableMeshVisible(bool isEnabled);
|
||||
|
||||
signals:
|
||||
void transformChanged();
|
||||
|
@ -314,6 +318,9 @@ private:
|
|||
std::unordered_set<int> _headBoneSet;
|
||||
RigPointer _rig;
|
||||
bool _prevShouldDrawHead;
|
||||
|
||||
bool _enableDebugDrawBindPose = false;
|
||||
bool _enableDebugDrawAnimPose = false;
|
||||
};
|
||||
|
||||
#endif // hifi_MyAvatar_h
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
NumTypes
|
||||
};
|
||||
using Pointer = std::shared_ptr<AnimNode>;
|
||||
using ConstPointer = std::shared_ptr<const AnimNode>;
|
||||
using Triggers = std::vector<std::string>;
|
||||
|
||||
friend class AnimDebugDraw;
|
||||
|
|
|
@ -159,6 +159,7 @@ public:
|
|||
|
||||
void setEnableRig(bool isEnabled) { _enableRig = isEnabled; }
|
||||
void setEnableAnimGraph(bool isEnabled) { _enableAnimGraph = isEnabled; }
|
||||
bool getEnableAnimGraph() const { return _enableAnimGraph; }
|
||||
|
||||
void updateFromHeadParameters(const HeadParameters& params);
|
||||
void updateEyeJoints(int leftEyeIndex, int rightEyeIndex, const glm::vec3& modelTranslation, const glm::quat& modelRotation,
|
||||
|
@ -169,6 +170,9 @@ public:
|
|||
|
||||
void initAnimGraph(const QUrl& url, const FBXGeometry& fbxGeometry);
|
||||
|
||||
AnimNode::ConstPointer getAnimNode() const { return _animNode; }
|
||||
AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; }
|
||||
|
||||
protected:
|
||||
|
||||
void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist);
|
||||
|
|
|
@ -80,6 +80,13 @@ static uint32_t toRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
|||
return ((uint32_t)r | (uint32_t)g << 8 | (uint32_t)b << 16 | (uint32_t)a << 24);
|
||||
}
|
||||
|
||||
static uint32_t toRGBA(const glm::vec4& v) {
|
||||
return toRGBA(static_cast<uint8_t>(v.r * 255.0f),
|
||||
static_cast<uint8_t>(v.g * 255.0f),
|
||||
static_cast<uint8_t>(v.b * 255.0f),
|
||||
static_cast<uint8_t>(v.a * 255.0f));
|
||||
}
|
||||
|
||||
gpu::PipelinePointer AnimDebugDraw::_pipeline;
|
||||
|
||||
AnimDebugDraw::AnimDebugDraw() :
|
||||
|
@ -145,16 +152,16 @@ AnimDebugDraw::~AnimDebugDraw() {
|
|||
}
|
||||
}
|
||||
|
||||
void AnimDebugDraw::addSkeleton(std::string key, AnimSkeleton::Pointer skeleton, const AnimPose& rootPose) {
|
||||
_skeletons[key] = SkeletonInfo(skeleton, rootPose);
|
||||
void AnimDebugDraw::addSkeleton(std::string key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color) {
|
||||
_skeletons[key] = SkeletonInfo(skeleton, rootPose, color);
|
||||
}
|
||||
|
||||
void AnimDebugDraw::removeSkeleton(std::string key) {
|
||||
_skeletons.erase(key);
|
||||
}
|
||||
|
||||
void AnimDebugDraw::addAnimNode(std::string key, AnimNode::Pointer animNode, const AnimPose& rootPose) {
|
||||
_animNodes[key] = AnimNodeInfo(animNode, rootPose);
|
||||
void AnimDebugDraw::addAnimNode(std::string key, AnimNode::ConstPointer animNode, const AnimPose& rootPose, const glm::vec4& color) {
|
||||
_animNodes[key] = AnimNodeInfo(animNode, rootPose, color);
|
||||
}
|
||||
|
||||
void AnimDebugDraw::removeAnimNode(std::string key) {
|
||||
|
@ -164,7 +171,6 @@ void AnimDebugDraw::removeAnimNode(std::string key) {
|
|||
static const uint32_t red = toRGBA(255, 0, 0, 255);
|
||||
static const uint32_t green = toRGBA(0, 255, 0, 255);
|
||||
static const uint32_t blue = toRGBA(0, 0, 255, 255);
|
||||
static const uint32_t cyan = toRGBA(0, 128, 128, 255);
|
||||
|
||||
const int NUM_CIRCLE_SLICES = 24;
|
||||
|
||||
|
@ -182,7 +188,7 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius
|
|||
float rSinTheta = radius * sin(dTheta * i);
|
||||
xRing[i] = finalPose * glm::vec3(0.0f, rCosTheta, rSinTheta);
|
||||
yRing[i] = finalPose * glm::vec3(rCosTheta, 0.0f, rSinTheta);
|
||||
zRing[i] = finalPose *glm::vec3(rCosTheta, rSinTheta, 0.0f);
|
||||
zRing[i] = finalPose * glm::vec3(rCosTheta, rSinTheta, 0.0f);
|
||||
}
|
||||
|
||||
// x-axis
|
||||
|
@ -240,8 +246,10 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius
|
|||
}
|
||||
}
|
||||
|
||||
static void addLink(const AnimPose& rootPose, const AnimPose& pose,
|
||||
const AnimPose& parentPose, float radius, Vertex*& v) {
|
||||
static void addLink(const AnimPose& rootPose, const AnimPose& pose, const AnimPose& parentPose,
|
||||
float radius, const glm::vec4& colorVec, Vertex*& v) {
|
||||
|
||||
uint32_t color = toRGBA(colorVec);
|
||||
|
||||
AnimPose pose0 = rootPose * parentPose;
|
||||
AnimPose pose1 = rootPose * pose;
|
||||
|
@ -271,19 +279,19 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose,
|
|||
|
||||
for (int i = 0; i < NUM_BASE_CORNERS; i++) {
|
||||
v->pos = boneBaseCorners[i];
|
||||
v->rgba = cyan;
|
||||
v->rgba = color;
|
||||
v++;
|
||||
v->pos = boneBaseCorners[(i + 1) % NUM_BASE_CORNERS];
|
||||
v->rgba = cyan;
|
||||
v->rgba = color;
|
||||
v++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_BASE_CORNERS; i++) {
|
||||
v->pos = boneBaseCorners[i];
|
||||
v->rgba = cyan;
|
||||
v->rgba = color;
|
||||
v++;
|
||||
v->pos = boneTip;
|
||||
v->rgba = cyan;
|
||||
v->rgba = color;
|
||||
v++;
|
||||
}
|
||||
} else {
|
||||
|
@ -292,10 +300,10 @@ static void addLink(const AnimPose& rootPose, const AnimPose& pose,
|
|||
// We add the same line multiple times, so the vertex count is correct.
|
||||
for (int i = 0; i < NUM_BASE_CORNERS * 2; i++) {
|
||||
v->pos = pose0.trans;
|
||||
v->rgba = cyan;
|
||||
v->rgba = color;
|
||||
v++;
|
||||
v->pos = pose1.trans;
|
||||
v->rgba = cyan;
|
||||
v->rgba = color;
|
||||
v++;
|
||||
}
|
||||
}
|
||||
|
@ -319,7 +327,7 @@ void AnimDebugDraw::update() {
|
|||
// figure out how many verts we will need.
|
||||
int numVerts = 0;
|
||||
for (auto&& iter : _skeletons) {
|
||||
AnimSkeleton::Pointer& skeleton = iter.second.first;
|
||||
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
||||
numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE;
|
||||
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
||||
auto parentIndex = skeleton->getParentIndex(i);
|
||||
|
@ -330,7 +338,7 @@ void AnimDebugDraw::update() {
|
|||
}
|
||||
|
||||
for (auto&& iter : _animNodes) {
|
||||
AnimNode::Pointer& animNode = iter.second.first;
|
||||
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
||||
auto poses = animNode->getPosesInternal();
|
||||
numVerts += poses.size() * VERTICES_PER_BONE;
|
||||
auto skeleton = animNode->getSkeleton();
|
||||
|
@ -346,8 +354,13 @@ void AnimDebugDraw::update() {
|
|||
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
||||
Vertex* v = verts;
|
||||
for (auto&& iter : _skeletons) {
|
||||
AnimSkeleton::Pointer& skeleton = iter.second.first;
|
||||
AnimPose& rootPose = iter.second.second;
|
||||
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
||||
AnimPose rootPose = std::get<1>(iter.second);
|
||||
int hipsIndex = skeleton->nameToJointIndex("Hips");
|
||||
if (hipsIndex >= 0) {
|
||||
rootPose.trans -= skeleton->getRelativeBindPose(hipsIndex).trans;
|
||||
}
|
||||
glm::vec4 color = std::get<2>(iter.second);
|
||||
|
||||
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
||||
AnimPose pose = skeleton->getAbsoluteBindPose(i);
|
||||
|
@ -362,14 +375,22 @@ void AnimDebugDraw::update() {
|
|||
if (parentIndex >= 0) {
|
||||
assert(parentIndex < skeleton->getNumJoints());
|
||||
AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex);
|
||||
addLink(rootPose, pose, parentPose, radius, v);
|
||||
addLink(rootPose, pose, parentPose, radius, color, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& iter : _animNodes) {
|
||||
AnimNode::Pointer& animNode = iter.second.first;
|
||||
AnimPose& rootPose = iter.second.second;
|
||||
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
||||
AnimPose rootPose = std::get<1>(iter.second);
|
||||
if (animNode->_skeleton) {
|
||||
int hipsIndex = animNode->_skeleton->nameToJointIndex("Hips");
|
||||
if (hipsIndex >= 0) {
|
||||
rootPose.trans -= animNode->_skeleton->getRelativeBindPose(hipsIndex).trans;
|
||||
}
|
||||
}
|
||||
glm::vec4 color = std::get<2>(iter.second);
|
||||
|
||||
auto poses = animNode->getPosesInternal();
|
||||
|
||||
auto skeleton = animNode->getSkeleton();
|
||||
|
@ -392,7 +413,7 @@ void AnimDebugDraw::update() {
|
|||
if (parentIndex >= 0) {
|
||||
assert((size_t)parentIndex < poses.size());
|
||||
// draw line to parent
|
||||
addLink(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, v);
|
||||
addLink(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, color, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#ifndef hifi_AnimDebugDraw_h
|
||||
#define hifi_AnimDebugDraw_h
|
||||
|
||||
#include <tuple>
|
||||
|
||||
#include "render/Scene.h"
|
||||
#include "gpu/Pipeline.h"
|
||||
#include "AnimNode.h"
|
||||
|
@ -25,10 +27,10 @@ public:
|
|||
AnimDebugDraw();
|
||||
~AnimDebugDraw();
|
||||
|
||||
void addSkeleton(std::string key, AnimSkeleton::Pointer skeleton, const AnimPose& rootPose);
|
||||
void addSkeleton(std::string key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color);
|
||||
void removeSkeleton(std::string key);
|
||||
|
||||
void addAnimNode(std::string key, AnimNode::Pointer skeleton, const AnimPose& rootPose);
|
||||
void addAnimNode(std::string key, AnimNode::ConstPointer animNode, const AnimPose& rootPose, const glm::vec4& color);
|
||||
void removeAnimNode(std::string key);
|
||||
|
||||
void update();
|
||||
|
@ -40,8 +42,8 @@ protected:
|
|||
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
|
||||
typedef std::pair<AnimSkeleton::Pointer, AnimPose> SkeletonInfo;
|
||||
typedef std::pair<AnimNode::Pointer, AnimPose> AnimNodeInfo;
|
||||
typedef std::tuple<AnimSkeleton::ConstPointer, AnimPose, glm::vec4> SkeletonInfo;
|
||||
typedef std::tuple<AnimNode::ConstPointer, AnimPose, glm::vec4> AnimNodeInfo;
|
||||
|
||||
std::unordered_map<std::string, SkeletonInfo> _skeletons;
|
||||
std::unordered_map<std::string, AnimNodeInfo> _animNodes;
|
||||
|
|
Loading…
Reference in a new issue