[godot] Add support for binary skeleton files, clean-up import and resource saving/loading infrastructure.

This commit is contained in:
Mario Zechner 2022-04-05 15:21:38 +02:00
parent e9e4a3af65
commit 9d31b83105
25 changed files with 286 additions and 387 deletions

View File

@ -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)

View File

@ -1,7 +1,7 @@
[remap]
importer="spine.json"
type="SpineSkeletonJsonDataResource"
type="SpineSkeletonFileResource"
path="res://.import/mix-and-match-pro.json-5ca1b9fd6cb1c37bf492ced0be2e27b8.spjson"
[deps]

View File

@ -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

Binary file not shown.

View File

@ -0,0 +1,13 @@
[remap]
importer="spine.skel"
type="SpineSkeletonFileResource"
path="res://.import/raptor-pro.skel-081da74993f6ecc0a4d44df29812228b.spskel"
[deps]
source_file="res://raptor/raptor-pro.skel"
dest_files=[ "res://.import/raptor-pro.skel-081da74993f6ecc0a4d44df29812228b.spskel" ]
[params]

View File

@ -0,0 +1,100 @@
raptor.png
size: 1024, 512
filter: Linear, Linear
scale: 0.5
back-arm
bounds: 829, 88, 46, 25
rotate: 90
back-bracer
bounds: 195, 238, 39, 28
rotate: 90
back-hand
bounds: 724, 140, 36, 34
rotate: 90
back-knee
bounds: 760, 131, 49, 67
rotate: 90
back-thigh
bounds: 225, 238, 39, 24
rotate: 90
eyes-open
bounds: 975, 204, 47, 45
front-arm
bounds: 969, 112, 48, 26
front-bracer
bounds: 724, 97, 41, 29
rotate: 90
front-hand
bounds: 251, 239, 41, 38
front-open-hand
bounds: 856, 76, 43, 44
rotate: 90
front-thigh
bounds: 729, 178, 57, 29
rotate: 90
gun
bounds: 894, 251, 107, 103
gun-nohand
bounds: 764, 241, 105, 102
head
bounds: 756, 345, 136, 149
lower-leg
bounds: 475, 237, 73, 98
rotate: 90
mouth-grind
bounds: 975, 172, 47, 30
mouth-smile
bounds: 975, 140, 47, 30
neck
bounds: 366, 282, 18, 21
raptor-back-arm
bounds: 636, 97, 82, 86
rotate: 90
raptor-body
bounds: 2, 2, 632, 233
raptor-front-arm
bounds: 871, 168, 81, 102
rotate: 90
raptor-front-leg
bounds: 2, 237, 191, 257
raptor-hindleg-back
bounds: 195, 279, 169, 215
raptor-horn
bounds: 431, 312, 182, 80
rotate: 90
raptor-horn-back
bounds: 513, 318, 176, 77
rotate: 90
raptor-jaw
bounds: 894, 356, 126, 138
raptor-jaw-tooth
bounds: 294, 240, 37, 48
rotate: 90
raptor-mouth-inside
bounds: 344, 241, 36, 41
rotate: 90
raptor-saddle-strap-back
bounds: 575, 242, 54, 74
raptor-saddle-strap-front
bounds: 764, 182, 57, 95
rotate: 90
raptor-saddle-w-shadow
bounds: 592, 323, 162, 171
raptor-tail-shadow
bounds: 366, 305, 189, 63
rotate: 90
raptor-tongue
bounds: 387, 239, 86, 64
stirrup-back
bounds: 829, 136, 44, 35
rotate: 90
stirrup-front
bounds: 866, 121, 45, 50
rotate: 90
stirrup-strap
bounds: 918, 120, 49, 46
torso
bounds: 636, 181, 54, 91
rotate: 90
visor
bounds: 631, 237, 131, 84

View File

