| 
									
										
										
										
											2018-08-29 22:38:13 +02:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  root_motion_editor_plugin.cpp                                        */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							|  |  |  | /*                      https://godotengine.org                          */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2022-01-03 21:27:34 +01:00
										 |  |  | /* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2018-08-29 22:38:13 +02:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | #include "root_motion_editor_plugin.h"
 | 
					
						
							|  |  |  | #include "editor/editor_node.h"
 | 
					
						
							| 
									
										
										
										
											2022-11-11 20:12:48 +01:00
										 |  |  | #include "scene/animation/animation_player.h"
 | 
					
						
							|  |  |  | #include "scene/animation/animation_tree.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-03 22:51:12 -03:00
										 |  |  | #include "scene/main/window.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::_confirmed() { | 
					
						
							|  |  |  | 	TreeItem *ti = filters->get_selected(); | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	if (!ti) { | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	NodePath path = ti->get_metadata(0); | 
					
						
							| 
									
										
										
										
											2019-01-18 13:01:24 -03:00
										 |  |  | 	emit_changed(get_edited_property(), path); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	update_property(); | 
					
						
							|  |  |  | 	filter_dialog->hide(); //may come from activated
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::_node_assign() { | 
					
						
							|  |  |  | 	NodePath current = get_edited_object()->get(get_edited_property()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AnimationTree *atree = Object::cast_to<AnimationTree>(get_edited_object()); | 
					
						
							|  |  |  | 	if (!atree->has_node(atree->get_animation_player())) { | 
					
						
							|  |  |  | 		EditorNode::get_singleton()->show_warning(TTR("AnimationTree has no path set to an AnimationPlayer")); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	AnimationPlayer *player = Object::cast_to<AnimationPlayer>(atree->get_node(atree->get_animation_player())); | 
					
						
							|  |  |  | 	if (!player) { | 
					
						
							|  |  |  | 		EditorNode::get_singleton()->show_warning(TTR("Path to AnimationPlayer is invalid")); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Node *base = player->get_node(player->get_root()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!base) { | 
					
						
							|  |  |  | 		EditorNode::get_singleton()->show_warning(TTR("Animation player has no valid root node path, so unable to retrieve track names.")); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-19 17:00:06 +02:00
										 |  |  | 	HashSet<String> paths; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		List<StringName> animations; | 
					
						
							|  |  |  | 		player->get_animation_list(&animations); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-24 15:46:25 +02:00
										 |  |  | 		for (const StringName &E : animations) { | 
					
						
							| 
									
										
										
										
											2021-07-15 23:45:57 -04:00
										 |  |  | 			Ref<Animation> anim = player->get_animation(E); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 			for (int i = 0; i < anim->get_track_count(); i++) { | 
					
						
							|  |  |  | 				paths.insert(anim->track_get_path(i)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	filters->clear(); | 
					
						
							|  |  |  | 	TreeItem *root = filters->create_item(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 15:04:37 +02:00
										 |  |  | 	HashMap<String, TreeItem *> parenthood; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-18 17:43:40 -06:00
										 |  |  | 	for (const String &E : paths) { | 
					
						
							|  |  |  | 		NodePath path = E; | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		TreeItem *ti = nullptr; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 		String accum; | 
					
						
							|  |  |  | 		for (int i = 0; i < path.get_name_count(); i++) { | 
					
						
							|  |  |  | 			String name = path.get_name(i); | 
					
						
							| 
									
										
										
										
											2021-12-09 03:42:46 -06:00
										 |  |  | 			if (!accum.is_empty()) { | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 				accum += "/"; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			accum += name; | 
					
						
							|  |  |  | 			if (!parenthood.has(accum)) { | 
					
						
							|  |  |  | 				if (ti) { | 
					
						
							|  |  |  | 					ti = filters->create_item(ti); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					ti = filters->create_item(root); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				parenthood[accum] = ti; | 
					
						
							|  |  |  | 				ti->set_text(0, name); | 
					
						
							|  |  |  | 				ti->set_selectable(0, false); | 
					
						
							|  |  |  | 				ti->set_editable(0, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (base->has_node(accum)) { | 
					
						
							|  |  |  | 					Node *node = base->get_node(accum); | 
					
						
							| 
									
										
										
										
											2018-09-02 16:40:51 -05:00
										 |  |  | 					ti->set_icon(0, EditorNode::get_singleton()->get_object_icon(node, "Node")); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				ti = parenthood[accum]; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 		Node *node = nullptr; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 		if (base->has_node(accum)) { | 
					
						
							|  |  |  | 			node = base->get_node(accum); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		if (!node) { | 
					
						
							| 
									
										
										
										
											2018-09-12 21:38:39 -04:00
										 |  |  | 			continue; //no node, can't edit
 | 
					
						
							| 
									
										
										
										
											2020-05-14 16:41:43 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (path.get_subname_count()) { | 
					
						
							|  |  |  | 			String concat = path.get_concatenated_subnames(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 18:49:16 -03:00
										 |  |  | 			Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 			if (skeleton && skeleton->find_bone(concat) != -1) { | 
					
						
							|  |  |  | 				//path in skeleton
 | 
					
						
							| 
									
										
										
										
											2019-06-26 15:08:25 +02:00
										 |  |  | 				const String &bone = concat; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 				int idx = skeleton->find_bone(bone); | 
					
						
							|  |  |  | 				List<String> bone_path; | 
					
						
							|  |  |  | 				while (idx != -1) { | 
					
						
							|  |  |  | 					bone_path.push_front(skeleton->get_bone_name(idx)); | 
					
						
							|  |  |  | 					idx = skeleton->get_bone_parent(idx); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				accum += ":"; | 
					
						
							|  |  |  | 				for (List<String>::Element *F = bone_path.front(); F; F = F->next()) { | 
					
						
							|  |  |  | 					if (F != bone_path.front()) { | 
					
						
							|  |  |  | 						accum += "/"; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					accum += F->get(); | 
					
						
							|  |  |  | 					if (!parenthood.has(accum)) { | 
					
						
							|  |  |  | 						ti = filters->create_item(ti); | 
					
						
							|  |  |  | 						parenthood[accum] = ti; | 
					
						
							|  |  |  | 						ti->set_text(0, F->get()); | 
					
						
							| 
									
										
										
										
											2018-06-27 16:30:48 -03:00
										 |  |  | 						ti->set_selectable(0, true); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 						ti->set_editable(0, false); | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 						ti->set_icon(0, get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"))); | 
					
						
							| 
									
										
										
										
											2018-06-27 16:30:48 -03:00
										 |  |  | 						ti->set_metadata(0, accum); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 					} else { | 
					
						
							|  |  |  | 						ti = parenthood[accum]; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ti->set_selectable(0, true); | 
					
						
							|  |  |  | 				ti->set_text(0, concat); | 
					
						
							| 
									
										
										
										
											2021-07-17 18:22:52 -03:00
										 |  |  | 				ti->set_icon(0, get_theme_icon(SNAME("BoneAttachment3D"), SNAME("EditorIcons"))); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 				ti->set_metadata(0, path); | 
					
						
							|  |  |  | 				if (path == current) { | 
					
						
							|  |  |  | 					ti->select(0); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				//just a property
 | 
					
						
							|  |  |  | 				ti = filters->create_item(ti); | 
					
						
							|  |  |  | 				ti->set_text(0, concat); | 
					
						
							|  |  |  | 				ti->set_selectable(0, true); | 
					
						
							|  |  |  | 				ti->set_metadata(0, path); | 
					
						
							|  |  |  | 				if (path == current) { | 
					
						
							|  |  |  | 					ti->select(0); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (ti) { | 
					
						
							|  |  |  | 				//just a node, likely call or animation track
 | 
					
						
							|  |  |  | 				ti->set_selectable(0, true); | 
					
						
							|  |  |  | 				ti->set_metadata(0, path); | 
					
						
							|  |  |  | 				if (path == current) { | 
					
						
							|  |  |  | 					ti->select(0); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	filters->ensure_cursor_is_visible(); | 
					
						
							|  |  |  | 	filter_dialog->popup_centered_ratio(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::_node_clear() { | 
					
						
							| 
									
										
										
										
											2019-01-18 13:01:24 -03:00
										 |  |  | 	emit_changed(get_edited_property(), NodePath()); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	update_property(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::update_property() { | 
					
						
							|  |  |  | 	NodePath p = get_edited_object()->get(get_edited_property()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-25 12:42:17 +02:00
										 |  |  | 	assign->set_tooltip_text(p); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	if (p == NodePath()) { | 
					
						
							| 
									
										
										
										
											2019-06-11 15:43:37 -03:00
										 |  |  | 		assign->set_icon(Ref<Texture2D>()); | 
					
						
							| 
									
										
										
										
											2019-01-07 16:57:52 +01:00
										 |  |  | 		assign->set_text(TTR("Assign...")); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 		assign->set_flat(false); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-02 01:20:12 +02:00
										 |  |  | 	Node *base_node = nullptr; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	if (base_hint != NodePath()) { | 
					
						
							|  |  |  | 		if (get_tree()->get_root()->has_node(base_hint)) { | 
					
						
							|  |  |  | 			base_node = get_tree()->get_root()->get_node(base_hint); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		base_node = Object::cast_to<Node>(get_edited_object()); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!base_node || !base_node->has_node(p)) { | 
					
						
							| 
									
										
										
										
											2019-06-11 15:43:37 -03:00
										 |  |  | 		assign->set_icon(Ref<Texture2D>()); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 		assign->set_text(p); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Node *target_node = base_node->get_node(p); | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!target_node); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	assign->set_text(target_node->get_name()); | 
					
						
							| 
									
										
										
										
											2018-09-02 16:40:51 -05:00
										 |  |  | 	assign->set_icon(EditorNode::get_singleton()->get_object_icon(target_node, "Node")); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) { | 
					
						
							|  |  |  | 	base_hint = p_base_hint; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::_notification(int p_what) { | 
					
						
							| 
									
										
										
										
											2022-02-15 21:44:22 -05:00
										 |  |  | 	switch (p_what) { | 
					
						
							| 
									
										
										
										
											2022-08-29 11:04:31 +02:00
										 |  |  | 		case NOTIFICATION_ENTER_TREE: | 
					
						
							| 
									
										
										
										
											2022-02-15 21:44:22 -05:00
										 |  |  | 		case NOTIFICATION_THEME_CHANGED: { | 
					
						
							|  |  |  | 			Ref<Texture2D> t = get_theme_icon(SNAME("Clear"), SNAME("EditorIcons")); | 
					
						
							|  |  |  | 			clear->set_icon(t); | 
					
						
							|  |  |  | 		} break; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EditorPropertyRootMotion::_bind_methods() { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EditorPropertyRootMotion::EditorPropertyRootMotion() { | 
					
						
							|  |  |  | 	HBoxContainer *hbc = memnew(HBoxContainer); | 
					
						
							|  |  |  | 	add_child(hbc); | 
					
						
							|  |  |  | 	assign = memnew(Button); | 
					
						
							|  |  |  | 	assign->set_h_size_flags(SIZE_EXPAND_FILL); | 
					
						
							|  |  |  | 	assign->set_clip_text(true); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	assign->connect("pressed", callable_mp(this, &EditorPropertyRootMotion::_node_assign)); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	hbc->add_child(assign); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	clear = memnew(Button); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	clear->connect("pressed", callable_mp(this, &EditorPropertyRootMotion::_node_clear)); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	hbc->add_child(clear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	filter_dialog = memnew(ConfirmationDialog); | 
					
						
							|  |  |  | 	add_child(filter_dialog); | 
					
						
							|  |  |  | 	filter_dialog->set_title(TTR("Edit Filtered Tracks:")); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	filter_dialog->connect("confirmed", callable_mp(this, &EditorPropertyRootMotion::_confirmed)); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	filters = memnew(Tree); | 
					
						
							|  |  |  | 	filter_dialog->add_child(filters); | 
					
						
							|  |  |  | 	filters->set_v_size_flags(SIZE_EXPAND_FILL); | 
					
						
							|  |  |  | 	filters->set_hide_root(true); | 
					
						
							| 
									
										
										
										
											2020-02-21 18:28:45 +01:00
										 |  |  | 	filters->connect("item_activated", callable_mp(this, &EditorPropertyRootMotion::_confirmed)); | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	//filters->connect("item_edited", this, "_filter_edited");
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-05-14 14:29:06 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | //////////////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool EditorInspectorRootMotionPlugin::can_handle(Object *p_object) { | 
					
						
							| 
									
										
										
										
											2021-11-10 17:49:19 +03:00
										 |  |  | 	return true; // Can handle everything.
 | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 21:24:34 -04:00
										 |  |  | bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) { | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 	if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) { | 
					
						
							|  |  |  | 		EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion); | 
					
						
							| 
									
										
										
										
											2021-12-09 03:42:46 -06:00
										 |  |  | 		if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && !p_hint_text.is_empty()) { | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | 			editor->setup(p_hint_text); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		add_property_editor(p_path, editor); | 
					
						
							|  |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-10 17:49:19 +03:00
										 |  |  | 	return false; | 
					
						
							| 
									
										
										
										
											2018-06-26 19:05:11 -03:00
										 |  |  | } |