22 _clips.push_back(clip);
27 if (index >= _clips.size()) {
30 _clips.erase(_clips.begin() +
static_cast<std::ptrdiff_t
>(index));
40 return a + (b - a) * alpha;
43 Quaternion AnimEvaluator::slerpQuat(
const Quaternion& a,
const Quaternion& b,
const float alpha)
55 float dot = ax * bx + ay * by + az * bz + aw * bw;
64 constexpr float epsilon = 1e-6f;
65 float scale0 = 1.0f - alpha;
68 if ((1.0f - dot) > epsilon) {
69 const float theta = std::acos(std::clamp(dot, -1.0f, 1.0f));
70 const float invSinTheta = 1.0f / std::sin(theta);
71 scale0 = std::sin((1.0f - alpha) * theta) * invSinTheta;
72 scale1 = std::sin(alpha * theta) * invSinTheta;
76 scale0 * ax + scale1 * bx,
77 scale0 * ay + scale1 * by,
78 scale0 * az + scale1 * bz,
79 scale0 * aw + scale1 * bw).normalized();
84 if (!_binder || _clips.empty()) {
88 for (
const auto& clip : _clips) {
98 _clips[0]->eval(_tmpA);
101 float blendWeight = 1.0f;
102 if (_clips.size() > 1 && _clips[1]) {
103 _clips[1]->eval(_tmpB);
104 blendWeight = std::clamp(_clips[1]->blendWeight(), 0.0f, 1.0f);
107 std::set<std::string> allNodes;
108 for (
const auto& [name, _] : _tmpA) {
110 allNodes.insert(name);
112 for (
const auto& [name, _] : _tmpB) {
114 allNodes.insert(name);
117 for (
const auto& nodeName : allNodes) {
118 GraphNode* node = _binder->resolve(nodeName);
123 const auto aIt = _tmpA.
find(nodeName);
124 const auto bIt = _tmpB.find(nodeName);
126 if (bIt == _tmpB.end()) {
127 const auto& a = aIt->second;
140 if (aIt == _tmpA.end()) {
141 const auto& b = bIt->second;
154 const auto& a = aIt->second;
155 const auto& b = bIt->second;
157 if (a.hasPosition || b.hasPosition) {
160 if (a.hasRotation || b.hasRotation) {
163 if (a.hasScale || b.hasScale) {
164 node->
setLocalScale(lerpVec3(a.scale, b.scale, blendWeight));
AnimEvaluator(std::unique_ptr< AnimBinder > binder)
void addClip(const std::shared_ptr< AnimClip > &clip)
void removeClip(size_t index)
Hierarchical scene graph node with local/world transforms and parent-child relationships.
void setLocalPosition(float x, float y, float z)
std::vector< GraphNode * > find(const std::function< bool(GraphNode *)> &predicate)
Find all descendants (and self) matching a predicate.
void setLocalRotation(const Quaternion &rotation)
void setLocalScale(float x, float y, float z)
3D vector for positions, directions, and normals with multi-backend SIMD acceleration.