@ -0,0 +1,14 @@
[remap]
importer="spine.atlas"
type="SpineAtlasResource"
path="res://.import/raptor.atlas-583a25d9ded86c934bc106fc3b7bf122.spatlas"
[deps]
source_file="res://raptor/raptor.atlas"
dest_files=[ "res://.import/raptor.atlas-583a25d9ded86c934bc106fc3b7bf122.spatlas" ]
[params]
normal_texture_prefix="n"

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/raptor.png-420f3263481783832181f91be3310d7c.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://raptor/raptor.png"
dest_files=[ "res://.import/raptor.png-420f3263481783832181f91be3310d7c.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -1,17 +1,18 @@
[gd_scene load_steps=10 format=2]
[gd_scene load_steps=11 format=2]
[ext_resource path="res://Spineboy.gd" type="Script" id=1]
[ext_resource path="res://spineboy/spineboy-data.tres" type="SpineSkeletonDataResource" id=2]
[ext_resource path="res://mix-and-match/mix-and-match-pro.json" type="SpineSkeletonJsonDataResource" id=3]
[ext_resource path="res://mix-and-match/mix-and-match-pro.json" type="SpineSkeletonFileResource" id=3]
[ext_resource path="res://mix-and-match/mix-and-match.atlas" type="SpineAtlasResource" id=4]
[ext_resource path="res://mix-and-match.gd" type="Script" id=5]
[ext_resource path="res://raptor/raprot-data.tres" type="SpineSkeletonDataResource" id=6]
[sub_resource type="SpineAnimationStateDataResource" id=2]
skeleton = ExtResource( 2 )
[sub_resource type="SpineSkeletonDataResource" id=4]
atlas_res = ExtResource( 4 )
skeleton_json_res = ExtResource( 3 )
skeleton_file_res = ExtResource( 3 )
animations = null
skins = null
@ -19,7 +20,7 @@ skins = null
skeleton = SubResource( 4 )
[sub_resource type="SpineAnimationStateDataResource" id=5]
skeleton = ExtResource( 2 )
skeleton = ExtResource( 6 )
[node name="Node2D" type="Node2D"]

View File

@ -1,10 +1,10 @@
[gd_resource type="SpineSkeletonDataResource" load_steps=3 format=2]
[ext_resource path="res://spineboy/spineboy.atlas" type="SpineAtlasResource" id=1]
[ext_resource path="res://spineboy/spineboy-pro.json" type="SpineSkeletonJsonDataResource" id=2]
[ext_resource path="res://spineboy/spineboy-pro.json" type="SpineSkeletonFileResource" id=2]
[resource]
atlas_res = ExtResource( 1 )
skeleton_json_res = ExtResource( 2 )
skeleton_file_res = ExtResource( 2 )
animations = null
skins = null

View File

@ -1,7 +1,7 @@
[remap]
importer="spine.json"
type="SpineSkeletonJsonDataResource"
type="SpineSkeletonFileResource"
path="res://.import/spineboy-pro.json-32eeb9972a49130cf636442038541a01.spjson"
[deps]

View File

@ -0,0 +1,13 @@
[remap]
importer="spine.skel"
type="SpineSkeletonFileResource"
path="res://.import/spineboy-pro.skel-88c7de1bbf310b7c70ac742b725847b2.spskel"
[deps]
source_file="res://spineboy/spineboy-pro.skel"
dest_files=[ "res://.import/spineboy-pro.skel-88c7de1bbf310b7c70ac742b725847b2.spskel" ]
[params]

View File

@ -1,56 +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 "ResourceFormatLoaderSpineSkeletonJsonData.h"
#include "SpineSkeletonJsonDataResource.h"
RES ResourceFormatLoaderSpineSkeletonJsonData::load(const String &p_path, const String &p_original_path, Error *r_error) {
Ref<SpineSkeletonJsonDataResource> skeleton = memnew(SpineSkeletonJsonDataResource);
skeleton->load_from_file(p_path);
if (r_error) {
*r_error = OK;
}
return skeleton;
}
void ResourceFormatLoaderSpineSkeletonJsonData::get_recognized_extensions(List<String> *r_extensions) const {
const char json_ext[] = "spjson";
if (!r_extensions->find(json_ext)) {
r_extensions->push_back(json_ext);
}
}
String ResourceFormatLoaderSpineSkeletonJsonData::get_resource_type(const String &p_path) const {
return "SpineSkeletonJsonDataResource";
}
bool ResourceFormatLoaderSpineSkeletonJsonData::handles_type(const String &p_type) const {
return p_type == "SpineSkeletonJsonDataResource" || ClassDB::is_parent_class(p_type, "SpineSkeletonJsonDataResource");
}

View File

@ -1,45 +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_RESOURCEFORMATLOADERSPINESKELETONJSONDATA_H
#define GODOT_RESOURCEFORMATLOADERSPINESKELETONJSONDATA_H
#include "core/io/resource_loader.h"
class ResourceFormatLoaderSpineSkeletonJsonData : public ResourceFormatLoader {
GDCLASS(ResourceFormatLoaderSpineSkeletonJsonData, ResourceFormatLoader);
public:
virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = NULL);
virtual void get_recognized_extensions(List<String> *r_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
#endif//GODOT_RESOURCEFORMATLOADERSPINESKELETONJSONDATA_H

View File

@ -1,48 +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 "ResourceFormatSaverSpineSkeletonJsonData.h"
#include "SpineSkeletonJsonDataResource.h"
Error ResourceFormatSaverSpineSkeletonJsonData::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
Ref<SpineSkeletonJsonDataResource> res = p_resource.get_ref_ptr();
Error error = res->save_to_file(p_path);
return error;
}
void ResourceFormatSaverSpineSkeletonJsonData::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
if (Object::cast_to<SpineSkeletonJsonDataResource>(*p_resource)) {
p_extensions->push_back("spjson");
}
}
bool ResourceFormatSaverSpineSkeletonJsonData::recognize(const RES &p_resource) const {
return Object::cast_to<SpineSkeletonJsonDataResource>(*p_resource) != nullptr;
}

