[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); animation_player->add_animation_library("", animation_library);
#endif #endif
for (int i = 0; i < (int) animations.size(); i++) { 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_ref = create_animation(animation, false);
Ref<Animation> animation_looped_ref = create_animation(animation, true); Ref<Animation> animation_looped_ref = create_animation(animation, true);
#if VERSION_MAJOR > 3 #if VERSION_MAJOR > 3
@ -285,7 +285,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
AnimationTreeEditor *tree_editor = AnimationTreeEditor::get_singleton(); AnimationTreeEditor *tree_editor = AnimationTreeEditor::get_singleton();
// When the animation tree dock is no longer visible, bail. // When the animation tree dock is no longer visible, bail.
if (!tree_editor->is_visible_in_tree()) { if (!tree_editor->is_visible_in_tree()) {
skeleton->setToSetupPose(); skeleton->setupPose();
animation_state->clearTracks(); animation_state->clearTracks();
animation_state->setTimeScale(1); animation_state->setTimeScale(1);
return; return;
@ -293,22 +293,22 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
auto current_entry = animation_state->getCurrent(track_index); auto current_entry = animation_state->getCurrent(track_index);
bool should_set_mix = mix_duration >= 0; bool should_set_mix = mix_duration >= 0;
String other_name; 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); bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop);
if (should_set_animation) { if (should_set_animation) {
if (!EMPTY(animation_name)) { if (!EMPTY(animation_name)) {
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop); auto &entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
if (should_set_mix) entry->setMixDuration(mix_duration); if (should_set_mix) entry.setMixDuration(mix_duration);
entry->setHoldPrevious(hold_previous); entry.setHoldPrevious(hold_previous);
entry->setReverse(reverse); entry.setReverse(reverse);
entry->setShortestRotation(shortest_rotation); entry.setShortestRotation(shortest_rotation);
entry->setTimeScale(time_scale); entry.setTimeScale(time_scale);
entry->setAlpha(alpha); entry.setAlpha(alpha);
entry->setMixAttachmentThreshold(mix_attachment_threshold); entry.setMixAttachmentThreshold(mix_attachment_threshold);
entry->setMixDrawOrderThreshold(mix_draw_order_threshold); entry.setMixDrawOrderThreshold(mix_draw_order_threshold);
entry->setMixBlend((spine::MixBlend) mix_blend); entry.setMixBlend((spine::MixBlend) mix_blend);
if (debug) if (debug)
print_line(String("Setting animation {0} with mix_duration {1} on track {2} on {3}") 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()); .ptr());
} else { } else {
if (!current_entry || (String("<empty>") != other_name)) { if (!current_entry || (String("<empty>") != other_name)) {
auto entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0); auto &entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0);
entry->setTrackEnd(FLT_MAX); entry.setTrackEnd(FLT_MAX);
if (debug) if (debug)
print_line(String("Setting empty animation with mix_duration {0} on track {1} on {2}") print_line(String("Setting empty animation with mix_duration {0} on track {1} on {2}")
.format(varray(mix_duration, track_index, sprite->get_name())) .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; auto player_editor = AnimationPlayerEditor::singleton;
#endif #endif
if (!player_editor->is_visible_in_tree()) { if (!player_editor->is_visible_in_tree()) {
skeleton->setToSetupPose(); skeleton->setupPose();
animation_state->clearTracks(); animation_state->clearTracks();
animation_state->setTimeScale(1); animation_state->setTimeScale(1);
return; return;
@ -348,7 +348,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
// for us. // for us.
Ref<Animation> edited_animation = player_editor->get_track_editor()->get_current_animation(); Ref<Animation> edited_animation = player_editor->get_track_editor()->get_current_animation();
if (!edited_animation.is_valid()) { if (!edited_animation.is_valid()) {
skeleton->setToSetupPose(); skeleton->setupPose();
animation_state->clearTracks(); animation_state->clearTracks();
animation_state->setTimeScale(1); animation_state->setTimeScale(1);
return; return;
@ -370,7 +370,7 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
// setting track times manually. Also, kill anything // setting track times manually. Also, kill anything
// currently in the track. // currently in the track.
if (track_index == 0) { if (track_index == 0) {
skeleton->setToSetupPose(); skeleton->setupPose();
animation_state->setTimeScale(0); animation_state->setTimeScale(0);
} }
animation_state->clearTrack(track_index); animation_state->clearTrack(track_index);
@ -411,40 +411,40 @@ void SpineAnimationTrack::update_animation_state(const Variant &variant_sprite)
// properties. // properties.
float track_time = (playback_position - key_time) * time_scale; float track_time = (playback_position - key_time) * time_scale;
if (track_time < 0) track_time = 0; if (track_time < 0) track_time = 0;
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop); auto &entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
entry->setMixDuration(0); entry.setMixDuration(0);
entry->setTrackTime(track_time); entry.setTrackTime(track_time);
entry->setHoldPrevious(hold_previous); entry.setHoldPrevious(hold_previous);
entry->setReverse(reverse); entry.setReverse(reverse);
entry->setShortestRotation(shortest_rotation); entry.setShortestRotation(shortest_rotation);
entry->setAlpha(alpha); entry.setAlpha(alpha);
entry->setMixAttachmentThreshold(mix_attachment_threshold); entry.setMixAttachmentThreshold(mix_attachment_threshold);
entry->setMixDrawOrderThreshold(mix_draw_order_threshold); entry.setMixDrawOrderThreshold(mix_draw_order_threshold);
entry->setMixBlend((spine::MixBlend) mix_blend); entry.setMixBlend((spine::MixBlend) mix_blend);
#endif #endif
} else { } else {
if (animation_player->is_playing()) { if (animation_player->is_playing()) {
auto current_entry = animation_state->getCurrent(track_index); auto current_entry = animation_state->getCurrent(track_index);
bool should_set_mix = mix_duration >= 0; bool should_set_mix = mix_duration >= 0;
String other_name; 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; bool should_set_animation = !current_entry || (animation_name != other_name || current_entry->getLoop() != loop) || animation_changed;
animation_changed = false; animation_changed = false;
if (should_set_animation) { if (should_set_animation) {
if (!EMPTY(animation_name)) { if (!EMPTY(animation_name)) {
auto entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop); auto &entry = animation_state->setAnimation(track_index, SPINE_STRING(animation_name), loop);
if (should_set_mix) entry->setMixDuration(mix_duration); if (should_set_mix) entry.setMixDuration(mix_duration);
entry->setHoldPrevious(hold_previous); entry.setHoldPrevious(hold_previous);
entry->setReverse(reverse); entry.setReverse(reverse);
entry->setShortestRotation(shortest_rotation); entry.setShortestRotation(shortest_rotation);
entry->setTimeScale(time_scale); entry.setTimeScale(time_scale);
entry->setAlpha(alpha); entry.setAlpha(alpha);
entry->setMixAttachmentThreshold(mix_attachment_threshold); entry.setMixAttachmentThreshold(mix_attachment_threshold);
entry->setMixDrawOrderThreshold(mix_draw_order_threshold); entry.setMixDrawOrderThreshold(mix_draw_order_threshold);
entry->setMixBlend((spine::MixBlend) mix_blend); entry.setMixBlend((spine::MixBlend) mix_blend);
if (debug) if (debug)
print_line(String("Setting animation {0} with mix_duration {1} on track {2} on {3}") 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()); .ptr());
} else { } else {
if (!current_entry || (String("<empty>") != other_name)) { if (!current_entry || (String("<empty>") != other_name)) {
auto entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0); auto &entry = animation_state->setEmptyAnimation(track_index, should_set_mix ? mix_duration : 0);
entry->setTrackEnd(FLT_MAX); entry.setTrackEnd(FLT_MAX);
if (debug) if (debug)
print_line(String("Setting empty animation with mix_duration {0} on track {1} on {2}") print_line(String("Setting empty animation with mix_duration {0} on track {1} on {2}")
.format(varray(mix_duration, track_index, sprite->get_name())) .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_data"), &SpineBone::get_data);
ClassDB::bind_method(D_METHOD("get_parent"), &SpineBone::get_parent); 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_children"), &SpineBone::get_children);
ClassDB::bind_method(D_METHOD("get_x"), &SpineBone::get_x); ClassDB::bind_method(D_METHOD("get_pose"), &SpineBone::get_pose);
ClassDB::bind_method(D_METHOD("set_x", "v"), &SpineBone::set_x); ClassDB::bind_method(D_METHOD("get_applied_pose"), &SpineBone::get_applied_pose);
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("is_active"), &SpineBone::is_active); 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_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("get_transform"), &SpineBone::get_transform);
ClassDB::bind_method(D_METHOD("set_transform", "local_transform"), &SpineBone::set_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); 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 SpineBone::get_children() {
Array result; Array result;
SPINE_CHECK(get_spine_object(), result) SPINE_CHECK(get_spine_object(), result)
auto children = get_spine_object()->getChildren(); auto &children = get_spine_object()->getChildren();
result.resize((int) children.size()); result.resize((int) children.size());
for (int i = 0; i < children.size(); ++i) { for (int i = 0; i < children.size(); ++i) {
auto child = children[i]; auto child = children[i];
@ -172,225 +128,20 @@ Array SpineBone::get_children() {
return result; return result;
} }
float SpineBone::get_x() { Ref<SpineBoneLocal> SpineBone::get_pose() {
SPINE_CHECK(get_spine_object(), 0) SPINE_CHECK(get_spine_object(), nullptr)
return get_spine_object()->getPose().getX(); 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) { Ref<SpineBonePose> SpineBone::get_applied_pose() {
SPINE_CHECK(get_spine_object(), ) SPINE_CHECK(get_spine_object(), nullptr)
get_spine_object()->getPose().setX(v); auto &applied_pose = get_spine_object()->getAppliedPose();
} Ref<SpineBonePose> pose_ref(memnew(SpineBonePose));
pose_ref->set_spine_object(get_spine_owner(), &applied_pose);
float SpineBone::get_y() { return pose_ref;
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();
} }
bool SpineBone::is_active() { bool SpineBone::is_active() {
@ -402,22 +153,13 @@ void SpineBone::set_active(bool v) {
get_spine_object()->setActive(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() { Transform2D SpineBone::get_transform() {
SPINE_CHECK(get_spine_object(), Transform2D()) SPINE_CHECK(get_spine_object(), Transform2D())
Transform2D transform; Transform2D transform;
transform.rotate(spine::MathUtil::Deg_Rad * get_rotation()); auto &pose = get_spine_object()->getPose();
transform.scale(Size2(get_scale_x(), get_scale_y())); transform.rotate(spine::MathUtil::Deg_Rad * pose.getRotation());
transform.set_origin(Vector2(get_x(), get_y())); transform.scale(Size2(pose.getScaleX(), pose.getScaleY()));
transform.set_origin(Vector2(pose.getX(), pose.getY()));
return transform; return transform;
} }
@ -427,11 +169,12 @@ void SpineBone::set_transform(Transform2D transform) {
float rotation = spine::MathUtil::Rad_Deg * transform.get_rotation(); float rotation = spine::MathUtil::Rad_Deg * transform.get_rotation();
Vector2 scale = transform.get_scale(); Vector2 scale = transform.get_scale();
set_x(position.x); auto &pose = get_spine_object()->getPose();
set_y(position.y); pose.setX(position.x);
set_rotation(rotation); pose.setY(position.y);
set_scale_x(scale.x); pose.setRotation(rotation);
set_scale_y(scale.y); pose.setScaleX(scale.x);
pose.setScaleY(scale.y);
get_spine_owner()->set_modified_bones(); 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()) return get_transform();
if (!get_spine_owner()->is_visible_in_tree()) return get_transform(); if (!get_spine_owner()->is_visible_in_tree()) return get_transform();
Transform2D local; Transform2D local;
local.rotate(spine::MathUtil::Deg_Rad * get_world_rotation_x()); auto &applied_pose = get_spine_object()->getAppliedPose();
local.scale(Vector2(get_world_scale_x(), get_world_scale_y())); local.rotate(spine::MathUtil::Deg_Rad * applied_pose.getWorldRotationX());
local.set_origin(Vector2(get_world_x(), get_world_y())); 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; return get_spine_owner()->get_global_transform() * local;
} }

View File

@ -31,6 +31,8 @@
#include "SpineCommon.h" #include "SpineCommon.h"
#include "SpineBoneData.h" #include "SpineBoneData.h"
#include "SpineBoneLocal.h"
#include "SpineBonePose.h"
#include "SpineConstant.h" #include "SpineConstant.h"
#ifdef SPINE_GODOT_EXTENSION #ifdef SPINE_GODOT_EXTENSION
#include <godot_cpp/classes/node2d.hpp> #include <godot_cpp/classes/node2d.hpp>
@ -69,102 +71,14 @@ public:
Array get_children(); Array get_children();
float get_x(); Ref<SpineBoneLocal> get_pose();
void set_x(float v); Ref<SpineBonePose> get_applied_pose();
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();
bool is_active(); bool is_active();
void set_active(bool v); void set_active(bool v);
SpineConstant::Inherit get_inherit();
void set_inherit(SpineConstant::Inherit inherit);
// External feature functions // External feature functions
void apply_world_transform_2d(const Variant &o); 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_parent"), &SpineBoneData::get_parent);
ClassDB::bind_method(D_METHOD("get_length"), &SpineBoneData::get_length); 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("set_length", "v"), &SpineBoneData::set_length);
ClassDB::bind_method(D_METHOD("get_x"), &SpineBoneData::get_x); ClassDB::bind_method(D_METHOD("get_setup_pose"), &SpineBoneData::get_setup_pose);
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("is_skin_required"), &SpineBoneData::is_skin_required); 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("set_skin_required", "v"), &SpineBoneData::set_skin_required);
ClassDB::bind_method(D_METHOD("get_color"), &SpineBoneData::get_color); 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); get_spine_object()->setLength(v);
} }
float SpineBoneData::get_x() { Ref<SpineBoneLocal> SpineBoneData::get_setup_pose() {
SPINE_CHECK(get_spine_object(), 0) SPINE_CHECK(get_spine_object(), nullptr)
return get_spine_object()->getSetupPose().getX(); auto &setup_pose = get_spine_object()->getSetupPose();
} Ref<SpineBoneLocal> pose_ref(memnew(SpineBoneLocal));
pose_ref->set_spine_object(get_spine_owner(), &setup_pose);
void SpineBoneData::set_x(float v) { return pose_ref;
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);
} }
bool SpineBoneData::is_skin_required() { bool SpineBoneData::is_skin_required() {
@ -184,7 +97,7 @@ void SpineBoneData::set_skin_required(bool v) {
Color SpineBoneData::get_color() { Color SpineBoneData::get_color() {
SPINE_CHECK(get_spine_object(), 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); return Color(color.r, color.g, color.b, color.a);
} }

View File

@ -30,6 +30,7 @@
#pragma once #pragma once
#include "SpineCommon.h" #include "SpineCommon.h"
#include "SpineBoneLocal.h"
#include "SpineConstant.h" #include "SpineConstant.h"
#include <spine/BoneData.h> #include <spine/BoneData.h>
@ -52,37 +53,7 @@ public:
void set_length(float v); void set_length(float v);
float get_x(); Ref<SpineBoneLocal> get_setup_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);
SpineConstant::Inherit get_inherit();
void set_inherit(SpineConstant::Inherit v);
bool is_skin_required(); 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 SpineIkConstraintData::get_bones() {
Array result; Array result;
SPINE_CHECK(get_spine_object(), 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()); result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) { for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData)); Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));

View File

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

View File

@ -30,6 +30,10 @@
#include "SpineSkeleton.h" #include "SpineSkeleton.h"
#include "SpineCommon.h" #include "SpineCommon.h"
#include "SpineSprite.h" #include "SpineSprite.h"
#include "spine/IkConstraint.h"
#include "spine/PathConstraint.h"
#include "spine/PhysicsConstraint.h"
#include "spine/TransformConstraint.h"
#include <spine/SkeletonClipping.h> #include <spine/SkeletonClipping.h>
void SpineSkeleton::_bind_methods() { void SpineSkeleton::_bind_methods() {
@ -89,7 +93,7 @@ void SpineSkeleton::set_spine_sprite(SpineSprite *_sprite) {
skeleton = nullptr; skeleton = nullptr;
sprite = _sprite; sprite = _sprite;
if (!sprite || !sprite->get_skeleton_data_res().is_valid() || !sprite->get_skeleton_data_res()->is_skeleton_data_loaded()) return; 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 { 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() { void SpineSkeleton::set_to_setup_pose() {
SPINE_CHECK(skeleton, ) SPINE_CHECK(skeleton, )
skeleton->setToSetupPose(); skeleton->setupPose();
} }
void SpineSkeleton::set_bones_to_setup_pose() { void SpineSkeleton::set_bones_to_setup_pose() {
SPINE_CHECK(skeleton, ) SPINE_CHECK(skeleton, )
skeleton->setBonesToSetupPose(); skeleton->setupPoseBones();
} }
void SpineSkeleton::set_slots_to_setup_pose() { void SpineSkeleton::set_slots_to_setup_pose() {
SPINE_CHECK(skeleton, ) SPINE_CHECK(skeleton, )
skeleton->setSlotsToSetupPose(); skeleton->setupPoseSlots();
} }
Ref<SpineBone> SpineSkeleton::find_bone(const String &name) { 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) { Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr) SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return 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; if (!constraint) return nullptr;
Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint)); Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint));
constraint_ref->set_spine_object(sprite, constraint); 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) { Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr) SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return 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; if (!constraint) return nullptr;
Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint)); Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint));
constraint_ref->set_spine_object(sprite, constraint); 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) { Ref<SpinePathConstraint> SpineSkeleton::find_path_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr) SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return 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; if (!constraint) return nullptr;
Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint)); Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint));
constraint_ref->set_spine_object(sprite, constraint); 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) { Ref<SpinePhysicsConstraint> SpineSkeleton::find_physics_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr) SPINE_CHECK(skeleton, nullptr)
if (EMPTY(constraint_name)) return 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; if (!constraint) return nullptr;
Ref<SpinePhysicsConstraint> constraint_ref(memnew(SpinePhysicsConstraint)); Ref<SpinePhysicsConstraint> constraint_ref(memnew(SpinePhysicsConstraint));
constraint_ref->set_spine_object(sprite, constraint); constraint_ref->set_spine_object(sprite, constraint);
@ -283,42 +287,54 @@ Array SpineSkeleton::get_draw_order() {
Array SpineSkeleton::get_ik_constraints() { Array SpineSkeleton::get_ik_constraints() {
Array result; Array result;
SPINE_CHECK(skeleton, result) SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getIkConstraints(); auto &constraints = skeleton->getConstraints();
result.resize((int) constraints.size()); 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]; auto constraint = constraints[i];
if (!constraint->getRTTI().isExactly(spine::IkConstraint::rtti) == false) continue;
Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint)); 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; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }
Array SpineSkeleton::get_transform_constraints() { Array SpineSkeleton::get_transform_constraints() {
Array result; Array result;
SPINE_CHECK(skeleton, result) SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getTransformConstraints(); auto &constraints = skeleton->getConstraints();
result.resize((int) constraints.size()); 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]; auto constraint = constraints[i];
if (!constraint->getRTTI().isExactly(spine::TransformConstraint::rtti) == false) continue;
Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint)); 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; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }
Array SpineSkeleton::get_path_constraints() { Array SpineSkeleton::get_path_constraints() {
Array result; Array result;
SPINE_CHECK(skeleton, result) SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getPathConstraints(); auto &constraints = skeleton->getConstraints();
result.resize((int) constraints.size()); 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]; auto constraint = constraints[i];
if (!constraint->getRTTI().isExactly(spine::PathConstraint::rtti) == false) continue;
Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint)); 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; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }
@ -327,7 +343,7 @@ Array SpineSkeleton::get_physics_constraints() {
SPINE_CHECK(skeleton, result) SPINE_CHECK(skeleton, result)
auto &constraints = skeleton->getPhysicsConstraints(); auto &constraints = skeleton->getPhysicsConstraints();
result.resize((int) constraints.size()); 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]; auto constraint = constraints[i];
Ref<SpinePhysicsConstraint> constraint_ref(memnew(SpinePhysicsConstraint)); Ref<SpinePhysicsConstraint> constraint_ref(memnew(SpinePhysicsConstraint));
constraint_ref->set_spine_object(sprite, constraint); 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; spine::SkeletonData *data;
if (!EMPTY(json)) { if (!EMPTY(json)) {
spine::SkeletonJson skeletonJson(atlas); spine::SkeletonJson skeletonJson(*atlas);
data = skeletonJson.readSkeletonData(json.utf8()); data = skeletonJson.readSkeletonData(json.utf8());
if (!data) { if (!data) {
ERR_PRINT(String("Error while loading skeleton data: ") + get_path()); ERR_PRINT(String("Error while loading skeleton data: ") + get_path());
@ -297,7 +297,7 @@ void SpineSkeletonDataResource::load_resources(spine::Atlas *atlas, const String
return; return;
} }
} else { } else {
spine::SkeletonBinary skeletonBinary(atlas); spine::SkeletonBinary skeletonBinary(*atlas);
data = skeletonBinary.readSkeletonData(binary.ptr(), binary.size()); data = skeletonBinary.readSkeletonData(binary.ptr(), binary.size());
if (!data) { if (!data) {
ERR_PRINT(String("Error while loading skeleton data: ") + get_path()); 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; skeleton_data = data;
animation_state_data = new spine::AnimationStateData(data); animation_state_data = new spine::AnimationStateData(*data);
update_mixes(); update_mixes();
} }
@ -339,7 +339,7 @@ void SpineSkeletonDataResource::get_animation_names(Vector<String> &animation_na
#endif #endif
animation_names.clear(); animation_names.clear();
if (!is_skeleton_data_loaded()) return; 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) { for (size_t i = 0; i < animations.size(); ++i) {
auto animation = animations[i]; auto animation = animations[i];
String name; String name;
@ -355,7 +355,7 @@ void SpineSkeletonDataResource::get_skin_names(Vector<String> &skin_names) const
#endif #endif
skin_names.clear(); skin_names.clear();
if (!is_skeleton_data_loaded()) return; 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) { for (size_t i = 0; i < skins.size(); ++i) {
auto skin = skins[i]; auto skin = skins[i];
String name; String name;
@ -371,7 +371,7 @@ void SpineSkeletonDataResource::get_slot_names(Vector<String> &slot_names) {
#endif #endif
slot_names.clear(); slot_names.clear();
if (!is_skeleton_data_loaded()) return; 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) { for (size_t i = 0; i < slots.size(); ++i) {
auto slot = slots[i]; auto slot = slots[i];
String name; String name;
@ -387,7 +387,7 @@ void SpineSkeletonDataResource::get_bone_names(Vector<String> &bone_names) {
#endif #endif
bone_names.clear(); bone_names.clear();
if (!is_skeleton_data_loaded()) return; 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) { for (size_t i = 0; i < bones.size(); ++i) {
auto bone = bones[i]; auto bone = bones[i];
String name; String name;
@ -442,7 +442,7 @@ void SpineSkeletonDataResource::update_mixes() {
from, to, to)); from, to, to));
continue; 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 { Ref<SpineIkConstraintData> SpineSkeletonDataResource::find_ik_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr) SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return 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; if (!constraint) return nullptr;
Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData)); Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData));
constraint_ref->set_spine_object(this, constraint); 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 { Ref<SpineTransformConstraintData> SpineSkeletonDataResource::find_transform_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr) SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return 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; if (!constraint) return nullptr;
Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData)); Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData));
constraint_ref->set_spine_object(this, constraint); 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 { Ref<SpinePathConstraintData> SpineSkeletonDataResource::find_path_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr) SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return 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; if (constraint == nullptr) return nullptr;
Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData)); Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData));
constraint_ref->set_spine_object(this, constraint); 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 { Ref<SpinePhysicsConstraintData> SpineSkeletonDataResource::find_physics_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr) SPINE_CHECK(skeleton_data, nullptr)
if (EMPTY(constraint_name)) return 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; if (constraint == nullptr) return nullptr;
Ref<SpinePhysicsConstraintData> constraint_ref(memnew(SpinePhysicsConstraintData)); Ref<SpinePhysicsConstraintData> constraint_ref(memnew(SpinePhysicsConstraintData));
constraint_ref->set_spine_object(this, constraint); constraint_ref->set_spine_object(this, constraint);
@ -546,7 +546,7 @@ String SpineSkeletonDataResource::get_skeleton_name() const {
Array SpineSkeletonDataResource::get_bones() const { Array SpineSkeletonDataResource::get_bones() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto bones = skeleton_data->getBones(); auto &bones = skeleton_data->getBones();
result.resize((int) bones.size()); result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) { for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData)); Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -559,7 +559,7 @@ Array SpineSkeletonDataResource::get_bones() const {
Array SpineSkeletonDataResource::get_slots() const { Array SpineSkeletonDataResource::get_slots() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto slots = skeleton_data->getSlots(); auto &slots = skeleton_data->getSlots();
result.resize((int) slots.size()); result.resize((int) slots.size());
for (int i = 0; i < slots.size(); ++i) { for (int i = 0; i < slots.size(); ++i) {
Ref<SpineSlotData> slot_ref(memnew(SpineSlotData)); Ref<SpineSlotData> slot_ref(memnew(SpineSlotData));
@ -572,7 +572,7 @@ Array SpineSkeletonDataResource::get_slots() const {
Array SpineSkeletonDataResource::get_skins() const { Array SpineSkeletonDataResource::get_skins() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto skins = skeleton_data->getSkins(); auto &skins = skeleton_data->getSkins();
result.resize((int) skins.size()); result.resize((int) skins.size());
for (int i = 0; i < skins.size(); ++i) { for (int i = 0; i < skins.size(); ++i) {
Ref<SpineSkin> skin_ref(memnew(SpineSkin)); Ref<SpineSkin> skin_ref(memnew(SpineSkin));
@ -599,7 +599,7 @@ void SpineSkeletonDataResource::set_default_skin(Ref<SpineSkin> skin) {
Array SpineSkeletonDataResource::get_events() const { Array SpineSkeletonDataResource::get_events() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto events = skeleton_data->getEvents(); auto &events = skeleton_data->getEvents();
result.resize((int) events.size()); result.resize((int) events.size());
for (int i = 0; i < events.size(); ++i) { for (int i = 0; i < events.size(); ++i) {
Ref<SpineEventData> event_ref(memnew(SpineEventData)); Ref<SpineEventData> event_ref(memnew(SpineEventData));
@ -612,7 +612,7 @@ Array SpineSkeletonDataResource::get_events() const {
Array SpineSkeletonDataResource::get_animations() const { Array SpineSkeletonDataResource::get_animations() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto animations = skeleton_data->getAnimations(); auto &animations = skeleton_data->getAnimations();
result.resize((int) animations.size()); result.resize((int) animations.size());
for (int i = 0; i < animations.size(); ++i) { for (int i = 0; i < animations.size(); ++i) {
Ref<SpineAnimation> animation_ref(memnew(SpineAnimation)); Ref<SpineAnimation> animation_ref(memnew(SpineAnimation));
@ -625,52 +625,68 @@ Array SpineSkeletonDataResource::get_animations() const {
Array SpineSkeletonDataResource::get_ik_constraints() const { Array SpineSkeletonDataResource::get_ik_constraints() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getIkConstraints(); auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size()); result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) { for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::IkConstraintData::rtti)) continue;
Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData)); Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData));
constraint_ref->set_spine_object(this, constraints[i]); constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }
Array SpineSkeletonDataResource::get_transform_constraints() const { Array SpineSkeletonDataResource::get_transform_constraints() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getTransformConstraints(); auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size()); result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) { for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::TransformConstraintData::rtti)) continue;
Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData)); Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData));
constraint_ref->set_spine_object(this, constraints[i]); constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }
Array SpineSkeletonDataResource::get_path_constraints() const { Array SpineSkeletonDataResource::get_path_constraints() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getPathConstraints(); auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size()); result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) { for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::PathConstraintData::rtti)) continue;
Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData)); Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData));
constraint_ref->set_spine_object(this, constraints[i]); constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }
Array SpineSkeletonDataResource::get_physics_constraints() const { Array SpineSkeletonDataResource::get_physics_constraints() const {
Array result; Array result;
SPINE_CHECK(skeleton_data, result) SPINE_CHECK(skeleton_data, result)
auto constraints = skeleton_data->getPhysicsConstraints(); auto &constraints = skeleton_data->getConstraints();
result.resize((int) constraints.size()); result.resize((int) constraints.size());
int size = 0;
for (int i = 0; i < constraints.size(); ++i) { for (int i = 0; i < constraints.size(); ++i) {
if (!constraints[i].getRtti().isExactly(spine::PhysicsConstraintData::rtti)) continue;
Ref<SpinePhysicsConstraintData> constraint_ref(memnew(SpinePhysicsConstraintData)); Ref<SpinePhysicsConstraintData> constraint_ref(memnew(SpinePhysicsConstraintData));
constraint_ref->set_spine_object(this, constraints[i]); constraint_ref->set_spine_object(this, constraints[i]);
result[i] = constraint_ref; result[i] = constraint_ref;
size++;
} }
result.resize(size);
return result; return result;
} }

