Quellcode durchsuchen

ability to keep user tracks when importing animations, closes #12801

Juan Linietsky vor 7 Jahren
Ursprung
Commit
5614902611

+ 27 - 3
editor/import/resource_importer_scene.cpp

@@ -95,6 +95,9 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const
 		if (p_option != "animation/import" && !bool(p_options["animation/import"]))
 			return false;
 
+		if (p_option == "animation/keep_custom_tracks" && int(p_options["animation/storage"]) == 0)
+			return false;
+
 		if (p_option.begins_with("animation/optimizer/") && p_option != "animation/optimizer/enabled" && !bool(p_options["animation/optimizer/enabled"]))
 			return false;
 
@@ -870,7 +873,7 @@ static String _make_extname(const String &p_str) {
 	return ext_name;
 }
 
-void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
+void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_keep_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
 
 	List<PropertyInfo> pi;
 
@@ -889,7 +892,26 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
 
 				if (!p_animations.has(anim)) {
 
+					//mark what comes from the file first, this helps eventually keep user data
+					for (int i = 0; i < anim->get_track_count(); i++) {
+						anim->track_set_imported(i, true);
+					}
+
 					String ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".anim");
+
+					if (FileAccess::exists(ext_name) && p_keep_animations) {
+						//try to keep custom animation tracks
+						Ref<Animation> old_anim = ResourceLoader::load(ext_name, "Animation", true);
+						if (old_anim.is_valid()) {
+							//meergeee
+							for (int i = 0; i < old_anim->get_track_count(); i++) {
+								if (!old_anim->track_is_imported(i)) {
+									old_anim->copy_track(i, anim);
+								}
+							}
+						}
+					}
+
 					ResourceSaver::save(ext_name, anim, ResourceSaver::FLAG_CHANGE_PATH);
 					p_animations[anim] = anim;
 				}
@@ -997,7 +1019,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
 
 	for (int i = 0; i < p_node->get_child_count(); i++) {
 
-		_make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_make_materials, p_keep_materials, p_make_meshes, p_animations, p_materials, p_meshes);
+		_make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_keep_animations, p_make_materials, p_keep_materials, p_make_meshes, p_animations, p_materials, p_meshes);
 	}
 }
 
@@ -1036,6 +1058,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
 	r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), ""));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), animations_out ? true : false));
+	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/keep_custom_tracks"), animations_out ? true : false));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_linear_error"), 0.05));
 	r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_angular_error"), 0.01));
@@ -1176,6 +1199,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 	}
 
 	bool external_animations = int(p_options["animation/storage"]) == 1;
+	bool keep_custom_tracks = p_options["animation/keep_custom_tracks"];
 	bool external_materials = p_options["materials/storage"];
 	bool external_meshes = p_options["meshes/storage"];
 	bool external_scenes = int(p_options["nodes/storage"]) == 1;
@@ -1202,7 +1226,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
 
 		bool keep_materials = bool(p_options["materials/keep_on_reimport"]);
 
-		_make_external_resources(scene, base_path, external_animations, external_materials, keep_materials, external_meshes, anim_map, mat_map, mesh_map);
+		_make_external_resources(scene, base_path, external_animations, keep_custom_tracks, external_materials, keep_materials, external_meshes, anim_map, mat_map, mesh_map);
 	}
 
 	progress.step(TTR("Running Custom Script.."), 2);

+ 1 - 1
editor/import/resource_importer_scene.h

@@ -128,7 +128,7 @@ public:
 	virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
 	virtual int get_import_order() const { return 100; } //after everything
 
-	void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
+	void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_keep_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
 
 	Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map, LightBakeMode p_light_bake_mode);
 

+ 16 - 0
scene/resources/animation.cpp

@@ -1595,6 +1595,21 @@ float Animation::get_step() const {
 	return step;
 }
 
+void Animation::copy_track(int src_track, Ref<Animation> p_to_animation) {
+	ERR_FAIL_COND(p_to_animation.is_null());
+	ERR_FAIL_INDEX(src_track, get_track_count());
+	int dst_track = p_to_animation->get_track_count();
+	p_to_animation->add_track(track_get_type(src_track));
+
+	p_to_animation->track_set_path(dst_track, track_get_path(src_track));
+	p_to_animation->track_set_imported(dst_track, track_is_imported(src_track));
+	p_to_animation->track_set_interpolation_type(dst_track, track_get_interpolation_type(src_track));
+	p_to_animation->track_set_interpolation_loop_wrap(dst_track, track_get_interpolation_loop_wrap(src_track));
+	for (int i = 0; i < track_get_key_count(src_track); i++) {
+		p_to_animation->track_insert_key(dst_track, track_get_key_time(src_track, i), track_get_key_value(src_track, i), track_get_key_transition(src_track, i));
+	}
+}
+
 void Animation::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
@@ -1650,6 +1665,7 @@ void Animation::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_step"), &Animation::get_step);
 
 	ClassDB::bind_method(D_METHOD("clear"), &Animation::clear);
+	ClassDB::bind_method(D_METHOD("copy_track", "track", "to_animation"), &Animation::copy_track);
 
 	BIND_ENUM_CONSTANT(TYPE_VALUE);
 	BIND_ENUM_CONSTANT(TYPE_TRANSFORM);

+ 2 - 0
scene/resources/animation.h

@@ -269,6 +269,8 @@ public:
 	Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const;
 	StringName method_track_get_name(int p_track, int p_key_idx) const;
 
+	void copy_track(int p_track, Ref<Animation> p_to_animation);
+
 	void set_length(float p_length);
 	float get_length() const;