View File

@ -1,45 +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_RESOURCEFORMATSAVERSPINESKELETONJSONDATA_H
#define GODOT_RESOURCEFORMATSAVERSPINESKELETONJSONDATA_H
#include "core/io/resource_saver.h"
class ResourceFormatSaverSpineSkeletonJsonData : public ResourceFormatSaver {
GDCLASS(ResourceFormatSaverSpineSkeletonJsonData, ResourceFormatSaver);
public:
Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0) override;
void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const override;
bool recognize(const RES &p_resource) const override;
};
#endif//GODOT_RESOURCEFORMATSAVERSPINESKELETONJSONDATA_H

View File

@ -64,7 +64,7 @@ void SpineAnimationStateDataResource::set_skeleton(const Ref<SpineSkeletonDataRe
if (skeleton.is_valid()) {
skeleton->connect("skeleton_data_loaded", this, "_on_skeleton_data_loaded");
skeleton->connect("atlas_res_changed", this, "_on_skeleton_data_changed");
skeleton->connect("skeleton_json_res_changed", this, "_on_skeleton_data_changed");
skeleton->connect("skeleton_file_res_changed", this, "_on_skeleton_data_changed");
if (skeleton->is_skeleton_data_loaded()) {
_on_skeleton_data_loaded();
@ -74,7 +74,6 @@ void SpineAnimationStateDataResource::set_skeleton(const Ref<SpineSkeletonDataRe
delete animation_state_data;
animation_state_data = NULL;
animation_state_data_created = false;
// print_line("Animation state data deleted.");
}
}
}
@ -84,20 +83,10 @@ Ref<SpineSkeletonDataResource> SpineAnimationStateDataResource::get_skeleton() c
void SpineAnimationStateDataResource::set_default_mix(float m) {
default_mix = m;
if (!is_animation_state_data_created()) {
// ERR_PRINT("'set_default_mix' fail. Animation state data is not created!");
return;
}
animation_state_data->setDefaultMix(((m >= 0 && m <= 1) ? m : m <= 0 ? 0
: 1));
// emit_signal("animation_state_data_changed");
if (!is_animation_state_data_created()) return;
animation_state_data->setDefaultMix(m);
}
float SpineAnimationStateDataResource::get_default_mix() {
if (!is_animation_state_data_created()) {
// ERR_PRINT("'get_default_mix' fail. Animation state data is not created!");
return default_mix;
}
default_mix = animation_state_data->getDefaultMix();
return default_mix;
}

View File

@ -31,7 +31,7 @@
#include "SpineRuntimeEditorPlugin.h"
#include "SpineAtlasResource.h"
#include "SpineSkeletonJsonDataResource.h"
#include "SpineSkeletonFileResource.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));
@ -55,7 +55,16 @@ void SpineAtlasResourceImportPlugin::get_import_options(List<ImportOption> *r_op
}
Error SpineJsonResourceImportPlugin::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<SpineSkeletonJsonDataResource> res(memnew(SpineSkeletonJsonDataResource));
Ref<SpineSkeletonFileResource> res(memnew(SpineSkeletonFileResource));
res->load_from_file(p_source_file);
String file_name = vformat("%s.%s", p_save_path, get_save_extension());
auto err = ResourceSaver::save(file_name, res);
return err;
}
Error SpineBinaryResourceImportPlugin::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<SpineSkeletonFileResource> res(memnew(SpineSkeletonFileResource));
res->load_from_file(p_source_file);
String file_name = vformat("%s.%s", p_save_path, get_save_extension());
@ -67,6 +76,7 @@ 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));
add_import_plugin(memnew(SpineBinaryResourceImportPlugin));
}
SpineRuntimeEditorPlugin::~SpineRuntimeEditorPlugin() {
@ -76,11 +86,4 @@ bool SpineRuntimeEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("SpineSprite");
}
void SpineRuntimeEditorPlugin::make_visible(bool p_visible) {
if (get_editor_interface()->get_selection()->get_selected_node_list().size() != 1) {
p_visible = false;
}
}
#endif

