[godot] More 4.3 porting and restructuring WIP

This commit is contained in:
Mario Zechner 2025-09-29 16:11:30 +02:00
parent 7496a4fb55
commit 28f93e993a
22 changed files with 1038 additions and 657 deletions

View File

@ -197,7 +197,7 @@ void SpineAnimationTrack::setup_animation_player() {
animation_player->add_animation_library("", animation_library);
#endif
for (int i = 0; i < (int) animations.size(); i++) {
auto &animation = animations[i];
auto animation = animations[i];
Ref<Animation> animation_ref = create_animation(animation, false);
Ref<Animation> animation_looped_ref = create_animation(animation, true);
#if VERSION_MAJOR > 3
@ -285,7 +285,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
AnimationTreeEditor *tree_editor = AnimationTreeEditor::get_singleton();
// When the animation tree dock is no longer visible, bail.
if (!tree_editor->is_visible_in_tree()) {
skeleton->setToSetupPose();
skeleton->setupPose();
animation_state->clearTracks();
animation_state->setTimeScale(1);
return;
@ -293,22 +293,22 @@ 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 (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer());
bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop);
if (should_set_animation) {
if (!EMPTY(animation_name)) {
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
if (should_set_mix) entry->setMixDuration(mix_duration);
auto &entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
if (should_set_mix) entry.setMixDuration(mix_duration);
entry->setHoldPrevious(hold_previous);
entry->setReverse(reverse);
entry->setShortestRotation(shortest_rotation);
entry->setTimeScale(time_scale);
entry->setAlpha(alpha);
entry->setMixAttachmentThreshold(mix_attachment_threshold);
entry->setMixDrawOrderThreshold(mix_draw_order_threshold);
entry->setMixBlend((spine::MixBlend) mix_blend);
entry.setHoldPrevious(hold_previous);
entry.setReverse(reverse);
entry.setShortestRotation(shortest_rotation);
entry.setTimeScale(time_scale);
entry.setAlpha(alpha);
entry.setMixAttachmentThreshold(mix_attachment_threshold);
entry.setMixDrawOrderThreshold(mix_draw_order_threshold);
entry.setMixBlend((spine::MixBlend) mix_blend);
if (debug)
print_line(String("Setting animation {0} with mix_duration {1} on track {2} on {3}")
@ -317,8 +317,8 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
.ptr());
} else {
if (!current_entry || (String("<empty>") != other_name)) {
auto entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0);
entry->setTrackEnd(FLT_MAX);
auto &entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0);
entry.setTrackEnd(FLT_MAX);
if (debug)
print_line(String("Setting empty animation with mix_duration {0} on track {1} on {2}")
.format(varray(mix_duration, track_index, sprite->get_name()))
@ -338,7 +338,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
auto player_editor = AnimationPlayerEditor::singleton;
#endif
if (!player_editor->is_visible_in_tree()) {
skeleton->setToSetupPose();
skeleton->setupPose();
animation_state->clearTracks();
animation_state->setTimeScale(1);
return;
@ -348,7 +348,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
// for us.
Ref<Animation> edited_animation = player_editor->get_track_editor()->get_current_animation();
if (!edited_animation.is_valid()) {
skeleton->setToSetupPose();
skeleton->setupPose();
animation_state->clearTracks();
animation_state->setTimeScale(1);
return;
@ -370,7 +370,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
// setting track times manually. Also, kill anything
// currently in the track.
if (track_index == 0) {
skeleton->setToSetupPose();
skeleton->setupPose();
animation_state->setTimeScale(0);
}
animation_state->clearTrack(track_index);
@ -411,40 +411,40 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
// properties.
float track_time = (playback_position - key_time) * time_scale;
if (track_time < 0) track_time = 0;
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
entry->setMixDuration(0);
entry->setTrackTime(track_time);
auto &entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
entry.setMixDuration(0);
entry.setTrackTime(track_time);
entry->setHoldPrevious(hold_previous);
entry->setReverse(reverse);
entry->setShortestRotation(shortest_rotation);
entry->setAlpha(alpha);
entry->setMixAttachmentThreshold(mix_attachment_threshold);
entry->setMixDrawOrderThreshold(mix_draw_order_threshold);
entry->setMixBlend((spine::MixBlend) mix_blend);
entry.setHoldPrevious(hold_previous);
entry.setReverse(reverse);
entry.setShortestRotation(shortest_rotation);
entry.setAlpha(alpha);
entry.setMixAttachmentThreshold(mix_attachment_threshold);
entry.setMixDrawOrderThreshold(mix_draw_order_threshold);
entry.setMixBlend((spine::MixBlend) mix_blend);
#endif
} else {
if (animation_player->is_playing()) {
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 (current_entry) other_name.parse_utf8(current_entry->getAnimation().getName().buffer());
bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop) || animation_changed;
animation_changed = false;
if (should_set_animation) {
if (!EMPTY(animation_name)) {
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
if (should_set_mix) entry->setMixDuration(mix_duration);
auto &entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
if (should_set_mix) entry.setMixDuration(mix_duration);
entry->setHoldPrevious(hold_previous);
entry->setReverse(reverse);
entry->setShortestRotation(shortest_rotation);
entry->setTimeScale(time_scale);
entry->setAlpha(alpha);
entry->setMixAttachmentThreshold(mix_attachment_threshold);
entry->setMixDrawOrderThreshold(mix_draw_order_threshold);
entry->setMixBlend((spine::MixBlend) mix_blend);
entry.setHoldPrevious(hold_previous);
entry.setReverse(reverse);
entry.setShortestRotation(shortest_rotation);
entry.setTimeScale(time_scale);
entry.setAlpha(alpha);
entry.setMixAttachmentThreshold(mix_attachment_threshold);
entry.setMixDrawOrderThreshold(mix_draw_order_threshold);
entry.setMixBlend((spine::MixBlend) mix_blend);
if (debug)
print_line(String("Setting animation {0} with mix_duration {1} on track {2} on {3}")
@ -453,8 +453,8 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
.ptr());
} else {
if (!current_entry || (String("<empty>") != other_name)) {
auto entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0);
entry->setTrackEnd(FLT_MAX);
auto &entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0);
entry.setTrackEnd(FLT_MAX);
if (debug)
print_line(String("Setting empty animation with mix_duration {0} on track {1} on {2}")
.format(varray(mix_duration, track_index, sprite->get_name()))

View File

@ -44,54 +44,10 @@ void SpineBone::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_data"), &SpineBone::get_data);
ClassDB::bind_method(D_METHOD("get_parent"), &SpineBone::get_parent);
ClassDB::bind_method(D_METHOD("get_children"), &SpineBone::get_children);
ClassDB::bind_method(D_METHOD("get_x"), &SpineBone::get_x);
ClassDB::bind_method(D_METHOD("set_x", "v"), &SpineBone::set_x);
ClassDB::bind_method(D_METHOD("get_y"), &SpineBone::get_y);
ClassDB::bind_method(D_METHOD("set_y", "v"), &SpineBone::set_y);
ClassDB::bind_method(D_METHOD("get_rotation"), &SpineBone::get_rotation);
ClassDB::bind_method(D_METHOD("set_rotation", "v"), &SpineBone::set_rotation);
ClassDB::bind_method(D_METHOD("get_scale_x"), &SpineBone::get_scale_x);
ClassDB::bind_method(D_METHOD("set_scale_x", "v"), &SpineBone::set_scale_x);
ClassDB::bind_method(D_METHOD("get_scale_y"), &SpineBone::get_scale_y);
ClassDB::bind_method(D_METHOD("set_scale_y", "v"), &SpineBone::set_scale_y);
ClassDB::bind_method(D_METHOD("get_shear_x"), &SpineBone::get_shear_x);
ClassDB::bind_method(D_METHOD("set_shear_x", "v"), &SpineBone::set_shear_x);
ClassDB::bind_method(D_METHOD("get_shear_y"), &SpineBone::get_shear_y);
ClassDB::bind_method(D_METHOD("set_shear_y", "v"), &SpineBone::set_shear_y);
ClassDB::bind_method(D_METHOD("get_applied_rotation"), &SpineBone::get_applied_rotation);
ClassDB::bind_method(D_METHOD("set_applied_rotation", "v"), &SpineBone::set_applied_rotation);
ClassDB::bind_method(D_METHOD("get_a_x"), &SpineBone::get_a_x);
ClassDB::bind_method(D_METHOD("set_a_x", "v"), &SpineBone::set_a_x);
ClassDB::bind_method(D_METHOD("get_a_y"), &SpineBone::get_a_y);
ClassDB::bind_method(D_METHOD("set_a_y", "v"), &SpineBone::set_a_y);
ClassDB::bind_method(D_METHOD("get_a_scale_x"), &SpineBone::get_a_scale_x);
ClassDB::bind_method(D_METHOD("set_a_scale_x", "v"), &SpineBone::set_a_scale_x);
ClassDB::bind_method(D_METHOD("get_a_scale_y"), &SpineBone::get_a_scale_y);
ClassDB::bind_method(D_METHOD("set_a_scale_y", "v"), &SpineBone::set_a_scale_y);
ClassDB::bind_method(D_METHOD("get_a_shear_x"), &SpineBone::get_a_shear_x);
ClassDB::bind_method(D_METHOD("set_a_shear_x", "v"), &SpineBone::set_a_shear_x);
ClassDB::bind_method(D_METHOD("get_a_shear_y"), &SpineBone::get_a_shear_y);
ClassDB::bind_method(D_METHOD("set_a_shear_y", "v"), &SpineBone::set_a_shear_y);
ClassDB::bind_method(D_METHOD("get_a"), &SpineBone::get_a);
ClassDB::bind_method(D_METHOD("set_a", "v"), &SpineBone::set_a);
ClassDB::bind_method(D_METHOD("get_b"), &SpineBone::get_b);
ClassDB::bind_method(D_METHOD("set_b", "v"), &SpineBone::set_b);
ClassDB::bind_method(D_METHOD("get_c"), &SpineBone::get_c);
ClassDB::bind_method(D_METHOD("set_c", "v"), &SpineBone::set_c);
ClassDB::bind_method(D_METHOD("get_d"), &SpineBone::get_d);
ClassDB::bind_method(D_METHOD("set_d", "v"), &SpineBone::set_d);
ClassDB::bind_method(D_METHOD("get_world_x"), &SpineBone::get_world_x);
ClassDB::bind_method(D_METHOD("set_world_x", "v"), &SpineBone::set_world_x);
ClassDB::bind_method(D_METHOD("get_world_y"), &SpineBone::get_world_y);
ClassDB::bind_method(D_METHOD("set_world_y", "v"), &SpineBone::set_world_y);
ClassDB::bind_method(D_METHOD("get_world_rotation_x"), &SpineBone::get_world_rotation_x);
ClassDB::bind_method(D_METHOD("get_world_rotation_y"), &SpineBone::get_world_rotation_y);
ClassDB::bind_method(D_METHOD("get_world_scale_x"), &SpineBone::get_world_scale_x);
ClassDB::bind_method(D_METHOD("get_world_scale_y"), &SpineBone::get_world_scale_y);
ClassDB::bind_method(D_METHOD("get_pose"), &SpineBone::get_pose);
ClassDB::bind_method(D_METHOD("get_applied_pose"), &SpineBone::get_applied_pose);
ClassDB::bind_method(D_METHOD("is_active"), &SpineBone::is_active);
ClassDB::bind_method(D_METHOD("set_active", "v"), &SpineBone::set_active);
ClassDB::bind_method(D_METHOD("set_inherit", "v"), &SpineBone::set_inherit);
ClassDB::bind_method(D_METHOD("get_inherit"), &SpineBone::get_inherit);
ClassDB::bind_method(D_METHOD("get_transform"), &SpineBone::get_transform);
ClassDB::bind_method(D_METHOD("set_transform", "local_transform"), &SpineBone::set_transform);
ClassDB::bind_method(D_METHOD("get_global_transform"), &SpineBone::get_global_transform);
@ -161,7 +117,7 @@ Ref<SpineBone> SpineBone::get_parent() {
Array SpineBone::get_children() {
Array result;
SPINE_CHECK(get_spine_object(), result)
auto children = get_spine_object()->getChildren();
auto &children = get_spine_object()->getChildren();
result.resize((int) children.size());
for (int i = 0; i < children.size(); ++i) {
auto child = children[i];
@ -172,225 +128,20 @@ Array SpineBone::get_children() {
return result;
}
float SpineBone::get_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getX();
Ref<SpineBoneLocal> SpineBone::get_pose() {
SPINE_CHECK(get_spine_object(), nullptr)
auto &pose = get_spine_object()->getPose();
Ref<SpineBoneLocal> pose_ref(memnew(SpineBoneLocal));
pose_ref->set_spine_object(get_spine_owner(), &pose);
return pose_ref;
}
void SpineBone::set_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setX(v);
}
float SpineBone::get_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getY();
}
void SpineBone::set_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setY(v);
}
float SpineBone::get_rotation() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getRotation();
}
void SpineBone::set_rotation(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setRotation(v);
}
float SpineBone::get_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getScaleX();
}
void SpineBone::set_scale_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setScaleX(v);
}
float SpineBone::get_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getScaleY();
}
void SpineBone::set_scale_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setScaleY(v);
}
float SpineBone::get_shear_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getShearX();
}
void SpineBone::set_shear_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setShearX(v);
}
float SpineBone::get_shear_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getPose().getShearY();
}
void SpineBone::set_shear_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getPose().setShearY(v);
}
float SpineBone::get_applied_rotation() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getRotation();
}
void SpineBone::set_applied_rotation(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setRotation(v);
}
float SpineBone::get_a_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getX();
}
void SpineBone::set_a_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setX(v);
}
float SpineBone::get_a_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getY();
}
void SpineBone::set_a_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setY(v);
}
float SpineBone::get_a_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getScaleX();
}
void SpineBone::set_a_scale_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setScaleX(v);
}
float SpineBone::get_a_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getScaleY();
}
void SpineBone::set_a_scale_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setScaleY(v);
}
float SpineBone::get_a_shear_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getShearX();
}
void SpineBone::set_a_shear_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setShearX(v);
}
float SpineBone::get_a_shear_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getShearY();
}
void SpineBone::set_a_shear_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setShearY(v);
}
float SpineBone::get_a() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getA();
}
void SpineBone::set_a(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setA(v);
}
float SpineBone::get_b() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getB();
}
void SpineBone::set_b(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setB(v);
}
float SpineBone::get_c() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getC();
}
void SpineBone::set_c(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setC(v);
}
float SpineBone::get_d() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getD();
}
void SpineBone::set_d(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setD(v);
}
float SpineBone::get_world_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getWorldX();
}
void SpineBone::set_world_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setWorldX(v);
}
float SpineBone::get_world_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getWorldY();
}
void SpineBone::set_world_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getAppliedPose().setWorldY(v);
}
float SpineBone::get_world_rotation_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getWorldRotationX();
}
float SpineBone::get_world_rotation_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getWorldRotationY();
}
float SpineBone::get_world_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getWorldScaleX();
}
float SpineBone::get_world_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAppliedPose().getWorldScaleY();
Ref<SpineBonePose> SpineBone::get_applied_pose() {
SPINE_CHECK(get_spine_object(), nullptr)
auto &applied_pose = get_spine_object()->getAppliedPose();
Ref<SpineBonePose> pose_ref(memnew(SpineBonePose));
pose_ref->set_spine_object(get_spine_owner(), &applied_pose);
return pose_ref;
}
bool SpineBone::is_active() {
@ -402,22 +153,13 @@ void SpineBone::set_active(bool v) {
get_spine_object()->setActive(v);
}
SpineConstant::Inherit SpineBone::get_inherit() {
SPINE_CHECK(get_spine_object(), SpineConstant::Inherit_Normal);
return (SpineConstant::Inherit) get_spine_object()->getPose().getInherit();
}
void SpineBone::set_inherit(SpineConstant::Inherit inherit) {
SPINE_CHECK(get_spine_object(), );
get_spine_object()->getPose().setInherit((spine::Inherit) inherit);
}
Transform2D SpineBone::get_transform() {
SPINE_CHECK(get_spine_object(), Transform2D())
Transform2D transform;
transform.rotate(spine::MathUtil::Deg_Rad * get_rotation());
transform.scale(Size2(get_scale_x(), get_scale_y()));
transform.set_origin(Vector2(get_x(), get_y()));
auto &pose = get_spine_object()->getPose();
transform.rotate(spine::MathUtil::Deg_Rad * pose.getRotation());
transform.scale(Size2(pose.getScaleX(), pose.getScaleY()));
transform.set_origin(Vector2(pose.getX(), pose.getY()));
return transform;
}
@ -427,11 +169,12 @@ void SpineBone::set_transform(Transform2D transform) {
float rotation = spine::MathUtil::Rad_Deg * transform.get_rotation();
Vector2 scale = transform.get_scale();
set_x(position.x);
set_y(position.y);
set_rotation(rotation);
set_scale_x(scale.x);
set_scale_y(scale.y);
auto &pose = get_spine_object()->getPose();
pose.setX(position.x);
pose.setY(position.y);
pose.setRotation(rotation);
pose.setScaleX(scale.x);
pose.setScaleY(scale.y);
get_spine_owner()->set_modified_bones();
}
@ -441,9 +184,10 @@ Transform2D SpineBone::get_global_transform() {
if (!get_spine_owner()) return get_transform();
if (!get_spine_owner()->is_visible_in_tree()) return get_transform();
Transform2D local;
local.rotate(spine::MathUtil::Deg_Rad * get_world_rotation_x());
local.scale(Vector2(get_world_scale_x(), get_world_scale_y()));
local.set_origin(Vector2(get_world_x(), get_world_y()));
auto &applied_pose = get_spine_object()->getAppliedPose();
local.rotate(spine::MathUtil::Deg_Rad * applied_pose.getWorldRotationX());
local.scale(Vector2(applied_pose.getWorldScaleX(), applied_pose.getWorldScaleY()));
local.set_origin(Vector2(applied_pose.getWorldX(), applied_pose.getWorldY()));
return get_spine_owner()->get_global_transform() * local;
}

View File

@ -31,6 +31,8 @@
#include "SpineCommon.h"
#include "SpineBoneData.h"
#include "SpineBoneLocal.h"
#include "SpineBonePose.h"
#include "SpineConstant.h"
#ifdef SPINE_GODOT_EXTENSION
#include <godot_cpp/classes/node2d.hpp>
@ -69,102 +71,14 @@ public:
Array get_children();
float get_x();
Ref<SpineBoneLocal> get_pose();
void set_x(float v);
float get_y();
void set_y(float v);
float get_rotation();
void set_rotation(float v);
float get_scale_x();
void set_scale_x(float v);
float get_scale_y();
void set_scale_y(float v);
float get_shear_x();
void set_shear_x(float v);
float get_shear_y();
void set_shear_y(float v);
float get_applied_rotation();
void set_applied_rotation(float v);
float get_a_x();
void set_a_x(float v);
float get_a_y();
void set_a_y(float v);
float get_a_scale_x();
void set_a_scale_x(float v);
float get_a_scale_y();
void set_a_scale_y(float v);
float get_a_shear_x();
void set_a_shear_x(float v);
float get_a_shear_y();
void set_a_shear_y(float v);
float get_a();
void set_a(float v);
float get_b();
void set_b(float v);
float get_c();
void set_c(float v);
float get_d();
void set_d(float v);
float get_world_x();
void set_world_x(float v);
float get_world_y();
void set_world_y(float v);
float get_world_rotation_x();
float get_world_rotation_y();
float get_world_scale_x();
float get_world_scale_y();
Ref<SpineBonePose> get_applied_pose();
bool is_active();
void set_active(bool v);
SpineConstant::Inherit get_inherit();
void set_inherit(SpineConstant::Inherit inherit);
// External feature functions
void apply_world_transform_2d(const Variant &o);

View File

@ -36,22 +36,7 @@ void SpineBoneData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_parent"), &SpineBoneData::get_parent);
ClassDB::bind_method(D_METHOD("get_length"), &SpineBoneData::get_length);
ClassDB::bind_method(D_METHOD("set_length", "v"), &SpineBoneData::set_length);
ClassDB::bind_method(D_METHOD("get_x"), &SpineBoneData::get_x);
ClassDB::bind_method(D_METHOD("set_x", "v"), &SpineBoneData::set_x);
ClassDB::bind_method(D_METHOD("get_y"), &SpineBoneData::get_y);
ClassDB::bind_method(D_METHOD("set_y", "v"), &SpineBoneData::set_y);
ClassDB::bind_method(D_METHOD("get_rotation"), &SpineBoneData::get_rotation);
ClassDB::bind_method(D_METHOD("set_rotation", "v"), &SpineBoneData::set_rotation);
ClassDB::bind_method(D_METHOD("get_scale_x"), &SpineBoneData::get_scale_x);
ClassDB::bind_method(D_METHOD("set_scale_x", "v"), &SpineBoneData::set_scale_x);
ClassDB::bind_method(D_METHOD("get_scale_y"), &SpineBoneData::get_scale_y);
ClassDB::bind_method(D_METHOD("set_scale_y", "v"), &SpineBoneData::set_scale_y);
ClassDB::bind_method(D_METHOD("get_shear_x"), &SpineBoneData::get_shear_x);
ClassDB::bind_method(D_METHOD("set_shear_x", "v"), &SpineBoneData::set_shear_x);
ClassDB::bind_method(D_METHOD("get_shear_y"), &SpineBoneData::get_shear_y);
ClassDB::bind_method(D_METHOD("set_shear_y", "v"), &SpineBoneData::set_shear_y);
ClassDB::bind_method(D_METHOD("get_inherit"), &SpineBoneData::get_inherit);
ClassDB::bind_method(D_METHOD("set_inherit", "v"), &SpineBoneData::set_inherit);
ClassDB::bind_method(D_METHOD("get_setup_pose"), &SpineBoneData::get_setup_pose);
ClassDB::bind_method(D_METHOD("is_skin_required"), &SpineBoneData::is_skin_required);
ClassDB::bind_method(D_METHOD("set_skin_required", "v"), &SpineBoneData::set_skin_required);
ClassDB::bind_method(D_METHOD("get_color"), &SpineBoneData::get_color);
@ -92,84 +77,12 @@ void SpineBoneData::set_length(float v) {
get_spine_object()->setLength(v);
}
float SpineBoneData::get_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getX();
}
void SpineBoneData::set_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setX(v);
}
float SpineBoneData::get_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getY();
}
void SpineBoneData::set_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setY(v);
}
float SpineBoneData::get_rotation() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getRotation();
}
void SpineBoneData::set_rotation(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setRotation(v);
}
float SpineBoneData::get_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getScaleX();
}
void SpineBoneData::set_scale_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setScaleX(v);
}
float SpineBoneData::get_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getScaleY();
}
void SpineBoneData::set_scale_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setScaleY(v);
}
float SpineBoneData::get_shear_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getShearX();
}
void SpineBoneData::set_shear_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setShearX(v);
}
float SpineBoneData::get_shear_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getSetupPose().getShearY();
}
void SpineBoneData::set_shear_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setShearY(v);
}
SpineConstant::Inherit SpineBoneData::get_inherit() {
SPINE_CHECK(get_spine_object(), SpineConstant::Inherit::Inherit_Normal)
return (SpineConstant::Inherit) get_spine_object()->getSetupPose().getInherit();
}
void SpineBoneData::set_inherit(SpineConstant::Inherit v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->getSetupPose().setInherit((spine::Inherit) v);
Ref<SpineBoneLocal> SpineBoneData::get_setup_pose() {
SPINE_CHECK(get_spine_object(), nullptr)
auto &setup_pose = get_spine_object()->getSetupPose();
Ref<SpineBoneLocal> pose_ref(memnew(SpineBoneLocal));
pose_ref->set_spine_object(get_spine_owner(), &setup_pose);
return pose_ref;
}
bool SpineBoneData::is_skin_required() {
@ -184,7 +97,7 @@ void SpineBoneData::set_skin_required(bool v) {
Color SpineBoneData::get_color() {
SPINE_CHECK(get_spine_object(), Color())
auto color = get_spine_object()->getColor();
auto &color = get_spine_object()->getColor();
return Color(color.r, color.g, color.b, color.a);
}

View File

@ -30,6 +30,7 @@
#pragma once
#include "SpineCommon.h"
#include "SpineBoneLocal.h"
#include "SpineConstant.h"
#include <spine/BoneData.h>
@ -52,37 +53,7 @@ public:
void set_length(float v);
float get_x();
void set_x(float v);
float get_y();
void set_y(float v);
float get_rotation();
void set_rotation(float v);
float get_scale_x();
void set_scale_x(float v);
float get_scale_y();
void set_scale_y(float v);
float get_shear_x();
void set_shear_x(float v);
float get_shear_y();
void set_shear_y(float v);
SpineConstant::Inherit get_inherit();
void set_inherit(SpineConstant::Inherit v);
Ref<SpineBoneLocal> get_setup_pose();
bool is_skin_required();

View File

@ -0,0 +1,130 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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 "SpineBoneLocal.h"
#include "SpineCommon.h"
void SpineBoneLocal::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_x"), &SpineBoneLocal::get_x);
ClassDB::bind_method(D_METHOD("set_x", "v"), &SpineBoneLocal::set_x);
ClassDB::bind_method(D_METHOD("get_y"), &SpineBoneLocal::get_y);
ClassDB::bind_method(D_METHOD("set_y", "v"), &SpineBoneLocal::set_y);
ClassDB::bind_method(D_METHOD("get_rotation"), &SpineBoneLocal::get_rotation);
ClassDB::bind_method(D_METHOD("set_rotation", "v"), &SpineBoneLocal::set_rotation);
ClassDB::bind_method(D_METHOD("get_scale_x"), &SpineBoneLocal::get_scale_x);
ClassDB::bind_method(D_METHOD("set_scale_x", "v"), &SpineBoneLocal::set_scale_x);
ClassDB::bind_method(D_METHOD("get_scale_y"), &SpineBoneLocal::get_scale_y);
ClassDB::bind_method(D_METHOD("set_scale_y", "v"), &SpineBoneLocal::set_scale_y);
ClassDB::bind_method(D_METHOD("get_shear_x"), &SpineBoneLocal::get_shear_x);
ClassDB::bind_method(D_METHOD("set_shear_x", "v"), &SpineBoneLocal::set_shear_x);
ClassDB::bind_method(D_METHOD("get_shear_y"), &SpineBoneLocal::get_shear_y);
ClassDB::bind_method(D_METHOD("set_shear_y", "v"), &SpineBoneLocal::set_shear_y);
ClassDB::bind_method(D_METHOD("get_inherit"), &SpineBoneLocal::get_inherit);
ClassDB::bind_method(D_METHOD("set_inherit", "v"), &SpineBoneLocal::set_inherit);
}
float SpineBoneLocal::get_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getX();
}
void SpineBoneLocal::set_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setX(v);
}
float SpineBoneLocal::get_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getY();
}
void SpineBoneLocal::set_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setY(v);
}
float SpineBoneLocal::get_rotation() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getRotation();
}
void SpineBoneLocal::set_rotation(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setRotation(v);
}
float SpineBoneLocal::get_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getScaleX();
}
void SpineBoneLocal::set_scale_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setScaleX(v);
}
float SpineBoneLocal::get_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getScaleY();
}
void SpineBoneLocal::set_scale_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setScaleY(v);
}
float SpineBoneLocal::get_shear_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getShearX();
}
void SpineBoneLocal::set_shear_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setShearX(v);
}
float SpineBoneLocal::get_shear_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getShearY();
}
void SpineBoneLocal::set_shear_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setShearY(v);
}
SpineConstant::Inherit SpineBoneLocal::get_inherit() {
SPINE_CHECK(get_spine_object(), SpineConstant::Inherit_Normal)
return (SpineConstant::Inherit) get_spine_object()->getInherit();
}
void SpineBoneLocal::set_inherit(SpineConstant::Inherit inherit) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setInherit((spine::Inherit) inherit);
}