View File

@ -168,7 +168,7 @@ Array SpineSkin::get_attachments() {
Array SpineSkin::get_bones() { Array SpineSkin::get_bones() {
Array result; Array result;
SPINE_CHECK(get_spine_object(), result) SPINE_CHECK(get_spine_object(), result)
auto bones = get_spine_object()->getBones(); auto &bones = get_spine_object()->getBones();
result.resize((int) bones.size()); result.resize((int) bones.size());
for (int i = 0; i < bones.size(); ++i) { for (int i = 0; i < bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData)); Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -181,7 +181,7 @@ Array SpineSkin::get_bones() {
Array SpineSkin::get_constraints() { Array SpineSkin::get_constraints() {
Array result; Array result;
SPINE_CHECK(get_spine_object(), result) SPINE_CHECK(get_spine_object(), result)
auto constraints = get_spine_object()->getConstraints(); auto &constraints = get_spine_object()->getConstraints();
result.resize((int) constraints.size()); result.resize((int) constraints.size());
for (int i = 0; i < constraints.size(); ++i) { for (int i = 0; i < constraints.size(); ++i) {
Ref<SpineConstraintData> constraint_ref(memnew(SpineConstraintData)); 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("set_deform", "v"), &SpineSlot::set_deform);
ClassDB::bind_method(D_METHOD("get_sequence_index"), &SpineSlot::get_sequence_index); 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("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() { void SpineSlot::set_to_setup_pose() {
SPINE_CHECK(get_spine_object(), ) SPINE_CHECK(get_spine_object(), )
get_spine_object()->setToSetupPose(); get_spine_object()->setupPose();
} }
Ref<SpineSlotData> SpineSlot::get_data() { Ref<SpineSlotData> SpineSlot::get_data() {
@ -85,36 +87,36 @@ Ref<SpineBone> SpineSlot::get_bone() {
Color SpineSlot::get_color() { Color SpineSlot::get_color() {
SPINE_CHECK(get_spine_object(), Color(0, 0, 0, 0)) 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); return Color(color.r, color.g, color.b, color.a);
} }
void SpineSlot::set_color(Color v) { void SpineSlot::set_color(Color v) {
SPINE_CHECK(get_spine_object(), ) 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.set(v.r, v.g, v.b, v.a);
} }
Color SpineSlot::get_dark_color() { Color SpineSlot::get_dark_color() {
SPINE_CHECK(get_spine_object(), Color(0, 0, 0, 0)) 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); return Color(color.r, color.g, color.b, color.a);
} }
void SpineSlot::set_dark_color(Color v) { void SpineSlot::set_dark_color(Color v) {
SPINE_CHECK(get_spine_object(), ) 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); color.set(v.r, v.g, v.b, v.a);
} }
bool SpineSlot::has_dark_color() { bool SpineSlot::has_dark_color() {
SPINE_CHECK(get_spine_object(), false) SPINE_CHECK(get_spine_object(), false)
return get_spine_object()->hasDarkColor(); return get_spine_object()->getAppliedPose().hasDarkColor();
} }
Ref<SpineAttachment> SpineSlot::get_attachment() { Ref<SpineAttachment> SpineSlot::get_attachment() {
SPINE_CHECK(get_spine_object(), nullptr) SPINE_CHECK(get_spine_object(), nullptr)
auto attachment = get_spine_object()->getAttachment(); auto attachment = get_spine_object()->getAppliedPose().getAttachment();
if (!attachment) return nullptr; if (!attachment) return nullptr;
Ref<SpineAttachment> attachment_ref(memnew(SpineAttachment)); Ref<SpineAttachment> attachment_ref(memnew(SpineAttachment));
attachment_ref->set_spine_object(*get_spine_owner()->get_skeleton_data_res(), attachment); 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) { void SpineSlot::set_attachment(Ref<SpineAttachment> v) {
SPINE_CHECK(get_spine_object(), ) 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() { int SpineSlot::get_attachment_state() {
// TODO: attachmentState is no longer exposed in the new API
SPINE_CHECK(get_spine_object(), 0) SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAttachmentState(); return 0;
} }
void SpineSlot::set_attachment_state(int v) { void SpineSlot::set_attachment_state(int v) {
// TODO: attachmentState is no longer exposed in the new API
SPINE_CHECK(get_spine_object(), ) SPINE_CHECK(get_spine_object(), )
get_spine_object()->setAttachmentState(v);
} }
Array SpineSlot::get_deform() { Array SpineSlot::get_deform() {
Array result; Array result;
SPINE_CHECK(get_spine_object(), 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()); result.resize((int) deform.size());
for (int i = 0; i < (int) deform.size(); ++i) { for (int i = 0; i < (int) deform.size(); ++i) {
result[i] = deform[i]; result[i] = deform[i];
@ -149,7 +152,7 @@ Array SpineSlot::get_deform() {
void SpineSlot::set_deform(Array v) { void SpineSlot::set_deform(Array v) {
SPINE_CHECK(get_spine_object(), ) SPINE_CHECK(get_spine_object(), )
auto &deform = get_spine_object()->getDeform(); auto &deform = get_spine_object()->getPose().getDeform();
deform.setSize(v.size(), 0); deform.setSize(v.size(), 0);
for (int i = 0; i < v.size(); ++i) { for (int i = 0; i < v.size(); ++i) {
deform[i] = v[i]; deform[i] = v[i];
@ -158,10 +161,26 @@ void SpineSlot::set_deform(Array v) {
int SpineSlot::get_sequence_index() { int SpineSlot::get_sequence_index() {
SPINE_CHECK(get_spine_object(), 0) SPINE_CHECK(get_spine_object(), 0)
return get_spine_object()->getAttachmentState(); return get_spine_object()->getAppliedPose().getSequenceIndex();
} }
void SpineSlot::set_sequence_index(int v) { void SpineSlot::set_sequence_index(int v) {
SPINE_CHECK(get_spine_object(), ) 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 "SpineSlotData.h"
#include "SpineAttachment.h" #include "SpineAttachment.h"
#include "SpineBone.h" #include "SpineBone.h"
#include "SpineSlotPose.h"
#include <spine/Slot.h>
class SpineSkeleton; class SpineSkeleton;
class SpineSprite; class SpineSprite;
@ -79,4 +81,8 @@ public:
int get_sequence_index(); int get_sequence_index();
void set_sequence_index(int v); 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: public:
Ref<CanvasItemMaterial> default_materials[4] = {}; Ref<CanvasItemMaterial> default_materials[4] = {};
int sprite_count; int sprite_count;
spine::Vector<unsigned short> quad_indices; spine::Array<unsigned short> quad_indices;
spine::Vector<float> scratch_vertices; spine::Array<float> scratch_vertices;
#ifdef SPINE_GODOT_EXTENSION #ifdef SPINE_GODOT_EXTENSION
PackedVector2Array scratch_points; PackedVector2Array scratch_points;
#else #else
@ -598,7 +598,7 @@ void SpineSprite::generate_meshes_for_slots(Ref<SpineSkeleton> skeleton_ref) {
mesh_instance->set_draw_behind_parent(true); mesh_instance->set_draw_behind_parent(true);
add_child(mesh_instance); add_child(mesh_instance);
mesh_instances.push_back(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); 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++) { for (int i = 0; i < get_child_count(); i++) {
auto child = cast_to<Node2D>(get_child(i)); auto child = cast_to<Node2D>(get_child(i));
if (!child) continue; if (!child) continue;
@ -633,7 +633,7 @@ void SpineSprite::sort_slot_nodes() {
for (int i = 0; i < (int) draw_order.size(); i++) { for (int i = 0; i < (int) draw_order.size(); i++) {
int slot_index = draw_order[i]->getData().getIndex(); int slot_index = draw_order[i]->getData().getIndex();
int mesh_index = mesh_instances[i]->get_index(); 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++) { for (int j = 0; j < (int) nodes.size(); j++) {
auto node = nodes[j]; auto node = nodes[j];
move_child(node, mesh_index + 1); 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(); spine::Skeleton *skeleton = skeleton_ref->get_spine_object();
for (int i = 0, n = (int) skeleton->getSlots().size(); i < n; ++i) { for (int i = 0, n = (int) skeleton->getSlots().size(); i < n; ++i) {
spine::Slot *slot = skeleton->getDrawOrder()[i]; spine::Slot *slot = skeleton->getDrawOrder()[i];
spine::Attachment *attachment = slot->getAttachment(); spine::Attachment *attachment = slot->getAppliedPose().getAttachment();
SpineMesh2D *mesh_instance = mesh_instances[i]; SpineMesh2D *mesh_instance = mesh_instances[i];
mesh_instance->renderer_object = nullptr; 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 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, 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); skeleton_color.a * slot_color.a);
SpineRendererObject *renderer_object; SpineRendererObject *renderer_object;
spine::Vector<float> *vertices = &statics.scratch_vertices; spine::Array<float> *vertices = &statics.scratch_vertices;
spine::Vector<float> *uvs; spine::Array<float> *uvs;
spine::Vector<unsigned short> *indices; spine::Array<unsigned short> *indices;
if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) { if (attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) {
auto *region = (spine::RegionAttachment *) attachment; auto region = (spine::RegionAttachment *) attachment;
vertices->setSize(8, 0); vertices->setSize(8, 0);
region->computeWorldVertices(*slot, *vertices, 0); region->computeWorldVertices(*slot, *vertices, 0);
@ -863,28 +863,28 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
uvs = &region->getUVs(); uvs = &region->getUVs();
indices = &statics.quad_indices; indices = &statics.quad_indices;
auto attachment_color = region->getColor(); auto &attachment_color = region->getColor();
tint.r *= attachment_color.r; tint.r *= attachment_color.r;
tint.g *= attachment_color.g; tint.g *= attachment_color.g;
tint.b *= attachment_color.b; tint.b *= attachment_color.b;
tint.a *= attachment_color.a; tint.a *= attachment_color.a;
} else if (attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) { } else if (attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) {
auto *mesh = (spine::MeshAttachment *) attachment; auto mesh = (spine::MeshAttachment *) attachment;
vertices->setSize(mesh->getWorldVerticesLength(), 0); vertices->setSize(mesh->getWorldVerticesLength(), 0);
mesh->computeWorldVertices(*slot, *vertices); mesh->computeWorldVertices(*skeleton, *slot, *vertices);
renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) mesh->getRegion())->page->texture; renderer_object = (SpineRendererObject *) ((spine::AtlasRegion *) mesh->getRegion())->page->texture;
uvs = &mesh->getUVs(); uvs = &mesh->getUVs();
indices = &mesh->getTriangles(); indices = &mesh->getTriangles();
auto attachment_color = mesh->getColor(); auto &attachment_color = mesh->getColor();
tint.r *= attachment_color.r; tint.r *= attachment_color.r;
tint.g *= attachment_color.g; tint.g *= attachment_color.g;
tint.b *= attachment_color.b; tint.b *= attachment_color.b;
tint.a *= attachment_color.a; tint.a *= attachment_color.a;
} else if (attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) { } else if (attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) {
auto clip = (spine::ClippingAttachment *) attachment; auto clip = (spine::ClippingAttachment *) attachment;
skeleton_clipper->clipStart(*slot, clip); skeleton_clipper->clipStart(*skeleton, *slot, clip);
continue; continue;
} else { } else {
skeleton_clipper->clipEnd(*slot); skeleton_clipper->clipEnd(*slot);
@ -994,9 +994,9 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> skeleton_ref) {
} }
#ifdef SPINE_GODOT_EXTENSION #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 #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 #endif
scratch_points.resize(0); scratch_points.resize(0);
for (int i = 0; i < triangles.size(); i += 3) { 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 (!animation_state.is_valid() && !skeleton.is_valid()) return;
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) 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 #if VERSION_MAJOR > 3
RS::get_singleton()->canvas_item_clear(this->get_canvas_item()); 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)); draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
auto &draw_order = skeleton->get_spine_object()->getDrawOrder(); auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < (int) draw_order.size(); i++) { 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; if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment(); auto attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue; if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) continue; if (!attachment->getRTTI().isExactly(spine::RegionAttachment::rtti)) continue;
auto *region = (spine::RegionAttachment *) attachment; auto region = (spine::RegionAttachment *) attachment;
auto *vertices = &statics.scratch_vertices; auto vertices = &statics.scratch_vertices;
vertices->setSize(8, 0); vertices->setSize(8, 0);
region->computeWorldVertices(*slot, *vertices, 0); region->computeWorldVertices(*slot, *vertices, 0);
@ -1077,7 +1077,7 @@ void SpineSprite::draw() {
for (int i = 0; i < (int) draw_order.size(); i++) { 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; if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment(); auto *attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue; if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) continue; if (!attachment->getRTTI().isExactly(spine::MeshAttachment::rtti)) continue;
auto *mesh = (spine::MeshAttachment *) attachment; auto *mesh = (spine::MeshAttachment *) attachment;
@ -1115,13 +1115,13 @@ void SpineSprite::draw() {
draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1)); draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
auto &draw_order = skeleton->get_spine_object()->getDrawOrder(); auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < (int) draw_order.size(); i++) { 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; if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment(); auto attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue; if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::BoundingBoxAttachment::rtti)) continue; if (!attachment->getRTTI().isExactly(spine::BoundingBoxAttachment::rtti)) continue;
auto *bounding_box = (spine::BoundingBoxAttachment *) attachment; auto bounding_box = (spine::BoundingBoxAttachment *) attachment;
auto *vertices = &statics.scratch_vertices; auto vertices = &statics.scratch_vertices;
vertices->setSize(bounding_box->getWorldVerticesLength(), 0); vertices->setSize(bounding_box->getWorldVerticesLength(), 0);
bounding_box->computeWorldVertices(*slot, *vertices); bounding_box->computeWorldVertices(*slot, *vertices);
size_t num_vertices = vertices->size() / 2; size_t num_vertices = vertices->size() / 2;
@ -1136,13 +1136,13 @@ void SpineSprite::draw() {
draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1)); draw_set_transform(Vector2(0, 0), 0, Vector2(1, 1));
auto &draw_order = skeleton->get_spine_object()->getDrawOrder(); auto &draw_order = skeleton->get_spine_object()->getDrawOrder();
for (int i = 0; i < (int) draw_order.size(); i++) { 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; if (!slot->getBone().isActive()) continue;
auto *attachment = slot->getAttachment(); auto attachment = slot->getAppliedPose().getAttachment();
if (!attachment) continue; if (!attachment) continue;
if (!attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) continue; if (!attachment->getRTTI().isExactly(spine::ClippingAttachment::rtti)) continue;
auto *clipping = (spine::ClippingAttachment *) attachment; auto clipping = (spine::ClippingAttachment *) attachment;
auto *vertices = &statics.scratch_vertices; auto vertices = &statics.scratch_vertices;
vertices->setSize(clipping->getWorldVerticesLength(), 0); vertices->setSize(clipping->getWorldVerticesLength(), 0);
clipping->computeWorldVertices(*slot, *vertices); clipping->computeWorldVertices(*slot, *vertices);
size_t num_vertices = vertices->size() / 2; 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(2, Vector2(bone_length, 0));
statics.scratch_points.set(3, Vector2(0, -debug_bones_thickness)); statics.scratch_points.set(3, Vector2(0, -debug_bones_thickness));
statics.scratch_points.set(4, Vector2(-debug_bones_thickness, 0)); statics.scratch_points.set(4, Vector2(-debug_bones_thickness, 0));
Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldX(), bone->getWorldY())); Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getAppliedPose().getWorldRotationX(), Vector2(bone->getAppliedPose().getWorldX(), bone->getAppliedPose().getWorldY()));
bone_transform.scale_basis(Vector2(bone->getWorldScaleX(), bone->getWorldScaleY())); bone_transform.scale_basis(Vector2(bone->getAppliedPose().getWorldScaleX(), bone->getAppliedPose().getWorldScaleY()));
auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position); auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position);
#ifdef SPINE_GODOT_EXTENSION #ifdef SPINE_GODOT_EXTENSION
if (GEOMETRY2D::get_singleton()->is_point_in_polygon(mouse_local_position, statics.scratch_points)) { if (GEOMETRY2D::get_singleton()->is_point_in_polygon(mouse_local_position, statics.scratch_points)) {
@ -1183,7 +1183,7 @@ void SpineSprite::draw() {
if (debug_bones) { if (debug_bones) {
auto &bones = skeleton->get_spine_object()->getBones(); auto &bones = skeleton->get_spine_object()->getBones();
for (int i = 0; i < (int) bones.size(); i++) { for (int i = 0; i < (int) bones.size(); i++) {
auto *bone = bones[i]; auto bone = bones[i];
if (!bone->isActive()) continue; if (!bone->isActive()) continue;
draw_bone(bone, debug_bones_color); 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(2, Vector2(bone_length, 0));
statics.scratch_points.set(3, Vector2(0, -debug_bones_thickness)); statics.scratch_points.set(3, Vector2(0, -debug_bones_thickness));
statics.scratch_points.set(4, Vector2(-debug_bones_thickness, 0)); statics.scratch_points.set(4, Vector2(-debug_bones_thickness, 0));
Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getWorldRotationX(), Vector2(bone->getWorldX(), bone->getWorldY())); Transform2D bone_transform(spine::MathUtil::Deg_Rad * bone->getAppliedPose().getWorldRotationX(), Vector2(bone->getAppliedPose().getWorldX(), bone->getAppliedPose().getWorldY()));
bone_transform.scale_basis(Vector2(bone->getWorldScaleX(), bone->getWorldScaleY())); bone_transform.scale_basis(Vector2(bone->getAppliedPose().getWorldScaleX(), bone->getAppliedPose().getWorldScaleY()));
auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position); auto mouse_local_position = bone_transform.affine_inverse().xform(mouse_position);
#ifdef SPINE_GODOT_EXTENSION #ifdef SPINE_GODOT_EXTENSION
if (GEOMETRY2D::get_singleton()->is_point_in_polygon(mouse_local_position, statics.scratch_points)) { 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() { Ref<SpineAnimation> SpineTrackEntry::get_animation() {
SPINE_CHECK(get_spine_object(), nullptr) SPINE_CHECK(get_spine_object(), nullptr)
auto animation = get_spine_object()->getAnimation(); auto animation = &get_spine_object()->getAnimation();
if (!animation) return nullptr;
Ref<SpineAnimation> animation_ref(memnew(SpineAnimation)); Ref<SpineAnimation> animation_ref(memnew(SpineAnimation));
animation_ref->set_spine_object(*get_spine_owner()->get_skeleton_data_res(), animation); animation_ref->set_spine_object(*get_spine_owner()->get_skeleton_data_res(), animation);
return animation_ref; 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_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_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("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 SpineTransformConstraintData::get_bones() {
Array result; Array result;
SPINE_CHECK(get_spine_constraint_data(), 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()); result.resize((int) bones.size());
for (int i = 0; i < (int) bones.size(); ++i) { for (int i = 0; i < (int) bones.size(); ++i) {
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData)); Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -73,32 +71,32 @@ Ref<SpineBoneData> SpineTransformConstraintData::get_target() {
float SpineTransformConstraintData::get_mix_rotate() { float SpineTransformConstraintData::get_mix_rotate() {
SPINE_CHECK(get_spine_constraint_data(), 0) 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() { float SpineTransformConstraintData::get_mix_x() {
SPINE_CHECK(get_spine_constraint_data(), 0) 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() { float SpineTransformConstraintData::get_mix_y() {
SPINE_CHECK(get_spine_constraint_data(), 0) 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() { float SpineTransformConstraintData::get_mix_scale_x() {
SPINE_CHECK(get_spine_constraint_data(), 0) 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() { float SpineTransformConstraintData::get_mix_scale_y() {
SPINE_CHECK(get_spine_constraint_data(), 0) 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() { float SpineTransformConstraintData::get_mix_shear_y() {
SPINE_CHECK(get_spine_constraint_data(), 0) 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() { float SpineTransformConstraintData::get_offset_rotation() {
@ -130,13 +128,3 @@ float SpineTransformConstraintData::get_offset_shear_y() {
SPINE_CHECK(get_spine_constraint_data(), 0) SPINE_CHECK(get_spine_constraint_data(), 0)
return get_spine_constraint_data()->getOffsetShearY(); 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 "SpineEvent.h"
#include "SpineTrackEntry.h" #include "SpineTrackEntry.h"
#include "SpineBoneData.h" #include "SpineBoneData.h"
#include "SpineBoneLocal.h"
#include "SpineBonePose.h"
#include "SpineSlotData.h" #include "SpineSlotData.h"
#include "SpineSlotPose.h"
#include "SpineAttachment.h" #include "SpineAttachment.h"
#include "SpineConstraintData.h" #include "SpineConstraintData.h"
#include "SpineSkin.h" #include "SpineSkin.h"
@ -130,6 +133,7 @@ void register_spine_godot_types() {
GDREGISTER_CLASS(SpineEvent); GDREGISTER_CLASS(SpineEvent);
GDREGISTER_CLASS(SpineBoneData); GDREGISTER_CLASS(SpineBoneData);
GDREGISTER_CLASS(SpineSlotData); GDREGISTER_CLASS(SpineSlotData);
GDREGISTER_CLASS(SpineSlotPose);
GDREGISTER_CLASS(SpineAttachment); GDREGISTER_CLASS(SpineAttachment);
GDREGISTER_CLASS(SpineSkinEntry); GDREGISTER_CLASS(SpineSkinEntry);
GDREGISTER_CLASS(SpineConstraintData); GDREGISTER_CLASS(SpineConstraintData);
@ -139,6 +143,8 @@ void register_spine_godot_types() {
GDREGISTER_CLASS(SpinePathConstraintData); GDREGISTER_CLASS(SpinePathConstraintData);
GDREGISTER_CLASS(SpinePhysicsConstraintData); GDREGISTER_CLASS(SpinePhysicsConstraintData);
GDREGISTER_CLASS(SpineBone); GDREGISTER_CLASS(SpineBone);
GDREGISTER_CLASS(SpineBoneLocal);
GDREGISTER_CLASS(SpineBonePose);
GDREGISTER_CLASS(SpineSlot); GDREGISTER_CLASS(SpineSlot);
GDREGISTER_CLASS(SpineIkConstraint); GDREGISTER_CLASS(SpineIkConstraint);
GDREGISTER_CLASS(SpinePathConstraint); GDREGISTER_CLASS(SpinePathConstraint);