68 void AnimTrack::eval(
float time, std::unordered_map<std::string, AnimTransform>& transforms)
const
70 if (_curves.empty()) {
74 const float t = std::clamp(time, 0.0f, _duration);
76 for (
const auto& curve : _curves) {
77 if (curve.inputIndex >= _inputs.size() || curve.outputIndex >= _outputs.size()) {
81 const auto& input = _inputs[curve.inputIndex];
82 const auto& output = _outputs[curve.outputIndex];
83 if (input.data.empty() || output.data.empty()) {
87 const size_t keyCount = input.count();
96 if (t <= input.data[0]) {
99 }
else if (t >= input.data[keyCount - 1]) {
103 size_t lo = 0, hi = keyCount - 1;
104 while (lo + 1 < hi) {
105 const size_t mid = (lo + hi) / 2;
106 if (input.data[mid] <= t) {
113 const float dt = input.data[i0 + 1] - input.data[i0];
114 alpha = (dt > 0.0f) ? (t - input.data[i0]) / dt : 0.0f;
117 auto& transform = transforms[curve.nodeName];
118 const int comp = output.components;
122 const float* v = &output.data[i0 *
static_cast<size_t>(comp)];
124 if (curve.propertyPath ==
"localPosition") {
125 transform.position =
Vector3(v[0], v[1], v[2]);
126 transform.hasPosition =
true;
127 }
else if (curve.propertyPath ==
"localRotation") {
128 transform.rotation =
Quaternion(v[0], v[1], v[2], v[3]);
129 transform.hasRotation =
true;
130 }
else if (curve.propertyPath ==
"localScale") {
131 transform.scale =
Vector3(v[0], v[1], v[2]);
132 transform.hasScale =
true;
136 const size_t i1 = std::min(i0 + 1, keyCount - 1);
137 const float* v0 = &output.data[i0 *
static_cast<size_t>(comp)];
138 const float* v1 = &output.data[i1 *
static_cast<size_t>(comp)];
140 if (curve.propertyPath ==
"localPosition") {
141 transform.position = lerpVec3(
143 Vector3(v1[0], v1[1], v1[2]), alpha);
144 transform.hasPosition =
true;
145 }
else if (curve.propertyPath ==
"localRotation") {
146 transform.rotation = slerpQuat(
148 Quaternion(v1[0], v1[1], v1[2], v1[3]), alpha);
149 transform.hasRotation =
true;
150 }
else if (curve.propertyPath ==
"localScale") {
151 transform.scale = lerpVec3(
153 Vector3(v1[0], v1[1], v1[2]), alpha);
154 transform.hasScale =
true;
160 const size_t i1 = std::min(i0 + 1, keyCount - 1);
161 const float timeDelta = input.data[std::min(i0 + 1, keyCount - 1)] - input.data[i0];
162 const int stride3 = comp * 3;
163 const float* g0 = &output.data[i0 *
static_cast<size_t>(stride3)];
164 const float* g1 = &output.data[i1 *
static_cast<size_t>(stride3)];
165 const float* val0 = g0 + comp;
166 const float* outTan0 = g0 + comp * 2;
167 const float* val1 = g1 + comp;
168 const float* inTan1 = g1;
172 for (
int c = 0; c < comp && c < 4; ++c) {
173 result[c] = hermite(alpha, val0[c], outTan0[c] * timeDelta, val1[c], inTan1[c] * timeDelta);
176 if (curve.propertyPath ==
"localPosition") {
177 transform.position =
Vector3(result[0], result[1], result[2]);
178 transform.hasPosition =
true;
179 }
else if (curve.propertyPath ==
"localRotation") {
181 transform.hasRotation =
true;
182 }
else if (curve.propertyPath ==
"localScale") {
183 transform.scale =
Vector3(result[0], result[1], result[2]);
184 transform.hasScale =
true;