Merge pull request #115690 from nikitalita/gltf-fix-value-track-interpolation

GLTF: fix value track interpolation
This commit is contained in:
Thaddeus Crews 2026-02-24 09:29:28 -06:00
commit 31817ef2ff
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC

View file

@ -5949,6 +5949,16 @@ GLTFNodeIndex GLTFDocument::_node_and_or_bone_to_gltf_node_index(Ref<GLTFState>
ERR_FAIL_V_MSG(-1, vformat("glTF: A node was animated, but it wasn't found in the GLTFState. Ensure that all nodes referenced by the AnimationPlayer are in the scene you are exporting."));
}
template <typename T>
static inline Error _try_interpolate_value_track(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index, double p_time, T &r_value) {
Variant val = p_godot_animation->value_track_interpolate(p_godot_anim_track_index, p_time, false);
if (val.get_type() != GetTypeInfo<T>::VARIANT_TYPE) {
return ERR_INVALID_PARAMETER;
}
r_value = val;
return OK;
}
bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAnimation::NodeTrack &p_gltf_node_track, const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index, Vector<double> &p_times) {
GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::godot_to_gltf_interpolation(p_godot_animation, p_godot_anim_track_index);
const Animation::TrackType track_type = p_godot_animation->track_get_type(p_godot_anim_track_index);
@ -6088,7 +6098,7 @@ bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAni
bool last = false;
while (true) {
Vector3 position;
Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position);
Error err = _try_interpolate_value_track(p_godot_animation, p_godot_anim_track_index, time, position);
if (err == OK) {
p_gltf_node_track.position_track.values.push_back(position);
p_gltf_node_track.position_track.times.push_back(time);
@ -6124,7 +6134,17 @@ bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAni
bool last = false;
while (true) {
Quaternion rotation;
Error err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation);
Error err;
if (node_prop == "quaternion") {
err = _try_interpolate_value_track(p_godot_animation, p_godot_anim_track_index, time, rotation);
} else {
Vector3 rotation_euler;
err = _try_interpolate_value_track(p_godot_animation, p_godot_anim_track_index, time, rotation_euler);
if (node_prop == "rotation_degrees") {
rotation_euler *= Math::TAU / 360.0;
}
rotation = Quaternion::from_euler(rotation_euler);
}
if (err == OK) {
p_gltf_node_track.rotation_track.values.push_back(rotation);
p_gltf_node_track.rotation_track.times.push_back(time);
@ -6170,7 +6190,7 @@ bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAni
bool last = false;
while (true) {
Vector3 scale;
Error err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale);
Error err = _try_interpolate_value_track(p_godot_animation, p_godot_anim_track_index, time, scale);
if (err == OK) {
p_gltf_node_track.scale_track.values.push_back(scale);
p_gltf_node_track.scale_track.times.push_back(time);
@ -6215,17 +6235,12 @@ bool GLTFDocument::_convert_animation_node_track(Ref<GLTFState> p_state, GLTFAni
double time = 0.0;
bool last = false;
while (true) {
Vector3 position;
Quaternion rotation;
Vector3 scale;
Error err = p_godot_animation->try_position_track_interpolate(p_godot_anim_track_index, time, &position);
if (err == OK) {
err = p_godot_animation->try_rotation_track_interpolate(p_godot_anim_track_index, time, &rotation);
if (err == OK) {
err = p_godot_animation->try_scale_track_interpolate(p_godot_anim_track_index, time, &scale);
}
}
Transform3D transform;
Error err = _try_interpolate_value_track(p_godot_animation, p_godot_anim_track_index, time, transform);
if (err == OK) {
Vector3 position = transform.get_origin();
Quaternion rotation = transform.basis.get_rotation_quaternion();
Vector3 scale = transform.basis.get_scale();
p_gltf_node_track.position_track.values.push_back(position);
p_gltf_node_track.position_track.times.push_back(time);
p_gltf_node_track.rotation_track.values.push_back(rotation);