View File

@ -0,0 +1,78 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#pragma once
#include "SpineCommon.h"
#include "SpineConstant.h"
#include <spine/BoneLocal.h>
class SpineSprite;
class SpineSkeletonDataResource;
class SpineBoneLocal : public SpineObjectWrapper {
GDCLASS(SpineBoneLocal, SpineObjectWrapper)
protected:
static void _bind_methods();
public:
// Can be used by both SpineSprite and SpineSkeletonDataResource
void set_spine_object(void *owner, spine::BoneLocal *object) {
_set_spine_object_internal(owner, object);
}
spine::BoneLocal *get_spine_object() {
return (spine::BoneLocal *) _get_spine_object_internal();
}
float get_x();
void set_x(float v);
float get_y();
void set_y(float v);
float get_rotation();
void set_rotation(float v);
float get_scale_x();
void set_scale_x(float v);
float get_scale_y();
void set_scale_y(float v);
float get_shear_x();
void set_shear_x(float v);
float get_shear_y();
void set_shear_y(float v);
SpineConstant::Inherit get_inherit();
void set_inherit(SpineConstant::Inherit inherit);
};

View File

@ -0,0 +1,284 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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 "SpineBonePose.h"
#include "SpineCommon.h"
void SpineBonePose::_bind_methods() {
// BoneLocal methods
ClassDB::bind_method(D_METHOD("get_x"), &SpineBonePose::get_x);
ClassDB::bind_method(D_METHOD("set_x", "v"), &SpineBonePose::set_x);
ClassDB::bind_method(D_METHOD("get_y"), &SpineBonePose::get_y);
ClassDB::bind_method(D_METHOD("set_y", "v"), &SpineBonePose::set_y);
ClassDB::bind_method(D_METHOD("get_rotation"), &SpineBonePose::get_rotation);
ClassDB::bind_method(D_METHOD("set_rotation", "v"), &SpineBonePose::set_rotation);
ClassDB::bind_method(D_METHOD("get_scale_x"), &SpineBonePose::get_scale_x);
ClassDB::bind_method(D_METHOD("set_scale_x", "v"), &SpineBonePose::set_scale_x);
ClassDB::bind_method(D_METHOD("get_scale_y"), &SpineBonePose::get_scale_y);
ClassDB::bind_method(D_METHOD("set_scale_y", "v"), &SpineBonePose::set_scale_y);
ClassDB::bind_method(D_METHOD("get_shear_x"), &SpineBonePose::get_shear_x);
ClassDB::bind_method(D_METHOD("set_shear_x", "v"), &SpineBonePose::set_shear_x);
ClassDB::bind_method(D_METHOD("get_shear_y"), &SpineBonePose::get_shear_y);
ClassDB::bind_method(D_METHOD("set_shear_y", "v"), &SpineBonePose::set_shear_y);
ClassDB::bind_method(D_METHOD("get_inherit"), &SpineBonePose::get_inherit);
ClassDB::bind_method(D_METHOD("set_inherit", "v"), &SpineBonePose::set_inherit);
// BonePose specific methods
ClassDB::bind_method(D_METHOD("get_a"), &SpineBonePose::get_a);
ClassDB::bind_method(D_METHOD("set_a", "v"), &SpineBonePose::set_a);
ClassDB::bind_method(D_METHOD("get_b"), &SpineBonePose::get_b);
ClassDB::bind_method(D_METHOD("set_b", "v"), &SpineBonePose::set_b);
ClassDB::bind_method(D_METHOD("get_c"), &SpineBonePose::get_c);
ClassDB::bind_method(D_METHOD("set_c", "v"), &SpineBonePose::set_c);
ClassDB::bind_method(D_METHOD("get_d"), &SpineBonePose::get_d);
ClassDB::bind_method(D_METHOD("set_d", "v"), &SpineBonePose::set_d);
ClassDB::bind_method(D_METHOD("get_world_x"), &SpineBonePose::get_world_x);
ClassDB::bind_method(D_METHOD("set_world_x", "v"), &SpineBonePose::set_world_x);
ClassDB::bind_method(D_METHOD("get_world_y"), &SpineBonePose::get_world_y);
ClassDB::bind_method(D_METHOD("set_world_y", "v"), &SpineBonePose::set_world_y);
ClassDB::bind_method(D_METHOD("get_world_rotation_x"), &SpineBonePose::get_world_rotation_x);
ClassDB::bind_method(D_METHOD("get_world_rotation_y"), &SpineBonePose::get_world_rotation_y);
ClassDB::bind_method(D_METHOD("get_world_scale_x"), &SpineBonePose::get_world_scale_x);
ClassDB::bind_method(D_METHOD("get_world_scale_y"), &SpineBonePose::get_world_scale_y);
// Transformation methods
ClassDB::bind_method(D_METHOD("world_to_local", "world_position"), &SpineBonePose::world_to_local);
ClassDB::bind_method(D_METHOD("local_to_world", "local_position"), &SpineBonePose::local_to_world);
ClassDB::bind_method(D_METHOD("world_to_parent", "world_position"), &SpineBonePose::world_to_parent);
ClassDB::bind_method(D_METHOD("parent_to_world", "parent_position"), &SpineBonePose::parent_to_world);
ClassDB::bind_method(D_METHOD("world_to_local_rotation", "world_rotation"), &SpineBonePose::world_to_local_rotation);
ClassDB::bind_method(D_METHOD("local_to_world_rotation", "local_rotation"), &SpineBonePose::local_to_world_rotation);
ClassDB::bind_method(D_METHOD("rotate_world", "degrees"), &SpineBonePose::rotate_world);
}
// BoneLocal properties
float SpineBonePose::get_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getX();
}
void SpineBonePose::set_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setX(v);
}
float SpineBonePose::get_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getY();
}
void SpineBonePose::set_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setY(v);
}
float SpineBonePose::get_rotation() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getRotation();
}
void SpineBonePose::set_rotation(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setRotation(v);
}
float SpineBonePose::get_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getScaleX();
}
void SpineBonePose::set_scale_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setScaleX(v);
}
float SpineBonePose::get_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getScaleY();
}
void SpineBonePose::set_scale_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setScaleY(v);
}
float SpineBonePose::get_shear_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getShearX();
}
void SpineBonePose::set_shear_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setShearX(v);
}
float SpineBonePose::get_shear_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getShearY();
}
void SpineBonePose::set_shear_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setShearY(v);
}
SpineConstant::Inherit SpineBonePose::get_inherit() {
SPINE_CHECK(get_spine_object(), SpineConstant::Inherit_Normal)
return (SpineConstant::Inherit) get_spine_object()->getInherit();
}
void SpineBonePose::set_inherit(SpineConstant::Inherit inherit) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setInherit((spine::Inherit) inherit);
}
// BonePose specific properties
float SpineBonePose::get_a() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getA();
}
void SpineBonePose::set_a(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setA(v);
}
float SpineBonePose::get_b() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getB();
}
void SpineBonePose::set_b(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setB(v);
}
float SpineBonePose::get_c() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getC();
}
void SpineBonePose::set_c(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setC(v);
}
float SpineBonePose::get_d() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getD();
}
void SpineBonePose::set_d(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setD(v);
}
float SpineBonePose::get_world_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getWorldX();
}
void SpineBonePose::set_world_x(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setWorldX(v);
}
float SpineBonePose::get_world_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getWorldY();
}
void SpineBonePose::set_world_y(float v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setWorldY(v);
}
float SpineBonePose::get_world_rotation_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getWorldRotationX();
}
float SpineBonePose::get_world_rotation_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getWorldRotationY();
}
float SpineBonePose::get_world_scale_x() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getWorldScaleX();
}
float SpineBonePose::get_world_scale_y() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getWorldScaleY();
}
// Transformation methods
Vector2 SpineBonePose::world_to_local(Vector2 world_position) {
SPINE_CHECK(get_spine_object(), Vector2())
float x, y;
get_spine_object()->worldToLocal(world_position.x, world_position.y, x, y);
return Vector2(x, y);
}
Vector2 SpineBonePose::local_to_world(Vector2 local_position) {
SPINE_CHECK(get_spine_object(), Vector2())
float x, y;
get_spine_object()->localToWorld(local_position.x, local_position.y, x, y);
return Vector2(x, y);
}
Vector2 SpineBonePose::world_to_parent(Vector2 world_position) {
SPINE_CHECK(get_spine_object(), Vector2())
float x, y;
get_spine_object()->worldToParent(world_position.x, world_position.y, x, y);
return Vector2(x, y);
}
Vector2 SpineBonePose::parent_to_world(Vector2 parent_position) {
SPINE_CHECK(get_spine_object(), Vector2())
float x, y;
get_spine_object()->parentToWorld(parent_position.x, parent_position.y, x, y);
return Vector2(x, y);
}
float SpineBonePose::world_to_local_rotation(float world_rotation) {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->worldToLocalRotation(world_rotation);
}
float SpineBonePose::local_to_world_rotation(float local_rotation) {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->localToWorldRotation(local_rotation);
}
void SpineBonePose::rotate_world(float degrees) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->rotateWorld(degrees);
}

View File

@ -0,0 +1,110 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#pragma once
#include "SpineCommon.h"
#include "SpineConstant.h"
#include <spine/BonePose.h>
class SpineSprite;
class SpineBonePose : public SpineObjectWrapper {
GDCLASS(SpineBonePose, SpineObjectWrapper)
protected:
static void _bind_methods();
public:
// Can be used by both SpineSprite and SpineSkeletonDataResource
void set_spine_object(void *owner, spine::BonePose *object) {
_set_spine_object_internal(owner, object);
}
spine::BonePose *get_spine_object() {
return (spine::BonePose *) _get_spine_object_internal();
}
// BoneLocal properties (inherited)
float get_x();
void set_x(float v);
float get_y();
void set_y(float v);
float get_rotation();
void set_rotation(float v);
float get_scale_x();
void set_scale_x(float v);
float get_scale_y();
void set_scale_y(float v);
float get_shear_x();
void set_shear_x(float v);
float get_shear_y();
void set_shear_y(float v);
SpineConstant::Inherit get_inherit();
void set_inherit(SpineConstant::Inherit inherit);
// BonePose specific properties
float get_a();
void set_a(float v);
float get_b();
void set_b(float v);
float get_c();
void set_c(float v);
float get_d();
void set_d(float v);
float get_world_x();
void set_world_x(float v);
float get_world_y();
void set_world_y(float v);
float get_world_rotation_x();
float get_world_rotation_y();
float get_world_scale_x();
float get_world_scale_y();
// Transformation methods
Vector2 world_to_local(Vector2 world_position);
Vector2 local_to_world(Vector2 local_position);
Vector2 world_to_parent(Vector2 world_position);
Vector2 parent_to_world(Vector2 parent_position);
float world_to_local_rotation(float world_rotation);
float local_to_world_rotation(float local_rotation);
void rotate_world(float degrees);
};

View File

@ -51,7 +51,7 @@ void SpineIkConstraintData::_bind_methods() {
Array SpineIkConstraintData::get_bones() {
Array result;
SPINE_CHECK(get_spine_object(), result)
auto bones = get_spine_constraint_data()->getBones();
auto &bones = get_spine_constraint_data()->getBones();
result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));

View File

@ -58,7 +58,7 @@ void SpinePathConstraintData::_bind_methods() {
Array SpinePathConstraintData::get_bones() {
Array result;
SPINE_CHECK(get_spine_constraint_data(), result)
auto bones = get_spine_constraint_data()->getBones();
auto &bones = get_spine_constraint_data()->getBones();
result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));

View File

@ -30,6 +30,10 @@
#include "SpineSkeleton.h"
#include "SpineCommon.h"
#include "SpineSprite.h"
#include "spine/IkConstraint.h"
#include "spine/PathConstraint.h"
#include "spine/PhysicsConstraint.h"
#include "spine/TransformConstraint.h"
#include <spine/SkeletonClipping.h>
void SpineSkeleton::_bind_methods() {
@ -89,7 +93,7 @@ void SpineSkeleton::set_spine_sprite(SpineSprite *_sprite) {
skeleton = nullptr;
sprite = _sprite;
if (!sprite || !sprite->get_skeleton_data_res().is_valid() || !sprite->get_skeleton_data_res()->is_skeleton_data_loaded()) return;
skeleton = new spine::Skeleton(sprite->get_skeleton_data_res()->get_skeleton_data());
skeleton = new spine::Skeleton(*sprite->get_skeleton_data_res()->get_skeleton_data());
}
Ref<SpineSkeletonDataResource> SpineSkeleton::get_skeleton_data_res() const {
@ -104,17 +108,17 @@ void SpineSkeleton::update_world_transform(SpineConstant::Physics physics) {
void SpineSkeleton::set_to_setup_pose() {
SPINE_CHECK(skeleton, )
skeleton->setToSetupPose();
skeleton->setupPose();
}
void SpineSkeleton::set_bones_to_setup_pose() {
SPINE_CHECK(skeleton, )
skeleton->setBonesToSetupPose();
skeleton->setupPoseBones();
}
void SpineSkeleton::set_slots_to_setup_pose() {
SPINE_CHECK(skeleton, )
skeleton->setSlotsToSetupPose();
skeleton->setupPoseSlots();
}
Ref<SpineBone> SpineSkeleton::find_bone(const String &name) {
@ -183,7 +187,7 @@ void SpineSkeleton::set_attachment(const String &slot_name, const String &attach
Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findIkConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton->findConstraint<spine::IkConstraint>(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint));
constraint_ref->set_spine_object(sprite, constraint);
@ -193,7 +197,7 @@ Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constrain
Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findTransformConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton->findConstraint<spine::TransformConstraint>(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint));
constraint_ref->set_spine_object(sprite, constraint);
@ -203,7 +207,7 @@ Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const Str
Ref<SpinePathConstraint> SpineSkeleton::find_path_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findPathConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton->findConstraint<spine::PathConstraint>(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint));
constraint_ref->set_spine_object(sprite, constraint);
@ -214,7 +218,7 @@ Ref<SpinePathConstraint> SpineSkeleton::find_path_constraint(const String &const
Ref<SpinePhysicsConstraint> SpineSkeleton::find_physics_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findPhysicsConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton->findConstraint<spine::PhysicsConstraint>(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpinePhysicsConstraint> constraint_ref(memnew(SpinePhysicsConstraint));
constraint_ref->set_spine_object(sprite, constraint);
@ -283,42 +287,54 @@ Array SpineSkeleton::get_draw_order() {
Array SpineSkeleton::get_ik_constraints() {
Array result;
SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getIkConstraints();
auto &constraints = skeleton->getConstraints();
result.resize((int) constraints.size());
for (int i = 0; i < result.size(); ++i) {
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
auto constraint = constraints[i];
if (!constraint->getRTTI().isExactly(spine::IkConstraint::rtti) == false) continue;
Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint));
constraint_ref->set_spine_object(sprite, constraint);
constraint_ref->set_spine_object(sprite, static_cast<spine::IkConstraint*>(constraint));
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}
Array SpineSkeleton::get_transform_constraints() {
Array result;
SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getTransformConstraints();
auto &constraints = skeleton->getConstraints();
result.resize((int) constraints.size());
for (int i = 0; i < result.size(); ++i) {
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
auto constraint = constraints[i];
if (!constraint->getRTTI().isExactly(spine::TransformConstraint::rtti) == false) continue;
Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint));
constraint_ref->set_spine_object(sprite, constraint);
constraint_ref->set_spine_object(sprite, static_cast<spine::TransformConstraint*>(constraint));
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}
Array SpineSkeleton::get_path_constraints() {
Array result;
SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getPathConstraints();
auto &constraints = skeleton->getConstraints();
result.resize((int) constraints.size());
for (int i = 0; i < result.size(); ++i) {
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
auto constraint = constraints[i];
if (!constraint->getRTTI().isExactly(spine::PathConstraint::rtti) == false) continue;
Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint));
constraint_ref->set_spine_object(sprite, constraint);
constraint_ref->set_spine_object(sprite, static_cast<spine::PathConstraint*>(constraint));
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}
@ -327,7 +343,7 @@ Array SpineSkeleton::get_physics_constraints() {
SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getPhysicsConstraints();
result.resize((int) constraints.size());
for (int i = 0; i < result.size(); ++i) {
for (int i = 0; i < constraints.size(); ++i) {
auto constraint = constraints[i];
Ref<SpinePhysicsConstraint> constraint_ref(memnew(SpinePhysicsConstraint));
constraint_ref->set_spine_object(sprite, constraint);

View File

@ -289,7 +289,7 @@ void SpineSkeletonDataResource::load_resources(spine::Atlas *atlas, const String
spine::SkeletonData *data;
if (!EMPTY(json)) {
spine::SkeletonJson skeletonJson(atlas);
spine::SkeletonJson skeletonJson(*atlas);
data = skeletonJson.readSkeletonData(json.utf8());
if (!data) {
ERR_PRINT(String("Error while loading skeleton data: ") + get_path());
@ -297,7 +297,7 @@ void SpineSkeletonDataResource::load_resources(spine::Atlas *atlas, const String
return;
}
} else {
spine::SkeletonBinary skeletonBinary(atlas);
spine::SkeletonBinary skeletonBinary(*atlas);
data = skeletonBinary.readSkeletonData(binary.ptr(), binary.size());
if (!data) {
ERR_PRINT(String("Error while loading skeleton data: ") + get_path());
@ -306,7 +306,7 @@ void SpineSkeletonDataResource::load_resources(spine::Atlas *atlas, const String
}
}
skeleton_data = data;
animation_state_data = new spine::AnimationStateData(data);
animation_state_data = new spine::AnimationStateData(*data);
update_mixes();
}
@ -339,7 +339,7 @@ void SpineSkeletonDataResource::get_animation_names(Vector<String> &animation_na
#endif
animation_names.clear();
if (!is_skeleton_data_loaded()) return;
auto animations = skeleton_data->getAnimations();
auto &animations = skeleton_data->getAnimations();
for (size_t i = 0; i < animations.size(); ++i) {
auto animation = animations[i];
String name;
@ -355,7 +355,7 @@ void SpineSkeletonDataResource::get_skin_names(Vector<String> &skin_names) const
#endif
skin_names.clear();
if (!is_skeleton_data_loaded()) return;
auto skins = skeleton_data->getSkins();
auto &skins = skeleton_data->getSkins();
for (size_t i = 0; i < skins.size(); ++i) {
auto skin = skins[i];
String name;
@ -371,7 +371,7 @@ void SpineSkeletonDataResource::get_slot_names(Vector<String> &slot_names) {
#endif
slot_names.clear();
if (!is_skeleton_data_loaded()) return;
auto slots = skeleton_data->getSlots();
auto &slots = skeleton_data->getSlots();
for (size_t i = 0; i < slots.size(); ++i) {
auto slot = slots[i];
String name;
@ -387,7 +387,7 @@ void SpineSkeletonDataResource::get_bone_names(Vector<String> &bone_names) {
#endif
bone_names.clear();
if (!is_skeleton_data_loaded()) return;
auto bones = skeleton_data->getBones();
auto &bones = skeleton_data->getBones();
for (size_t i = 0; i < bones.size(); ++i) {
auto bone = bones[i];
String name;
@ -442,7 +442,7 @@ void SpineSkeletonDataResource::update_mixes() {
from, to, to));
continue;
}
animation_state_data->setMix(from, to, mix->get_mix());
animation_state_data->setMix(*from, *to, mix->get_mix());
}
}
@ -499,7 +499,7 @@ Ref<SpineEventData> SpineSkeletonDataResource::find_event(const String &event_da
Ref<SpineIkConstraintData> SpineSkeletonDataResource::find_ik_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findIkConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton_data->findConstraint<spine::IkConstraintData>(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData));
constraint_ref->set_spine_object(this, constraint);
@ -509,7 +509,7 @@ Ref<SpineIkConstraintData> SpineSkeletonDataResource::find_ik_constraint(const S
Ref<SpineTransformConstraintData> SpineSkeletonDataResource::find_transform_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findTransformConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton_data->findConstraint<spine::TransformConstraintData>(SPINE_STRING_TMP(constraint_name));
if (!constraint) return nullptr;
Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData));
constraint_ref->set_spine_object(this, constraint);
@ -519,7 +519,7 @@ Ref<SpineTransformConstraintData> SpineSkeletonDataResource::find_transform_cons
Ref<SpinePathConstraintData> SpineSkeletonDataResource::find_path_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findPathConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton_data->findConstraint<spine::PathConstraintData>(SPINE_STRING_TMP(constraint_name));
if (constraint == nullptr) return nullptr;
Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData));
constraint_ref->set_spine_object(this, constraint);
@ -529,7 +529,7 @@ Ref<SpinePathConstraintData> SpineSkeletonDataResource::find_path_constraint(con
Ref<SpinePhysicsConstraintData> SpineSkeletonDataResource::find_physics_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findPhysicsConstraint(SPINE_STRING_TMP(constraint_name));
auto constraint = skeleton_data->findConstraint<spine::PhysicsConstraintData>(SPINE_STRING_TMP(constraint_name));
if (constraint == nullptr) return nullptr;
Ref<SpinePhysicsConstraintData> constraint_ref(memnew(SpinePhysicsConstraintData));
constraint_ref->set_spine_object(this, constraint);
@ -546,7 +546,7 @@ String SpineSkeletonDataResource::get_skeleton_name() const {
Array SpineSkeletonDataResource::get_bones() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto bones = skeleton_data->getBones();
auto &bones = skeleton_data->getBones();
result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -559,7 +559,7 @@ Array SpineSkeletonDataResource::get_bones() const {
Array SpineSkeletonDataResource::get_slots() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto slots = skeleton_data->getSlots();
auto &slots = skeleton_data->getSlots();
result.resize((int) slots.size());
for (int i = 0; i < slots.size(); ++i) {
Ref<SpineSlotData> slot_ref(memnew(SpineSlotData));
@ -572,7 +572,7 @@ Array SpineSkeletonDataResource::get_slots() const {
Array SpineSkeletonDataResource::get_skins() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto skins = skeleton_data->getSkins();
auto &skins = skeleton_data->getSkins();
result.resize((int) skins.size());
for (int i = 0; i < skins.size(); ++i) {
Ref<SpineSkin> skin_ref(memnew(SpineSkin));
@ -599,7 +599,7 @@ void SpineSkeletonDataResource::set_default_skin(Ref<SpineSkin> skin) {
Array SpineSkeletonDataResource::get_events() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto events = skeleton_data->getEvents();
auto &events = skeleton_data->getEvents();
result.resize((int) events.size());
for (int i = 0; i < events.size(); ++i) {
Ref<SpineEventData> event_ref(memnew(SpineEventData));
@ -612,7 +612,7 @@ Array SpineSkeletonDataResource::get_events() const {
Array SpineSkeletonDataResource::get_animations() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto animations = skeleton_data->getAnimations();
auto &animations = skeleton_data->getAnimations();
result.resize((int) animations.size());
for (int i = 0; i < animations.size(); ++i) {
Ref<SpineAnimation> animation_ref(memnew(SpineAnimation));
@ -625,52 +625,68 @@ Array SpineSkeletonDataResource::get_animations() const {
Array SpineSkeletonDataResource::get_ik_constraints() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getIkConstraints();
auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::IkConstraintData::rtti)) continue;
Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData));
constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}
Array SpineSkeletonDataResource::get_transform_constraints() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getTransformConstraints();
auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::TransformConstraintData::rtti)) continue;
Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData));
constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}
Array SpineSkeletonDataResource::get_path_constraints() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getPathConstraints();
auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::PathConstraintData::rtti)) continue;
Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData));
constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}
Array SpineSkeletonDataResource::get_physics_constraints() const {
Array result;
SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getPhysicsConstraints();
auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::PhysicsConstraintData::rtti)) continue;
Ref<SpinePhysicsConstraintData> constraint_ref(memnew(SpinePhysicsConstraintData));
constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref;
size++;
}
result.resize(size);
return result;
}

