Merge branch 'EsotericSoftware:4.2' into 4.2

This commit is contained in:
brogan 2024-10-03 22:04:00 +13:00 committed by GitHub
commit ff6e4e7541
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 156 additions and 35 deletions

View File

@ -33,7 +33,7 @@ jobs:
./spine-godot/build/build.sh release_debug ./spine-godot/build/build.sh release_debug
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-editor-windows.zip name: godot-editor-windows.zip
path: spine-godot/godot/bin/godot.windows.opt.tools.64.exe path: spine-godot/godot/bin/godot.windows.opt.tools.64.exe
@ -57,7 +57,7 @@ jobs:
./spine-godot/build/build.sh release_debug ./spine-godot/build/build.sh release_debug
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-editor-linux.zip name: godot-editor-linux.zip
path: spine-godot/godot/bin/godot.x11.opt.tools.64 path: spine-godot/godot/bin/godot.x11.opt.tools.64
@ -82,7 +82,7 @@ jobs:
popd popd
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-editor-macos.zip name: godot-editor-macos.zip
path: spine-godot/godot/bin/godot-editor-macos.zip path: spine-godot/godot/bin/godot-editor-macos.zip
@ -103,7 +103,7 @@ jobs:
./spine-godot/build/build-templates.sh ios ./spine-godot/build/build-templates.sh ios
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-ios.zip name: godot-template-ios.zip
path: spine-godot/godot/bin/iphone.zip path: spine-godot/godot/bin/iphone.zip
@ -124,7 +124,7 @@ jobs:
./spine-godot/build/build-templates.sh macos ./spine-godot/build/build-templates.sh macos
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-macos.zip name: godot-template-macos.zip
path: spine-godot/godot/bin/osx.zip path: spine-godot/godot/bin/osx.zip
@ -147,13 +147,13 @@ jobs:
./spine-godot/build/build-templates.sh linux ./spine-godot/build/build-templates.sh linux
- name: Upload artifacts debug - name: Upload artifacts debug
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-linux-debug.zip name: godot-template-linux-debug.zip
path: spine-godot/godot/bin/linux_x11_64_debug path: spine-godot/godot/bin/linux_x11_64_debug
- name: Upload artifacts release - name: Upload artifacts release
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-linux-release.zip name: godot-template-linux-release.zip
path: spine-godot/godot/bin/linux_x11_64_release path: spine-godot/godot/bin/linux_x11_64_release
@ -175,13 +175,13 @@ jobs:
./spine-godot/build/build-templates.sh windows ./spine-godot/build/build-templates.sh windows
- name: Upload artifacts debug - name: Upload artifacts debug
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-windows-debug.zip name: godot-template-windows-debug.zip
path: spine-godot/godot/bin/windows_64_debug.exe path: spine-godot/godot/bin/windows_64_debug.exe
- name: Upload artifacts release - name: Upload artifacts release
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-windows-release.zip name: godot-template-windows-release.zip
path: spine-godot/godot/bin/windows_64_release.exe path: spine-godot/godot/bin/windows_64_release.exe
@ -215,19 +215,19 @@ jobs:
./spine-godot/build/build-templates.sh android ./spine-godot/build/build-templates.sh android
- name: Upload artifacts debug - name: Upload artifacts debug
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-android-debug.zip name: godot-template-android-debug.zip
path: spine-godot/godot/bin/android_debug.apk path: spine-godot/godot/bin/android_debug.apk
- name: Upload artifacts release - name: Upload artifacts release
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-android-release.zip name: godot-template-android-release.zip
path: spine-godot/godot/bin/android_release.apk path: spine-godot/godot/bin/android_release.apk
- name: Upload artifacts source - name: Upload artifacts source
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-android-source.zip name: godot-template-android-source.zip
path: spine-godot/godot/bin/android_source.zip path: spine-godot/godot/bin/android_source.zip
@ -257,13 +257,13 @@ jobs:
./spine-godot/build/build-templates.sh web ./spine-godot/build/build-templates.sh web
- name: Upload artifacts debug - name: Upload artifacts debug
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-web-debug.zip name: godot-template-web-debug.zip
path: spine-godot/godot/bin/webassembly_debug.zip path: spine-godot/godot/bin/webassembly_debug.zip
- name: Upload artifacts release - name: Upload artifacts release
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: godot-template-web-release.zip name: godot-template-web-release.zip
path: spine-godot/godot/bin/webassembly_release.zip path: spine-godot/godot/bin/webassembly_release.zip

View File

@ -179,7 +179,7 @@ namespace spine {
return *this; return *this;
} }
bool startsWith(const String &needle) { bool startsWith(const String &needle) const {
if (needle.length() > length()) return false; if (needle.length() > length()) return false;
for (int i = 0; i < (int)needle.length(); i++) { for (int i = 0; i < (int)needle.length(); i++) {
if (buffer()[i] != needle.buffer()[i]) return false; if (buffer()[i] != needle.buffer()[i]) return false;
@ -187,7 +187,7 @@ namespace spine {
return true; return true;
} }
int lastIndexOf(const char c) { int lastIndexOf(const char c) const {
for (int i = (int)length() - 1; i >= 0; i--) { for (int i = (int)length() - 1; i >= 0; i--) {
if (buffer()[i] == c) return i; if (buffer()[i] == c) return i;
} }

View File

@ -77,5 +77,5 @@ void InheritTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vect
return; return;
} }
int idx = Animation::search(_frames, time, ENTRIES) + INHERIT; int idx = Animation::search(_frames, time, ENTRIES) + INHERIT;
bone->_inherit = (Inherit) _frames[idx]; bone->_inherit = static_cast<Inherit>(_frames[idx]);
} }

View File

@ -1,5 +1,5 @@
{ {
"cmake.configureOnOpen": false, "cmake.configureOnOpen": false,
"C_Cpp.intelliSenseEngine": "disabled", "C_Cpp.intelliSenseEngine": "default",
"dotnet.defaultSolution": "disable" "dotnet.defaultSolution": "disable"
} }

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://dr1u7vj8mm6ed"]
[ext_resource type="Script" path="res://examples/13-load-from-disk/load_from_disk.gd" id="1_krs2n"]
[node name="Load-from-disk" type="Node2D"]
script = ExtResource("1_krs2n")

View File

@ -0,0 +1,24 @@
extends Node2D
func _ready():
# Load the skeleton file
var skeleton_file_res = SpineSkeletonFileResource.new();
skeleton_file_res.load_from_file("/Users/badlogic/workspaces/spine-runtimes/examples/coin/export/coin-pro.skel");
# Load the atlas file
var atlas_res = SpineAtlasResource.new();
atlas_res.load_from_atlas_file("/Users/badlogic/workspaces/spine-runtimes/examples/coin/export/coin.atlas");
# Create a skeleton data resource, you can share this across multiple sprites
var skeleton_data_res = SpineSkeletonDataResource.new();
skeleton_data_res.skeleton_file_res = skeleton_file_res;
skeleton_data_res.atlas_res = atlas_res
# Create a sprite from the skeleton data and add it as a child
var sprite = SpineSprite.new();
sprite.skeleton_data_res = skeleton_data_res;
sprite.position.x = 200;
sprite.position.y = 200;
sprite.get_animation_state().set_animation("animation", true, 0);
self.add_child(sprite)
pass

View File

@ -37,7 +37,7 @@
#include "scene/resources/animation.h" #include "scene/resources/animation.h"
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
#include "godot/editor/editor_node.h" #include "editor/editor_node.h"
#include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/animation_player_editor_plugin.h"
#include "editor/plugins/animation_tree_editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h"
#endif #endif

View File

@ -30,45 +30,106 @@
#include "SpineAtlasResource.h" #include "SpineAtlasResource.h"
#include "SpineRendererObject.h" #include "SpineRendererObject.h"
#include "core/io/json.h" #include "core/io/json.h"
#include "core/io/image.h"
#include "scene/resources/image_texture.h"
#include "scene/resources/texture.h" #include "scene/resources/texture.h"
#include <spine/TextureLoader.h> #include <spine/TextureLoader.h>
#ifdef TOOLS_ENABLED
#include "editor/editor_file_system.h"
#endif
class GodotSpineTextureLoader : public spine::TextureLoader { class GodotSpineTextureLoader : public spine::TextureLoader {
Array *textures; Array *textures;
Array *normal_maps; Array *normal_maps;
String normal_map_prefix; String normal_map_prefix;
bool is_importing;
public: public:
GodotSpineTextureLoader(Array *_textures, Array *_normal_maps, const String &normal_map_prefix) : textures(_textures), normal_maps(_normal_maps), normal_map_prefix(normal_map_prefix) { GodotSpineTextureLoader(Array *_textures, Array *_normal_maps, const String &normal_map_prefix, bool is_importing) : textures(_textures), normal_maps(_normal_maps), normal_map_prefix(normal_map_prefix), is_importing(is_importing) {
} }
static String fix_path(const String &path) { static bool fix_path(String &path) {
if (path.size() > 5 && path[4] == '/' && path[5] == '/') return path;
const String prefix = "res:/"; const String prefix = "res:/";
auto i = path.find(prefix); auto i = path.find(prefix);
auto sub_str_pos = i + prefix.size() - 1; if (i == std::string::npos) {
if (sub_str_pos < 0) return path; return false;
auto res = path.substr(sub_str_pos); }
auto sub_str_pos = i + prefix.size() - 1;
auto res = path.substr(sub_str_pos);
if (!EMPTY(res)) { if (!EMPTY(res)) {
if (res[0] != '/') { if (res[0] != '/') {
return prefix + "/" + res; path = prefix + "/" + res;
} else { } else {
return prefix + res; path = prefix + res;
} }
} }
return path; return true;
}
#if VERSION_MAJOR > 3
Ref<Texture2D> get_texture_from_image(const String &path, bool is_resource) {
Error error = OK;
if (is_resource) {
return ResourceLoader::load(path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &error);
} else {
Ref<Image> img;
img.instantiate();
img = img->load_from_file(path);
return ImageTexture::create_from_image(img);
}
}
#else
Ref<Texture> get_texture_from_image(const String &path, bool is_resource) {
Error error = OK;
if (is_resource) {
return ResourceLoader::load(path, "", false, &error);
} else {
Vector<uint8_t> buf = FileAccess::get_file_as_array(path, &error);
if (error == OK) {
Ref<Image> img;
img.instantiate();
String filename = path.get_filename().to_lower();
if (filename.ends_with(".png")) {
img->load_png_from_buffer(buf);
} else if (filename_lower.ends_with(".jpg")) {
img->load_jpg_from_buffer(buf);
}
return ImageTexture::create_from_image(img);
}
}
return Ref<Texture>();
}
#endif
void import_image_resource(const String &path) {
#ifdef VERSION_MAJOR> 4
#ifdef TOOLS_ENABLED
// Required when importing into editor by e.g. drag & drop. The .png files
// of the atlas might not have been imported yet.
// See https://github.com/EsotericSoftware/spine-runtimes/issues/2385
if (is_importing) {
HashMap<StringName, Variant> custom_options;
Dictionary generator_parameters;
EditorFileSystem::get_singleton()->reimport_append(path, custom_options, "", generator_parameters);
}
#endif
#endif
} }
void load(spine::AtlasPage &page, const spine::String &path) override { void load(spine::AtlasPage &page, const spine::String &path) override {
Error error = OK; Error error = OK;
auto fixed_path = fix_path(String(path.buffer())); String fixed_path = String(path.buffer());
bool is_resource = fix_path(fixed_path);
import_image_resource(fixed_path);
#if VERSION_MAJOR > 3 #if VERSION_MAJOR > 3
Ref<Texture2D> texture = ResourceLoader::load(fixed_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &error); Ref<Texture2D> texture = get_texture_from_image(fixed_path, is_resource);
#else #else
Ref<Texture> texture = ResourceLoader::load(fixed_path, "", false, &error); Ref<Texture> texture = get_texture_from_image(fixed_path, is_resource);
#endif #endif
if (error != OK || !texture.is_valid()) { if (error != OK || !texture.is_valid()) {
ERR_PRINT(vformat("Can't load texture: \"%s\"", String(path.buffer()))); ERR_PRINT(vformat("Can't load texture: \"%s\"", String(path.buffer())));
@ -86,7 +147,8 @@ public:
String new_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), normal_map_prefix, fixed_path.get_file()); String new_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), normal_map_prefix, fixed_path.get_file());
if (ResourceLoader::exists(new_path)) { if (ResourceLoader::exists(new_path)) {
Ref<Texture> normal_map = ResourceLoader::load(new_path); import_image_resource(new_path);
Ref<Texture> normal_map = get_texture_from_image(new_path, is_resource);
normal_maps->append(normal_map); normal_maps->append(normal_map);
renderer_object->normal_map = normal_map; renderer_object->normal_map = normal_map;
} }
@ -156,13 +218,17 @@ String SpineAtlasResource::get_source_path() {
} }
Error SpineAtlasResource::load_from_atlas_file(const String &path) { Error SpineAtlasResource::load_from_atlas_file(const String &path) {
load_from_atlas_file_internal(path, false);
}
Error SpineAtlasResource::load_from_atlas_file_internal(const String &path, bool is_importing) {
Error err; Error err;
source_path = path; source_path = path;
atlas_data = FileAccess::get_file_as_string(path, &err); atlas_data = FileAccess::get_file_as_string(path, &err);
if (err != OK) return err; if (err != OK) return err;
clear(); clear();
texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, normal_map_prefix); texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, normal_map_prefix, is_importing);
auto atlas_utf8 = atlas_data.utf8(); auto atlas_utf8 = atlas_data.utf8();
atlas = new spine::Atlas(atlas_utf8, atlas_utf8.length(), source_path.get_base_dir().utf8(), texture_loader); atlas = new spine::Atlas(atlas_utf8, atlas_utf8.length(), source_path.get_base_dir().utf8(), texture_loader);
if (atlas) return OK; if (atlas) return OK;
@ -195,7 +261,7 @@ Error SpineAtlasResource::load_from_file(const String &path) {
normal_map_prefix = content["normal_texture_prefix"]; normal_map_prefix = content["normal_texture_prefix"];
clear(); clear();
texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, normal_map_prefix); texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, normal_map_prefix, false);
auto utf8 = atlas_data.utf8(); auto utf8 = atlas_data.utf8();
atlas = new spine::Atlas(utf8.ptr(), utf8.size(), source_path.get_base_dir().utf8(), texture_loader); atlas = new spine::Atlas(utf8.ptr(), utf8.size(), source_path.get_base_dir().utf8(), texture_loader);
if (atlas) return OK; if (atlas) return OK;

View File

@ -65,6 +65,8 @@ public:
Error load_from_atlas_file(const String &path);// .atlas Error load_from_atlas_file(const String &path);// .atlas
Error load_from_atlas_file_internal(const String &path, bool is_importing);// .atlas
Error load_from_file(const String &path);// .spatlas Error load_from_file(const String &path);// .spatlas
Error save_to_file(const String &path);// .spatlas Error save_to_file(const String &path);// .spatlas

View File

@ -26,6 +26,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE * (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. * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/ *****************************************************************************/
#define VERSION_MAJOR 4
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
#include "SpineEditorPlugin.h" #include "SpineEditorPlugin.h"
@ -40,7 +41,7 @@ Error SpineAtlasResourceImportPlugin::import(const String &source_file, const St
#endif #endif
Ref<SpineAtlasResource> atlas(memnew(SpineAtlasResource)); Ref<SpineAtlasResource> atlas(memnew(SpineAtlasResource));
atlas->set_normal_texture_prefix(options["normal_map_prefix"]); atlas->set_normal_texture_prefix(options["normal_map_prefix"]);
atlas->load_from_atlas_file(source_file); atlas->load_from_atlas_file_internal(source_file, true);
String file_name = vformat("%s.%s", save_path, get_save_extension()); String file_name = vformat("%s.%s", save_path, get_save_extension());
#if VERSION_MAJOR > 3 #if VERSION_MAJOR > 3

View File

@ -47,6 +47,7 @@ void SpineSkeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("find_ik_constraint", "constraint_name"), &SpineSkeleton::find_ik_constraint); ClassDB::bind_method(D_METHOD("find_ik_constraint", "constraint_name"), &SpineSkeleton::find_ik_constraint);
ClassDB::bind_method(D_METHOD("find_transform_constraint", "constraint_name"), &SpineSkeleton::find_transform_constraint); ClassDB::bind_method(D_METHOD("find_transform_constraint", "constraint_name"), &SpineSkeleton::find_transform_constraint);
ClassDB::bind_method(D_METHOD("find_path_constraint", "constraint_name"), &SpineSkeleton::find_path_constraint); ClassDB::bind_method(D_METHOD("find_path_constraint", "constraint_name"), &SpineSkeleton::find_path_constraint);
ClassDB::bind_method(D_METHOD("find_physics_constraint", "constraint_name"), &SpineSkeleton::find_physics_constraint);
ClassDB::bind_method(D_METHOD("get_bounds"), &SpineSkeleton::get_bounds); ClassDB::bind_method(D_METHOD("get_bounds"), &SpineSkeleton::get_bounds);
ClassDB::bind_method(D_METHOD("get_root_bone"), &SpineSkeleton::get_root_bone); ClassDB::bind_method(D_METHOD("get_root_bone"), &SpineSkeleton::get_root_bone);
ClassDB::bind_method(D_METHOD("get_data"), &SpineSkeleton::get_skeleton_data_res); ClassDB::bind_method(D_METHOD("get_data"), &SpineSkeleton::get_skeleton_data_res);

View File

@ -101,6 +101,8 @@ void SpineSkeletonDataResource::_bind_methods() {
&SpineSkeletonDataResource::find_transform_constraint); &SpineSkeletonDataResource::find_transform_constraint);
ClassDB::bind_method(D_METHOD("find_path_constraint_data", "constraint_name"), ClassDB::bind_method(D_METHOD("find_path_constraint_data", "constraint_name"),
&SpineSkeletonDataResource::find_path_constraint); &SpineSkeletonDataResource::find_path_constraint);
ClassDB::bind_method(D_METHOD("find_physics_constraint_data", "constraint_name"),
&SpineSkeletonDataResource::find_physics_constraint);
ClassDB::bind_method(D_METHOD("get_skeleton_name"), ClassDB::bind_method(D_METHOD("get_skeleton_name"),
&SpineSkeletonDataResource::get_skeleton_name); &SpineSkeletonDataResource::get_skeleton_name);
ClassDB::bind_method(D_METHOD("get_bones"), ClassDB::bind_method(D_METHOD("get_bones"),
@ -123,6 +125,8 @@ void SpineSkeletonDataResource::_bind_methods() {
&SpineSkeletonDataResource::get_transform_constraints); &SpineSkeletonDataResource::get_transform_constraints);
ClassDB::bind_method(D_METHOD("get_path_constraints"), ClassDB::bind_method(D_METHOD("get_path_constraints"),
&SpineSkeletonDataResource::get_path_constraints); &SpineSkeletonDataResource::get_path_constraints);
ClassDB::bind_method(D_METHOD("get_physics_constraints"),
&SpineSkeletonDataResource::get_physics_constraints);
ClassDB::bind_method(D_METHOD("get_x"), &SpineSkeletonDataResource::get_x); ClassDB::bind_method(D_METHOD("get_x"), &SpineSkeletonDataResource::get_x);
ClassDB::bind_method(D_METHOD("get_y"), &SpineSkeletonDataResource::get_y); ClassDB::bind_method(D_METHOD("get_y"), &SpineSkeletonDataResource::get_y);
ClassDB::bind_method(D_METHOD("get_width"), ClassDB::bind_method(D_METHOD("get_width"),

View File

@ -89,6 +89,7 @@ static char *readString(BinaryInput *input) {
} }
void SpineSkeletonFileResource::_bind_methods() { void SpineSkeletonFileResource::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_from_file", "path"), &SpineSkeletonFileResource::load_from_file);
ADD_SIGNAL(MethodInfo("skeleton_file_changed")); ADD_SIGNAL(MethodInfo("skeleton_file_changed"));
} }

View File

@ -9,6 +9,12 @@
<tutorials> <tutorials>
</tutorials> </tutorials>
<methods> <methods>
<method name="load_from_file">
<return type="int" enum="Error" />
<argument index="0" name="path" type="String" />
<description>
</description>
</method>
</methods> </methods>
<constants> <constants>
</constants> </constants>

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ff4000"><path d="m5.21 2.36c0 1.15.84 1.79 2.43 2 1.35.21 2.57.11 3-1.05.75-2.22-1.09-1.66-2.64-1.91s-2.85-.9-2.79.96z"/><path d="m5.69 7.1c.15.86.95 1.36 2.18 1.32s2.13-.51 2.28-1.42c.23-1.74-1.15-1.08-2.36-1s-2.39-.59-2.1 1.1z"/><path d="m7.29 11.05c.24.64.91.91 1.82.72s1.53-.49 1.48-1.23c-.09-1.35-1-.93-1.89-.73s-1.89-.03-1.41 1.24z"/><path d="m8.07 14.06c.07.54.54.86 1.27.86s1.3-.3 1.39-.88c.18-1.08-.64-.68-1.38-.67s-1.42-.37-1.28.69z"/></g></svg>

After

Width:  |  Height:  |  Size: 548 B

View File

@ -48,6 +48,7 @@
#include "SpineIkConstraintData.h" #include "SpineIkConstraintData.h"
#include "SpineTransformConstraintData.h" #include "SpineTransformConstraintData.h"
#include "SpinePathConstraintData.h" #include "SpinePathConstraintData.h"
#include "SpinePhysicsConstraintData.h"
#include "SpineTimeline.h" #include "SpineTimeline.h"
#include "SpineConstant.h" #include "SpineConstant.h"
#include "SpineSlotNode.h" #include "SpineSlotNode.h"
@ -109,11 +110,13 @@ void register_spine_godot_types() {
GDREGISTER_CLASS(SpineIkConstraintData); GDREGISTER_CLASS(SpineIkConstraintData);
GDREGISTER_CLASS(SpineTransformConstraintData); GDREGISTER_CLASS(SpineTransformConstraintData);
GDREGISTER_CLASS(SpinePathConstraintData); GDREGISTER_CLASS(SpinePathConstraintData);
GDREGISTER_CLASS(SpinePhysicsConstraintData);
GDREGISTER_CLASS(SpineBone); GDREGISTER_CLASS(SpineBone);
GDREGISTER_CLASS(SpineSlot); GDREGISTER_CLASS(SpineSlot);
GDREGISTER_CLASS(SpineIkConstraint); GDREGISTER_CLASS(SpineIkConstraint);
GDREGISTER_CLASS(SpinePathConstraint); GDREGISTER_CLASS(SpinePathConstraint);
GDREGISTER_CLASS(SpineTransformConstraint); GDREGISTER_CLASS(SpineTransformConstraint);
GDREGISTER_CLASS(SpinePhysicsConstraint);
GDREGISTER_CLASS(SpineTimeline); GDREGISTER_CLASS(SpineTimeline);
GDREGISTER_CLASS(SpineConstant); GDREGISTER_CLASS(SpineConstant);