View File

@ -67,7 +67,27 @@ public:
}
int get_preset_count() const override { return 1; }
String get_save_extension() const override { return "spjson"; }
String get_resource_type() const override { return "SpineSkeletonJsonDataResource"; }
String get_resource_type() const override { return "SpineSkeletonFileResource"; }
void get_import_options(List<ImportOption> *r_options, int p_preset) const override {}
bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override { return true; }
Error 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) override;
};
class SpineBinaryResourceImportPlugin : public EditorImportPlugin {
GDCLASS(SpineBinaryResourceImportPlugin, EditorImportPlugin);
public:
String get_importer_name() const override { return "spine.skel"; }
String get_visible_name() const override { return "Spine Runtime Binary"; }
void get_recognized_extensions(List<String> *p_extensions) const override { p_extensions->push_back("skel"); }
String get_preset_name(int p_idx) const override {
if (p_idx == 0) return "Default";
else
return "Unknown";
}
int get_preset_count() const override { return 1; }
String get_save_extension() const override { return "spskel"; }
String get_resource_type() const override { return "SpineSkeletonFileResource"; }
void get_import_options(List<ImportOption> *r_options, int p_preset) const override {}
bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override { return true; }
Error 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) override;
@ -82,11 +102,7 @@ public:
String get_name() const override { return "SpineRuntimeEditorPlugin"; }
bool has_main_screen() const { return false; }
bool handles(Object *p_object) const override;
void make_visible(bool p_visible) override;
void _on_animate_button_pressed();
};
#endif

View File

