mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 20:36:38 +02:00
148 lines
5.2 KiB
C++
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;
|
|
}
|