Add remove immutable tracks option to glTF importer

Co-authored-by: Lyuma <xn.lyuma@gmail.com>
This commit is contained in:
Silc Renew 2023-01-30 08:49:55 +09:00
parent a3dae9e548
commit 8b3be51d17
7 changed files with 55 additions and 36 deletions

View File

@ -1865,6 +1865,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/remove_immutable_tracks"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary()));

View File

@ -51,6 +51,7 @@
<param index="0" name="state" type="GLTFState" />
<param index="1" name="bake_fps" type="float" default="30" />
<param index="2" name="trimming" type="bool" default="false" />
<param index="3" name="remove_immutable_tracks" type="bool" default="true" />
<description>
Takes a [GLTFState] object through the [param state] parameter and returns a Godot Engine scene node.
</description>

View File

@ -233,7 +233,7 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_
}
return nullptr;
}
return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"]);
return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]);
}
Variant EditorSceneFormatImporterBlend::get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option,

View File

@ -100,7 +100,7 @@ Node *EditorSceneFormatImporterFBX::import_scene(const String &p_path, uint32_t
}
return nullptr;
}
return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"]);
return gltf->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]);
}
Variant EditorSceneFormatImporterFBX::get_option_visibility(const String &p_path, bool p_for_animation,

View File

@ -66,11 +66,23 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t
state->set_create_animations(bool(p_options["animation/import"]));
}
#ifndef DISABLE_DEPRECATED
if (p_options.has("animation/trimming")) {
return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"]);
if (p_options.has("animation/remove_immutable_tracks")) {
return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]);
} else {
return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], true);
}
} else {
return doc->generate_scene(state, (float)p_options["animation/fps"], false);
if (p_options.has("animation/remove_immutable_tracks")) {
return doc->generate_scene(state, (float)p_options["animation/fps"], false, (bool)p_options["animation/remove_immutable_tracks"]);
} else {
return doc->generate_scene(state, (float)p_options["animation/fps"], false, true);
}
}
#else
return doc->generate_scene(state, (float)p_options["animation/fps"], (bool)p_options["animation/trimming"], (bool)p_options["animation/remove_immutable_tracks"]);
#endif
}
void EditorSceneFormatImporterGLTF::get_import_options(const String &p_path,

View File

@ -5961,7 +5961,7 @@ T GLTFDocument::_interpolate_track(const Vector<real_t> &p_times, const Vector<T
ERR_FAIL_V(p_values[0]);
}
void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming) {
void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player, const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks) {
Ref<GLTFAnimation> anim = p_state->animations[p_index];
String anim_name = anim->get_name();
@ -6064,35 +6064,38 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_
int scale_idx = -1;
if (track.position_track.values.size()) {
Vector3 base_pos = p_state->nodes[track_i.key]->position;
bool not_default = false; //discard the track if all it contains is default values
for (int i = 0; i < track.position_track.times.size(); i++) {
Vector3 value = track.position_track.values[track.position_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i];
if (!value.is_equal_approx(base_pos)) {
not_default = true;
break;
bool is_default = true; //discard the track if all it contains is default values
if (p_remove_immutable_tracks) {
Vector3 base_pos = p_state->nodes[track_i.key]->position;
for (int i = 0; i < track.position_track.times.size(); i++) {
Vector3 value = track.position_track.values[track.position_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i];
if (!value.is_equal_approx(base_pos)) {
is_default = false;
break;
}
}
}
if (not_default) {
if (!p_remove_immutable_tracks || !is_default) {
position_idx = base_idx;
animation->add_track(Animation::TYPE_POSITION_3D);
animation->track_set_path(position_idx, transform_node_path);
animation->track_set_imported(position_idx, true); //helps merging later
base_idx++;
}
}
if (track.rotation_track.values.size()) {
Quaternion base_rot = p_state->nodes[track_i.key]->rotation.normalized();
bool not_default = false; //discard the track if all it contains is default values
for (int i = 0; i < track.rotation_track.times.size(); i++) {
Quaternion value = track.rotation_track.values[track.rotation_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i].normalized();
if (!value.is_equal_approx(base_rot)) {
not_default = true;
break;
bool is_default = true; //discard the track if all it contains is default values
if (p_remove_immutable_tracks) {
Quaternion base_rot = p_state->nodes[track_i.key]->rotation.normalized();
for (int i = 0; i < track.rotation_track.times.size(); i++) {
Quaternion value = track.rotation_track.values[track.rotation_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i].normalized();
if (!value.is_equal_approx(base_rot)) {
is_default = false;
break;
}
}
}
if (not_default) {
if (!p_remove_immutable_tracks || !is_default) {
rotation_idx = base_idx;
animation->add_track(Animation::TYPE_ROTATION_3D);
animation->track_set_path(rotation_idx, transform_node_path);
@ -6101,16 +6104,18 @@ void GLTFDocument::_import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_
}
}
if (track.scale_track.values.size()) {
Vector3 base_scale = p_state->nodes[track_i.key]->scale;
bool not_default = false; //discard the track if all it contains is default values
for (int i = 0; i < track.scale_track.times.size(); i++) {
Vector3 value = track.scale_track.values[track.scale_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i];
if (!value.is_equal_approx(base_scale)) {
not_default = true;
break;
bool is_default = true; //discard the track if all it contains is default values
if (p_remove_immutable_tracks) {
Vector3 base_scale = p_state->nodes[track_i.key]->scale;
for (int i = 0; i < track.scale_track.times.size(); i++) {
Vector3 value = track.scale_track.values[track.scale_track.interpolation == GLTFAnimation::INTERP_CUBIC_SPLINE ? (1 + i * 3) : i];
if (!value.is_equal_approx(base_scale)) {
is_default = false;
break;
}
}
}
if (not_default) {
if (!p_remove_immutable_tracks || !is_default) {
scale_idx = base_idx;
animation->add_track(Animation::TYPE_SCALE_3D);
animation->track_set_path(scale_idx, transform_node_path);
@ -6895,8 +6900,8 @@ void GLTFDocument::_bind_methods() {
&GLTFDocument::append_from_buffer, DEFVAL(0));
ClassDB::bind_method(D_METHOD("append_from_scene", "node", "state", "flags"),
&GLTFDocument::append_from_scene, DEFVAL(0));
ClassDB::bind_method(D_METHOD("generate_scene", "state", "bake_fps", "trimming"),
&GLTFDocument::generate_scene, DEFVAL(30), DEFVAL(false));
ClassDB::bind_method(D_METHOD("generate_scene", "state", "bake_fps", "trimming", "remove_immutable_tracks"),
&GLTFDocument::generate_scene, DEFVAL(30), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("generate_buffer", "state"),
&GLTFDocument::generate_buffer);
ClassDB::bind_method(D_METHOD("write_to_filesystem", "state", "path"),
@ -7005,7 +7010,7 @@ Error GLTFDocument::write_to_filesystem(Ref<GLTFState> p_state, const String &p_
return OK;
}
Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool p_trimming) {
Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, bool p_trimming, bool p_remove_immutable_tracks) {
ERR_FAIL_NULL_V(p_state, nullptr);
ERR_FAIL_INDEX_V(0, p_state->root_nodes.size(), nullptr);
Error err = OK;
@ -7019,7 +7024,7 @@ Node *GLTFDocument::generate_scene(Ref<GLTFState> p_state, float p_bake_fps, boo
root->add_child(ap, true);
ap->set_owner(root);
for (int i = 0; i < p_state->animations.size(); i++) {
_import_animation(p_state, ap, i, p_bake_fps, p_trimming);
_import_animation(p_state, ap, i, p_bake_fps, p_trimming, p_remove_immutable_tracks);
}
}
for (KeyValue<GLTFNodeIndex, Node *> E : p_state->scene_nodes) {

View File

@ -296,7 +296,7 @@ public:
Error append_from_scene(Node *p_node, Ref<GLTFState> r_state, uint32_t p_flags = 0);
public:
Node *generate_scene(Ref<GLTFState> p_state, float p_bake_fps = 30.0f, bool p_trimming = false);
Node *generate_scene(Ref<GLTFState> p_state, float p_bake_fps = 30.0f, bool p_trimming = false, bool p_remove_immutable_tracks = true);
PackedByteArray generate_buffer(Ref<GLTFState> p_state);
Error write_to_filesystem(Ref<GLTFState> p_state, const String &p_path);
@ -309,7 +309,7 @@ public:
const GLTFNodeIndex p_node_index);
void _generate_skeleton_bone_node(Ref<GLTFState> p_state, Node *p_scene_parent, Node3D *p_scene_root, const GLTFNodeIndex p_node_index);
void _import_animation(Ref<GLTFState> p_state, AnimationPlayer *p_animation_player,
const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming);
const GLTFAnimationIndex p_index, const float p_bake_fps, const bool p_trimming, const bool p_remove_immutable_tracks);
void _convert_mesh_instances(Ref<GLTFState> p_state);
GLTFCameraIndex _convert_camera(Ref<GLTFState> p_state, Camera3D *p_camera);
void _convert_light_to_gltf(Light3D *p_light, Ref<GLTFState> p_state, Ref<GLTFNode> p_gltf_node);