From 9d31b8310585bdbde743e34cda1ac2d3497be0a7 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Tue, 5 Apr 2022 15:21:38 +0200 Subject: [PATCH] [godot] Add support for binary skeleton files, clean-up import and resource saving/loading infrastructure. --- spine-godot/example/mix-and-match.gd | 1 + .../mix-and-match-pro.json.import | 2 +- spine-godot/example/raptor/raprot-data.tres | 10 ++ spine-godot/example/raptor/raptor-pro.skel | Bin 0 -> 82233 bytes .../example/raptor/raptor-pro.skel.import | 13 +++ spine-godot/example/raptor/raptor.atlas | 100 ++++++++++++++++++ .../example/raptor/raptor.atlas.import | 14 +++ spine-godot/example/raptor/raptor.png | Bin 0 -> 421121 bytes spine-godot/example/raptor/raptor.png.import | 35 ++++++ spine-godot/example/spineboy.tscn | 9 +- .../example/spineboy/spineboy-data.tres | 4 +- .../example/spineboy/spineboy-pro.json.import | 2 +- .../example/spineboy/spineboy-pro.skel.import | 13 +++ ...ourceFormatLoaderSpineSkeletonJsonData.cpp | 56 ---------- ...esourceFormatLoaderSpineSkeletonJsonData.h | 45 -------- ...sourceFormatSaverSpineSkeletonJsonData.cpp | 48 --------- ...ResourceFormatSaverSpineSkeletonJsonData.h | 45 -------- .../SpineAnimationStateDataResource.cpp | 17 +-- .../spine_godot/SpineRuntimeEditorPlugin.cpp | 21 ++-- .../spine_godot/SpineRuntimeEditorPlugin.h | 26 ++++- .../spine_godot/SpineSkeletonDataResource.cpp | 64 +++++------ .../spine_godot/SpineSkeletonDataResource.h | 16 +-- .../SpineSkeletonJsonDataResource.cpp | 55 ---------- .../SpineSkeletonJsonDataResource.h | 50 --------- .../modules/spine_godot/register_types.cpp | 27 +++-- 25 files changed, 286 insertions(+), 387 deletions(-) create mode 100644 spine-godot/example/raptor/raprot-data.tres create mode 100644 spine-godot/example/raptor/raptor-pro.skel create mode 100644 spine-godot/example/raptor/raptor-pro.skel.import create mode 100644 spine-godot/example/raptor/raptor.atlas create mode 100644 spine-godot/example/raptor/raptor.atlas.import create mode 100644 spine-godot/example/raptor/raptor.png create mode 100644 spine-godot/example/raptor/raptor.png.import create mode 100644 spine-godot/example/spineboy/spineboy-pro.skel.import delete mode 100644 spine-godot/godot/modules/spine_godot/ResourceFormatLoaderSpineSkeletonJsonData.cpp delete mode 100644 spine-godot/godot/modules/spine_godot/ResourceFormatLoaderSpineSkeletonJsonData.h delete mode 100644 spine-godot/godot/modules/spine_godot/ResourceFormatSaverSpineSkeletonJsonData.cpp delete mode 100644 spine-godot/godot/modules/spine_godot/ResourceFormatSaverSpineSkeletonJsonData.h delete mode 100644 spine-godot/godot/modules/spine_godot/SpineSkeletonJsonDataResource.cpp delete mode 100644 spine-godot/godot/modules/spine_godot/SpineSkeletonJsonDataResource.h diff --git a/spine-godot/example/mix-and-match.gd b/spine-godot/example/mix-and-match.gd index 62b63df48..424b75c9a 100644 --- a/spine-godot/example/mix-and-match.gd +++ b/spine-godot/example/mix-and-match.gd @@ -14,4 +14,5 @@ func _ready(): customSkin.add_skin(data.find_skin("accessories/bag")) customSkin.add_skin(data.find_skin("accessories/hat-red-yellow")) get_skeleton().set_skin(customSkin); + get_animation_state().set_animation("dance", true, 0) diff --git a/spine-godot/example/mix-and-match/mix-and-match-pro.json.import b/spine-godot/example/mix-and-match/mix-and-match-pro.json.import index 819be40c6..6cc3ca6f3 100644 --- a/spine-godot/example/mix-and-match/mix-and-match-pro.json.import +++ b/spine-godot/example/mix-and-match/mix-and-match-pro.json.import @@ -1,7 +1,7 @@ [remap] importer="spine.json" -type="SpineSkeletonJsonDataResource" +type="SpineSkeletonFileResource" path="res://.import/mix-and-match-pro.json-5ca1b9fd6cb1c37bf492ced0be2e27b8.spjson" [deps] diff --git a/spine-godot/example/raptor/raprot-data.tres b/spine-godot/example/raptor/raprot-data.tres new file mode 100644 index 000000000..4106432b7 --- /dev/null +++ b/spine-godot/example/raptor/raprot-data.tres @@ -0,0 +1,10 @@ +[gd_resource type="SpineSkeletonDataResource" load_steps=3 format=2] + +[ext_resource path="res://raptor/raptor.atlas" type="SpineAtlasResource" id=1] +[ext_resource path="res://raptor/raptor-pro.skel" type="SpineSkeletonFileResource" id=2] + +[resource] +atlas_res = ExtResource( 1 ) +skeleton_file_res = ExtResource( 2 ) +animations = null +skins = null diff --git a/spine-godot/example/raptor/raptor-pro.skel b/spine-godot/example/raptor/raptor-pro.skel new file mode 100644 index 0000000000000000000000000000000000000000..32ab530d790c0dbb019ea2d52b7f68de5a6b49f1 GIT binary patch literal 82233 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