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:
Anthony J. Thibault 2015-09-02 21:04:29 -07:00
parent 471400e595
commit 30264e9c3d
8 changed files with 113 additions and 26 deletions

View file

@ -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,

View file

@ -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";

View file

@ -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);
}

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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;