mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-08 04:47:44 +02:00
Added AnimVariantMap argument to evaluate.
This commit is contained in:
parent
62f86e6a46
commit
496c706bba
11 changed files with 41 additions and 20 deletions
|
@ -170,7 +170,7 @@ void MyAvatar::update(float deltaTime) {
|
||||||
blend->setAlpha(0.5f * sin(t) + 0.5f);
|
blend->setAlpha(0.5f * sin(t) + 0.5f);
|
||||||
*/
|
*/
|
||||||
t += deltaTime;
|
t += deltaTime;
|
||||||
_animNode->evaluate(deltaTime);
|
_animNode->evaluate(_animVars, deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_referential) {
|
if (_referential) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <Rig.h>
|
#include <Rig.h>
|
||||||
|
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
|
#include "AnimVariant.h"
|
||||||
|
|
||||||
class ModelItemID;
|
class ModelItemID;
|
||||||
class AnimNode;
|
class AnimNode;
|
||||||
|
@ -315,6 +316,7 @@ private:
|
||||||
bool _prevShouldDrawHead;
|
bool _prevShouldDrawHead;
|
||||||
|
|
||||||
std::shared_ptr<AnimNode> _animNode;
|
std::shared_ptr<AnimNode> _animNode;
|
||||||
|
AnimVariantMap _animVars;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_MyAvatar_h
|
#endif // hifi_MyAvatar_h
|
||||||
|
|
|
@ -22,22 +22,24 @@ AnimBlendLinear::~AnimBlendLinear() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<AnimPose>& AnimBlendLinear::evaluate(float dt) {
|
const std::vector<AnimPose>& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, float dt) {
|
||||||
|
|
||||||
|
// TODO: update _alpha from animVars
|
||||||
|
|
||||||
if (_children.size() == 0) {
|
if (_children.size() == 0) {
|
||||||
for (auto&& pose : _poses) {
|
for (auto&& pose : _poses) {
|
||||||
pose = AnimPose::identity;
|
pose = AnimPose::identity;
|
||||||
}
|
}
|
||||||
} else if (_children.size() == 1) {
|
} else if (_children.size() == 1) {
|
||||||
_poses = _children[0]->evaluate(dt);
|
_poses = _children[0]->evaluate(animVars, dt);
|
||||||
} else {
|
} else {
|
||||||
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
|
float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1));
|
||||||
size_t prevPoseIndex = glm::floor(clampedAlpha);
|
size_t prevPoseIndex = glm::floor(clampedAlpha);
|
||||||
size_t nextPoseIndex = glm::ceil(clampedAlpha);
|
size_t nextPoseIndex = glm::ceil(clampedAlpha);
|
||||||
float alpha = glm::fract(clampedAlpha);
|
float alpha = glm::fract(clampedAlpha);
|
||||||
if (prevPoseIndex != nextPoseIndex) {
|
if (prevPoseIndex != nextPoseIndex) {
|
||||||
auto prevPoses = _children[prevPoseIndex]->evaluate(dt);
|
auto prevPoses = _children[prevPoseIndex]->evaluate(animVars, dt);
|
||||||
auto nextPoses = _children[nextPoseIndex]->evaluate(dt);
|
auto nextPoses = _children[nextPoseIndex]->evaluate(animVars, dt);
|
||||||
|
|
||||||
if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) {
|
if (prevPoses.size() > 0 && prevPoses.size() == nextPoses.size()) {
|
||||||
_poses.resize(prevPoses.size());
|
_poses.resize(prevPoses.size());
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
AnimBlendLinear(const std::string& id, float alpha);
|
AnimBlendLinear(const std::string& id, float alpha);
|
||||||
virtual ~AnimBlendLinear() override;
|
virtual ~AnimBlendLinear() override;
|
||||||
|
|
||||||
virtual const std::vector<AnimPose>& evaluate(float dt) override;
|
virtual const std::vector<AnimPose>& evaluate(const AnimVariantMap& animVars, float dt) override;
|
||||||
|
|
||||||
void setAlpha(float alpha) { _alpha = alpha; }
|
void setAlpha(float alpha) { _alpha = alpha; }
|
||||||
float getAlpha() const { return _alpha; }
|
float getAlpha() const { return _alpha; }
|
||||||
|
|
|
@ -45,7 +45,10 @@ void AnimClip::setLoopFlag(bool loopFlag) {
|
||||||
_loopFlag = loopFlag;
|
_loopFlag = loopFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<AnimPose>& AnimClip::evaluate(float dt) {
|
const std::vector<AnimPose>& AnimClip::evaluate(const AnimVariantMap& animVars, float dt) {
|
||||||
|
|
||||||
|
// TODO: update _frame, _startFrame, _endFrame, _timeScale, _loopFlag from animVars.
|
||||||
|
|
||||||
_frame = accumulateTime(_frame, dt);
|
_frame = accumulateTime(_frame, dt);
|
||||||
|
|
||||||
if (_networkAnim && _networkAnim->isLoaded() && _skeleton) {
|
if (_networkAnim && _networkAnim->isLoaded() && _skeleton) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
void setLoopFlag(bool loopFlag);
|
void setLoopFlag(bool loopFlag);
|
||||||
bool getLoopFlag() const { return _loopFlag; }
|
bool getLoopFlag() const { return _loopFlag; }
|
||||||
|
|
||||||
virtual const std::vector<AnimPose>& evaluate(float dt) override;
|
virtual const std::vector<AnimPose>& evaluate(const AnimVariantMap& animVars, float dt) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setCurrentFrameInternal(float frame) override;
|
virtual void setCurrentFrameInternal(float frame) override;
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
#include "AnimSkeleton.h"
|
#include "AnimSkeleton.h"
|
||||||
|
#include "AnimVariant.h"
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
|
|
||||||
|
@ -78,9 +79,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::vector<AnimPose>& evaluate(float dt) = 0;
|
virtual const std::vector<AnimPose>& evaluate(const AnimVariantMap& animVars, float dt) = 0;
|
||||||
virtual const std::vector<AnimPose>& overlay(float dt, const std::vector<AnimPose>& underPoses) {
|
virtual const std::vector<AnimPose>& overlay(const AnimVariantMap& animVars, float dt, const std::vector<AnimPose>& underPoses) {
|
||||||
return evaluate(dt);
|
return evaluate(animVars, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -37,17 +37,18 @@ void AnimOverlay::setBoneSet(BoneSet boneSet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<AnimPose>& AnimOverlay::evaluate(float dt) {
|
const std::vector<AnimPose>& AnimOverlay::evaluate(const AnimVariantMap& animVars, float dt) {
|
||||||
|
|
||||||
if (_children.size() >= 2) {
|
if (_children.size() >= 2) {
|
||||||
auto underPoses = _children[1]->evaluate(dt);
|
auto underPoses = _children[1]->evaluate(animVars, dt);
|
||||||
auto overPoses = _children[0]->overlay(dt, underPoses);
|
auto overPoses = _children[0]->overlay(animVars, dt, underPoses);
|
||||||
|
|
||||||
if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
|
if (underPoses.size() > 0 && underPoses.size() == overPoses.size()) {
|
||||||
_poses.resize(underPoses.size());
|
_poses.resize(underPoses.size());
|
||||||
assert(_boneSetVec.size() == _poses.size());
|
assert(_boneSetVec.size() == _poses.size());
|
||||||
|
|
||||||
for (size_t i = 0; i < _poses.size(); i++) {
|
for (size_t i = 0; i < _poses.size(); i++) {
|
||||||
float alpha = _boneSetVec[i]; // TODO: PULL from boneSet
|
float alpha = _boneSetVec[i];
|
||||||
blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]);
|
blend(1, &underPoses[i], &overPoses[i], alpha, &_poses[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
void setBoneSet(BoneSet boneSet);
|
void setBoneSet(BoneSet boneSet);
|
||||||
BoneSet getBoneSet() const { return _boneSet; }
|
BoneSet getBoneSet() const { return _boneSet; }
|
||||||
|
|
||||||
virtual const std::vector<AnimPose>& evaluate(float dt) override;
|
virtual const std::vector<AnimPose>& evaluate(const AnimVariantMap& animVars, float dt) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// for AnimDebugDraw rendering
|
// for AnimDebugDraw rendering
|
||||||
|
|
|
@ -18,6 +18,7 @@ class AnimVariant {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
BoolType = 0,
|
BoolType = 0,
|
||||||
|
IntType,
|
||||||
FloatType,
|
FloatType,
|
||||||
Vec3Type,
|
Vec3Type,
|
||||||
QuatType,
|
QuatType,
|
||||||
|
@ -27,24 +28,28 @@ public:
|
||||||
|
|
||||||
AnimVariant() : _type(BoolType) { memset(&_val, 0, sizeof(_val)); }
|
AnimVariant() : _type(BoolType) { memset(&_val, 0, sizeof(_val)); }
|
||||||
AnimVariant(bool value) : _type(BoolType) { _val.boolVal = value; }
|
AnimVariant(bool value) : _type(BoolType) { _val.boolVal = value; }
|
||||||
|
AnimVariant(int value) : _type(IntType) { _val.intVal = value; }
|
||||||
AnimVariant(float value) : _type(FloatType) { _val.floats[0] = value; }
|
AnimVariant(float value) : _type(FloatType) { _val.floats[0] = value; }
|
||||||
AnimVariant(const glm::vec3& value) : _type(Vec3Type) { *reinterpret_cast<glm::vec3*>(&_val) = value; }
|
AnimVariant(const glm::vec3& value) : _type(Vec3Type) { *reinterpret_cast<glm::vec3*>(&_val) = value; }
|
||||||
AnimVariant(const glm::quat& value) : _type(QuatType) { *reinterpret_cast<glm::quat*>(&_val) = value; }
|
AnimVariant(const glm::quat& value) : _type(QuatType) { *reinterpret_cast<glm::quat*>(&_val) = value; }
|
||||||
AnimVariant(const glm::mat4& value) : _type(Mat4Type) { *reinterpret_cast<glm::mat4*>(&_val) = value; }
|
AnimVariant(const glm::mat4& value) : _type(Mat4Type) { *reinterpret_cast<glm::mat4*>(&_val) = value; }
|
||||||
|
|
||||||
bool isBool() const { return _type == BoolType; }
|
bool isBool() const { return _type == BoolType; }
|
||||||
|
bool isInt() const { return _type == IntType; }
|
||||||
bool isFloat() const { return _type == FloatType; }
|
bool isFloat() const { return _type == FloatType; }
|
||||||
bool isVec3() const { return _type == Vec3Type; }
|
bool isVec3() const { return _type == Vec3Type; }
|
||||||
bool isQuat() const { return _type == QuatType; }
|
bool isQuat() const { return _type == QuatType; }
|
||||||
bool isMat4() const { return _type == Mat4Type; }
|
bool isMat4() const { return _type == Mat4Type; }
|
||||||
|
|
||||||
void setBool(bool value) { assert(_type == BoolType); _val.boolVal = value; }
|
void setBool(bool value) { assert(_type == BoolType); _val.boolVal = value; }
|
||||||
|
void setInt(int value) { assert(_type == IntType); _val.intVal = value; }
|
||||||
void setFloat(float value) { assert(_type == FloatType); _val.floats[0] = value; }
|
void setFloat(float value) { assert(_type == FloatType); _val.floats[0] = value; }
|
||||||
void setVec3(const glm::vec3& value) { assert(_type == Vec3Type); *reinterpret_cast<glm::vec3*>(&_val) = value; }
|
void setVec3(const glm::vec3& value) { assert(_type == Vec3Type); *reinterpret_cast<glm::vec3*>(&_val) = value; }
|
||||||
void setQuat(const glm::quat& value) { assert(_type == QuatType); *reinterpret_cast<glm::quat*>(&_val) = value; }
|
void setQuat(const glm::quat& value) { assert(_type == QuatType); *reinterpret_cast<glm::quat*>(&_val) = value; }
|
||||||
void setMat4(const glm::mat4& value) { assert(_type == Mat4Type); *reinterpret_cast<glm::mat4*>(&_val) = value; }
|
void setMat4(const glm::mat4& value) { assert(_type == Mat4Type); *reinterpret_cast<glm::mat4*>(&_val) = value; }
|
||||||
|
|
||||||
bool getBool() { assert(_type == BoolType); return _val.boolVal; }
|
bool getBool() { assert(_type == BoolType); return _val.boolVal; }
|
||||||
|
int getInt() { assert(_type == IntType); return _val.intVal; }
|
||||||
float getFloat() { assert(_type == FloatType); return _val.floats[0]; }
|
float getFloat() { assert(_type == FloatType); return _val.floats[0]; }
|
||||||
const glm::vec3& getVec3() { assert(_type == Vec3Type); return *reinterpret_cast<glm::vec3*>(&_val); }
|
const glm::vec3& getVec3() { assert(_type == Vec3Type); return *reinterpret_cast<glm::vec3*>(&_val); }
|
||||||
const glm::quat& getQuat() { assert(_type == QuatType); return *reinterpret_cast<glm::quat*>(&_val); }
|
const glm::quat& getQuat() { assert(_type == QuatType); return *reinterpret_cast<glm::quat*>(&_val); }
|
||||||
|
@ -54,10 +59,11 @@ protected:
|
||||||
Type _type;
|
Type _type;
|
||||||
union {
|
union {
|
||||||
bool boolVal;
|
bool boolVal;
|
||||||
|
int intVal;
|
||||||
float floats[16];
|
float floats[16];
|
||||||
} _val;
|
} _val;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, AnimVariant> AnimVarantMap;
|
typedef std::map<std::string, AnimVariant> AnimVariantMap;
|
||||||
|
|
||||||
#endif // hifi_AnimVariant_h
|
#endif // hifi_AnimVariant_h
|
||||||
|
|
|
@ -80,18 +80,20 @@ void AnimTests::testEvaulate() {
|
||||||
float timeScale = 1.0f;
|
float timeScale = 1.0f;
|
||||||
float loopFlag = true;
|
float loopFlag = true;
|
||||||
|
|
||||||
|
auto vars = AnimVariantMap();
|
||||||
|
|
||||||
AnimClip clip(id, url, startFrame, endFrame, timeScale, loopFlag);
|
AnimClip clip(id, url, startFrame, endFrame, timeScale, loopFlag);
|
||||||
|
|
||||||
clip.evaluate(framesToSec(10.0f));
|
clip.evaluate(vars, framesToSec(10.0f));
|
||||||
QCOMPARE_WITH_ABS_ERROR(clip._frame, 12.0f, EPSILON);
|
QCOMPARE_WITH_ABS_ERROR(clip._frame, 12.0f, EPSILON);
|
||||||
|
|
||||||
// does it loop?
|
// does it loop?
|
||||||
clip.evaluate(framesToSec(11.0f));
|
clip.evaluate(vars, framesToSec(11.0f));
|
||||||
QCOMPARE_WITH_ABS_ERROR(clip._frame, 3.0f, EPSILON);
|
QCOMPARE_WITH_ABS_ERROR(clip._frame, 3.0f, EPSILON);
|
||||||
|
|
||||||
// does it pause at end?
|
// does it pause at end?
|
||||||
clip.setLoopFlag(false);
|
clip.setLoopFlag(false);
|
||||||
clip.evaluate(framesToSec(20.0f));
|
clip.evaluate(vars, framesToSec(20.0f));
|
||||||
QCOMPARE_WITH_ABS_ERROR(clip._frame, 22.0f, EPSILON);
|
QCOMPARE_WITH_ABS_ERROR(clip._frame, 22.0f, EPSILON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +157,7 @@ void AnimTests::testLoader() {
|
||||||
void AnimTests::testVariant() {
|
void AnimTests::testVariant() {
|
||||||
auto defaultVar = AnimVariant();
|
auto defaultVar = AnimVariant();
|
||||||
auto boolVar = AnimVariant(true);
|
auto boolVar = AnimVariant(true);
|
||||||
|
auto intVar = AnimVariant(1);
|
||||||
auto floatVar = AnimVariant(1.0f);
|
auto floatVar = AnimVariant(1.0f);
|
||||||
auto vec3Var = AnimVariant(glm::vec3(1.0f, 2.0f, 3.0f));
|
auto vec3Var = AnimVariant(glm::vec3(1.0f, 2.0f, 3.0f));
|
||||||
auto quatVar = AnimVariant(glm::quat(1.0f, 2.0f, 3.0f, 4.0f));
|
auto quatVar = AnimVariant(glm::quat(1.0f, 2.0f, 3.0f, 4.0f));
|
||||||
|
@ -168,6 +171,9 @@ void AnimTests::testVariant() {
|
||||||
QVERIFY(boolVar.isBool());
|
QVERIFY(boolVar.isBool());
|
||||||
QVERIFY(boolVar.getBool() == true);
|
QVERIFY(boolVar.getBool() == true);
|
||||||
|
|
||||||
|
QVERIFY(intVar.isInt());
|
||||||
|
QVERIFY(intVar.getInt() == 1);
|
||||||
|
|
||||||
QVERIFY(floatVar.isFloat());
|
QVERIFY(floatVar.isFloat());
|
||||||
QVERIFY(floatVar.getFloat() == 1.0f);
|
QVERIFY(floatVar.getFloat() == 1.0f);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue