From 73a38df35577e12acb20cb1f149c0df822cee06c Mon Sep 17 00:00:00 2001 From: Luke Ingram Date: Wed, 1 Oct 2025 09:49:23 -0400 Subject: [PATCH 1/8] [godot] Current WIP to get Spine-Godot working. --- spine-godot/spine_godot/SpineAnimation.cpp | 6 +++- .../spine_godot/SpineAnimationTrack.cpp | 21 +++++++++-- .../spine_godot/SpineAtlasResource.cpp | 17 +++++++-- spine-godot/spine_godot/SpineAttachment.cpp | 6 +++- spine-godot/spine_godot/SpineBoneData.cpp | 6 +++- spine-godot/spine_godot/SpineCommon.h | 4 +-- .../spine_godot/SpineConstraintData.cpp | 6 +++- spine-godot/spine_godot/SpineEditorPlugin.h | 5 +++ spine-godot/spine_godot/SpineEvent.cpp | 2 +- spine-godot/spine_godot/SpineEventData.cpp | 10 ++++-- .../spine_godot/SpineSkeletonDataResource.cpp | 36 +++++++++++++++---- .../spine_godot/SpineSkeletonFileResource.cpp | 2 +- spine-godot/spine_godot/SpineSkin.cpp | 6 +++- spine-godot/spine_godot/SpineSlotData.cpp | 6 +++- spine-godot/spine_godot/SpineSprite.cpp | 12 +++++-- 15 files changed, 119 insertions(+), 26 deletions(-) diff --git a/spine-godot/spine_godot/SpineAnimation.cpp b/spine-godot/spine_godot/SpineAnimation.cpp index 84582a68c..61a5545e6 100644 --- a/spine-godot/spine_godot/SpineAnimation.cpp +++ b/spine-godot/spine_godot/SpineAnimation.cpp @@ -49,7 +49,11 @@ void SpineAnimation::_bind_methods() { String SpineAnimation::get_name() { SPINE_CHECK(get_spine_object(), "") String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineAnimationTrack.cpp b/spine-godot/spine_godot/SpineAnimationTrack.cpp index fd67a65b4..414333872 100644 --- a/spine-godot/spine_godot/SpineAnimationTrack.cpp +++ b/spine-godot/spine_godot/SpineAnimationTrack.cpp @@ -40,9 +40,14 @@ #ifdef TOOLS_ENABLED #include "editor/editor_node.h" +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#include "editor/animation/animation_player_editor_plugin.h" +#include "editor/animation/animation_tree_editor_plugin.h" +#else #include "editor/plugins/animation_player_editor_plugin.h" #include "editor/plugins/animation_tree_editor_plugin.h" #endif +#endif void SpineAnimationTrack::_bind_methods() { ClassDB::bind_method(D_METHOD("set_animation_name", "animation_name"), &SpineAnimationTrack::set_animation_name); @@ -243,7 +248,11 @@ Ref SpineAnimationTrack::create_animation(spine::Animation *animation Ref animation_ref; INSTANTIATE(animation_ref); String name; - name.parse_utf8(animation->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(animation->getName().buffer()); + #else + name.parse_utf8(animation->getName().buffer()); + #endif animation_ref->set_name(name + (loop ? "" : "_looped")); #if VERSION_MAJOR > 3 // animation_ref->set_loop(!loop); @@ -293,7 +302,11 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite) auto current_entry = animation_state->getCurrent(track_index); bool should_set_mix = mix_duration >= 0; String other_name; - if (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + if (current_entry) other_name = String::utf8(current_entry->getAnimation().getName().buffer()); + #else + if (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer()); + #endif bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop); if (should_set_animation) { @@ -428,7 +441,11 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite) auto current_entry = animation_state->getCurrent(track_index); bool should_set_mix = mix_duration >= 0; String other_name; + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + if (current_entry) other_name = String::utf8(current_entry->getAnimation().getName().buffer()); + #else if (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer()); + #endif bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop) || animation_changed; animation_changed = false; diff --git a/spine-godot/spine_godot/SpineAtlasResource.cpp b/spine-godot/spine_godot/SpineAtlasResource.cpp index 482c20e2b..e0763bf2c 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.cpp +++ b/spine-godot/spine_godot/SpineAtlasResource.cpp @@ -51,9 +51,13 @@ #ifdef SPINE_GODOT_EXTENSION #include #else +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#include "editor/file_system/editor_file_system.h" +#else #include "editor/editor_file_system.h" #endif #endif +#endif #include @@ -146,7 +150,11 @@ public: void load(spine::AtlasPage &page, const spine::String &path) override { String fixed_path; - fixed_path.parse_utf8(path.buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + fixed_path = String::utf8(path.buffer()); + #else + fixed_path.parse_utf8(path.buffer()); + #endif bool is_resource = fix_path(fixed_path); import_image_resource(fixed_path); @@ -295,7 +303,9 @@ Error SpineAtlasResource::load_from_atlas_file_internal(const String &path, bool clear(); texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, &specular_maps, normal_map_prefix, specular_map_prefix, is_importing); auto atlas_utf8 = atlas_data.utf8(); - atlas = new spine::Atlas(atlas_utf8, atlas_utf8.length(), source_path.get_base_dir().utf8(), texture_loader); + auto dir_utf8 = source_path.get_base_dir().utf8(); + atlas = new spine::Atlas(atlas_utf8.ptr(), atlas_utf8.length(), dir_utf8.ptr(), texture_loader); + //atlas = new spine::Atlas(atlas_utf8, atlas_utf8.length(), source_path.get_base_dir().utf8(), texture_loader); if (atlas) return OK; clear(); @@ -338,7 +348,8 @@ Error SpineAtlasResource::load_from_file(const String &path) { clear(); texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, &specular_maps, normal_map_prefix, specular_map_prefix, false); auto utf8 = atlas_data.utf8(); - atlas = new spine::Atlas(utf8.ptr(), utf8.size(), source_path.get_base_dir().utf8(), texture_loader); + auto dir_utf8 = source_path.get_base_dir().utf8(); + atlas = new spine::Atlas(utf8.ptr(), utf8.size(), dir_utf8.ptr(), texture_loader); if (atlas) return OK; clear(); diff --git a/spine-godot/spine_godot/SpineAttachment.cpp b/spine-godot/spine_godot/SpineAttachment.cpp index 0161a43ad..87df45e74 100644 --- a/spine-godot/spine_godot/SpineAttachment.cpp +++ b/spine-godot/spine_godot/SpineAttachment.cpp @@ -42,7 +42,11 @@ SpineAttachment::~SpineAttachment() { String SpineAttachment::get_attachment_name() { SPINE_CHECK(get_spine_object(), "") String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineBoneData.cpp b/spine-godot/spine_godot/SpineBoneData.cpp index 2a218161c..a168ad7ca 100644 --- a/spine-godot/spine_godot/SpineBoneData.cpp +++ b/spine-godot/spine_godot/SpineBoneData.cpp @@ -54,7 +54,11 @@ int SpineBoneData::get_index() { String SpineBoneData::get_bone_name() { SPINE_CHECK(get_spine_object(), "") String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineCommon.h b/spine-godot/spine_godot/SpineCommon.h index 14ce5b229..7dc21df8d 100644 --- a/spine-godot/spine_godot/SpineCommon.h +++ b/spine-godot/spine_godot/SpineCommon.h @@ -100,8 +100,8 @@ using namespace godot; return ret; \ } -#define SPINE_STRING(x) spine::String((x).utf8()) -#define SPINE_STRING_TMP(x) spine::String((x).utf8(), true, false) +#define SPINE_STRING(x) spine::String((x).utf8().ptr()) +#define SPINE_STRING_TMP(x) spine::String((x).utf8().ptr(), true, false) // Can't do template classes with Godot's object model :( class SpineObjectWrapper : public REFCOUNTED { diff --git a/spine-godot/spine_godot/SpineConstraintData.cpp b/spine-godot/spine_godot/SpineConstraintData.cpp index 7ff974bc7..863c8a06d 100644 --- a/spine-godot/spine_godot/SpineConstraintData.cpp +++ b/spine-godot/spine_godot/SpineConstraintData.cpp @@ -39,7 +39,11 @@ void SpineConstraintData::_bind_methods() { String SpineConstraintData::get_constraint_name() { SPINE_CHECK(get_spine_object(), "") String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineEditorPlugin.h b/spine-godot/spine_godot/SpineEditorPlugin.h index d84f8ff99..5b1b35a84 100644 --- a/spine-godot/spine_godot/SpineEditorPlugin.h +++ b/spine-godot/spine_godot/SpineEditorPlugin.h @@ -44,9 +44,14 @@ #include #else #include "editor/editor_node.h" +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#include "editor/inspector/editor_properties.h" +#include "editor/inspector/editor_properties_array_dict.h" +#else #include "editor/editor_properties.h" #include "editor/editor_properties_array_dict.h" #endif +#endif class SpineAtlasResourceImportPlugin : public EditorImportPlugin { GDCLASS(SpineAtlasResourceImportPlugin, EditorImportPlugin) diff --git a/spine-godot/spine_godot/SpineEvent.cpp b/spine-godot/spine_godot/SpineEvent.cpp index 3cf68d63b..3a50148cb 100644 --- a/spine-godot/spine_godot/SpineEvent.cpp +++ b/spine-godot/spine_godot/SpineEvent.cpp @@ -85,7 +85,7 @@ String SpineEvent::get_string_value() { void SpineEvent::set_string_value(const String &v) { SPINE_CHECK(get_spine_object(), ) - get_spine_object()->setString(spine::String(v.utf8())); + get_spine_object()->setString(spine::String(v.utf8().ptr())); } float SpineEvent::get_volume() { diff --git a/spine-godot/spine_godot/SpineEventData.cpp b/spine-godot/spine_godot/SpineEventData.cpp index 43c2893b9..0df62af9a 100644 --- a/spine-godot/spine_godot/SpineEventData.cpp +++ b/spine-godot/spine_godot/SpineEventData.cpp @@ -49,7 +49,11 @@ void SpineEventData::_bind_methods() { String SpineEventData::get_event_name() { SPINE_CHECK(get_spine_object(), "") String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } @@ -80,7 +84,7 @@ String SpineEventData::get_string_value() { void SpineEventData::set_string_value(const String &v) { SPINE_CHECK(get_spine_object(), ) - get_spine_object()->setString(spine::String(v.utf8())); + get_spine_object()->setString(spine::String(v.utf8().ptr())); } String SpineEventData::get_audio_path() { @@ -90,7 +94,7 @@ String SpineEventData::get_audio_path() { void SpineEventData::set_audio_path(const String &v) { SPINE_CHECK(get_spine_object(), ) - get_spine_object()->setAudioPath(spine::String(v.utf8())); + get_spine_object()->setAudioPath(spine::String(v.utf8().ptr())); } float SpineEventData::get_volume() { diff --git a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp index fec05a063..636f4ddfe 100644 --- a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp @@ -48,9 +48,13 @@ #ifdef SPINE_GODOT_EXTENSION #include #else +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#include "editor/file_system/editor_file_system.h" +#else #include "editor/editor_file_system.h" #endif #endif +#endif void SpineAnimationMix::_bind_methods() { ClassDB::bind_method(D_METHOD("set_from", "from"), &SpineAnimationMix::set_from); @@ -290,7 +294,7 @@ void SpineSkeletonDataResource::load_resources(spine::Atlas *atlas, const String spine::SkeletonData *data; if (!EMPTY(json)) { spine::SkeletonJson skeletonJson(*atlas); - data = skeletonJson.readSkeletonData(json.utf8()); + data = skeletonJson.readSkeletonData(json.utf8().ptr()); if (!data) { ERR_PRINT(String("Error while loading skeleton data: ") + get_path()); ERR_PRINT(String("Error message: ") + skeletonJson.getError().buffer()); @@ -343,7 +347,11 @@ void SpineSkeletonDataResource::get_animation_names(Vector &animation_na for (size_t i = 0; i < animations.size(); ++i) { auto animation = animations[i]; String name; - name.parse_utf8(animation->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(animation->getName().buffer()); + #else + name.parse_utf8(animation->getName().buffer()); + #endif animation_names.push_back(name); } } @@ -359,7 +367,11 @@ void SpineSkeletonDataResource::get_skin_names(Vector &skin_names) const for (size_t i = 0; i < skins.size(); ++i) { auto skin = skins[i]; String name; - name.parse_utf8(skin->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(skin->getName().buffer()); + #else + name.parse_utf8(skin->getName().buffer()); + #endif skin_names.push_back(name); } } @@ -375,7 +387,11 @@ void SpineSkeletonDataResource::get_slot_names(Vector &slot_names) { for (size_t i = 0; i < slots.size(); ++i) { auto slot = slots[i]; String name; - name.parse_utf8(slot->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(slot->getName().buffer()); + #else + name.parse_utf8(slot->getName().buffer()); + #endif slot_names.push_back(name); } } @@ -391,7 +407,11 @@ void SpineSkeletonDataResource::get_bone_names(Vector &bone_names) { for (size_t i = 0; i < bones.size(); ++i) { auto bone = bones[i]; String name; - name.parse_utf8(bone->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(bone->getName().buffer()); + #else + name.parse_utf8(bone->getName().buffer()); + #endif bone_names.push_back(name); } } @@ -539,7 +559,11 @@ Ref SpineSkeletonDataResource::find_physics_constrai String SpineSkeletonDataResource::get_skeleton_name() const { SPINE_CHECK(skeleton_data, "") String name; - name.parse_utf8(skeleton_data->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(skeleton_data->getName().buffer()); + #else + name.parse_utf8(skeleton_data->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineSkeletonFileResource.cpp b/spine-godot/spine_godot/SpineSkeletonFileResource.cpp index 830c61d94..966dc648d 100644 --- a/spine-godot/spine_godot/SpineSkeletonFileResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonFileResource.cpp @@ -135,7 +135,7 @@ Error SpineSkeletonFileResource::load_from_file(const String &path) { json = FileAccess::get_file_as_string(path, &error); if (error != OK) return error; #endif - if (!checkJson(json.utf8())) return ERR_INVALID_DATA; + if (!checkJson(json.utf8().ptr())) return ERR_INVALID_DATA; } else { #ifdef SPINE_GODOT_EXTENSION binary = FileAccess::get_file_as_bytes(path); diff --git a/spine-godot/spine_godot/SpineSkin.cpp b/spine-godot/spine_godot/SpineSkin.cpp index 88d602e03..7fcf71747 100644 --- a/spine-godot/spine_godot/SpineSkin.cpp +++ b/spine-godot/spine_godot/SpineSkin.cpp @@ -125,7 +125,11 @@ Array SpineSkin::find_attachments_for_slot(int slot_index) { String SpineSkin::get_name() { SPINE_CHECK(get_spine_object(), "") String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineSlotData.cpp b/spine-godot/spine_godot/SpineSlotData.cpp index 29b0f24e0..20e5fc308 100644 --- a/spine-godot/spine_godot/SpineSlotData.cpp +++ b/spine-godot/spine_godot/SpineSlotData.cpp @@ -54,7 +54,11 @@ int SpineSlotData::get_index() { String SpineSlotData::get_name() { SPINE_CHECK(get_spine_object(), String("")) String name; - name.parse_utf8(get_spine_object()->getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); + #else + name.parse_utf8(get_spine_object()->getName().buffer()); + #endif return name; } diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index 8845a9d53..80fa9b66b 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -1220,7 +1220,11 @@ void SpineSprite::draw() { Vector hover_text_lines; if (hovered_slot) { String name; - name.parse_utf8(hovered_slot->getData().getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(hovered_slot->getData().getName().buffer()); + #else + name.parse_utf8(hovered_slot->getData().getName().buffer()); + #endif hover_text_lines.push_back(String("Slot: ") + name); } @@ -1230,7 +1234,11 @@ void SpineSprite::draw() { draw_bone(hovered_bone, Color(debug_bones_color.r, debug_bones_color.g, debug_bones_color.b, 1)); debug_bones_thickness = thickness; String name; - name.parse_utf8(hovered_bone->getData().getName().buffer()); + #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(hovered_bone->getData().getName().buffer()); + #else + name.parse_utf8(hovered_bone->getData().getName().buffer()); + #endif hover_text_lines.push_back(String("Bone: ") + name); } From eccc04fc11e5601b6e713cd4b17acd479ee8e82b Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 1 Oct 2025 15:41:22 +0200 Subject: [PATCH 2/8] [godot] Fix friend classes in SpineSkeleton --- spine-godot/spine_godot/SpineSkeleton.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spine-godot/spine_godot/SpineSkeleton.h b/spine-godot/spine_godot/SpineSkeleton.h index 72b2f7cfc..f28c982a9 100644 --- a/spine-godot/spine_godot/SpineSkeleton.h +++ b/spine-godot/spine_godot/SpineSkeleton.h @@ -61,6 +61,8 @@ class SpineSkeleton : public REFCOUNTED { friend class SpineTransformConstraint; friend class SpinePathConstraint; friend class SpineSlider; + friend class SpineBonePose; + friend class SpineBoneLocal; protected: static void _bind_methods(); From 12d48a79dede86a74c11ec14a15d7677216ca211 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 1 Oct 2025 16:22:46 +0200 Subject: [PATCH 3/8] Updated CHANGELOG for 4.3 --- CHANGELOG.md | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 295 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a81447aec..b800126a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,129 @@ # 4.3 +## C + +- **Additions** + - Added `spine_slider` and `spine_slider_data` types for slider constraints + - Added `spine_slider_timeline` and `spine_slider_mix_timeline` for animating sliders + - Added new pose system with `spine_bone_local`, `spine_bone_pose`, and related types + - Added `spine_pose`, `spine_posed`, and `spine_posed_active` base types + +- **Breaking changes** + - **IMPORTANT**: The C runtime has been completely rewritten as an auto-generated wrapper around the C++ runtime. This is a major breaking change. Users must update their code to use the new API. See https://esotericsoftware.com/spine-c + - All types, functions, and headers have been restructured + - The new runtime provides full feature parity with C++ through automatic code generation, has nullability annotations and documentation, and supports lightweight RTTI, allowing language specific wrappers to be built around it that expose the full type hierarchy idiomatically. See spine-ios and spine-flutter for examples. + - Renamed setup pose functions: + - `spSkeleton_setToSetupPose()` → `spine_skeleton_setup_pose()` + - `spSkeleton_setBonesToSetupPose()` → `spine_skeleton_setup_pose_bones()` + - `spSkeleton_setSlotsToSetupPose()` → `spine_skeleton_setup_pose_slots()` + +### SFML + +- **Restructuring** + - Reorganized directory structure - merged with C++ SFML into unified structure + +- **Breaking changes** + - Updated to use new C runtime API + +### SDL + +- **Additions** + - Added CMakePresets.json for modern CMake configuration + - Updated examples with improved rendering + +- **Restructuring** + - Simplified build system with build.sh script + +- **Breaking changes** + - Updated to use new C runtime API + - `spSkeletonDrawable_update()` now takes additional `spine_physics` parameter + +### GLFW + +- **Additions** + - Added CMakePresets.json for modern CMake configuration + - Added physics example (physics.cpp) + - Added IK following example (ik-following.cpp) + +- **Restructuring** + - Renamed main-cpp-lite.cpp to main-c.cpp + - Simplified build system with build.sh script + +- **Breaking changes** + - Updated to use new C runtime API + +## C++ + +- **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system with `BoneLocal`, `BonePose`, and related classes for improved transform handling + - Added `Pose`, `Posed`, and `PosedActive` base classes for unified pose management + - Added `ConstraintTimeline` interface for unified constraint timeline indexing + - Added `Animation::getBones()` to get bone indices used by an animation + - Added template method `SkeletonData::findConstraint()` for type-safe constraint queries + - Added `SkeletonRenderer` class with `RenderCommand` for batched rendering + - Added `HasRendererObject` interface for attachments with renderer-specific data + +- **Breaking changes** + - Headers reorganized from `spine-cpp/spine-cpp/include/spine/` to `spine-cpp/include/spine/` + - Timeline `apply()` methods now take an additional `appliedPose` parameter + - `Bone` now extends `PosedActive` with separate pose, constrained, and applied states + - Renamed timeline constraint index methods to use unified `getConstraintIndex()` + - Changed timeline class hierarchy with new base classes `BoneTimeline`, `SlotCurveTimeline`, and `ConstraintTimeline` + - Renamed setup pose methods: + - `Skeleton::setToSetupPose()` → `Skeleton::setupPose()` + - `Skeleton::setBonesToSetupPose()` → `Skeleton::setupPoseBones()` + - `Skeleton::setSlotsToSetupPose()` → `Skeleton::setupPoseSlots()` + +### Cocos2d-x +- The runtime has been removed, as Cocos2d-x has not been maintained in years, and the latest version no longer compiles out of the box on macOS, iOS, and other platforms. + +### SFML + +- **Restructuring** + - Reorganized directory structure - merged C and C++ examples into a single structure + - Moved from `spine-sfml/c/` and `spine-sfml/cpp/` to unified `spine-sfml/` structure + - Added CMakePresets.json for modern CMake configuration + - Simplified example structure with single main.cpp + +- **Breaking changes** + - Updated to use new C++ runtime with all breaking changes above + +### UE + +- **Breaking changes** + - Updated to use new C++ runtime with all breaking changes above + +### Godot + +- **Additions** + - Added `SpineSlider` and `SpineSliderData` classes for slider constraints + - Added `SpineBoneLocal` and `SpineBonePose` classes for new pose system + - Added pose classes for constraints: `SpineIkConstraintPose`, `SpinePathConstraintPose`, `SpinePhysicsConstraintPose`, `SpineSliderPose`, `SpineTransformConstraintPose` + +- **Breaking changes** + - Updated to use new C++ pose system with all breaking changes above + ## C# - **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system with `BoneLocal`, `BonePose`, and related classes + - Added `IPose`, `Posed`, and `PosedActive` base classes for unified pose management + - Added `ConstraintTimeline` interface for unified constraint timeline indexing + - Added `Animation.Bones` property to get bone indices used by an animation + - **Breaking changes** + - Timeline `Apply()` methods now take an additional `appliedPose` parameter + - `Bone` now extends `PosedActive` with separate pose, constrained, and applied states + - Reorganized timeline class hierarchy with new base classes + - Renamed timeline constraint index methods to use unified `ConstraintIndex` property + - Renamed setup pose methods: + - `Skeleton.SetToSetupPose()` → `Skeleton.SetupPose()` + - `Skeleton.SetBonesToSetupPose()` → `Skeleton.SetupPoseBones()` + - `Skeleton.SetSlotsToSetupPose()` → `Skeleton.SetupPoseSlots()` ### Unity @@ -15,6 +135,7 @@ - **Breaking changes** - Example skeletons in Spine Examples are now using straight alpha textures and materials for better compatibility with Linear colorspace. + - Updated to use new C# runtime with all breaking changes above - **Changes of default values** - Changed default atlas texture workflow from PMA to straight alpha textures. This move was done because straight alpha textures are compatible with both Gamma and Linear color space, with the latter being the default for quite some time now in Unity. Note that `PMA Vertex Color` is unaffected and shall be enabled as usual to allow for single-pass additive rendering. @@ -24,6 +145,179 @@ - **Restructuring (Non-Breaking)** - Spine Examples have been moved and are now part of the main spine-unity UPM package. To import, select the `spine-unity Runtime` package in the Package Manager window, and in the `Samples` tab and hit `Import`. +### MonoGame + +- **Breaking changes** + - Updated to use new C# runtime with all breaking changes above + +## Dart + +- **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system with `BoneLocal`, `BonePose`, and related classes + - Added `Pose`, `Posed`, and `PosedActive` base classes for unified pose management + +- **Breaking changes** + - The Dart runtime is now fully auto-generated from the C runtime, maintaining the full C++ type hierarchy with proper nullability annotations + - All properties are now exposed as getters and setters instead of methods + - API changes to match C++ naming conventions: + - `AnimationState.getData()` → `AnimationState.data` (property) + - `AnimationState.setAnimationByName()` → `AnimationState.setAnimation()` + - `AnimationState.addAnimationByName()` → `AnimationState.addAnimation()` + - `AnimationState.getCurrent()` → `AnimationState.getCurrent()` + - `Skeleton.setSkinByName()` → `Skeleton.setSkin()` + - `Skeleton.setSkin()` → `Skeleton.setSkin2()` + - `Skeleton.setToSetupPose()` → `Skeleton.setupPose()` + - `Skeleton.setBonesToSetupPose()` → `Skeleton.setupPoseBones()` + - `Skeleton.setSlotsToSetupPose()` → `Skeleton.setupPoseSlots()` + - Timeline `apply()` methods now take an additional `appliedPose` parameter + +### Flutter + +- **Breaking changes** + - Updated to use the new auto-generated Dart runtime with all the Dart API changes above + +## Haxe + +- **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system classes matching the Java implementation + +- **Breaking changes** + - Timeline `apply()` methods now take an additional `appliedPose` parameter + - Updated to use new pose system architecture + - Renamed setup pose methods: + - `Skeleton.setToSetupPose()` → `Skeleton.setupPose()` + - `Skeleton.setBonesToSetupPose()` → `Skeleton.setupPoseBones()` + - `Skeleton.setSlotsToSetupPose()` → `Skeleton.setupPoseSlots()` + +## Java + +- **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system with `BoneLocal`, `BonePose`, and related classes + - Added `Pose`, `Posed`, and `PosedActive` base classes for unified pose management + - Added `ConstraintTimeline` interface for unified constraint timeline indexing + - Added `Animation.getBones()` to get bone indices used by an animation + - Added `SequenceTimeline` for sequence animation + +- **Breaking changes** + - Timeline `apply()` methods now take an additional `appliedPose` parameter + - `Bone` now extends `PosedActive` with separate pose, constrained, and applied states + - Reorganized timeline class hierarchy with `BoneTimeline1`, `BoneTimeline2`, and `SlotCurveTimeline` base classes + - Renamed timeline constraint index methods to use unified `getConstraintIndex()` + - `Bone` constructor no longer takes `Skeleton` parameter + - Renamed setup pose methods: + - `Skeleton.setToSetupPose()` → `Skeleton.setupPose()` + - `Skeleton.setBonesToSetupPose()` → `Skeleton.setupPoseBones()` + - `Skeleton.setSlotsToSetupPose()` → `Skeleton.setupPoseSlots()` + +### libGDX + +- **Breaking changes** + - Updated to use new pose system from Java runtime + +### Android + +- **Breaking changes** + - Updated to use new Java runtime with all breaking changes above + +## Swift + +- **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system with `BoneLocal`, `BonePose`, and related classes + - Added `Pose`, `Posed`, and `PosedActive` base classes for unified pose management + +- **Breaking changes** + - The Swift runtime is now fully auto-generated from the C runtime, maintaining the full C++ type hierarchy with proper nullability annotations + - All properties are now exposed as getters and setters instead of methods + - API changes to match C++ naming conventions: + - `AnimationState.setAnimationByName()` → `AnimationState.setAnimation()` + - `AnimationState.addAnimationByName()` → `AnimationState.addAnimation()` + - `AnimationState.getCurrent()` → `AnimationState.getCurrent()` + - `Skeleton.findSlot(slotName:)` → `Skeleton.findSlot()` + - `Skeleton.setToSetupPose()` → `Skeleton.setupPose()` + - `Skeleton.setBonesToSetupPose()` → `Skeleton.setupPoseBones()` + - `Skeleton.setSlotsToSetupPose()` → `Skeleton.setupPoseSlots()` + - Timeline `apply()` methods now take an additional `appliedPose` parameter + +### iOS + +- **Breaking changes** + - Updated to use the new auto-generated Swift runtime with all the Swift API changes above + +## TypeScript/JavaScript + +- **Additions** + - Added `Slider` and `SliderData` classes for slider constraints + - Added `SliderTimeline` and `SliderMixTimeline` for animating sliders + - Added new pose system classes matching the Java implementation + +- **Breaking changes** + - Timeline `apply()` methods now take an additional `appliedPose` parameter + - Updated to use new pose system architecture + - Renamed setup pose methods: + - `Skeleton.setToSetupPose()` → `Skeleton.setupPose()` + - `Skeleton.setBonesToSetupPose()` → `Skeleton.setupPoseBones()` + - `Skeleton.setSlotsToSetupPose()` → `Skeleton.setupPoseSlots()` + +### WebGL backend + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Canvas backend + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### CanvasKit backend + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + - Simplified rendering implementation + +### Three.js backend + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Player + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Pixi v7 + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Pixi v8 + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Phaser v3 + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Phaser v4 + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + +### Web Components + +- **Breaking changes** + - Updated to use new TypeScript/JavaScript runtime + - Updated skeleton and overlay component implementations + # 4.2 ## C @@ -218,7 +512,7 @@ - Fixed SkeletonRootMotion components ignoring parent bone scale when set by transform constraints. Using applied scale of parent bone now. If you need the old behaviour, comment out the line `#define USE_APPLIED_PARENT_SCALE` in SkeletonRootMotionBase.cs. - Fixed SkeletonUtility callback update order when used with SkeletonRootMotion components so that the position when following a bone is updated after SkeletonRootMotion clears root-bone position. The order of SkeletonUtilityBone callbacks is changed to be later to achieve this. This is a breaking change in the unlikely case that you are using SkeletonRootMotion together with SkeletonUtility and subscribed to `UpdateLocal`, `UpdateWorld` or `UpdateComplete` yourself and relied on a certain callback order. One solution is to then resubscribe your own callback events accordingly by calling `.UpdateLocal -= Callback; .UpdateLocal += Callback;`. - + - **Changes of default values** - **Deprecated** From 8f06f7368aa6342f68a65acf9dff4d8dd9212fb4 Mon Sep 17 00:00:00 2001 From: Davide Tantillo Date: Wed, 1 Oct 2025 16:46:55 +0200 Subject: [PATCH 4/8] [ts] Aligned setMix with reference runtime. --- spine-ts/spine-core/src/AnimationStateData.ts | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/spine-ts/spine-core/src/AnimationStateData.ts b/spine-ts/spine-core/src/AnimationStateData.ts index 3c4112349..725b34a8c 100644 --- a/spine-ts/spine-core/src/AnimationStateData.ts +++ b/spine-ts/spine-core/src/AnimationStateData.ts @@ -49,19 +49,29 @@ export class AnimationStateData { /** Sets a mix duration by animation name. * - * See {@link #setMixWith()}. */ - setMix (fromName: string, toName: string, duration: number) { - let from = this.skeletonData.findAnimation(fromName); - if (!from) throw new Error("Animation not found: " + fromName); - let to = this.skeletonData.findAnimation(toName); - if (!to) throw new Error("Animation not found: " + toName); - this.setMixWith(from, to, duration); - } + * See {@link #setMix()}. */ + setMix (fromName: string, to: string, duration: number): any; /** Sets the mix duration when changing from the specified animation to the other. * * See {@link TrackEntry#mixDuration}. */ - setMixWith (from: Animation, to: Animation, duration: number) { + setMix (from: Animation, to: Animation, duration: number): any; + + setMix (from: string | Animation, to: string | Animation, duration: number) { + if (typeof from === "string") + return this.setMix1(from, to as string, duration); + return this.setMix2(from, to as Animation, duration); + } + + private setMix1 (fromName: string, toName: string, duration: number) { + let from = this.skeletonData.findAnimation(fromName); + if (!from) throw new Error("Animation not found: " + fromName); + let to = this.skeletonData.findAnimation(toName); + if (!to) throw new Error("Animation not found: " + toName); + this.setMix2(from, to, duration); + } + + private setMix2 (from: Animation, to: Animation, duration: number) { if (!from) throw new Error("from cannot be null."); if (!to) throw new Error("to cannot be null."); let key = from.name + "." + to.name; From 666b136a37b8ef2dfed724012a604f55adab4085 Mon Sep 17 00:00:00 2001 From: Davide Tantillo Date: Wed, 1 Oct 2025 16:58:31 +0200 Subject: [PATCH 5/8] Updated CHANGELOG for 4.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b800126a3..2055fffe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -265,6 +265,12 @@ - `Skeleton.setToSetupPose()` → `Skeleton.setupPose()` - `Skeleton.setBonesToSetupPose()` → `Skeleton.setupPoseBones()` - `Skeleton.setSlotsToSetupPose()` → `Skeleton.setupPoseSlots()` + - API changes to match reference runtime naming conventions: + - `addAnimationWith()` → `addAnimation()` + - `setAnimationWith()` → `setAnimation()` + - `setMixWith()` → `setMix()` + - `setSkinByName()` → `setSkin()` + - `getAttachmentByName()` → `getAttachment()` ### WebGL backend From 2f48bf16e26ae4f3260cc9501b9d3de85897e794 Mon Sep 17 00:00:00 2001 From: Luke Ingram Date: Wed, 1 Oct 2025 11:35:20 -0400 Subject: [PATCH 6/8] [godot] Formatting fixes per latest format.sh --- spine-godot/spine_godot/SpineAnimation.cpp | 10 ++-- .../spine_godot/SpineAnimationTrack.cpp | 28 +++++----- .../spine_godot/SpineAtlasResource.cpp | 12 ++--- spine-godot/spine_godot/SpineAttachment.cpp | 10 ++-- spine-godot/spine_godot/SpineBone.cpp | 2 +- spine-godot/spine_godot/SpineBoneData.cpp | 10 ++-- .../spine_godot/SpineConstraintData.cpp | 10 ++-- spine-godot/spine_godot/SpineEditorPlugin.h | 2 +- spine-godot/spine_godot/SpineEventData.cpp | 10 ++-- spine-godot/spine_godot/SpineSkeleton.cpp | 2 +- .../spine_godot/SpineSkeletonDataResource.cpp | 52 +++++++++---------- spine-godot/spine_godot/SpineSkin.cpp | 10 ++-- spine-godot/spine_godot/SpineSlotData.cpp | 10 ++-- spine-godot/spine_godot/SpineSprite.cpp | 26 +++++----- 14 files changed, 98 insertions(+), 96 deletions(-) diff --git a/spine-godot/spine_godot/SpineAnimation.cpp b/spine-godot/spine_godot/SpineAnimation.cpp index 61a5545e6..3a0ece1e3 100644 --- a/spine-godot/spine_godot/SpineAnimation.cpp +++ b/spine-godot/spine_godot/SpineAnimation.cpp @@ -49,11 +49,11 @@ void SpineAnimation::_bind_methods() { String SpineAnimation::get_name() { SPINE_CHECK(get_spine_object(), "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineAnimationTrack.cpp b/spine-godot/spine_godot/SpineAnimationTrack.cpp index 414333872..63faaa212 100644 --- a/spine-godot/spine_godot/SpineAnimationTrack.cpp +++ b/spine-godot/spine_godot/SpineAnimationTrack.cpp @@ -40,7 +40,7 @@ #ifdef TOOLS_ENABLED #include "editor/editor_node.h" -#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) #include "editor/animation/animation_player_editor_plugin.h" #include "editor/animation/animation_tree_editor_plugin.h" #else @@ -248,11 +248,11 @@ Ref SpineAnimationTrack::create_animation(spine::Animation *animation Ref animation_ref; INSTANTIATE(animation_ref); String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(animation->getName().buffer()); - #else - name.parse_utf8(animation->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(animation->getName().buffer()); +#else + name.parse_utf8(animation->getName().buffer()); +#endif animation_ref->set_name(name + (loop ? "" : "_looped")); #if VERSION_MAJOR > 3 // animation_ref->set_loop(!loop); @@ -302,11 +302,11 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite) auto current_entry = animation_state->getCurrent(track_index); bool should_set_mix = mix_duration >= 0; String other_name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - if (current_entry) other_name = String::utf8(current_entry->getAnimation().getName().buffer()); - #else - if (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + if (current_entry) other_name = String::utf8(current_entry->getAnimation().getName().buffer()); +#else + if (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer()); +#endif bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop); if (should_set_animation) { @@ -441,11 +441,11 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite) auto current_entry = animation_state->getCurrent(track_index); bool should_set_mix = mix_duration >= 0; String other_name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) if (current_entry) other_name = String::utf8(current_entry->getAnimation().getName().buffer()); - #else +#else if (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer()); - #endif +#endif bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop) || animation_changed; animation_changed = false; diff --git a/spine-godot/spine_godot/SpineAtlasResource.cpp b/spine-godot/spine_godot/SpineAtlasResource.cpp index e0763bf2c..bddac0dbf 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.cpp +++ b/spine-godot/spine_godot/SpineAtlasResource.cpp @@ -51,7 +51,7 @@ #ifdef SPINE_GODOT_EXTENSION #include #else -#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) #include "editor/file_system/editor_file_system.h" #else #include "editor/editor_file_system.h" @@ -150,11 +150,11 @@ public: void load(spine::AtlasPage &page, const spine::String &path) override { String fixed_path; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - fixed_path = String::utf8(path.buffer()); - #else - fixed_path.parse_utf8(path.buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + fixed_path = String::utf8(path.buffer()); +#else + fixed_path.parse_utf8(path.buffer()); +#endif bool is_resource = fix_path(fixed_path); import_image_resource(fixed_path); diff --git a/spine-godot/spine_godot/SpineAttachment.cpp b/spine-godot/spine_godot/SpineAttachment.cpp index 87df45e74..73535ca8c 100644 --- a/spine-godot/spine_godot/SpineAttachment.cpp +++ b/spine-godot/spine_godot/SpineAttachment.cpp @@ -42,11 +42,11 @@ SpineAttachment::~SpineAttachment() { String SpineAttachment::get_attachment_name() { SPINE_CHECK(get_spine_object(), "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineBone.cpp b/spine-godot/spine_godot/SpineBone.cpp index 6a40f723c..5d26ae690 100644 --- a/spine-godot/spine_godot/SpineBone.cpp +++ b/spine-godot/spine_godot/SpineBone.cpp @@ -223,5 +223,5 @@ void SpineBone::set_global_transform(Transform2D transform) { void SpineBone::update(Ref skeleton, SpineConstant::Physics physics) { SPINE_CHECK(get_spine_object(), ) SPINE_CHECK(skeleton.is_valid() && skeleton->get_spine_object(), ) - get_spine_object()->update(*skeleton->get_spine_object(), (spine::Physics)physics); + get_spine_object()->update(*skeleton->get_spine_object(), (spine::Physics) physics); } diff --git a/spine-godot/spine_godot/SpineBoneData.cpp b/spine-godot/spine_godot/SpineBoneData.cpp index a168ad7ca..0cd43f6af 100644 --- a/spine-godot/spine_godot/SpineBoneData.cpp +++ b/spine-godot/spine_godot/SpineBoneData.cpp @@ -54,11 +54,11 @@ int SpineBoneData::get_index() { String SpineBoneData::get_bone_name() { SPINE_CHECK(get_spine_object(), "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineConstraintData.cpp b/spine-godot/spine_godot/SpineConstraintData.cpp index 863c8a06d..5816181ba 100644 --- a/spine-godot/spine_godot/SpineConstraintData.cpp +++ b/spine-godot/spine_godot/SpineConstraintData.cpp @@ -39,11 +39,11 @@ void SpineConstraintData::_bind_methods() { String SpineConstraintData::get_constraint_name() { SPINE_CHECK(get_spine_object(), "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineEditorPlugin.h b/spine-godot/spine_godot/SpineEditorPlugin.h index 5b1b35a84..abad5b7d5 100644 --- a/spine-godot/spine_godot/SpineEditorPlugin.h +++ b/spine-godot/spine_godot/SpineEditorPlugin.h @@ -44,7 +44,7 @@ #include #else #include "editor/editor_node.h" -#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) #include "editor/inspector/editor_properties.h" #include "editor/inspector/editor_properties_array_dict.h" #else diff --git a/spine-godot/spine_godot/SpineEventData.cpp b/spine-godot/spine_godot/SpineEventData.cpp index 0df62af9a..6812d38df 100644 --- a/spine-godot/spine_godot/SpineEventData.cpp +++ b/spine-godot/spine_godot/SpineEventData.cpp @@ -49,11 +49,11 @@ void SpineEventData::_bind_methods() { String SpineEventData::get_event_name() { SPINE_CHECK(get_spine_object(), "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineSkeleton.cpp b/spine-godot/spine_godot/SpineSkeleton.cpp index 388c41a06..19a990bc0 100644 --- a/spine-godot/spine_godot/SpineSkeleton.cpp +++ b/spine-godot/spine_godot/SpineSkeleton.cpp @@ -378,7 +378,7 @@ Array SpineSkeleton::get_sliders() { auto constraint = constraints[i]; if (!constraint->getRTTI().isExactly(spine::Slider::rtti) == false) continue; Ref slider_ref(memnew(SpineSlider)); - slider_ref->set_spine_object(sprite, (spine::Slider *)constraint); + slider_ref->set_spine_object(sprite, (spine::Slider *) constraint); result.append(slider_ref); } return result; diff --git a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp index 636f4ddfe..dd6b9ab01 100644 --- a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp @@ -48,7 +48,7 @@ #ifdef SPINE_GODOT_EXTENSION #include #else -#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) #include "editor/file_system/editor_file_system.h" #else #include "editor/editor_file_system.h" @@ -347,11 +347,11 @@ void SpineSkeletonDataResource::get_animation_names(Vector &animation_na for (size_t i = 0; i < animations.size(); ++i) { auto animation = animations[i]; String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(animation->getName().buffer()); - #else - name.parse_utf8(animation->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(animation->getName().buffer()); +#else + name.parse_utf8(animation->getName().buffer()); +#endif animation_names.push_back(name); } } @@ -367,11 +367,11 @@ void SpineSkeletonDataResource::get_skin_names(Vector &skin_names) const for (size_t i = 0; i < skins.size(); ++i) { auto skin = skins[i]; String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(skin->getName().buffer()); - #else - name.parse_utf8(skin->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(skin->getName().buffer()); +#else + name.parse_utf8(skin->getName().buffer()); +#endif skin_names.push_back(name); } } @@ -387,11 +387,11 @@ void SpineSkeletonDataResource::get_slot_names(Vector &slot_names) { for (size_t i = 0; i < slots.size(); ++i) { auto slot = slots[i]; String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(slot->getName().buffer()); - #else - name.parse_utf8(slot->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(slot->getName().buffer()); +#else + name.parse_utf8(slot->getName().buffer()); +#endif slot_names.push_back(name); } } @@ -407,11 +407,11 @@ void SpineSkeletonDataResource::get_bone_names(Vector &bone_names) { for (size_t i = 0; i < bones.size(); ++i) { auto bone = bones[i]; String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(bone->getName().buffer()); - #else - name.parse_utf8(bone->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(bone->getName().buffer()); +#else + name.parse_utf8(bone->getName().buffer()); +#endif bone_names.push_back(name); } } @@ -559,11 +559,11 @@ Ref SpineSkeletonDataResource::find_physics_constrai String SpineSkeletonDataResource::get_skeleton_name() const { SPINE_CHECK(skeleton_data, "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(skeleton_data->getName().buffer()); - #else - name.parse_utf8(skeleton_data->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(skeleton_data->getName().buffer()); +#else + name.parse_utf8(skeleton_data->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineSkin.cpp b/spine-godot/spine_godot/SpineSkin.cpp index 7fcf71747..32bc8a07f 100644 --- a/spine-godot/spine_godot/SpineSkin.cpp +++ b/spine-godot/spine_godot/SpineSkin.cpp @@ -125,11 +125,11 @@ Array SpineSkin::find_attachments_for_slot(int slot_index) { String SpineSkin::get_name() { SPINE_CHECK(get_spine_object(), "") String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineSlotData.cpp b/spine-godot/spine_godot/SpineSlotData.cpp index 20e5fc308..f9a210094 100644 --- a/spine-godot/spine_godot/SpineSlotData.cpp +++ b/spine-godot/spine_godot/SpineSlotData.cpp @@ -54,11 +54,11 @@ int SpineSlotData::get_index() { String SpineSlotData::get_name() { SPINE_CHECK(get_spine_object(), String("")) String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(get_spine_object()->getName().buffer()); - #else - name.parse_utf8(get_spine_object()->getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(get_spine_object()->getName().buffer()); +#else + name.parse_utf8(get_spine_object()->getName().buffer()); +#endif return name; } diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index 80fa9b66b..d542eb465 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -1124,7 +1124,8 @@ void SpineSprite::draw() { auto bounding_box = (spine::BoundingBoxAttachment *) attachment; auto vertices = &statics.scratch_vertices; vertices->setSize(bounding_box->getWorldVerticesLength(), 0); - bounding_box->computeWorldVertices(*skeleton->get_spine_object(), *slot, 0, bounding_box->getWorldVerticesLength(), vertices->buffer(), 0, 2); + bounding_box->computeWorldVertices(*skeleton->get_spine_object(), *slot, 0, bounding_box->getWorldVerticesLength(), vertices->buffer(), 0, + 2); size_t num_vertices = vertices->size() / 2; statics.scratch_points.resize((int) num_vertices); memcpy(statics.scratch_points.ptrw(), vertices->buffer(), num_vertices * 2 * sizeof(float)); @@ -1220,11 +1221,11 @@ void SpineSprite::draw() { Vector hover_text_lines; if (hovered_slot) { String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(hovered_slot->getData().getName().buffer()); - #else - name.parse_utf8(hovered_slot->getData().getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(hovered_slot->getData().getName().buffer()); +#else + name.parse_utf8(hovered_slot->getData().getName().buffer()); +#endif hover_text_lines.push_back(String("Slot: ") + name); } @@ -1234,11 +1235,11 @@ void SpineSprite::draw() { draw_bone(hovered_bone, Color(debug_bones_color.r, debug_bones_color.g, debug_bones_color.b, 1)); debug_bones_thickness = thickness; String name; - #if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) - name = String::utf8(hovered_bone->getData().getName().buffer()); - #else - name.parse_utf8(hovered_bone->getData().getName().buffer()); - #endif +#if (VERSION_MAJOR >= 4 && VERSION_MINOR >= 5) + name = String::utf8(hovered_bone->getData().getName().buffer()); +#else + name.parse_utf8(hovered_bone->getData().getName().buffer()); +#endif hover_text_lines.push_back(String("Bone: ") + name); } @@ -1297,7 +1298,8 @@ void SpineSprite::draw() { } void SpineSprite::draw_bone(spine::Bone *bone, const Color &color) { - draw_set_transform(Vector2(bone->getAppliedPose().getWorldX(), bone->getAppliedPose().getWorldY()), spine::MathUtil::Deg_Rad * bone->getAppliedPose().getWorldRotationX(), + draw_set_transform(Vector2(bone->getAppliedPose().getWorldX(), bone->getAppliedPose().getWorldY()), + spine::MathUtil::Deg_Rad * bone->getAppliedPose().getWorldRotationX(), Vector2(bone->getAppliedPose().getWorldScaleX(), bone->getAppliedPose().getWorldScaleY())); float bone_length = bone->getData().getLength(); if (bone_length == 0) bone_length = debug_bones_thickness * 2; From d3b62a2a730d3e41a69097d87aac891705ce0085 Mon Sep 17 00:00:00 2001 From: Luke Ingram Date: Wed, 1 Oct 2025 13:51:12 -0400 Subject: [PATCH 7/8] [godot] Godot 3.x does not have support for specular maps --- spine-godot/spine_godot/SpineSprite.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index d542eb465..ba6cae8e8 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -171,10 +171,16 @@ static void add_triangles(SpineMesh2D *mesh_instance, const Vector &vert auto texture = renderer_object->texture; auto normal_map = renderer_object->normal_map; auto specular_map = renderer_object->specular_map; +#if VERSION_MAJOR > 3 VisualServer::get_singleton()->canvas_item_add_triangle_array(mesh_instance->get_canvas_item(), indices, vertices, colors, uvs, Vector(), Vector(), texture.is_null() ? RID() : texture->get_rid(), -1, normal_map.is_null() ? RID() : normal_map->get_rid(), specular_map.is_null() ? RID() : specular_map->get_rid()); +#else + VisualServer::get_singleton()->canvas_item_add_triangle_array(mesh_instance->get_canvas_item(), indices, vertices, colors, uvs, Vector(), + Vector(), texture.is_null() ? RID() : texture->get_rid(), -1, + normal_map.is_null() ? RID() : normal_map->get_rid()); +#endif #endif #endif } @@ -374,11 +380,16 @@ void SpineMesh2D::update_mesh(const Vector &vertices, const Vectormesh_surface_update_region(mesh, 0, 0, mesh_buffer); VS::get_singleton()->mesh_set_custom_aabb(mesh, aabb_new); } - +#if VERSION_MAJOR > 3 VS::get_singleton()->canvas_item_add_mesh(this->get_canvas_item(), mesh, Transform2D(), Color(1, 1, 1, 1), renderer_object->texture.is_null() ? RID() : renderer_object->texture->get_rid(), renderer_object->normal_map.is_null() ? RID() : renderer_object->normal_map->get_rid(), renderer_object->specular_map.is_null() ? RID() : renderer_object->specular_map->get_rid()); +#else + VS::get_singleton()->canvas_item_add_mesh(this->get_canvas_item(), mesh, Transform2D(), Color(1, 1, 1, 1), + renderer_object->texture.is_null() ? RID() : renderer_object->texture->get_rid(), + renderer_object->normal_map.is_null() ? RID() : renderer_object->normal_map->get_rid()); +#endif #endif } #endif From cc12304bacd701dcdd8b1a02834e6b51ab8dc497 Mon Sep 17 00:00:00 2001 From: Luke Ingram Date: Wed, 1 Oct 2025 19:00:33 -0400 Subject: [PATCH 8/8] [godot] Adds guards needed to build 4.5-stable export templates --- spine-godot/spine_godot/SpineSkeletonDataResource.cpp | 4 ++++ spine-godot/spine_godot/SpineSprite.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp index dd6b9ab01..eadf9f46d 100644 --- a/spine-godot/spine_godot/SpineSkeletonDataResource.cpp +++ b/spine-godot/spine_godot/SpineSkeletonDataResource.cpp @@ -33,11 +33,15 @@ #ifdef SPINE_GODOT_EXTENSION #include #include +#ifdef TOOLS_ENABLED #include +#endif #else #if VERSION_MAJOR > 3 #include "core/config/engine.h" +#ifdef TOOLS_ENABLED #include "editor/editor_interface.h" +#endif #else #include "core/engine.h" #endif diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index ba6cae8e8..752c613dc 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -41,7 +41,9 @@ #include #include #include +#ifdef TOOLS_ENABLED #include +#endif #include #include #include @@ -60,7 +62,7 @@ #include "scene/resources/mesh.h" #include "servers/rendering_server.h" #include "scene/resources/canvas_item_material.h" -#if VERSION_MINOR > 0 +#if VERSION_MINOR > 0 && defined(TOOLS_ENABLED) #include "editor/editor_interface.h" #endif #else