overte/libraries/animation/src/AnimBlendDirectional.cpp
Anthony J. Thibault aa848df227 warning fixes
2019-09-05 17:43:07 -07:00

148 lines
5.2 KiB
C++

//
// AnimBlendDirectional.cpp
//
// Created by Anthony J. Thibault on Augest 30 2019.
// Copyright (c) 2019 High Fidelity, Inc. All rights reserved.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "AnimBlendDirectional.h"
#include "GLMHelpers.h"
#include "AnimationLogging.h"
#include "AnimUtil.h"
AnimBlendDirectional::AnimBlendDirectional(const QString& id, glm::vec3 alpha, const QString& centerId,
const QString& upId, const QString& downId, const QString& leftId, const QString& rightId,
const QString& upLeftId, const QString& upRightId, const QString& downLeftId, const QString& downRightId) :
AnimNode(AnimNode::Type::BlendDirectional, id),
_alpha(alpha),
_centerId(centerId),
_upId(upId),
_downId(downId),
_leftId(leftId),
_rightId(rightId),
_upLeftId(upLeftId),
_upRightId(upRightId),
_downLeftId(downLeftId),
_downRightId(downRightId) {
}
AnimBlendDirectional::~AnimBlendDirectional() {
}
const AnimPoseVec& AnimBlendDirectional::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) {
// lookupRaw don't transform the vector.
_alpha = animVars.lookupRaw(_alphaVar, _alpha);
float parentDebugAlpha = context.getDebugAlpha(_id);
if (_children.size() == 9) {
// try to keep the order the same as quadrants, for _childIndices.
// +---+---+
// | 1 | 0 |
// +---+---+
// | 2 | 3 |
// +---+---+
std::array<int, 4> indices;
glm::vec2 alpha = _alpha;
if (_alpha.x > 0.0f) {
if (_alpha.y > 0.0f) {
// quadrant 0
indices = {{_childIndices[0][2], _childIndices[0][1], _childIndices[1][1], _childIndices[1][2]}};
} else {
// quadrant 3
indices = {{_childIndices[1][2], _childIndices[1][1], _childIndices[2][1], _childIndices[2][2]}};
// shift alpha up so both alpha.x and alpha.y are in the (0, 1) range.
alpha.y += 1.0f;
}
} else {
if (_alpha.y > 0.0f) {
// quadrant 1
indices = {{_childIndices[0][1], _childIndices[0][0], _childIndices[1][0], _childIndices[1][1]}};
// shift alpha right so both alpha.x and alpha.y are in the (0, 1) range.
alpha.x += 1.0f;
} else {
// quadrant 2
indices = {{_childIndices[1][1], _childIndices[1][0], _childIndices[2][0], _childIndices[2][1]}};
// shift alpha up and right so both alpha.x and alpha.y are in the (0, 1) range.
alpha.x += 1.0f;
alpha.y += 1.0f;
}
}
std::array<float, 4> alphas = {{
alpha.x * alpha.y,
(1.0f - alpha.x) * alpha.y,
(1.0f - alpha.x) * (1.0f - alpha.y),
alpha.x * (1.0f - alpha.y)
}};
// evaluate children
std::array<AnimPoseVec, 4> poseVecs;
for (int i = 0; i < 4; i++) {
poseVecs[i] = _children[indices[i]]->evaluate(animVars, context, dt, triggersOut);
}
// blend children
size_t minSize = INT_MAX;
for (int i = 0; i < 4; i++) {
if (poseVecs[i].size() < minSize) {
minSize = poseVecs[i].size();
}
}
_poses.resize(minSize);
blend4(minSize, &poseVecs[0][0], &poseVecs[1][0], &poseVecs[2][0], &poseVecs[3][0], &alphas[0], &_poses[0]);
// animation stack debug stats
for (int i = 0; i < 9; i++) {
context.setDebugAlpha(_children[i]->getID(), 0.0f, _children[i]->getType());
}
for (int i = 0; i < 4; i++) {
context.setDebugAlpha(_children[indices[i]]->getID(), alphas[i] * parentDebugAlpha, _children[indices[i]]->getType());
}
} else {
for (auto&& pose : _poses) {
pose = AnimPose::identity;
}
}
return _poses;
}
// for AnimDebugDraw rendering
const AnimPoseVec& AnimBlendDirectional::getPosesInternal() const {
return _poses;
}
bool AnimBlendDirectional::lookupChildIds() {
_childIndices[0][0] = findChildIndexByName(_upLeftId);
_childIndices[0][1] = findChildIndexByName(_upId);
_childIndices[0][2] = findChildIndexByName(_upRightId);
_childIndices[1][0] = findChildIndexByName(_leftId);
_childIndices[1][1] = findChildIndexByName(_centerId);
_childIndices[1][2] = findChildIndexByName(_rightId);
_childIndices[2][0] = findChildIndexByName(_downLeftId);
_childIndices[2][1] = findChildIndexByName(_downId);
_childIndices[2][2] = findChildIndexByName(_downRightId);
// manditory children
// TODO: currently all are manditory.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (_childIndices[i][j] == -1) {
qDebug(animation) << "Error in AnimBlendDirectional::lookupChildIds() could not find child[" << i << "," << j << "]";
return false;
}
}
}
return true;
}