@ -32,8 +32,8 @@
void SpineSkeletonDataResource::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_atlas_res", "atlas_res"), &SpineSkeletonDataResource::set_atlas_res);
ClassDB::bind_method(D_METHOD("get_atlas_res"), &SpineSkeletonDataResource::get_atlas_res);
ClassDB::bind_method(D_METHOD("set_skeleton_json_res", "skeleton_json_res"), &SpineSkeletonDataResource::set_skeleton_json_res);
ClassDB::bind_method(D_METHOD("get_skeleton_json_res"), &SpineSkeletonDataResource::get_skeleton_json_res);
ClassDB::bind_method(D_METHOD("set_skeleton_file_res", "skeleton_file_res"), &SpineSkeletonDataResource::set_skeleton_file_res);
ClassDB::bind_method(D_METHOD("get_skeleton_file_res"), &SpineSkeletonDataResource::get_skeleton_file_res);
ClassDB::bind_method(D_METHOD("is_skeleton_data_loaded"), &SpineSkeletonDataResource::is_skeleton_data_loaded);
ClassDB::bind_method(D_METHOD("find_animation", "animation_name"), &SpineSkeletonDataResource::find_animation);
ClassDB::bind_method(D_METHOD("get_sk_name"), &SpineSkeletonDataResource::get_sk_name);
@ -68,10 +68,10 @@ void SpineSkeletonDataResource::_bind_methods() {
ADD_SIGNAL(MethodInfo("skeleton_data_loaded"));
ADD_SIGNAL(MethodInfo("atlas_res_changed"));
ADD_SIGNAL(MethodInfo("skeleton_json_res_changed"));
ADD_SIGNAL(MethodInfo("skeleton_file_res_changed"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineAtlasResource"), "set_atlas_res", "get_atlas_res");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton_json_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineSkeletonJsonDataResource"), "set_skeleton_json_res", "get_skeleton_json_res");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton_file_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineSkeletonFileResource"), "set_skeleton_file_res", "get_skeleton_file_res");
}
SpineSkeletonDataResource::SpineSkeletonDataResource() : valid(false), spine_object(false), skeleton_data(NULL) {
@ -87,29 +87,40 @@ bool SpineSkeletonDataResource::is_skeleton_data_loaded() const {
return valid || spine_object;
}
void SpineSkeletonDataResource::load_res(spine::Atlas *a, const String &json_string) {
if (json_string.empty()) return;
auto path = get_path();
spine::SkeletonJson json(a);
auto temp_skeleton_data = json.readSkeletonData(json_string.utf8());
if (!temp_skeleton_data) {
print_error(String("Error happened while loading skeleton json data: ") + path);
print_error(String("Error msg: ") + json.getError().buffer());
return;
}
void SpineSkeletonDataResource::load_res(spine::Atlas *atlas, const String &json, const Vector<uint8_t> &binary) {
valid = false;
if (skeleton_data) {
delete skeleton_data;
skeleton_data = NULL;
}
skeleton_data = temp_skeleton_data;
if ((json.empty() && binary.empty()) || atlas == NULL) return;
spine::SkeletonData *skeletonData = NULL;
if (!json.empty()) {
spine::SkeletonJson skeletonJson(atlas);
skeletonData = skeletonJson.readSkeletonData(json.utf8());
if (!skeletonData) {
print_error(String("Error while loading skeleton data: ") + get_path());
print_error(String("Error message: ") + skeletonJson.getError().buffer());
return;
}
} else {
spine::SkeletonBinary skeletonBinary(atlas);
skeletonData = skeletonBinary.readSkeletonData(binary.ptr(), binary.size());
if (!skeletonData) {
print_error(String("Error while loading skeleton data: ") + get_path());
print_error(String("Error message: ") + skeletonBinary.getError().buffer());
return;
}
}
skeleton_data = skeletonData;
valid = true;
// print_line("Skeleton json data loaded!");
}
void SpineSkeletonDataResource::update_skeleton_data() {
if (atlas_res.is_valid() && skeleton_json_res.is_valid()) {
load_res(atlas_res->get_spine_atlas(), skeleton_json_res->get_json_string());
if (atlas_res.is_valid() && skeleton_file_res.is_valid()) {
load_res(atlas_res->get_spine_atlas(), skeleton_file_res->get_json(), skeleton_file_res->get_binary());
if (valid) {
emit_signal("skeleton_data_loaded");
}
@ -123,24 +134,17 @@ void SpineSkeletonDataResource::set_atlas_res(const Ref<SpineAtlasResource> &a)
update_skeleton_data();
}
Ref<SpineAtlasResource> SpineSkeletonDataResource::get_atlas_res() {
if (spine_object) {
print_line("Getting atlas res from a spine_object skeleton! The result may be NULL!");
}
return atlas_res;
}
void SpineSkeletonDataResource::set_skeleton_json_res(const Ref<SpineSkeletonJsonDataResource> &s) {
skeleton_json_res = s;
void SpineSkeletonDataResource::set_skeleton_file_res(const Ref<SpineSkeletonFileResource> &s) {
skeleton_file_res = s;
valid = false;
// print_line("skeleton_json_res_changed emitted");
emit_signal("skeleton_json_res_changed");
emit_signal("skeleton_file_res_changed");
update_skeleton_data();
}
Ref<SpineSkeletonJsonDataResource> SpineSkeletonDataResource::get_skeleton_json_res() {
if (spine_object) {
print_line("Getting atlas res from a spine_object skeleton! The result may be NULL!");
}
return skeleton_json_res;
Ref<SpineSkeletonFileResource> SpineSkeletonDataResource::get_skeleton_file_res() {
return skeleton_file_res;
}
#define CHECK_V \

View File

@ -35,7 +35,7 @@
#include <spine/spine.h>
#include "SpineAtlasResource.h"
#include "SpineSkeletonJsonDataResource.h"
#include "SpineSkeletonFileResource.h"
#include "SpineAnimation.h"
#include "SpineBoneData.h"
#include "SpineSlotData.h"
@ -53,7 +53,7 @@ protected:
private:
Ref<SpineAtlasResource> atlas_res;
Ref<SpineSkeletonJsonDataResource> skeleton_json_res;
Ref<SpineSkeletonFileResource> skeleton_file_res;
bool valid;
bool spine_object;
@ -62,6 +62,9 @@ private:
void update_skeleton_data();
public:
SpineSkeletonDataResource();
virtual ~SpineSkeletonDataResource();
inline void set_spine_object(spine::SkeletonData *s) {
skeleton_data = s;
if (s)
@ -71,18 +74,15 @@ public:
return skeleton_data;
}
void load_res(spine::Atlas *a, const String &json_path);
SpineSkeletonDataResource();
virtual ~SpineSkeletonDataResource();
void load_res(spine::Atlas *atlas, const String &json, const Vector<uint8_t> &binary);
void _get_property_list(List<PropertyInfo> *p_list) const;
void set_atlas_res(const Ref<SpineAtlasResource> &a);
Ref<SpineAtlasResource> get_atlas_res();
void set_skeleton_json_res(const Ref<SpineSkeletonJsonDataResource> &s);
Ref<SpineSkeletonJsonDataResource> get_skeleton_json_res();
void set_skeleton_file_res(const Ref<SpineSkeletonFileResource> &s);
Ref<SpineSkeletonFileResource> get_skeleton_file_res();
inline spine::SkeletonData *get_skeleton_data() { return skeleton_data; }

View File

@ -1,55 +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 "SpineSkeletonJsonDataResource.h"
void SpineSkeletonJsonDataResource::_bind_methods() {
}
Error SpineSkeletonJsonDataResource::load_from_file(const String &p_path) {
Error err;
json_string = FileAccess::get_file_as_string(p_path, &err);
return err;
}
Error SpineSkeletonJsonDataResource::save_to_file(const String &p_path) {
Error err;
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err != OK) {
if (file) file->close();
return err;
}
file->store_string(json_string);
file->close();
return OK;
}

View File

@ -1,50 +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_SPINESKELETONJSONDATARESOURCE_H
#define GODOT_SPINESKELETONJSONDATARESOURCE_H
#include "core/variant_parser.h"
class SpineSkeletonJsonDataResource : public Resource {
GDCLASS(SpineSkeletonJsonDataResource, Resource);
protected:
static void _bind_methods();
String json_string;
public:
inline const String &get_json_string() { return json_string; }
Error load_from_file(const String &p_path);
Error save_to_file(const String &p_path);
};
#endif//GODOT_SPINESKELETONJSONDATARESOURCE_H

View File

@ -32,9 +32,8 @@
#include "core/class_db.h"
#include "SpineAtlasResource.h"
#include "SpineSkeletonFileResource.h"
#include "SpineSkeletonDataResource.h"
#include "ResourceFormatLoaderSpineSkeletonJsonData.h"
#include "ResourceFormatSaverSpineSkeletonJsonData.h"
#include "SpineSprite.h"
#include "SpineAnimationStateDataResource.h"
#include "SpineSkeleton.h"
@ -59,8 +58,8 @@
static Ref<SpineAtlasResourceFormatLoader> atlas_loader;
static Ref<SpineAtlasResourceFormatSaver> atlas_saver;
static Ref<ResourceFormatLoaderSpineSkeletonJsonData> json_skeleton_loader;
static Ref<ResourceFormatSaverSpineSkeletonJsonData> json_skeleton_saver;
static Ref<SpineSkeletonFileResourceFormatLoader> skeleton_file_loader;
static Ref<SpineSkeletonFileResourceFormatSaver> skeleton_file_saver;
// editor plugin
#ifdef TOOLS_ENABLED
@ -82,10 +81,10 @@ void register_spine_godot_types() {
#endif
ClassDB::register_class<SpineAtlasResource>();
ClassDB::register_class<SpineSprite>();
ClassDB::register_class<SpineSkeletonFileResource>();
ClassDB::register_class<SpineSkeletonDataResource>();
ClassDB::register_class<SpineAnimationStateDataResource>();
ClassDB::register_class<SpineSkeletonJsonDataResource>();
ClassDB::register_class<SpineSprite>();
ClassDB::register_class<SpineSkeleton>();
ClassDB::register_class<SpineAnimationState>();
ClassDB::register_class<SpineAnimation>();
@ -118,11 +117,11 @@ void register_spine_godot_types() {
atlas_saver.instance();
ResourceSaver::add_resource_format_saver(atlas_saver);
json_skeleton_loader.instance();
ResourceLoader::add_resource_format_loader(json_skeleton_loader);
skeleton_file_loader.instance();
ResourceLoader::add_resource_format_loader(skeleton_file_loader);
json_skeleton_saver.instance();
ResourceSaver::add_resource_format_saver(json_skeleton_saver);
skeleton_file_saver.instance();
ResourceSaver::add_resource_format_saver(skeleton_file_saver);
}
void unregister_spine_godot_types() {
@ -132,9 +131,9 @@ void unregister_spine_godot_types() {
ResourceSaver::remove_resource_format_saver(atlas_saver);
atlas_saver.unref();
ResourceLoader::remove_resource_format_loader(json_skeleton_loader);
json_skeleton_loader.unref();
ResourceLoader::remove_resource_format_loader(skeleton_file_loader);
skeleton_file_loader.unref();
ResourceSaver::remove_resource_format_saver(json_skeleton_saver);
json_skeleton_saver.unref();
ResourceSaver::remove_resource_format_saver(skeleton_file_saver);
skeleton_file_saver.unref();
}