mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-15 19:41:36 +08:00
[godot] Remove SpineSpriteAnimateDialog, clean-up SpineAnimationStateDataResource, rename SpineSprite.manual_update -> update_all
This commit is contained in:
parent
7f92b6893b
commit
b760bb7606
@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=9 format=2]
|
||||
[gd_scene load_steps=10 format=2]
|
||||
|
||||
[ext_resource path="res://Spineboy.gd" type="Script" id=1]
|
||||
[ext_resource path="res://spineboy/spineboy-data.tres" type="SpineSkeletonDataResource" id=2]
|
||||
@ -18,15 +18,22 @@ skins = null
|
||||
[sub_resource type="SpineAnimationStateDataResource" id=3]
|
||||
skeleton = SubResource( 4 )
|
||||
|
||||
[sub_resource type="SpineAnimationStateDataResource" id=5]
|
||||
skeleton = ExtResource( 2 )
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
|
||||
[node name="Spineboy" type="SpineSprite" parent="."]
|
||||
position = Vector2( 721.498, 460.558 )
|
||||
position = Vector2( 696.833, 438.135 )
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
animation_state_data_res = SubResource( 2 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="MixAndMatch" type="SpineSprite" parent="."]
|
||||
position = Vector2( 309.431, 511.233 )
|
||||
position = Vector2( 487.69, 515.718 )
|
||||
animation_state_data_res = SubResource( 3 )
|
||||
script = ExtResource( 5 )
|
||||
|
||||
[node name="SpineSprite" type="SpineSprite" parent="."]
|
||||
position = Vector2( 181.623, 491.053 )
|
||||
animation_state_data_res = SubResource( 5 )
|
||||
|
||||
@ -78,7 +78,7 @@ void SpineAnimationStateDataResource::set_skeleton(const Ref<SpineSkeletonDataRe
|
||||
}
|
||||
}
|
||||
}
|
||||
Ref<SpineSkeletonDataResource> SpineAnimationStateDataResource::get_skeleton() {
|
||||
Ref<SpineSkeletonDataResource> SpineAnimationStateDataResource::get_skeleton() const {
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
@ -160,4 +160,4 @@ void SpineAnimationStateDataResource::_on_skeleton_data_changed() {
|
||||
|
||||
bool SpineAnimationStateDataResource::is_animation_state_data_created() {
|
||||
return animation_state_data_created;
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ private:
|
||||
|
||||
public:
|
||||
void set_skeleton(const Ref<SpineSkeletonDataResource> &s);
|
||||
Ref<SpineSkeletonDataResource> get_skeleton();
|
||||
Ref<SpineSkeletonDataResource> get_skeleton() const;
|
||||
|
||||
inline spine::AnimationStateData *get_animation_state_data() {
|
||||
return animation_state_data;
|
||||
|
||||
@ -32,9 +32,6 @@
|
||||
|
||||
#include "SpineAtlasResource.h"
|
||||
#include "SpineSkeletonJsonDataResource.h"
|
||||
#include "SpineSpriteAnimateDialog.h"
|
||||
|
||||
#include "SpineSprite.h"
|
||||
|
||||
Error SpineAtlasResourceImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
|
||||
Ref<SpineAtlasResource> res(memnew(SpineAtlasResource));
|
||||
@ -70,15 +67,6 @@ Error SpineJsonResourceImportPlugin::import(const String &p_source_file, const S
|
||||
SpineRuntimeEditorPlugin::SpineRuntimeEditorPlugin(EditorNode *p_node) {
|
||||
add_import_plugin(memnew(SpineAtlasResourceImportPlugin));
|
||||
add_import_plugin(memnew(SpineJsonResourceImportPlugin));
|
||||
|
||||
auto animate_button = memnew(ToolButton);
|
||||
animate_button->set_text("Animate");
|
||||
add_control_to_container(CONTAINER_CANVAS_EDITOR_MENU, animate_button);
|
||||
|
||||
animate_dialog = memnew(SpineSpriteAnimateDialog);
|
||||
get_editor_interface()->get_base_control()->add_child(animate_dialog);
|
||||
animate_dialog->set_animate_button(animate_button);
|
||||
animate_dialog->set_plugin(this);
|
||||
}
|
||||
|
||||
SpineRuntimeEditorPlugin::~SpineRuntimeEditorPlugin() {
|
||||
@ -92,8 +80,7 @@ void SpineRuntimeEditorPlugin::make_visible(bool p_visible) {
|
||||
if (get_editor_interface()->get_selection()->get_selected_node_list().size() != 1) {
|
||||
p_visible = false;
|
||||
}
|
||||
animate_dialog->get_animate_button()->set_visible(p_visible);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -420,17 +420,15 @@ void SpineSkeletonDataResource::get_animation_names(Vector<String> &res) const {
|
||||
}
|
||||
void SpineSkeletonDataResource::get_skin_names(Vector<String> &res) const {
|
||||
res.clear();
|
||||
if (!is_skeleton_data_loaded()) {
|
||||
return;
|
||||
}
|
||||
if (!is_skeleton_data_loaded()) return;
|
||||
auto as = get_skins();
|
||||
res.resize(as.size());
|
||||
for (size_t i = 0; i < as.size(); ++i) {
|
||||
auto a = Ref<SpineSkin>(as[i]);
|
||||
if (a.is_valid()) {
|
||||
res.push_back(a->get_skin_name());
|
||||
res.set(i, a->get_skin_name());
|
||||
} else {
|
||||
res.push_back("");
|
||||
res.set(i, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,9 +40,6 @@ void SpineSprite::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_animation_state"), &SpineSprite::get_animation_state);
|
||||
ClassDB::bind_method(D_METHOD("_on_animation_data_changed"), &SpineSprite::_on_animation_data_changed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_preview_animation"), &SpineSprite::get_preview_animation);
|
||||
ClassDB::bind_method(D_METHOD("set_preview_animation", "preview_animation"), &SpineSprite::set_preview_animation);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_bind_slot_nodes"), &SpineSprite::get_bind_slot_nodes);
|
||||
ClassDB::bind_method(D_METHOD("set_bind_slot_nodes", "v"), &SpineSprite::set_bind_slot_nodes);
|
||||
|
||||
@ -55,7 +52,7 @@ void SpineSprite::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_process_mode", "v"), &SpineSprite::set_process_mode);
|
||||
ClassDB::bind_method(D_METHOD("get_process_mode"), &SpineSprite::get_process_mode);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("manual_update", "delta"), &SpineSprite::_update_all);
|
||||
ClassDB::bind_method(D_METHOD("update_all", "delta"), &SpineSprite::_update_all);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("animation_state_ready", PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "skeleton", PROPERTY_HINT_TYPE_STRING, "SpineSkeleton")));
|
||||
ADD_SIGNAL(MethodInfo("animation_start", PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_TYPE_STRING, "SpineEvent")));
|
||||
@ -66,11 +63,10 @@ void SpineSprite::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("animation_event", PropertyInfo(Variant::OBJECT, "animation_state", PROPERTY_HINT_TYPE_STRING, "SpineAnimationState"), PropertyInfo(Variant::OBJECT, "track_entry", PROPERTY_HINT_TYPE_STRING, "SpineTrackEntry"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_TYPE_STRING, "SpineEvent")));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_state_data_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineAnimationStateDataResource"), "set_animation_state_data_res", "get_animation_state_data_res");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "preview_animation"), "set_preview_animation", "get_preview_animation");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "overlap"), "set_overlap", "get_overlap");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "bind_slot_nodes"), "set_bind_slot_nodes", "get_bind_slot_nodes");
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Process,Physics,Manually"), "set_process_mode", "get_process_mode");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Process,Physics,Manual"), "set_process_mode", "get_process_mode");
|
||||
|
||||
BIND_ENUM_CONSTANT(ProcessMode::ProcessMode_Process);
|
||||
BIND_ENUM_CONSTANT(ProcessMode::ProcessMode_Physics);
|
||||
@ -531,14 +527,6 @@ void SpineSprite::callback(spine::AnimationState *state, spine::EventType type,
|
||||
}
|
||||
}
|
||||
|
||||
String SpineSprite::get_preview_animation() {
|
||||
return preview_animation;
|
||||
}
|
||||
void SpineSprite::set_preview_animation(String animation) {
|
||||
preview_animation = animation;
|
||||
_validate_and_play_current_animations();
|
||||
}
|
||||
|
||||
Array SpineSprite::get_bind_slot_nodes() {
|
||||
return bind_slot_nodes;
|
||||
}
|
||||
@ -589,6 +577,29 @@ void SpineSprite::set_process_mode(SpineSprite::ProcessMode v) {
|
||||
}
|
||||
|
||||
void SpineSprite::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
Vector<String> animations;
|
||||
Vector<String> skins;
|
||||
if (animation_state_data_res.is_valid() && animation_state_data_res->get_skeleton().is_valid()) {
|
||||
animation_state_data_res->get_skeleton()->get_animation_names(animations);
|
||||
animation_state_data_res->get_skeleton()->get_skin_names(skins);
|
||||
}
|
||||
animations.insert(0, "- None -");
|
||||
|
||||
PropertyInfo animationListProperty;
|
||||
animationListProperty.name = "Preview animation";
|
||||
animationListProperty.type = Variant::STRING;
|
||||
animationListProperty.hint_string = String(",").join(animations);
|
||||
animationListProperty.hint = PROPERTY_HINT_ENUM;
|
||||
animationListProperty.usage = PROPERTY_USAGE_EDITOR;
|
||||
p_list->push_back(animationListProperty);
|
||||
|
||||
PropertyInfo skinListProperty;
|
||||
skinListProperty.name = "Preview skin";
|
||||
skinListProperty.type = Variant::STRING;
|
||||
skinListProperty.hint_string = String(",").join(skins);
|
||||
skinListProperty.hint = PROPERTY_HINT_ENUM;
|
||||
skinListProperty.usage = PROPERTY_USAGE_EDITOR;
|
||||
p_list->push_back(skinListProperty);
|
||||
}
|
||||
|
||||
bool SpineSprite::_get(const StringName &p_property, Variant &r_value) const {
|
||||
@ -596,13 +607,28 @@ bool SpineSprite::_get(const StringName &p_property, Variant &r_value) const {
|
||||
}
|
||||
|
||||
bool SpineSprite::_set(const StringName &p_property, const Variant &p_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SpineSprite::_validate_and_play_current_animations() {
|
||||
if (animation_state.is_valid() && skeleton.is_valid()) {
|
||||
if (skeleton->get_data()->find_animation(preview_animation).is_valid()) {
|
||||
animation_state->set_animation(preview_animation, true, 0);
|
||||
if (p_property == "Preview animation") {
|
||||
if (animation_state.is_valid() && skeleton.is_valid()) {
|
||||
auto animName = p_value.operator String();
|
||||
skeleton->set_to_setup_pose();
|
||||
if (skeleton->get_data()->find_animation(animName).is_valid()) {
|
||||
animation_state->set_animation(animName, true, 0);
|
||||
} else {
|
||||
animation_state->clear_tracks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_property == "Preview skin") {
|
||||
if (animation_state.is_valid() && skeleton.is_valid()) {
|
||||
auto skinName = p_value.operator String();
|
||||
if (skeleton->get_data()->find_skin(skinName).is_valid()) {
|
||||
skeleton->set_skin_by_name(skinName);
|
||||
} else {
|
||||
skeleton->set_skin(NULL);
|
||||
}
|
||||
skeleton->set_to_setup_pose();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -102,9 +102,6 @@ public:
|
||||
|
||||
void _update_all(float delta);
|
||||
|
||||
String get_preview_animation();
|
||||
void set_preview_animation(String animation);
|
||||
|
||||
Array get_bind_slot_nodes();
|
||||
void set_bind_slot_nodes(Array v);
|
||||
|
||||
|
||||
@ -1,351 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSpriteAnimateDialog.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
#include "SpineSprite.h"
|
||||
|
||||
void SpineSpriteAnimateDialog::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("_on_animate_button_pressed"), &SpineSpriteAnimateDialog::_on_animate_button_pressed);
|
||||
ClassDB::bind_method(D_METHOD("_on_scene_tree_selected"), &SpineSpriteAnimateDialog::_on_scene_tree_selected);
|
||||
ClassDB::bind_method(D_METHOD("_on_scene_tree_hide"), &SpineSpriteAnimateDialog::_on_scene_tree_hide);
|
||||
ClassDB::bind_method(D_METHOD("_on_animate_dialog_action"), &SpineSpriteAnimateDialog::_on_animate_dialog_action);
|
||||
}
|
||||
|
||||
SpineSpriteAnimateDialog::SpineSpriteAnimateDialog() {
|
||||
animate_dialog = memnew(ConfirmationDialog);
|
||||
add_child(animate_dialog);
|
||||
animate_dialog->get_ok()->set_text("Generate");
|
||||
animate_dialog_override_button = animate_dialog->add_button("Override", false, "override");
|
||||
animate_dialog_override_button->set_visible(false);
|
||||
animate_dialog->set_title("Animations Generator");
|
||||
animate_dialog->set_resizable(true);
|
||||
animate_dialog->set_custom_minimum_size(Vector2(550, 400));
|
||||
animate_dialog->set_hide_on_ok(false);
|
||||
animate_dialog->connect("custom_action", this, "_on_animate_dialog_action");
|
||||
Vector<Variant> al;
|
||||
al.push_back("confirmed");
|
||||
animate_dialog->connect("confirmed", this, "_on_animate_dialog_action", al);
|
||||
|
||||
auto vb = memnew(VBoxContainer);
|
||||
animate_dialog->add_child(vb);
|
||||
|
||||
auto scroll = memnew(ScrollContainer);
|
||||
scroll->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
// vb->add_margin_child("Animations", scroll);
|
||||
vb->add_child(scroll);
|
||||
|
||||
animate_dialog_tree = memnew(Tree);
|
||||
animate_dialog_tree->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
animate_dialog_tree->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
scroll->add_child(animate_dialog_tree);
|
||||
|
||||
animate_dialog_tree->set_columns(3);
|
||||
animate_dialog_tree->set_column_titles_visible(true);
|
||||
animate_dialog_tree->set_hide_folding(true);
|
||||
animate_dialog_tree->set_hide_root(true);
|
||||
|
||||
animate_dialog_tree->set_column_title(0, TTR("Animation"));
|
||||
animate_dialog_tree->set_column_title(1, TTR("Loop"));
|
||||
animate_dialog_tree->set_column_title(2, TTR("Track ID"));
|
||||
|
||||
animate_dialog_tree->create_item();
|
||||
add_row("test1");
|
||||
add_row("test12");
|
||||
add_row("test13");
|
||||
|
||||
auto l = memnew(Label);
|
||||
l->set_text("W.I.P");
|
||||
vb->add_child(l);
|
||||
|
||||
scene_tree_dialog = memnew(SceneTreeDialog);
|
||||
scene_tree_dialog->set_title("Choose a AnimationPlayer to override, or choose none to create a new one.");
|
||||
Vector<StringName> valid_types;
|
||||
valid_types.push_back("AnimationPlayer");
|
||||
scene_tree_dialog->get_scene_tree()->set_valid_types(valid_types);
|
||||
scene_tree_dialog->get_scene_tree()->set_show_enabled_subscene(true);
|
||||
scene_tree_dialog->get_ok()->hide();
|
||||
add_child(scene_tree_dialog);
|
||||
scene_tree_dialog->connect("selected", this, "_on_scene_tree_selected");
|
||||
scene_tree_dialog->connect("popup_hide", this, "_on_scene_tree_hide");
|
||||
|
||||
error_dialog = memnew(AcceptDialog);
|
||||
add_child(error_dialog);
|
||||
}
|
||||
|
||||
SpineSpriteAnimateDialog::~SpineSpriteAnimateDialog() {
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::set_animate_button(ToolButton *b) {
|
||||
animate_button = b;
|
||||
animate_button->connect("pressed", this, "_on_animate_button_pressed");
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::add_row(const String &animation, bool loop, int64_t track_id) {
|
||||
auto item = animate_dialog_tree->create_item();
|
||||
item->set_text(0, animation);
|
||||
|
||||
item->set_cell_mode(1, TreeItem::CELL_MODE_CHECK);
|
||||
item->set_checked(1, loop);
|
||||
item->set_editable(1, true);
|
||||
|
||||
item->set_cell_mode(2, TreeItem::CELL_MODE_RANGE);
|
||||
item->set_range(2, track_id);
|
||||
item->set_editable(2, true);
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::clear_tree() {
|
||||
animate_dialog_tree->clear();
|
||||
animate_dialog_tree->create_item();
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::error(const String &text, const String &title) {
|
||||
error_dialog->set_text(text);
|
||||
error_dialog->set_title(title);
|
||||
error_dialog->popup_centered();
|
||||
}
|
||||
|
||||
#define ERROR_MSG(x) \
|
||||
do { \
|
||||
error(x); \
|
||||
err = true; \
|
||||
return; \
|
||||
} while (false)
|
||||
void SpineSpriteAnimateDialog::load_data_from_sprite(SpineSprite *sprite, bool &err) {
|
||||
if (sprite == nullptr) {
|
||||
ERROR_MSG("The sprite is null.");
|
||||
}
|
||||
if (!sprite->get_animation_state().is_valid() || !sprite->get_skeleton().is_valid()) {
|
||||
ERROR_MSG("The sprite is not loaded.");
|
||||
}
|
||||
clear_tree();
|
||||
|
||||
Vector<String> animations;
|
||||
sprite->get_skeleton()->get_data()->get_animation_names(animations);
|
||||
|
||||
for (size_t i = 0; i < animations.size(); ++i) {
|
||||
add_row(animations[i]);
|
||||
}
|
||||
|
||||
err = false;
|
||||
}
|
||||
|
||||
#define MIN_TRACK_LENGTH 0.15
|
||||
|
||||
void SpineSpriteAnimateDialog::gen_new_animation_player(SpineSprite *sprite, bool &err) {
|
||||
if (sprite == nullptr) {
|
||||
ERROR_MSG("The sprite player is null.");
|
||||
}
|
||||
if (!sprite->get_animation_state().is_valid() || !sprite->get_skeleton().is_valid()) {
|
||||
ERROR_MSG("The sprite is not loaded.");
|
||||
}
|
||||
auto p = sprite->get_parent();
|
||||
if (p == nullptr) {
|
||||
p = sprite;
|
||||
}
|
||||
|
||||
auto anim_player = memnew(AnimationPlayer);
|
||||
anim_player->set_name("AnimationPlayer");
|
||||
p->add_child(anim_player);
|
||||
anim_player->set_owner(sprite->get_owner());
|
||||
anim_player->set_root(anim_player->get_path_to(p));
|
||||
|
||||
gen_animations(sprite, anim_player, get_data_from_tree(), MIN_TRACK_LENGTH, err);
|
||||
}
|
||||
|
||||
Dictionary SpineSpriteAnimateDialog::get_data_from_tree() {
|
||||
Dictionary res;
|
||||
if (animate_dialog_tree->get_root() == nullptr) return res;
|
||||
|
||||
auto item = animate_dialog_tree->get_root()->get_children();
|
||||
while (item) {
|
||||
Dictionary row;
|
||||
row["loop"] = item->is_checked(1);
|
||||
row["track_id"] = item->get_range(2);
|
||||
|
||||
res[item->get_text(0)] = row;
|
||||
item = item->get_next();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::gen_animations(SpineSprite *sprite, AnimationPlayer *anim_player, const Dictionary &config, float min_duration, bool &err) {
|
||||
if (sprite == nullptr || anim_player == nullptr) {
|
||||
ERROR_MSG("The sprite or animation player is null.");
|
||||
}
|
||||
if (!sprite->get_animation_state().is_valid() || !sprite->get_skeleton().is_valid()) {
|
||||
ERROR_MSG("The sprite is not loaded.");
|
||||
}
|
||||
if (anim_player->get_node_or_null(anim_player->get_root()) == nullptr) {
|
||||
ERROR_MSG("The root node of animation player is null.");
|
||||
}
|
||||
|
||||
auto path_to_sprite = anim_player->get_node(anim_player->get_root())->get_path_to(sprite);
|
||||
|
||||
Array animations = sprite->get_skeleton()->get_data()->get_animations();
|
||||
for (size_t i = 0; i < animations.size(); ++i) {
|
||||
auto spine_anim = (Ref<SpineAnimation>) animations[i];
|
||||
|
||||
Dictionary ca;
|
||||
if (config.has(spine_anim->get_anim_name())) {
|
||||
ca = config[spine_anim->get_anim_name()];
|
||||
}
|
||||
|
||||
if (!ca.has("loop")) ca["loop"] = true;
|
||||
if (!ca.has("track_id")) ca["track_id"] = 0;
|
||||
|
||||
Array key_frame_value;
|
||||
key_frame_value.push_back(gen_current_animation_data(spine_anim->get_anim_name(), ca["track_id"], ca["loop"], false, false, 0.3, 0));
|
||||
|
||||
auto anim = Ref<Animation>(memnew(Animation));
|
||||
auto track_index = anim->add_track(Animation::TYPE_VALUE);
|
||||
anim->set_length(min_duration > spine_anim->get_duration() ? min_duration : spine_anim->get_duration());
|
||||
anim->track_set_path(track_index, NodePath(vformat("%s:current_animations", path_to_sprite)));
|
||||
anim->track_insert_key(track_index, 0.0, key_frame_value);
|
||||
anim->value_track_set_update_mode(track_index, Animation::UPDATE_DISCRETE);
|
||||
|
||||
if (anim_player->has_animation(spine_anim->get_anim_name()))
|
||||
anim_player->remove_animation(spine_anim->get_anim_name());
|
||||
anim_player->add_animation(spine_anim->get_anim_name(), anim);
|
||||
}
|
||||
|
||||
err = false;
|
||||
}
|
||||
|
||||
Dictionary SpineSpriteAnimateDialog::gen_current_animation_data(const String &animation, int64_t track_id, bool loop, bool clear, bool empty, bool empty_duration, float delay) {
|
||||
Dictionary res;
|
||||
res["animation"] = animation;
|
||||
res["track_id"] = track_id;
|
||||
res["loop"] = loop;
|
||||
res["clear"] = clear;
|
||||
res["empty"] = empty;
|
||||
res["empty_animation_duration"] = empty_duration;
|
||||
res["delay"] = delay;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void SpineSpriteAnimateDialog::load_data_from_anim_player(AnimationPlayer *anim_player, bool &err) {
|
||||
if (anim_player == nullptr) {
|
||||
ERROR_MSG("The animation player is null.");
|
||||
}
|
||||
auto root = anim_player->get_node_or_null(anim_player->get_root());
|
||||
if (root == nullptr) return;
|
||||
|
||||
auto sprite = get_node_or_null(spine_sprite_path);
|
||||
if (sprite == nullptr) return;
|
||||
|
||||
auto item = animate_dialog_tree->get_root()->get_children();
|
||||
while (item) {
|
||||
String animation = item->get_text(0);
|
||||
|
||||
auto anim = anim_player->get_animation(animation);
|
||||
if (anim.is_valid() && anim->get_track_count() > 0) {
|
||||
if (anim->track_get_type(0) == Animation::TYPE_VALUE) {
|
||||
auto track_path = anim->track_get_path(0);
|
||||
if (root->get_node_or_null(track_path) == sprite) {
|
||||
if (anim->track_get_key_count(0) > 0) {
|
||||
Array key_frame_value = anim->track_get_key_value(0, 0);
|
||||
if (!key_frame_value.empty()) {
|
||||
Dictionary _ca = key_frame_value.front();
|
||||
if (_ca.has("loop")) item->set_checked(1, _ca["loop"]);
|
||||
if (_ca.has("track_id")) item->set_range(2, _ca["track_id"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item = item->get_next();
|
||||
}
|
||||
|
||||
err = false;
|
||||
}
|
||||
|
||||
//----- Signals -----
|
||||
void SpineSpriteAnimateDialog::_on_scene_tree_selected(NodePath path) {
|
||||
// print_line(vformat("anime: %s", path));
|
||||
auto node = get_node_or_null(path);
|
||||
if (node == nullptr) {
|
||||
error("The node you chose is null.");
|
||||
return;
|
||||
}
|
||||
if (!node->is_class("AnimationPlayer")) {
|
||||
error("The node you chose is not AnimationPlayer.");
|
||||
return;
|
||||
}
|
||||
anim_player_path = path;
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::_on_animate_button_pressed() {
|
||||
anim_player_path = String("");
|
||||
auto node = (Node *) the_plugin->get_editor_interface()->get_selection()->get_selected_nodes().back();
|
||||
spine_sprite_path = node->get_path();
|
||||
|
||||
// print_line(vformat("sp: %s", spine_sprite_path));
|
||||
|
||||
animate_dialog_override_button->set_visible(false);
|
||||
scene_tree_dialog->popup_centered_ratio();
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::_on_scene_tree_hide() {
|
||||
animate_dialog->popup_centered();
|
||||
|
||||
bool err = false;
|
||||
load_data_from_sprite((SpineSprite *) get_node_or_null(spine_sprite_path), err);
|
||||
|
||||
if (err) animate_dialog->hide();
|
||||
|
||||
err = false;
|
||||
auto node = get_node_or_null(anim_player_path);
|
||||
if (node != nullptr) {
|
||||
load_data_from_anim_player((AnimationPlayer *) node, err);
|
||||
animate_dialog_override_button->set_visible(!err);
|
||||
} else {
|
||||
animate_dialog_override_button->set_visible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SpineSpriteAnimateDialog::_on_animate_dialog_action(const String &act) {
|
||||
bool err = false;
|
||||
if (act == "confirmed") {
|
||||
gen_new_animation_player((SpineSprite *) get_node_or_null(spine_sprite_path), err);
|
||||
} else if (act == "override") {
|
||||
gen_animations((SpineSprite *) get_node_or_null(spine_sprite_path), (AnimationPlayer *) get_node_or_null(anim_player_path), get_data_from_tree(), MIN_TRACK_LENGTH, err);
|
||||
}
|
||||
if (!err) {
|
||||
animate_dialog->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
@ -1,87 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef GODOT_SPINESPRITEANIMATEDIALOG_H
|
||||
#define GODOT_SPINESPRITEANIMATEDIALOG_H
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/editor_node.h"
|
||||
|
||||
class SpineSprite;
|
||||
|
||||
class SpineSpriteAnimateDialog : public Control {
|
||||
GDCLASS(SpineSpriteAnimateDialog, Control);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
AcceptDialog *error_dialog;
|
||||
|
||||
ToolButton *animate_button;
|
||||
EditorPlugin *the_plugin;
|
||||
|
||||
ConfirmationDialog *animate_dialog;
|
||||
Button *animate_dialog_override_button;
|
||||
Tree *animate_dialog_tree;
|
||||
SceneTreeDialog *scene_tree_dialog;
|
||||
|
||||
NodePath spine_sprite_path;
|
||||
NodePath anim_player_path;
|
||||
|
||||
void add_row(const String &animation, bool loop = true, int64_t track_id = 0);
|
||||
void clear_tree();
|
||||
|
||||
void error(const String &text, const String &title = "Error");
|
||||
|
||||
void load_data_from_sprite(SpineSprite *sprite, bool &err);
|
||||
void load_data_from_anim_player(AnimationPlayer *anim_player, bool &err);
|
||||
|
||||
Dictionary get_data_from_tree();
|
||||
|
||||
void gen_new_animation_player(SpineSprite *sprite, bool &err);
|
||||
void gen_animations(SpineSprite *sprite, AnimationPlayer *anim_player, const Dictionary &config, float min_duration, bool &err);
|
||||
Dictionary gen_current_animation_data(const String &animation, int64_t track_id, bool loop, bool clear, bool empty, bool empty_duration, float delay);
|
||||
|
||||
public:
|
||||
SpineSpriteAnimateDialog();
|
||||
~SpineSpriteAnimateDialog();
|
||||
|
||||
void set_animate_button(ToolButton *b);
|
||||
inline ToolButton *get_animate_button() { return animate_button; }
|
||||
|
||||
inline void set_plugin(EditorPlugin *p) { the_plugin = p; }
|
||||
|
||||
void _on_animate_button_pressed();
|
||||
void _on_scene_tree_selected(NodePath path);
|
||||
void _on_scene_tree_hide();
|
||||
void _on_animate_dialog_action(const String &act);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif//GODOT_SPINESPRITEANIMATEDIALOG_H
|
||||
@ -55,7 +55,6 @@
|
||||
#include "SpineTimeline.h"
|
||||
#include "SpineConstant.h"
|
||||
#include "SpineCollisionShapeProxy.h"
|
||||
#include "SpineSpriteAnimateDialog.h"
|
||||
|
||||
|
||||
static Ref<SpineAtlasResourceFormatLoader> atlas_loader;
|
||||
@ -141,4 +140,4 @@ void unregister_spine_godot_types() {
|
||||
|
||||
ResourceSaver::remove_resource_format_saver(json_skeleton_saver);
|
||||
json_skeleton_saver.unref();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user