View File

@ -168,7 +168,7 @@ Array SpineSkin::get_attachments() {
Array SpineSkin::get_bones() {
Array result;
SPINE_CHECK(get_spine_object(), result)
auto bones = get_spine_object()->getBones();
auto &bones = get_spine_object()->getBones();
result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -181,7 +181,7 @@ Array SpineSkin::get_bones() {
Array SpineSkin::get_constraints() {
Array result;
SPINE_CHECK(get_spine_object(), result)
auto constraints = get_spine_object()->getConstraints();
auto &constraints = get_spine_object()->getConstraints();
result.resize((int) constraints.size());
for (int i = 0; i < constraints.size(); ++i) {
Ref<SpineConstraintData> constraint_ref(memnew(SpineConstraintData));

View File

@ -50,11 +50,13 @@ void SpineSlot::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_deform", "v"), &SpineSlot::set_deform);
ClassDB::bind_method(D_METHOD("get_sequence_index"), &SpineSlot::get_sequence_index);
ClassDB::bind_method(D_METHOD("set_sequence_index", "v"), &SpineSlot::set_sequence_index);
ClassDB::bind_method(D_METHOD("get_pose"), &SpineSlot::get_pose);
ClassDB::bind_method(D_METHOD("get_applied_pose"), &SpineSlot::get_applied_pose);
}
void SpineSlot::set_to_setup_pose() {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setToSetupPose();
get_spine_object()->setupPose();
}
Ref<SpineSlotData> SpineSlot::get_data() {
@ -85,36 +87,36 @@ Ref<SpineBone> SpineSlot::get_bone() {
Color SpineSlot::get_color() {
SPINE_CHECK(get_spine_object(), Color(0, 0, 0, 0))
auto &color = get_spine_object()->getColor();
auto &color = get_spine_object()->getAppliedPose().getColor();
return Color(color.r, color.g, color.b, color.a);
}
void SpineSlot::set_color(Color v) {
SPINE_CHECK(get_spine_object(), )
auto &color = get_spine_object()->getColor();
auto &color = get_spine_object()->getPose().getColor();
color.set(v.r, v.g, v.b, v.a);
}
Color SpineSlot::get_dark_color() {
SPINE_CHECK(get_spine_object(), Color(0, 0, 0, 0))
auto &color = get_spine_object()->getDarkColor();
auto &color = get_spine_object()->getAppliedPose().getDarkColor();
return Color(color.r, color.g, color.b, color.a);
}
void SpineSlot::set_dark_color(Color v) {
SPINE_CHECK(get_spine_object(), )
auto &color = get_spine_object()->getDarkColor();
auto &color = get_spine_object()->getPose().getDarkColor();
color.set(v.r, v.g, v.b, v.a);
}
bool SpineSlot::has_dark_color() {
SPINE_CHECK(get_spine_object(), false)
return get_spine_object()->hasDarkColor();
return get_spine_object()->getAppliedPose().hasDarkColor();
}
Ref<SpineAttachment> SpineSlot::get_attachment() {
SPINE_CHECK(get_spine_object(), nullptr)
auto attachment = get_spine_object()->getAttachment();
auto attachment = get_spine_object()->getAppliedPose().getAttachment();
if (!attachment) return nullptr;
Ref<SpineAttachment> attachment_ref(memnew(SpineAttachment));
attachment_ref->set_spine_object(*get_spine_owner()->get_skeleton_data_res(), attachment);
@ -123,23 +125,24 @@ Ref<SpineAttachment> SpineSlot::get_attachment() {
void SpineSlot::set_attachment(Ref<SpineAttachment> v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setAttachment(v.is_valid() && v->get_spine_object() ? v->get_spine_object() : nullptr);
get_spine_object()->getPose().setAttachment(v.is_valid() && v->get_spine_object() ? v->get_spine_object() : nullptr);
}
int SpineSlot::get_attachment_state() {
// TODO: attachmentState is no longer exposed in the new API
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAttachmentState();
return 0;
}
void SpineSlot::set_attachment_state(int v) {
// TODO: attachmentState is no longer exposed in the new API
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setAttachmentState(v);
}
Array SpineSlot::get_deform() {
Array result;
SPINE_CHECK(get_spine_object(), result)
auto &deform = get_spine_object()->getDeform();
auto &deform = get_spine_object()->getAppliedPose().getDeform();
result.resize((int) deform.size());
for (int i = 0; i < (int) deform.size(); ++i) {
result[i] = deform[i];
@ -149,7 +152,7 @@ Array SpineSlot::get_deform() {
void SpineSlot::set_deform(Array v) {
SPINE_CHECK(get_spine_object(), )
auto &deform = get_spine_object()->getDeform();
auto &deform = get_spine_object()->getPose().getDeform();
deform.setSize(v.size(), 0);
for (int i = 0; i < v.size(); ++i) {
deform[i] = v[i];
@ -158,10 +161,26 @@ void SpineSlot::set_deform(Array v) {
int SpineSlot::get_sequence_index() {
SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAttachmentState();
return get_spine_object()->getAppliedPose().getSequenceIndex();
}
void SpineSlot::set_sequence_index(int v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setAttachmentState(v);
get_spine_object()->getPose().setSequenceIndex(v);
}
Ref<SpineSlotPose> SpineSlot::get_pose() {
SPINE_CHECK(get_spine_object(), nullptr)
auto &pose = get_spine_object()->getPose();
Ref<SpineSlotPose> pose_ref(memnew(SpineSlotPose));
pose_ref->set_spine_object(get_spine_owner(), &pose);
return pose_ref;
}
Ref<SpineSlotPose> SpineSlot::get_applied_pose() {
SPINE_CHECK(get_spine_object(), nullptr)
auto &applied_pose = get_spine_object()->getAppliedPose();
Ref<SpineSlotPose> pose_ref(memnew(SpineSlotPose));
pose_ref->set_spine_object(get_spine_owner(), &applied_pose);
return pose_ref;
}

View File

@ -33,6 +33,8 @@
#include "SpineSlotData.h"
#include "SpineAttachment.h"
#include "SpineBone.h"
#include "SpineSlotPose.h"
#include <spine/Slot.h>
class SpineSkeleton;
class SpineSprite;
@ -79,4 +81,8 @@ public:
int get_sequence_index();
void set_sequence_index(int v);
Ref<SpineSlotPose> get_pose();
Ref<SpineSlotPose> get_applied_pose();
};

View File

@ -0,0 +1,125 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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 "SpineSlotPose.h"
#include "SpineCommon.h"
#include "SpineSprite.h"
void SpineSlotPose::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_color"), &SpineSlotPose::get_color);
ClassDB::bind_method(D_METHOD("set_color", "v"), &SpineSlotPose::set_color);
ClassDB::bind_method(D_METHOD("get_dark_color"), &SpineSlotPose::get_dark_color);
ClassDB::bind_method(D_METHOD("set_dark_color", "v"), &SpineSlotPose::set_dark_color);
ClassDB::bind_method(D_METHOD("has_dark_color"), &SpineSlotPose::has_dark_color);
ClassDB::bind_method(D_METHOD("set_has_dark_color", "v"), &SpineSlotPose::set_has_dark_color);
ClassDB::bind_method(D_METHOD("get_attachment"), &SpineSlotPose::get_attachment);
ClassDB::bind_method(D_METHOD("set_attachment", "v"), &SpineSlotPose::set_attachment);
ClassDB::bind_method(D_METHOD("get_sequence_index"), &SpineSlotPose::get_sequence_index);
ClassDB::bind_method(D_METHOD("set_sequence_index", "v"), &SpineSlotPose::set_sequence_index);
ClassDB::bind_method(D_METHOD("get_deform"), &SpineSlotPose::get_deform);
ClassDB::bind_method(D_METHOD("set_deform", "v"), &SpineSlotPose::set_deform);
}
Color SpineSlotPose::get_color() {
SPINE_CHECK(get_spine_object(), Color(0, 0, 0, 0))
auto &color = get_spine_object()->getColor();
return Color(color.r, color.g, color.b, color.a);
}
void SpineSlotPose::set_color(Color v) {
SPINE_CHECK(get_spine_object(), )
auto &color = get_spine_object()->getColor();
color.set(v.r, v.g, v.b, v.a);
}
Color SpineSlotPose::get_dark_color() {
SPINE_CHECK(get_spine_object(), Color(0, 0, 0, 0))
auto &color = get_spine_object()->getDarkColor();
return Color(color.r, color.g, color.b, color.a);
}
void SpineSlotPose::set_dark_color(Color v) {
SPINE_CHECK(get_spine_object(), )
auto &color = get_spine_object()->getDarkColor();
color.set(v.r, v.g, v.b, v.a);
}
bool SpineSlotPose::has_dark_color() {
SPINE_CHECK(get_spine_object(), false)
return get_spine_object()->hasDarkColor();
}
void SpineSlotPose::set_has_dark_color(bool v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setHasDarkColor(v);
}
Ref<SpineAttachment> SpineSlotPose::get_attachment() {
SPINE_CHECK(get_spine_object(), nullptr)
auto attachment = get_spine_object()->getAttachment();
if (!attachment) return nullptr;
Ref<SpineAttachment> attachment_ref(memnew(SpineAttachment));
attachment_ref->set_spine_object(*get_spine_owner()->get_skeleton_data_res(), attachment);
return attachment_ref;
}
void SpineSlotPose::set_attachment(Ref<SpineAttachment> v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setAttachment(v.is_valid() && v->get_spine_object() ? v->get_spine_object() : nullptr);
}
int SpineSlotPose::get_sequence_index() {
SPINE_CHECK(get_spine_object(), -1)
return get_spine_object()->getSequenceIndex();
}
void SpineSlotPose::set_sequence_index(int v) {
SPINE_CHECK(get_spine_object(), )
get_spine_object()->setSequenceIndex(v);
}
Array SpineSlotPose::get_deform() {
Array result;
SPINE_CHECK(get_spine_object(), result)
auto &deform = get_spine_object()->getDeform();
result.resize((int) deform.size());
for (int i = 0; i < (int) deform.size(); ++i) {
result[i] = deform[i];
}
return result;
}
void SpineSlotPose::set_deform(const Array &v) {
SPINE_CHECK(get_spine_object(), )
auto &deform = get_spine_object()->getDeform();
deform.setSize(v.size(), 0);
for (int i = 0; i < v.size(); ++i) {
deform[i] = v[i];
}
}

View File

@ -0,0 +1,62 @@
/******************************************************************************
* Spine Runtimes License Agreement
* Last updated April 5, 2025. Replaces all prior versions.
*
* Copyright (c) 2013-2025, 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.
*****************************************************************************/
#pragma once
#include "SpineCommon.h"
#include "SpineAttachment.h"
#include <spine/SlotPose.h>
class SpineSprite;
class SpineSlotPose : public SpineSpriteOwnedObject<spine::SlotPose> {
GDCLASS(SpineSlotPose, SpineObjectWrapper)
protected:
static void _bind_methods();
public:
Color get_color();
void set_color(Color v);
Color get_dark_color();
void set_dark_color(Color v);
bool has_dark_color();
void set_has_dark_color(bool v);
Ref<SpineAttachment> get_attachment();
void set_attachment(Ref<SpineAttachment> v);
int get_sequence_index();
void set_sequence_index(int v);
Array get_deform();
void set_deform(const Array &v);
};

View File

@ -94,8 +94,8 @@ private:
public:
Ref<CanvasItemMaterial> default_materials[4] = {};
int sprite_count;
spine::Vector<unsigned short> quad_indices;
spine::Vector<float> scratch_vertices;
spine::Array<unsigned short> quad_indices;
spine::Array<float> scratch_vertices;
#ifdef SPINE_GODOT_EXTENSION
PackedVector2Array scratch_points;
#else
@ -598,7 +598,7 @@ void SpineSprite::generate_meshes_for_slots(Ref<SpineSkeleton> skeleton_ref) {
mesh_instance->set_draw_behind_parent(true);
add_child(mesh_instance);
mesh_instances.push_back(mesh_instance);
slot_nodes.add(spine::Vector<SpineSlotNode *>());
slot_nodes.add(spine::Array<SpineSlotNode *>());
}
}
@ -616,7 +616,7 @@ void SpineSprite::sort_slot_nodes() {
slot_nodes[i].setSize(0, nullptr);
}
auto draw_order = skeleton->get_spine_object()->getDrawOrder();
auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < get_child_count(); i++) {
auto child = cast_to<Node2D>(get_child(i));
if (!child) continue;
@ -633,7 +633,7 @@ void SpineSprite::sort_slot_nodes() {
for (int i = 0; i < (int) draw_order.size(); i++) {
int slot_index = draw_order[i]->getData().getIndex();
int mesh_index = mesh_instances[i]->get_index();
spine::Vector<SpineSlotNode *> &nodes = slot_nodes[slot_index];
spine::Array<SpineSlotNode *> &nodes = slot_nodes[slot_index];
for (int j = 0; j < (int) nodes.size(); j++) {
auto node = nodes[j];
move_child(node, mesh_index + 1);
@ -832,7 +832,7 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
spine::Skeleton *skeleton = skeleton_ref->get_spine_object();
for (int i = 0, n = (int) skeleton->getSlots().size(); i < n; ++i) {
spine::Slot *slot = skeleton->getDrawOrder()[i];
spine::Attachment *attachment = slot->getAttachment();
spine::Attachment *attachment = slot->getAppliedPose().getAttachment();
SpineMesh2D *mesh_instance = mesh_instances[i];
mesh_instance->renderer_object = nullptr;
@ -846,16 +846,16 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
}
spine::Color skeleton_color = skeleton->getColor();
spine::Color slot_color = slot->getColor();
spine::Color slot_color = slot->getAppliedPose().getColor();
spine::Color tint(skeleton_color.r * slot_color.r, skeleton_color.g * slot_color.g, skeleton_color.b * slot_color.b,
skeleton_color.a * slot_color.a);
SpineRendererObject *renderer_object;
spine::Vector<float> *vertices = &statics.scratch_vertices;
spine::Vector<float> *uvs;
spine::Vector<unsigned short> *indices;
spine::Array<float> *vertices = &statics.scratch_vertices;
spine::Array<float> *uvs;
spine::Array<unsigned short> *indices;
if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
auto *region = (spine::RegionAttachment *) attachment;
auto region = (spine::RegionAttachment *) attachment;
vertices->setSize(8, 0);
region->computeWorldVertices(*slot, *vertices, 0);
@ -863,28 +863,28 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
uvs = &region->getUVs();
indices = &statics.quad_indices;
auto attachment_color = region->getColor();
auto &attachment_color = region->getColor();
tint.r *= attachment_color.r;
tint.g *= attachment_color.g;
tint.b *= attachment_color.b;
tint.a *= attachment_color.a;
} else if (attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) {
auto *mesh = (spine::MeshAttachment *) attachment;
auto mesh = (spine::MeshAttachment *) attachment;
vertices->setSize(mesh->getWorldVerticesLength(), 0);
mesh->computeWorldVertices(*slot, *vertices);
mesh->computeWorldVertices(*skeleton, *slot, *vertices);
renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) mesh->getRegion())->page->texture;
uvs = &mesh->getUVs();
indices = &mesh->getTriangles();
auto attachment_color = mesh->getColor();
auto &attachment_color = mesh->getColor();
tint.r *= attachment_color.r;
tint.g *= attachment_color.g;
tint.b *= attachment_color.b;
tint.a *= attachment_color.a;
} else if (attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) {
auto clip = (spine::ClippingAttachment *) attachment;
skeleton_clipper->clipStart(*slot, clip);
skeleton_clipper->clipStart(*skeleton, *slot, clip);
continue;
} else {
skeleton_clipper->clipEnd(*slot);
@ -994,9 +994,9 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
}
#ifdef SPINE_GODOT_EXTENSION
void createLinesFromMesh(PackedVector2Array &scratch_points, spine::Vector<unsigned short> &triangles, spine::Vector<float> *vertices) {
void createLinesFromMesh(PackedVector2Array &scratch_points, spine::Array<unsigned short> &triangles, spine::Array<float> *vertices) {
#else
void createLinesFromMesh(Vector<Vector2> &scratch_points, spine::Vector<unsigned short> &triangles, spine::Vector<float> *vertices) {
void createLinesFromMesh(Vector<Vector2> &scratch_points, spine::Array<unsigned short> &triangles, spine::Array<float> *vertices) {
#endif
scratch_points.resize(0);
for (int i = 0; i < triangles.size(); i += 3) {
@ -1019,7 +1019,7 @@ void SpineSprite::draw() {
if (!animation_state.is_valid() && !skeleton.is_valid()) return;
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) return;
auto statics = SpineSpriteStatics::instance();
auto &statics = SpineSpriteStatics::instance();
#if VERSION_MAJOR > 3
RS::get_singleton()->canvas_item_clear(this->get_canvas_item());
@ -1034,13 +1034,13 @@ void SpineSprite::draw() {
draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < (int) draw_order.size(); i++) {
auto *slot = draw_order[i];
auto slot = draw_order[i];
if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment();
auto attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) continue;
auto *region = (spine::RegionAttachment *) attachment;
auto *vertices = &statics.scratch_vertices;
auto region = (spine::RegionAttachment *) attachment;
auto vertices = &statics.scratch_vertices;
vertices->setSize(8, 0);
region->computeWorldVertices(*slot, *vertices, 0);
@ -1077,7 +1077,7 @@ void SpineSprite::draw() {
for (int i = 0; i < (int) draw_order.size(); i++) {
auto *slot = draw_order[i];
if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment();
auto *attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) continue;
auto *mesh = (spine::MeshAttachment *) attachment;
@ -1115,13 +1115,13 @@ void SpineSprite::draw() {
draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < (int) draw_order.size(); i++) {
auto *slot = draw_order[i];
auto slot = draw_order[i];
if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment();
auto attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::BoundingBoxAttachment::rtti)) continue;
auto *bounding_box = (spine::BoundingBoxAttachment *) attachment;
auto *vertices = &statics.scratch_vertices;
auto bounding_box = (spine::BoundingBoxAttachment *) attachment;
auto vertices = &statics.scratch_vertices;
vertices->setSize(bounding_box->getWorldVerticesLength(), 0);
bounding_box->computeWorldVertices(*slot, *vertices);
size_t num_vertices = vertices->size() / 2;
@ -1136,13 +1136,13 @@ void SpineSprite::draw() {
draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < (int) draw_order.size(); i++) {
auto *slot = draw_order[i];
auto slot = draw_order[i];
if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment();
auto attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) continue;
auto *clipping = (spine::ClippingAttachment *) attachment;
auto *vertices = &statics.scratch_vertices;
auto clipping = (spine::ClippingAttachment *) attachment;
auto vertices = &statics.scratch_vertices;
vertices->setSize(clipping->getWorldVerticesLength(), 0);
clipping->computeWorldVertices(*slot, *vertices);
size_t num_vertices = vertices->size() / 2;
@ -1168,8 +1168,8 @@ void SpineSprite::draw() {
statics.scratch_points.set(2, Vector2(bone_length, 0));
statics.scratch_points.set(3, Vector2(0, -debug_bones_thickness));
statics.scratch_points.set(4, Vector2(-debug_bones_thickness, 0));
Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldX(), bone->getWorldY()));
bone_transform.scale_basis(Vector2(bone->getWorldScaleX(), bone->getWorldScaleY()));
Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getAppliedPose().getWorldRotationX(), Vector2(bone->getAppliedPose().getWorldX(), bone->getAppliedPose().getWorldY()));
bone_transform.scale_basis(Vector2(bone->getAppliedPose().getWorldScaleX(), bone->getAppliedPose().getWorldScaleY()));
auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position);
#ifdef SPINE_GODOT_EXTENSION
if (GEOMETRY2D::get_singleton()->is_point_in_polygon(mouse_local_position, statics.scratch_points)) {
@ -1183,7 +1183,7 @@ void SpineSprite::draw() {
if (debug_bones) {
auto &bones = skeleton->get_spine_object()->getBones();
for (int i = 0; i < (int) bones.size(); i++) {
auto *bone = bones[i];
auto bone = bones[i];
if (!bone->isActive()) continue;
draw_bone(bone, debug_bones_color);
@ -1196,8 +1196,8 @@ void SpineSprite::draw() {
statics.scratch_points.set(2, Vector2(bone_length, 0));
statics.scratch_points.set(3, Vector2(0, -debug_bones_thickness));
statics.scratch_points.set(4, Vector2(-debug_bones_thickness, 0));
Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldX(), bone->getWorldY()));
bone_transform.scale_basis(Vector2(bone->getWorldScaleX(), bone->getWorldScaleY()));
Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getAppliedPose().getWorldRotationX(), Vector2(bone->getAppliedPose().getWorldX(), bone->getAppliedPose().getWorldY()));
bone_transform.scale_basis(Vector2(bone->getAppliedPose().getWorldScaleX(), bone->getAppliedPose().getWorldScaleY()));
auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position);
#ifdef SPINE_GODOT_EXTENSION
if (GEOMETRY2D::get_singleton()->is_point_in_polygon(mouse_local_position, statics.scratch_points)) {

View File

@ -90,8 +90,7 @@ int SpineTrackEntry::get_track_index() {
Ref<SpineAnimation> SpineTrackEntry::get_animation() {
SPINE_CHECK(get_spine_object(), nullptr)
auto animation = get_spine_object()->getAnimation();
if (!animation) return nullptr;
auto animation = &get_spine_object()->getAnimation();
Ref<SpineAnimation> animation_ref(memnew(SpineAnimation));
animation_ref->set_spine_object(*get_spine_owner()->get_skeleton_data_res(), animation);
return animation_ref;

View File

@ -45,14 +45,12 @@ void SpineTransformConstraintData::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_offset_scale_x"), &SpineTransformConstraintData::get_offset_scale_x);
ClassDB::bind_method(D_METHOD("get_offset_scale_y"), &SpineTransformConstraintData::get_offset_scale_y);
ClassDB::bind_method(D_METHOD("get_offset_shear_y"), &SpineTransformConstraintData::get_offset_shear_y);
ClassDB::bind_method(D_METHOD("is_relative"), &SpineTransformConstraintData::is_relative);
ClassDB::bind_method(D_METHOD("is_local"), &SpineTransformConstraintData::is_local);
}
Array SpineTransformConstraintData::get_bones() {
Array result;
SPINE_CHECK(get_spine_constraint_data(), result)
auto bones = get_spine_constraint_data()->getBones();
auto &bones = get_spine_constraint_data()->getBones();
result.resize((int) bones.size());
for (int i = 0; i < (int) bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -73,32 +71,32 @@ Ref<SpineBoneData> SpineTransformConstraintData::get_target() {
float SpineTransformConstraintData::get_mix_rotate() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getMixRotate();
return get_spine_constraint_data()->getSetupPose().getMixRotate();
}
float SpineTransformConstraintData::get_mix_x() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getMixX();
return get_spine_constraint_data()->getSetupPose().getMixX();
}
float SpineTransformConstraintData::get_mix_y() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getMixY();
return get_spine_constraint_data()->getSetupPose().getMixY();
}
float SpineTransformConstraintData::get_mix_scale_x() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getMixScaleX();
return get_spine_constraint_data()->getSetupPose().getMixScaleX();
}
float SpineTransformConstraintData::get_mix_scale_y() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getMixScaleY();
return get_spine_constraint_data()->getSetupPose().getMixScaleY();
}
float SpineTransformConstraintData::get_mix_shear_y() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getMixShearY();
return get_spine_constraint_data()->getSetupPose().getMixShearY();
}
float SpineTransformConstraintData::get_offset_rotation() {
@ -130,13 +128,3 @@ float SpineTransformConstraintData::get_offset_shear_y() {
SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getOffsetShearY();
}
bool SpineTransformConstraintData::is_relative() {
SPINE_CHECK(get_spine_constraint_data(), false)
return get_spine_constraint_data()->isRelative();
}
bool SpineTransformConstraintData::is_local() {
SPINE_CHECK(get_spine_constraint_data(), false)
return get_spine_constraint_data()->isLocal();
}

View File

@ -44,7 +44,10 @@
#include "SpineEvent.h"
#include "SpineTrackEntry.h"
#include "SpineBoneData.h"
#include "SpineBoneLocal.h"
#include "SpineBonePose.h"
#include "SpineSlotData.h"
#include "SpineSlotPose.h"
#include "SpineAttachment.h"
#include "SpineConstraintData.h"
#include "SpineSkin.h"
@ -130,6 +133,7 @@ void register_spine_godot_types() {
GDREGISTER_CLASS(SpineEvent);
GDREGISTER_CLASS(SpineBoneData);
GDREGISTER_CLASS(SpineSlotData);
GDREGISTER_CLASS(SpineSlotPose);
GDREGISTER_CLASS(SpineAttachment);
GDREGISTER_CLASS(SpineSkinEntry);
GDREGISTER_CLASS(SpineConstraintData);
@ -139,6 +143,8 @@ void register_spine_godot_types() {
GDREGISTER_CLASS(SpinePathConstraintData);
GDREGISTER_CLASS(SpinePhysicsConstraintData);
GDREGISTER_CLASS(SpineBone);
GDREGISTER_CLASS(SpineBoneLocal);
GDREGISTER_CLASS(SpineBonePose);
GDREGISTER_CLASS(SpineSlot);
GDREGISTER_CLASS(SpineIkConstraint);
GDREGISTER_CLASS(SpinePathConstraint);