mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 23:53:26 +02:00
WIP, animNode rendering
This commit is contained in:
parent
d1fdbe32d2
commit
df79463750
9 changed files with 136 additions and 46 deletions
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include "AnimDebugDraw.h"
|
||||
#include "AnimSkeleton.h"
|
||||
#include "AnimClip.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -147,6 +148,11 @@ void MyAvatar::reset() {
|
|||
}
|
||||
|
||||
void MyAvatar::update(float deltaTime) {
|
||||
|
||||
if (_animNode) {
|
||||
_animNode->evaluate(deltaTime);
|
||||
}
|
||||
|
||||
if (_referential) {
|
||||
_referential->update();
|
||||
}
|
||||
|
@ -1206,6 +1212,8 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
|||
initHeadBones();
|
||||
_skeletonModel.setCauterizeBoneSet(_headBoneSet);
|
||||
|
||||
// AJT: SETUP DEBUG RENDERING OF NEW ANIMATION SYSTEM
|
||||
|
||||
// create a skeleton and hand it over to the debug draw instance
|
||||
auto geom = _skeletonModel.getGeometry()->getFBXGeometry();
|
||||
std::vector<FBXJoint> joints;
|
||||
|
@ -1213,7 +1221,11 @@ void MyAvatar::preRender(RenderArgs* renderArgs) {
|
|||
joints.push_back(joint);
|
||||
}
|
||||
auto skeleton = make_shared<AnimSkeleton>(joints);
|
||||
AnimDebugDraw::getInstance().addSkeleton("my-avatar", skeleton, Transform());
|
||||
//AnimDebugDraw::getInstance().addSkeleton("my-avatar", skeleton, AnimPose::identity);
|
||||
|
||||
_animNode = make_shared<AnimClip>("clip", "https://hifi-public.s3.amazonaws.com/ozan/support/FightClubBotTest1/Animations/standard_idle.fbx", 0.0f, 90.0f, 1.0f, true);
|
||||
_animNode->setSkeleton(skeleton);
|
||||
AnimDebugDraw::getInstance().addAnimNode("clip", _animNode, AnimPose::identity);
|
||||
}
|
||||
|
||||
if (shouldDrawHead != _prevShouldDrawHead) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Avatar.h"
|
||||
|
||||
class ModelItemID;
|
||||
class AnimNode;
|
||||
|
||||
enum eyeContactTarget {
|
||||
LEFT_EYE,
|
||||
|
@ -281,6 +282,8 @@ private:
|
|||
RigPointer _rig;
|
||||
bool _prevShouldDrawHead;
|
||||
std::unordered_set<int> _headBoneSet;
|
||||
|
||||
std::shared_ptr<AnimNode> _animNode;
|
||||
};
|
||||
|
||||
#endif // hifi_MyAvatar_h
|
||||
|
|
|
@ -13,14 +13,13 @@
|
|||
|
||||
AnimClip::AnimClip(const std::string& id, const std::string& url, float startFrame, float endFrame, float timeScale, bool loopFlag) :
|
||||
AnimNode(AnimNode::ClipType, id),
|
||||
_url(url),
|
||||
_startFrame(startFrame),
|
||||
_endFrame(endFrame),
|
||||
_timeScale(timeScale),
|
||||
_loopFlag(loopFlag),
|
||||
_frame(startFrame)
|
||||
{
|
||||
|
||||
setURL(url);
|
||||
}
|
||||
|
||||
AnimClip::~AnimClip() {
|
||||
|
@ -128,6 +127,9 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
jointMap.reserve(animJointCount);
|
||||
for (int i = 0; i < animJointCount; i++) {
|
||||
int skeletonJoint = _skeleton->nameToJointIndex(joints.at(i).name);
|
||||
if (skeletonJoint == -1) {
|
||||
qCWarning(animation) << "animation contains joint =" << joints.at(i).name << " which is not in the skeleton, url =" << _url.c_str();
|
||||
}
|
||||
jointMap.push_back(skeletonJoint);
|
||||
}
|
||||
|
||||
|
@ -151,4 +153,10 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
}
|
||||
}
|
||||
}
|
||||
_poses.resize(skeletonJointCount);
|
||||
}
|
||||
|
||||
|
||||
const std::vector<AnimPose>& AnimClip::getPosesInternal() const {
|
||||
return _poses;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ public:
|
|||
friend class AnimClipTests;
|
||||
|
||||
AnimClip(const std::string& id, const std::string& url, float startFrame, float endFrame, float timeScale, bool loopFlag);
|
||||
virtual ~AnimClip();
|
||||
virtual ~AnimClip() override;
|
||||
|
||||
void setURL(const std::string& url);
|
||||
const std::string& getURL() const { return _url; }
|
||||
|
@ -36,12 +36,15 @@ public:
|
|||
void setLoopFlag(bool loopFlag);
|
||||
bool getLoopFlag() const { return _loopFlag; }
|
||||
|
||||
virtual const std::vector<AnimPose>& evaluate(float dt);
|
||||
virtual const std::vector<AnimPose>& evaluate(float dt) override;
|
||||
|
||||
protected:
|
||||
float accumulateTime(float frame, float dt) const;
|
||||
void copyFromNetworkAnim();
|
||||
|
||||
// for AnimDebugDraw rendering
|
||||
virtual const std::vector<AnimPose>& getPosesInternal() const override;
|
||||
|
||||
AnimationPointer _networkAnim;
|
||||
std::vector<AnimPose> _poses;
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@ class QJsonObject;
|
|||
|
||||
class AnimNode {
|
||||
public:
|
||||
friend class AnimDebugDraw;
|
||||
|
||||
enum Type {
|
||||
ClipType = 0,
|
||||
NumTypes
|
||||
|
@ -55,6 +57,9 @@ public:
|
|||
virtual const std::vector<AnimPose>& evaluate(float dt) = 0;
|
||||
|
||||
protected:
|
||||
// for AnimDebugDraw rendering
|
||||
virtual const std::vector<AnimPose>& getPosesInternal() const = 0;
|
||||
|
||||
Type _type;
|
||||
std::string _id;
|
||||
std::vector<AnimNode::Pointer> _children;
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include "AnimSkeleton.h"
|
||||
#include "glmHelpers.h"
|
||||
|
||||
const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f),
|
||||
glm::quat(),
|
||||
glm::vec3(0.0f));
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) {
|
||||
_joints = joints;
|
||||
|
||||
|
|
|
@ -17,6 +17,11 @@
|
|||
struct AnimPose {
|
||||
AnimPose() {}
|
||||
AnimPose(const glm::vec3& scaleIn, const glm::quat& rotIn, const glm::vec3& transIn) : scale(scaleIn), rot(rotIn), trans(transIn) {}
|
||||
static const AnimPose identity;
|
||||
|
||||
glm::vec3 operator*(const glm::vec3& pos) const {
|
||||
return trans + (rot * (scale * pos));
|
||||
}
|
||||
|
||||
glm::vec3 scale;
|
||||
glm::quat rot;
|
||||
|
|
|
@ -58,7 +58,7 @@ public:
|
|||
typedef render::Payload<AnimDebugDrawData> AnimDebugDrawPayload;
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return ItemKey::Builder::transparentShape(); }
|
||||
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return ItemKey::Builder::opaqueShape(); }
|
||||
template <> const Item::Bound payloadGetBound(const AnimDebugDrawData::Pointer& data) { return Item::Bound(); }
|
||||
template <> void payloadRender(const AnimDebugDrawData::Pointer& data, RenderArgs* args) {
|
||||
data->render(args);
|
||||
|
@ -143,14 +143,65 @@ AnimDebugDraw::~AnimDebugDraw() {
|
|||
}
|
||||
}
|
||||
|
||||
void AnimDebugDraw::addSkeleton(std::string key, AnimSkeleton::Pointer skeleton, const Transform& worldTransform) {
|
||||
_skeletons[key] = SkeletonInfo(skeleton, worldTransform);
|
||||
void AnimDebugDraw::addSkeleton(std::string key, AnimSkeleton::Pointer skeleton, const AnimPose& rootPose) {
|
||||
_skeletons[key] = SkeletonInfo(skeleton, rootPose);
|
||||
}
|
||||
|
||||
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::removeAnimNode(std::string key) {
|
||||
_animNodes.erase(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);
|
||||
|
||||
static void addWireframeSphereWithAxes(const AnimPose& rootPose, const AnimPose& pose, float radius, Vertex*& v) {
|
||||
|
||||
// x-axis
|
||||
v->pos = rootPose * pose.trans;
|
||||
v->rgba = red;
|
||||
v++;
|
||||
v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(radius * 2.0f, 0.0f, 0.0f));
|
||||
v->rgba = red;
|
||||
v++;
|
||||
|
||||
// y-axis
|
||||
v->pos = rootPose * pose.trans;
|
||||
v->rgba = green;
|
||||
v++;
|
||||
v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, radius * 2.0f, 0.0f));
|
||||
v->rgba = green;
|
||||
v++;
|
||||
|
||||
// z-axis
|
||||
v->pos = rootPose * pose.trans;
|
||||
v->rgba = blue;
|
||||
v++;
|
||||
v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, 0.0f, radius * 2.0f));
|
||||
v->rgba = blue;
|
||||
v++;
|
||||
}
|
||||
|
||||
static void addWireframeBoneAxis(const AnimPose& rootPose, const AnimPose& pose,
|
||||
const AnimPose& parentPose, float radius, Vertex*& v) {
|
||||
v->pos = rootPose * pose.trans;
|
||||
v->rgba = cyan;
|
||||
v++;
|
||||
v->pos = rootPose * parentPose.trans;
|
||||
v->rgba = cyan;
|
||||
v++;
|
||||
}
|
||||
|
||||
|
||||
void AnimDebugDraw::update() {
|
||||
|
||||
render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
|
@ -173,59 +224,53 @@ void AnimDebugDraw::update() {
|
|||
}
|
||||
}
|
||||
|
||||
const uint32_t red = toRGBA(255, 0, 0, 255);
|
||||
const uint32_t green = toRGBA(0, 255, 0, 255);
|
||||
const uint32_t blue = toRGBA(0, 0, 255, 255);
|
||||
const uint32_t gray = toRGBA(64, 64, 64, 255);
|
||||
for (auto&& iter : _animNodes) {
|
||||
AnimNode::Pointer& animNode = iter.second.first;
|
||||
auto poses = animNode->getPosesInternal();
|
||||
numVerts += poses.size() * 6;
|
||||
|
||||
/*
|
||||
for (int i = 0; i < poses.size(); i++) {
|
||||
// TODO: need skeleton!
|
||||
if (skeleton->getParentIndex(i) >= 0) {
|
||||
numVerts += 2;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
data._vertexBuffer->resize(sizeof(Vertex) * numVerts);
|
||||
Vertex* verts = (Vertex*)data._vertexBuffer->editData();
|
||||
Vertex* v = verts;
|
||||
for (auto&& iter : _skeletons) {
|
||||
AnimSkeleton::Pointer& skeleton = iter.second.first;
|
||||
Transform& xform = iter.second.second;
|
||||
AnimPose& rootPose = iter.second.second;
|
||||
for (int i = 0; i < skeleton->getNumJoints(); i++) {
|
||||
AnimPose pose = skeleton->getBindPose(i);
|
||||
|
||||
glm::vec3 base = xform.transform(pose.trans);
|
||||
|
||||
// x-axis
|
||||
v->pos = base;
|
||||
v->rgba = red;
|
||||
v++;
|
||||
v->pos = base + pose.rot * glm::vec3(1.0f, 0.0f, 0.0f);
|
||||
v->rgba = red;
|
||||
v++;
|
||||
|
||||
// y-axis
|
||||
v->pos = xform.transform(pose.trans);
|
||||
v->rgba = green;
|
||||
v++;
|
||||
v->pos = base + pose.rot * glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
v->rgba = green;
|
||||
v++;
|
||||
|
||||
// z-axis
|
||||
v->pos = base;
|
||||
v->rgba = blue;
|
||||
v++;
|
||||
v->pos = base + pose.rot * glm::vec3(0.0f, 0.0f, 1.0f);
|
||||
v->rgba = blue;
|
||||
v++;
|
||||
// draw axes
|
||||
const float radius = 1.0f;
|
||||
addWireframeSphereWithAxes(rootPose, pose, radius, v);
|
||||
|
||||
// line to parent.
|
||||
if (skeleton->getParentIndex(i) >= 0) {
|
||||
AnimPose parentPose = skeleton->getBindPose(skeleton->getParentIndex(i));
|
||||
v->pos = base;
|
||||
v->rgba = gray;
|
||||
v++;
|
||||
v->pos = xform.transform(parentPose.trans);
|
||||
v->rgba = gray;
|
||||
v++;
|
||||
addWireframeBoneAxis(rootPose, pose, parentPose, radius, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto&& iter : _animNodes) {
|
||||
AnimNode::Pointer& animNode = iter.second.first;
|
||||
AnimPose& rootPose = iter.second.second;
|
||||
auto poses = animNode->getPosesInternal();
|
||||
for (size_t i = 0; i < poses.size(); i++) {
|
||||
// draw axes
|
||||
const float radius = 1.0f;
|
||||
addWireframeSphereWithAxes(rootPose, poses[i], radius, v);
|
||||
}
|
||||
}
|
||||
|
||||
data._indexBuffer->resize(sizeof(uint16_t) * numVerts);
|
||||
uint16_t* indices = (uint16_t*)data._indexBuffer->editData();
|
||||
for (int i = 0; i < numVerts; i++) {
|
||||
|
|
|
@ -25,9 +25,12 @@ public:
|
|||
AnimDebugDraw();
|
||||
~AnimDebugDraw();
|
||||
|
||||
void addSkeleton(std::string key, AnimSkeleton::Pointer skeleton, const Transform& worldTransform);
|
||||
void addSkeleton(std::string key, AnimSkeleton::Pointer skeleton, const AnimPose& rootPose);
|
||||
void removeSkeleton(std::string key);
|
||||
|
||||
void addAnimNode(std::string key, AnimNode::Pointer skeleton, const AnimPose& rootPose);
|
||||
void removeAnimNode(std::string key);
|
||||
|
||||
void update();
|
||||
|
||||
protected:
|
||||
|
@ -37,9 +40,11 @@ protected:
|
|||
|
||||
static gpu::PipelinePointer _pipeline;
|
||||
|
||||
typedef std::pair<AnimSkeleton::Pointer, Transform> SkeletonInfo;
|
||||
typedef std::pair<AnimSkeleton::Pointer, AnimPose> SkeletonInfo;
|
||||
typedef std::pair<AnimNode::Pointer, AnimPose> AnimNodeInfo;
|
||||
|
||||
std::unordered_map<std::string, SkeletonInfo> _skeletons;
|
||||
std::unordered_map<std::string, AnimNodeInfo> _animNodes;
|
||||
};
|
||||
|
||||
#endif // hifi_AnimDebugDraw
|
||||
|
|
Loading…
Reference in a new issue