GLTF: Clean up animation code to make way for KHR_animation_pointer

This commit is contained in:
Aaron Franke
2024-07-10 01:26:35 -07:00
parent c7391d2ee3
commit 834189a618
5 changed files with 506 additions and 485 deletions

View File

@ -1389,7 +1389,7 @@ Error FBXDocument::_parse_animations(Ref<FBXState> p_state) {
for (const ufbx_baked_node &fbx_baked_node : fbx_baked_anim->nodes) {
const GLTFNodeIndex node = fbx_baked_node.typed_id;
GLTFAnimation::Track &track = animation->get_tracks()[node];
GLTFAnimation::NodeTrack &track = animation->get_node_tracks()[node];
for (const ufbx_baked_vec3 &key : fbx_baked_node.translation_keys) {
track.position_track.times.push_back(float(key.time));
@ -1779,8 +1779,8 @@ void FBXDocument::_import_animation(Ref<FBXState> p_state, AnimationPlayer *p_an
double anim_start_offset = p_trimming ? double(additional_animation_data["time_begin"]) : 0.0;
for (const KeyValue<int, GLTFAnimation::Track> &track_i : anim->get_tracks()) {
const GLTFAnimation::Track &track = track_i.value;
for (const KeyValue<int, GLTFAnimation::NodeTrack> &track_i : anim->get_node_tracks()) {
const GLTFAnimation::NodeTrack &track = track_i.value;
//need to find the path: for skeletons, weight tracks will affect the mesh
NodePath node_path;
//for skeletons, transform tracks always affect bones

File diff suppressed because it is too large Load Diff

View File

@ -209,7 +209,7 @@ private:
Node3D *_generate_spatial(Ref<GLTFState> p_state, const GLTFNodeIndex p_node_index);
void _assign_node_names(Ref<GLTFState> p_state);
template <typename T>
T _interpolate_track(const Vector<real_t> &p_times, const Vector<T> &p_values,
T _interpolate_track(const Vector<double> &p_times, const Vector<T> &p_values,
const float p_time,
const GLTFAnimation::Interpolation p_interp);
GLTFAccessorIndex _encode_accessor_as_quaternions(Ref<GLTFState> p_state,
@ -222,7 +222,7 @@ private:
const Vector<Color> p_attribs,
const bool p_for_vertex);
GLTFAccessorIndex _encode_accessor_as_floats(Ref<GLTFState> p_state,
const Vector<real_t> p_attribs,
const Vector<double> p_attribs,
const bool p_for_vertex);
GLTFAccessorIndex _encode_accessor_as_vec2(Ref<GLTFState> p_state,
const Vector<Vector2> p_attribs,
@ -273,11 +273,6 @@ private:
Error _serialize_nodes(Ref<GLTFState> p_state);
Error _serialize_scenes(Ref<GLTFState> p_state);
String interpolation_to_string(const GLTFAnimation::Interpolation p_interp);
GLTFAnimation::Track _convert_animation_track(Ref<GLTFState> p_state,
GLTFAnimation::Track p_track,
Ref<Animation> p_animation,
int32_t p_track_i,
GLTFNodeIndex p_node_i);
Error _encode_buffer_bins(Ref<GLTFState> p_state, const String &p_path);
Error _encode_buffer_glb(Ref<GLTFState> p_state, const String &p_path);
PackedByteArray _serialize_glb_buffer(Ref<GLTFState> p_state, Error *r_err);
@ -335,11 +330,6 @@ public:
void _convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeIndex p_gltf_parent, Ref<GLTFNode> p_gltf_node, Ref<GLTFState> p_state);
#endif // MODULE_CSG_ENABLED
void _convert_animation_player_to_gltf(
AnimationPlayer *p_animation_player, Ref<GLTFState> p_state,
GLTFNodeIndex p_gltf_current,
GLTFNodeIndex p_gltf_root_index,
Ref<GLTFNode> p_gltf_node, Node *p_scene_parent);
void _check_visibility(Node *p_node, bool &r_retflag);
void _convert_camera_to_gltf(Camera3D *p_camera, Ref<GLTFState> p_state,
Ref<GLTFNode> p_gltf_node);
@ -370,7 +360,15 @@ public:
Ref<GLTFNode> p_gltf_node);
GLTFMeshIndex _convert_mesh_to_gltf(Ref<GLTFState> p_state,
MeshInstance3D *p_mesh_instance);
void _convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, String p_animation_track_name);
GLTFNodeIndex _node_and_or_bone_to_gltf_node_index(Ref<GLTFState> p_state, const Vector<StringName> &p_node_subpath, const Node *p_godot_node);
bool _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);
void _convert_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const String &p_animation_track_name);
Error _serialize(Ref<GLTFState> p_state);
Error _parse(Ref<GLTFState> p_state, String p_path, Ref<FileAccess> p_file);
};

View File

@ -42,6 +42,34 @@ void GLTFAnimation::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "loop"), "set_loop", "get_loop"); // bool
}
GLTFAnimation::Interpolation GLTFAnimation::godot_to_gltf_interpolation(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index) {
Animation::InterpolationType interpolation = p_godot_animation->track_get_interpolation_type(p_godot_anim_track_index);
switch (interpolation) {
case Animation::INTERPOLATION_LINEAR:
case Animation::INTERPOLATION_LINEAR_ANGLE:
return INTERP_LINEAR;
case Animation::INTERPOLATION_NEAREST:
return INTERP_STEP;
case Animation::INTERPOLATION_CUBIC:
case Animation::INTERPOLATION_CUBIC_ANGLE:
return INTERP_CUBIC_SPLINE;
}
return INTERP_LINEAR;
}
Animation::InterpolationType GLTFAnimation::gltf_to_godot_interpolation(Interpolation p_gltf_interpolation) {
switch (p_gltf_interpolation) {
case INTERP_LINEAR:
return Animation::INTERPOLATION_LINEAR;
case INTERP_STEP:
return Animation::INTERPOLATION_NEAREST;
case INTERP_CATMULLROMSPLINE:
case INTERP_CUBIC_SPLINE:
return Animation::INTERPOLATION_CUBIC;
}
return Animation::INTERPOLATION_LINEAR;
}
String GLTFAnimation::get_original_name() {
return original_name;
}
@ -58,8 +86,12 @@ void GLTFAnimation::set_loop(bool p_val) {
loop = p_val;
}
HashMap<int, GLTFAnimation::Track> &GLTFAnimation::get_tracks() {
return tracks;
HashMap<int, GLTFAnimation::NodeTrack> &GLTFAnimation::get_node_tracks() {
return node_tracks;
}
bool GLTFAnimation::is_empty_of_tracks() const {
return node_tracks.is_empty();
}
GLTFAnimation::GLTFAnimation() {

View File

@ -50,33 +50,39 @@ public:
template <typename T>
struct Channel {
Interpolation interpolation = INTERP_LINEAR;
Vector<real_t> times;
Vector<double> times;
Vector<T> values;
};
struct Track {
struct NodeTrack {
Channel<Vector3> position_track;
Channel<Quaternion> rotation_track;
Channel<Vector3> scale_track;
Vector<Channel<real_t>> weight_tracks;
};
String original_name;
bool loop = false;
HashMap<int, NodeTrack> node_tracks;
Dictionary additional_data;
public:
static Interpolation godot_to_gltf_interpolation(const Ref<Animation> &p_godot_animation, int32_t p_godot_anim_track_index);
static Animation::InterpolationType gltf_to_godot_interpolation(Interpolation p_gltf_interpolation);
String get_original_name();
void set_original_name(String p_name);
bool get_loop() const;
void set_loop(bool p_val);
HashMap<int, GLTFAnimation::Track> &get_tracks();
HashMap<int, GLTFAnimation::NodeTrack> &get_node_tracks();
bool is_empty_of_tracks() const;
Variant get_additional_data(const StringName &p_extension_name);
void set_additional_data(const StringName &p_extension_name, Variant p_additional_data);
GLTFAnimation();
private:
String original_name;
bool loop = false;
HashMap<int, Track> tracks;
Dictionary additional_data;
GLTFAnimation();
};
#endif // GLTF_ANIMATION_H