AddAbsolute now works! added blendType to AnimClip

This commit is contained in:
Anthony J. Thibault 2019-08-28 18:19:35 -07:00
parent adda7774d3
commit 16a20a5ead
5 changed files with 31 additions and 23 deletions

View file

@ -93,16 +93,14 @@ void AnimBlendLinear::evaluateAndBlendChildren(const AnimVariantMap& animVars, c
AnimPoseVec relOffsetPoses;
relOffsetPoses.reserve(nextPoses.size());
for (size_t i = 0; i < nextPoses.size(); ++i) {
// copy translation and scale from nextPoses
AnimPose pose = nextPoses[i];
// AJT: HACK nuke trans
pose.trans() = glm::vec3(0.0f);
int parentIndex = _skeleton->getParentIndex(i);
int parentIndex = _skeleton->getParentIndex((int)i);
if (parentIndex >= 0) {
// but transform nextPoses rot into absPrev parent frame.
pose.rot() = glm::inverse(absPrev[parentIndex].rot()) * nextPoses[i].rot();
pose.rot() = glm::inverse(absPrev[parentIndex].rot()) * pose.rot() * absPrev[parentIndex].rot();
}
relOffsetPoses.push_back(pose);

View file

@ -83,9 +83,9 @@ void bakeAbsoluteDeltaAnim(std::vector<AnimPoseVec>& anim, const AnimPoseVec& ba
animPoses[i] = animPoses[i] * invBasePoses[i];
// but transform the rotation delta into the absolute frame.
int parentIndex = skeleton->getParentIndex(i);
int parentIndex = skeleton->getParentIndex((int)i);
if (parentIndex >= 0) {
animPoses[i].rot() = absBasePoses[parentIndex].rot() * animPoses[i].rot();
animPoses[i].rot() = absBasePoses[parentIndex].rot() * animPoses[i].rot() * glm::inverse(absBasePoses[parentIndex].rot());
}
}
}
@ -226,7 +226,7 @@ static std::vector<AnimPoseVec> copyAndRetargetFromNetworkAnim(AnimationPointer
}
AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag,
bool relativeFlag, const QString& baseURL, float baseFrame) :
AnimBlendType blendType, const QString& baseURL, float baseFrame) :
AnimNode(AnimNode::Type::Clip, id),
_startFrame(startFrame),
_endFrame(endFrame),
@ -234,12 +234,12 @@ AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, floa
_loopFlag(loopFlag),
_mirrorFlag(mirrorFlag),
_frame(startFrame),
_relativeFlag(relativeFlag),
_blendType(blendType),
_baseFrame(baseFrame)
{
loadURL(url);
if (relativeFlag) {
if (blendType != AnimBlendType_Normal) {
auto animCache = DependencyManager::get<AnimationCache>();
_baseNetworkAnim = animCache->getAnimation(baseURL);
_baseURL = baseURL;
@ -263,7 +263,7 @@ const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, const Anim
_frame = ::accumulateTime(_startFrame, _endFrame, _timeScale, frame, dt, _loopFlag, _id, triggersOut);
// poll network anim to see if it's finished loading yet.
if (!_relativeFlag) {
if (_blendType == AnimBlendType_Normal) {
if (_networkAnim && _networkAnim->isLoaded() && _skeleton) {
// loading is complete, copy & retarget animation.
_anim = copyAndRetargetFromNetworkAnim(_networkAnim, _skeleton);
@ -277,6 +277,7 @@ const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, const Anim
_poses.resize(_skeleton->getNumJoints());
}
} else {
// an additive blend type
if (_networkAnim && _networkAnim->isLoaded() && _baseNetworkAnim && _baseNetworkAnim->isLoaded() && _skeleton) {
// loading is complete, copy & retarget animation.
_anim = copyAndRetargetFromNetworkAnim(_networkAnim, _skeleton);
@ -293,13 +294,12 @@ const AnimPoseVec& AnimClip::evaluate(const AnimVariantMap& animVars, const Anim
// copy & retarget baseAnim!
auto baseAnim = copyAndRetargetFromNetworkAnim(_baseNetworkAnim, _skeleton);
//#define BLEND_ADD_ABSOLUTE
#ifdef BLEND_ADD_ABSOLUTE
bakeAbsoluteDeltaAnim(_anim, baseAnim[(int)_baseFrame], _skeleton);
#else
bakeRelativeDeltaAnim(_anim, baseAnim[(int)_baseFrame]);
#endif
if (_blendType == AnimBlendType_AddAbsolute) {
bakeAbsoluteDeltaAnim(_anim, baseAnim[(int)_baseFrame], _skeleton);
} else {
// AnimBlendType_AddRelative
bakeRelativeDeltaAnim(_anim, baseAnim[(int)_baseFrame]);
}
}
}

View file

@ -26,7 +26,7 @@ public:
friend class AnimTests;
AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag,
bool relativeFlag, const QString& baseURL, float baseFrame);
AnimBlendType blendType, const QString& baseURL, float baseFrame);
virtual ~AnimClip() override;
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override;
@ -80,7 +80,7 @@ protected:
bool _loopFlag;
bool _mirrorFlag;
float _frame;
bool _relativeFlag;
AnimBlendType _blendType;
QString _baseURL;
float _baseFrame;

View file

@ -387,7 +387,7 @@ static AnimNode::Pointer loadClipNode(const QJsonObject& jsonObj, const QString&
READ_FLOAT(timeScale, jsonObj, id, jsonUrl, nullptr);
READ_BOOL(loopFlag, jsonObj, id, jsonUrl, nullptr);
READ_OPTIONAL_BOOL(mirrorFlag, jsonObj, false);
READ_OPTIONAL_BOOL(relativeFlag, jsonObj, false);
READ_OPTIONAL_STRING(blendType, jsonObj);
READ_OPTIONAL_STRING(baseURL, jsonObj);
READ_OPTIONAL_FLOAT(baseFrame, jsonObj, 0.0f);
@ -402,7 +402,17 @@ static AnimNode::Pointer loadClipNode(const QJsonObject& jsonObj, const QString&
auto tempUrl = QUrl(url);
tempUrl = jsonUrl.resolved(tempUrl);
auto node = std::make_shared<AnimClip>(id, tempUrl.toString(), startFrame, endFrame, timeScale, loopFlag, mirrorFlag, relativeFlag, baseURL, baseFrame);
// AJT:
AnimBlendType blendTypeEnum = AnimBlendType_Normal; // default value
if (!blendType.isEmpty()) {
blendTypeEnum = stringToAnimBlendType(blendType);
if (blendTypeEnum == AnimBlendType_NumTypes) {
qCCritical(animation) << "AnimNodeLoader, bad blendType on clip, id = " << id;
return nullptr;
}
}
auto node = std::make_shared<AnimClip>(id, tempUrl.toString(), startFrame, endFrame, timeScale, loopFlag, mirrorFlag, blendTypeEnum, baseURL, baseFrame);
if (!startFrameVar.isEmpty()) {
node->setStartFrameVar(startFrameVar);

View file

@ -564,7 +564,7 @@ void Rig::overrideRoleAnimation(const QString& role, const QString& url, float f
_origRoleAnimations[role] = node;
const float REFERENCE_FRAMES_PER_SECOND = 30.0f;
float timeScale = fps / REFERENCE_FRAMES_PER_SECOND;
auto clipNode = std::make_shared<AnimClip>(role, url, firstFrame, lastFrame, timeScale, loop, false, false, "", 0.0f);
auto clipNode = std::make_shared<AnimClip>(role, url, firstFrame, lastFrame, timeScale, loop, false, AnimBlendType_Normal, "", 0.0f);
_roleAnimStates[role] = { role, url, fps, loop, firstFrame, lastFrame };
AnimNode::Pointer parent = node->getParent();
parent->replaceChild(node, clipNode);