mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-10 20:07:22 +02:00
Merge pull request #5724 from hyperlogic/tony/anim-debug-draw-improvements
AnimDebugDraw Improvements
This commit is contained in:
commit
e06461ea15
8 changed files with 158 additions and 70 deletions
|
@ -735,7 +735,7 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
|
||||||
_enableDebugDrawAnimPose = isEnabled;
|
_enableDebugDrawAnimPose = isEnabled;
|
||||||
|
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
AnimDebugDraw::getInstance().removeAnimNode("myAvatar");
|
AnimDebugDraw::getInstance().removePoses("myAvatar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1248,8 +1248,6 @@ void MyAvatar::initAnimGraph() {
|
||||||
|
|
||||||
void MyAvatar::destroyAnimGraph() {
|
void MyAvatar::destroyAnimGraph() {
|
||||||
_rig->destroyAnimGraph();
|
_rig->destroyAnimGraph();
|
||||||
AnimDebugDraw::getInstance().removeSkeleton("myAvatar");
|
|
||||||
AnimDebugDraw::getInstance().removeAnimNode("myAvatar");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||||
|
@ -1261,26 +1259,35 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
||||||
initHeadBones();
|
initHeadBones();
|
||||||
_skeletonModel.setCauterizeBoneSet(_headBoneSet);
|
_skeletonModel.setCauterizeBoneSet(_headBoneSet);
|
||||||
initAnimGraph();
|
initAnimGraph();
|
||||||
|
_debugDrawSkeleton = std::make_shared<AnimSkeleton>(_skeletonModel.getGeometry()->getFBXGeometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_enableDebugDrawBindPose || _enableDebugDrawAnimPose) {
|
if (_enableDebugDrawBindPose || _enableDebugDrawAnimPose) {
|
||||||
|
|
||||||
AnimSkeleton::ConstPointer animSkeleton = _rig->getAnimSkeleton();
|
// bones are aligned such that z is forward, not -z.
|
||||||
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));
|
glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
AnimPose xform(glm::vec3(1), rotY180 * getOrientation(), getPosition());
|
AnimPose xform(glm::vec3(1), rotY180 * getOrientation(), getPosition());
|
||||||
|
|
||||||
if (animSkeleton && _enableDebugDrawBindPose) {
|
if (_enableDebugDrawBindPose && _debugDrawSkeleton) {
|
||||||
glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f);
|
glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f);
|
||||||
AnimDebugDraw::getInstance().addSkeleton("myAvatar", animSkeleton, xform, gray);
|
AnimDebugDraw::getInstance().addSkeleton("myAvatar", _debugDrawSkeleton, xform, gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This only works for when new anim system is enabled, at the moment.
|
if (_enableDebugDrawAnimPose && _debugDrawSkeleton) {
|
||||||
if (animNode && animSkeleton && _enableDebugDrawAnimPose && _rig->getEnableAnimGraph()) {
|
|
||||||
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
|
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
|
||||||
AnimDebugDraw::getInstance().addAnimNode("myAvatar", animNode, xform, cyan);
|
|
||||||
|
// build AnimPoseVec from JointStates.
|
||||||
|
AnimPoseVec poses;
|
||||||
|
poses.reserve(_debugDrawSkeleton->getNumJoints());
|
||||||
|
for (int i = 0; i < _debugDrawSkeleton->getNumJoints(); i++) {
|
||||||
|
AnimPose pose = _debugDrawSkeleton->getRelativeBindPose(i);
|
||||||
|
glm::quat jointRot;
|
||||||
|
_rig->getJointRotationInConstrainedFrame(i, jointRot);
|
||||||
|
pose.rot = pose.rot * jointRot;
|
||||||
|
poses.push_back(pose);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimDebugDraw::getInstance().addPoses("myAvatar", _debugDrawSkeleton, poses, xform, cyan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,6 +321,7 @@ private:
|
||||||
|
|
||||||
bool _enableDebugDrawBindPose = false;
|
bool _enableDebugDrawBindPose = false;
|
||||||
bool _enableDebugDrawAnimPose = false;
|
bool _enableDebugDrawAnimPose = false;
|
||||||
|
AnimSkeleton::ConstPointer _debugDrawSkeleton = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_MyAvatar_h
|
#endif // hifi_MyAvatar_h
|
||||||
|
|
|
@ -58,7 +58,52 @@ AnimPose::operator glm::mat4() const {
|
||||||
glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f));
|
glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) {
|
||||||
|
// convert to std::vector of joints
|
||||||
|
std::vector<FBXJoint> joints;
|
||||||
|
joints.reserve(fbxGeometry.joints.size());
|
||||||
|
for (auto& joint : fbxGeometry.joints) {
|
||||||
|
joints.push_back(joint);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimPose geometryOffset(fbxGeometry.offset);
|
||||||
|
buildSkeletonFromJoints(joints, geometryOffset);
|
||||||
|
}
|
||||||
|
|
||||||
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset) {
|
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset) {
|
||||||
|
buildSkeletonFromJoints(joints, geometryOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
|
||||||
|
for (size_t i = 0; i < _joints.size(); i++) {
|
||||||
|
if (_joints[i].name == jointName) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AnimSkeleton::getNumJoints() const {
|
||||||
|
return _joints.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimPose& AnimSkeleton::getAbsoluteBindPose(int jointIndex) const {
|
||||||
|
return _absoluteBindPoses[jointIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
const AnimPose& AnimSkeleton::getRelativeBindPose(int jointIndex) const {
|
||||||
|
return _relativeBindPoses[jointIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
int AnimSkeleton::getParentIndex(int jointIndex) const {
|
||||||
|
return _joints[jointIndex].parentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString& AnimSkeleton::getJointName(int jointIndex) const {
|
||||||
|
return _joints[jointIndex].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset) {
|
||||||
_joints = joints;
|
_joints = joints;
|
||||||
|
|
||||||
// build a cache of bind poses
|
// build a cache of bind poses
|
||||||
|
@ -113,35 +158,6 @@ AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
|
|
||||||
for (size_t i = 0; i < _joints.size(); i++) {
|
|
||||||
if (_joints[i].name == jointName) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AnimSkeleton::getNumJoints() const {
|
|
||||||
return _joints.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
AnimPose AnimSkeleton::getAbsoluteBindPose(int jointIndex) const {
|
|
||||||
return _absoluteBindPoses[jointIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
AnimPose AnimSkeleton::getRelativeBindPose(int jointIndex) const {
|
|
||||||
return _relativeBindPoses[jointIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
int AnimSkeleton::getParentIndex(int jointIndex) const {
|
|
||||||
return _joints[jointIndex].parentIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString& AnimSkeleton::getJointName(int jointIndex) const {
|
|
||||||
return _joints[jointIndex].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void AnimSkeleton::dump() const {
|
void AnimSkeleton::dump() const {
|
||||||
qCDebug(animation) << "[";
|
qCDebug(animation) << "[";
|
||||||
|
|
|
@ -47,16 +47,17 @@ public:
|
||||||
using Pointer = std::shared_ptr<AnimSkeleton>;
|
using Pointer = std::shared_ptr<AnimSkeleton>;
|
||||||
using ConstPointer = std::shared_ptr<const AnimSkeleton>;
|
using ConstPointer = std::shared_ptr<const AnimSkeleton>;
|
||||||
|
|
||||||
|
AnimSkeleton(const FBXGeometry& fbxGeometry);
|
||||||
AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset);
|
AnimSkeleton(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset);
|
||||||
int nameToJointIndex(const QString& jointName) const;
|
int nameToJointIndex(const QString& jointName) const;
|
||||||
const QString& getJointName(int jointIndex) const;
|
const QString& getJointName(int jointIndex) const;
|
||||||
int getNumJoints() const;
|
int getNumJoints() const;
|
||||||
|
|
||||||
// absolute pose, not relative to parent
|
// absolute pose, not relative to parent
|
||||||
AnimPose getAbsoluteBindPose(int jointIndex) const;
|
const AnimPose& getAbsoluteBindPose(int jointIndex) const;
|
||||||
|
|
||||||
// relative to parent pose
|
// relative to parent pose
|
||||||
AnimPose getRelativeBindPose(int jointIndex) const;
|
const AnimPose& getRelativeBindPose(int jointIndex) const;
|
||||||
|
|
||||||
int getParentIndex(int jointIndex) const;
|
int getParentIndex(int jointIndex) const;
|
||||||
|
|
||||||
|
@ -66,6 +67,8 @@ public:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints, const AnimPose& geometryOffset);
|
||||||
|
|
||||||
std::vector<FBXJoint> _joints;
|
std::vector<FBXJoint> _joints;
|
||||||
AnimPoseVec _absoluteBindPoses;
|
AnimPoseVec _absoluteBindPoses;
|
||||||
AnimPoseVec _relativeBindPoses;
|
AnimPoseVec _relativeBindPoses;
|
||||||
|
|
|
@ -901,6 +901,14 @@ glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targ
|
||||||
return endRotation;
|
return endRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Rig::getJointRotationInConstrainedFrame(int jointIndex, glm::quat& quatOut) const {
|
||||||
|
if (jointIndex == -1 || _jointStates.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
quatOut = _jointStates[jointIndex].getRotationInConstrainedFrame();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Rig::updateVisibleJointStates() {
|
void Rig::updateVisibleJointStates() {
|
||||||
for (int i = 0; i < _jointStates.size(); i++) {
|
for (int i = 0; i < _jointStates.size(); i++) {
|
||||||
_jointStates[i].slaveVisibleTransform();
|
_jointStates[i].slaveVisibleTransform();
|
||||||
|
@ -1010,16 +1018,7 @@ void Rig::initAnimGraph(const QUrl& url, const FBXGeometry& fbxGeometry) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert to std::vector of joints
|
_animSkeleton = std::make_shared<AnimSkeleton>(fbxGeometry);
|
||||||
std::vector<FBXJoint> joints;
|
|
||||||
joints.reserve(fbxGeometry.joints.size());
|
|
||||||
for (auto& joint : fbxGeometry.joints) {
|
|
||||||
joints.push_back(joint);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create skeleton
|
|
||||||
AnimPose geometryOffset(fbxGeometry.offset);
|
|
||||||
_animSkeleton = std::make_shared<AnimSkeleton>(joints, geometryOffset);
|
|
||||||
|
|
||||||
// load the anim graph
|
// load the anim graph
|
||||||
_animLoader.reset(new AnimNodeLoader(url));
|
_animLoader.reset(new AnimNodeLoader(url));
|
||||||
|
|
|
@ -50,7 +50,6 @@ class Rig;
|
||||||
typedef std::shared_ptr<Rig> RigPointer;
|
typedef std::shared_ptr<Rig> RigPointer;
|
||||||
|
|
||||||
class Rig : public QObject, public std::enable_shared_from_this<Rig> {
|
class Rig : public QObject, public std::enable_shared_from_this<Rig> {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct HeadParameters {
|
struct HeadParameters {
|
||||||
|
@ -153,6 +152,7 @@ public:
|
||||||
glm::vec3 getJointDefaultTranslationInConstrainedFrame(int jointIndex);
|
glm::vec3 getJointDefaultTranslationInConstrainedFrame(int jointIndex);
|
||||||
glm::quat setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation,
|
glm::quat setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation,
|
||||||
float priority, bool constrain = false, float mix = 1.0f);
|
float priority, bool constrain = false, float mix = 1.0f);
|
||||||
|
bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const;
|
||||||
glm::quat getJointDefaultRotationInParentFrame(int jointIndex);
|
glm::quat getJointDefaultRotationInParentFrame(int jointIndex);
|
||||||
void updateVisibleJointStates();
|
void updateVisibleJointStates();
|
||||||
|
|
||||||
|
|
|
@ -152,22 +152,30 @@ AnimDebugDraw::~AnimDebugDraw() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimDebugDraw::addSkeleton(std::string key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color) {
|
void AnimDebugDraw::addSkeleton(const std::string& key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color) {
|
||||||
_skeletons[key] = SkeletonInfo(skeleton, rootPose, color);
|
_skeletons[key] = SkeletonInfo(skeleton, rootPose, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimDebugDraw::removeSkeleton(std::string key) {
|
void AnimDebugDraw::removeSkeleton(const std::string& key) {
|
||||||
_skeletons.erase(key);
|
_skeletons.erase(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimDebugDraw::addAnimNode(std::string key, AnimNode::ConstPointer animNode, const AnimPose& rootPose, const glm::vec4& color) {
|
void AnimDebugDraw::addAnimNode(const std::string& key, AnimNode::ConstPointer animNode, const AnimPose& rootPose, const glm::vec4& color) {
|
||||||
_animNodes[key] = AnimNodeInfo(animNode, rootPose, color);
|
_animNodes[key] = AnimNodeInfo(animNode, rootPose, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimDebugDraw::removeAnimNode(std::string key) {
|
void AnimDebugDraw::removeAnimNode(const std::string& key) {
|
||||||
_animNodes.erase(key);
|
_animNodes.erase(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimDebugDraw::addPoses(const std::string& key, AnimSkeleton::ConstPointer skeleton, const AnimPoseVec& poses, const AnimPose& rootPose, const glm::vec4& color) {
|
||||||
|
_poses[key] = PosesInfo(skeleton, poses, rootPose, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimDebugDraw::removePoses(const std::string& key) {
|
||||||
|
_poses.erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
static const uint32_t red = toRGBA(255, 0, 0, 255);
|
static const uint32_t red = toRGBA(255, 0, 0, 255);
|
||||||
static const uint32_t green = toRGBA(0, 255, 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 blue = toRGBA(0, 0, 255, 255);
|
||||||
|
@ -176,6 +184,8 @@ const int NUM_CIRCLE_SLICES = 24;
|
||||||
|
|
||||||
static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius, Vertex*& v) {
|
static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius, Vertex*& v) {
|
||||||
|
|
||||||
|
const float XYZ_AXIS_LENGTH = radius * 4.0f;
|
||||||
|
|
||||||
AnimPose finalPose = rootPose * pose;
|
AnimPose finalPose = rootPose * pose;
|
||||||
glm::vec3 base = rootPose * pose.trans;
|
glm::vec3 base = rootPose * pose.trans;
|
||||||
|
|
||||||
|
@ -195,7 +205,7 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius
|
||||||
v->pos = base;
|
v->pos = base;
|
||||||
v->rgba = red;
|
v->rgba = red;
|
||||||
v++;
|
v++;
|
||||||
v->pos = finalPose * glm::vec3(radius * 2.0f, 0.0f, 0.0f);
|
v->pos = finalPose * glm::vec3(XYZ_AXIS_LENGTH, 0.0f, 0.0f);
|
||||||
v->rgba = red;
|
v->rgba = red;
|
||||||
v++;
|
v++;
|
||||||
|
|
||||||
|
@ -213,7 +223,7 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius
|
||||||
v->pos = base;
|
v->pos = base;
|
||||||
v->rgba = green;
|
v->rgba = green;
|
||||||
v++;
|
v++;
|
||||||
v->pos = finalPose * glm::vec3(0.0f, radius * 2.0f, 0.0f);
|
v->pos = finalPose * glm::vec3(0.0f, XYZ_AXIS_LENGTH, 0.0f);
|
||||||
v->rgba = green;
|
v->rgba = green;
|
||||||
v++;
|
v++;
|
||||||
|
|
||||||
|
@ -231,7 +241,7 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius
|
||||||
v->pos = base;
|
v->pos = base;
|
||||||
v->rgba = blue;
|
v->rgba = blue;
|
||||||
v++;
|
v++;
|
||||||
v->pos = finalPose * glm::vec3(0.0f, 0.0f, radius * 2.0f);
|
v->pos = finalPose * glm::vec3(0.0f, 0.0f, XYZ_AXIS_LENGTH);
|
||||||
v->rgba = blue;
|
v->rgba = blue;
|
||||||
v++;
|
v++;
|
||||||
|
|
||||||
|
@ -322,11 +332,11 @@ void AnimDebugDraw::update() {
|
||||||
const size_t VERTICES_PER_BONE = (6 + (NUM_CIRCLE_SLICES * 2) * 3);
|
const size_t VERTICES_PER_BONE = (6 + (NUM_CIRCLE_SLICES * 2) * 3);
|
||||||
const size_t VERTICES_PER_LINK = 8 * 2;
|
const size_t VERTICES_PER_LINK = 8 * 2;
|
||||||
|
|
||||||
const float BONE_RADIUS = 0.0075f;
|
const float BONE_RADIUS = 0.01f; // 1 cm
|
||||||
|
|
||||||
// figure out how many verts we will need.
|
// figure out how many verts we will need.
|
||||||
int numVerts = 0;
|
int numVerts = 0;
|
||||||
for (auto&& iter : _skeletons) {
|
for (auto& iter : _skeletons) {
|
||||||
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
||||||
numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE;
|
numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE;
|
||||||
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
||||||
|
@ -337,7 +347,7 @@ void AnimDebugDraw::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto&& iter : _animNodes) {
|
for (auto& iter : _animNodes) {
|
||||||
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
||||||
auto poses = animNode->getPosesInternal();
|
auto poses = animNode->getPosesInternal();
|
||||||
numVerts += poses.size() * VERTICES_PER_BONE;
|
numVerts += poses.size() * VERTICES_PER_BONE;
|
||||||
|
@ -350,10 +360,21 @@ void AnimDebugDraw::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& iter : _poses) {
|
||||||
|
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);
|
||||||
|
if (parentIndex >= 0) {
|
||||||
|
numVerts += VERTICES_PER_LINK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data._vertexBuffer->resize(sizeof(Vertex) * numVerts);
|
data._vertexBuffer->resize(sizeof(Vertex) * numVerts);
|
||||||
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
||||||
Vertex* v = verts;
|
Vertex* v = verts;
|
||||||
for (auto&& iter : _skeletons) {
|
for (auto& iter : _skeletons) {
|
||||||
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
||||||
AnimPose rootPose = std::get<1>(iter.second);
|
AnimPose rootPose = std::get<1>(iter.second);
|
||||||
int hipsIndex = skeleton->nameToJointIndex("Hips");
|
int hipsIndex = skeleton->nameToJointIndex("Hips");
|
||||||
|
@ -380,7 +401,7 @@ void AnimDebugDraw::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto&& iter : _animNodes) {
|
for (auto& iter : _animNodes) {
|
||||||
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
AnimNode::ConstPointer& animNode = std::get<0>(iter.second);
|
||||||
AnimPose rootPose = std::get<1>(iter.second);
|
AnimPose rootPose = std::get<1>(iter.second);
|
||||||
if (animNode->_skeleton) {
|
if (animNode->_skeleton) {
|
||||||
|
@ -418,6 +439,42 @@ void AnimDebugDraw::update() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto& iter : _poses) {
|
||||||
|
AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second);
|
||||||
|
AnimPoseVec& poses = std::get<1>(iter.second);
|
||||||
|
AnimPose rootPose = std::get<2>(iter.second);
|
||||||
|
int hipsIndex = skeleton->nameToJointIndex("Hips");
|
||||||
|
if (hipsIndex >= 0) {
|
||||||
|
rootPose.trans -= skeleton->getRelativeBindPose(hipsIndex).trans;
|
||||||
|
}
|
||||||
|
glm::vec4 color = std::get<3>(iter.second);
|
||||||
|
|
||||||
|
std::vector<AnimPose> absAnimPose;
|
||||||
|
absAnimPose.resize(skeleton->getNumJoints());
|
||||||
|
|
||||||
|
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
||||||
|
const AnimPose& pose = poses[i];
|
||||||
|
|
||||||
|
const float radius = BONE_RADIUS / (pose.scale.x * rootPose.scale.x);
|
||||||
|
|
||||||
|
auto parentIndex = skeleton->getParentIndex(i);
|
||||||
|
if (parentIndex >= 0) {
|
||||||
|
absAnimPose[i] = absAnimPose[parentIndex] * pose;
|
||||||
|
} else {
|
||||||
|
absAnimPose[i] = pose;
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw bone
|
||||||
|
addBone(rootPose, absAnimPose[i], radius, v);
|
||||||
|
|
||||||
|
// draw link to parent
|
||||||
|
if (parentIndex >= 0) {
|
||||||
|
assert(parentIndex < skeleton->getNumJoints());
|
||||||
|
addLink(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, color, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(numVerts == (v - verts));
|
assert(numVerts == (v - verts));
|
||||||
|
|
||||||
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
||||||
|
|
|
@ -27,11 +27,14 @@ public:
|
||||||
AnimDebugDraw();
|
AnimDebugDraw();
|
||||||
~AnimDebugDraw();
|
~AnimDebugDraw();
|
||||||
|
|
||||||
void addSkeleton(std::string key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color);
|
void addSkeleton(const std::string& key, AnimSkeleton::ConstPointer skeleton, const AnimPose& rootPose, const glm::vec4& color);
|
||||||
void removeSkeleton(std::string key);
|
void removeSkeleton(const std::string& key);
|
||||||
|
|
||||||
void addAnimNode(std::string key, AnimNode::ConstPointer animNode, const AnimPose& rootPose, const glm::vec4& color);
|
void addAnimNode(const std::string& key, AnimNode::ConstPointer animNode, const AnimPose& rootPose, const glm::vec4& color);
|
||||||
void removeAnimNode(std::string key);
|
void removeAnimNode(const std::string& key);
|
||||||
|
|
||||||
|
void addPoses(const std::string& key, AnimSkeleton::ConstPointer skeleton, const AnimPoseVec& poses, const AnimPose& rootPose, const glm::vec4& color);
|
||||||
|
void removePoses(const std::string& key);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
@ -44,9 +47,11 @@ protected:
|
||||||
|
|
||||||
typedef std::tuple<AnimSkeleton::ConstPointer, AnimPose, glm::vec4> SkeletonInfo;
|
typedef std::tuple<AnimSkeleton::ConstPointer, AnimPose, glm::vec4> SkeletonInfo;
|
||||||
typedef std::tuple<AnimNode::ConstPointer, AnimPose, glm::vec4> AnimNodeInfo;
|
typedef std::tuple<AnimNode::ConstPointer, AnimPose, glm::vec4> AnimNodeInfo;
|
||||||
|
typedef std::tuple<AnimSkeleton::ConstPointer, AnimPoseVec, AnimPose, glm::vec4> PosesInfo;
|
||||||
|
|
||||||
std::unordered_map<std::string, SkeletonInfo> _skeletons;
|
std::unordered_map<std::string, SkeletonInfo> _skeletons;
|
||||||
std::unordered_map<std::string, AnimNodeInfo> _animNodes;
|
std::unordered_map<std::string, AnimNodeInfo> _animNodes;
|
||||||
|
std::unordered_map<std::string, PosesInfo> _poses;
|
||||||
|
|
||||||
// no copies
|
// no copies
|
||||||
AnimDebugDraw(const AnimDebugDraw&) = delete;
|
AnimDebugDraw(const AnimDebugDraw&) = delete;
|
||||||
|
|
Loading…
Reference in a new issue