mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-14 19:11:36 +08:00
[godot] New SpineSprite implementation with more coherent resource management.
This commit is contained in:
parent
702c685b32
commit
88038fa906
@ -0,0 +1,10 @@
|
||||
[gd_resource type="SpineNewSkeletonDataResource" load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://assets/spineboy/spineboy.atlas" type="SpineAtlasResource" id=1]
|
||||
[ext_resource path="res://assets/spineboy/spineboy-pro.skel" type="SpineSkeletonFileResource" id=2]
|
||||
|
||||
[resource]
|
||||
atlas_res = ExtResource( 1 )
|
||||
skeleton_file_res = ExtResource( 2 )
|
||||
animations = null
|
||||
skins = null
|
||||
@ -1,8 +1,9 @@
|
||||
[gd_scene load_steps=9 format=2]
|
||||
[gd_scene load_steps=10 format=2]
|
||||
|
||||
[ext_resource path="res://Spineboy.gd" type="Script" id=1]
|
||||
[ext_resource path="res://assets/spineboy/spineboy-data.tres" type="SpineSkeletonDataResource" id=2]
|
||||
[ext_resource path="res://assets/mix-and-match/mix-and-match-data.tres" type="SpineSkeletonDataResource" id=3]
|
||||
[ext_resource path="res://assets/spineboy/spinebody-data-new-res.tres" type="SpineNewSkeletonDataResource" id=4]
|
||||
[ext_resource path="res://mix-and-match.gd" type="Script" id=5]
|
||||
[ext_resource path="res://assets/raptor/raprot-data.tres" type="SpineSkeletonDataResource" id=6]
|
||||
|
||||
@ -33,3 +34,7 @@ script = ExtResource( 5 )
|
||||
position = Vector2( 261.223, 541.504 )
|
||||
scale = Vector2( 0.5, 0.5 )
|
||||
animation_state_data_res = SubResource( 5 )
|
||||
|
||||
[node name="SpineNewSprite" type="SpineNewSprite" parent="."]
|
||||
position = Vector2( 631.194, 1005.65 )
|
||||
skeleton_data_res = ExtResource( 4 )
|
||||
|
||||
171
spine-godot/godot/modules/spine_godot/SpineNewAnimationState.cpp
Normal file
171
spine-godot/godot/modules/spine_godot/SpineNewAnimationState.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineNewAnimationState.h"
|
||||
|
||||
void SpineNewAnimationState::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_animation", "anim_name", "loop", "track_id"), &SpineNewAnimationState::set_animation, DEFVAL(true), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("update", "delta"), &SpineNewAnimationState::update, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("apply", "skeleton"), &SpineNewAnimationState::apply);
|
||||
ClassDB::bind_method(D_METHOD("clear_tracks"), &SpineNewAnimationState::clear_tracks);
|
||||
ClassDB::bind_method(D_METHOD("clear_track"), &SpineNewAnimationState::clear_track);
|
||||
ClassDB::bind_method(D_METHOD("add_animation", "anim_name", "delay", "loop", "track_id"), &SpineNewAnimationState::add_animation, DEFVAL(0), DEFVAL(true), DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("set_empty_animation", "track_id", "mix_duration"), &SpineNewAnimationState::set_empty_animation);
|
||||
ClassDB::bind_method(D_METHOD("add_empty_animation", "track_id", "mix_duration", "delay"), &SpineNewAnimationState::add_empty_animation);
|
||||
ClassDB::bind_method(D_METHOD("set_empty_animations", "mix_duration"), &SpineNewAnimationState::set_empty_animations);
|
||||
ClassDB::bind_method(D_METHOD("get_time_scale"), &SpineNewAnimationState::get_time_scale);
|
||||
ClassDB::bind_method(D_METHOD("set_time_scale", "time_scale"), &SpineNewAnimationState::set_time_scale);
|
||||
ClassDB::bind_method(D_METHOD("disable_queue"), &SpineNewAnimationState::disable_queue);
|
||||
ClassDB::bind_method(D_METHOD("enable_queue"), &SpineNewAnimationState::enable_queue);
|
||||
ClassDB::bind_method(D_METHOD("get_current", "track_id"), &SpineNewAnimationState::get_current);
|
||||
}
|
||||
|
||||
SpineNewAnimationState::SpineNewAnimationState() : animation_state(nullptr), skeleton_data_res(nullptr) {
|
||||
}
|
||||
|
||||
SpineNewAnimationState::~SpineNewAnimationState() {
|
||||
delete animation_state;
|
||||
}
|
||||
|
||||
void SpineNewAnimationState::set_skeleton_data_res(Ref<SpineNewSkeletonDataResource> data_res) {
|
||||
delete animation_state;
|
||||
animation_state = nullptr;
|
||||
skeleton_data_res = data_res;
|
||||
if (!skeleton_data_res.is_valid() || !skeleton_data_res->is_skeleton_data_loaded()) return;
|
||||
animation_state = new spine::AnimationState(skeleton_data_res->get_animation_state_data());
|
||||
}
|
||||
|
||||
Ref<SpineNewSkeletonDataResource> SpineNewAnimationState::get_skeleton_data_res() const {
|
||||
return skeleton_data_res;
|
||||
}
|
||||
|
||||
#define CHECK_V \
|
||||
if (!animation_state) { \
|
||||
ERR_PRINT("The animation state is not loaded yet!"); \
|
||||
return; \
|
||||
}
|
||||
#define CHECK_X(x) \
|
||||
if (!animation_state) { \
|
||||
ERR_PRINT("The animation state is not loaded yet!"); \
|
||||
return x; \
|
||||
}
|
||||
#define S_T(x) (spine::String(x.utf8()))
|
||||
Ref<SpineTrackEntry> SpineNewAnimationState::set_animation(const String &anim_name, bool loop, uint64_t track) {
|
||||
CHECK_X(nullptr);
|
||||
auto skeleton_data = animation_state->getData()->getSkeletonData();
|
||||
auto anim = skeleton_data->findAnimation(anim_name.utf8().ptr());
|
||||
if (!anim) {
|
||||
ERR_PRINT(String("Can not find animation: ") + anim_name);
|
||||
return nullptr;
|
||||
}
|
||||
auto entry = animation_state->setAnimation(track, anim, loop);
|
||||
Ref<SpineTrackEntry> gd_entry(memnew(SpineTrackEntry));
|
||||
gd_entry->set_spine_object(entry);
|
||||
return gd_entry;
|
||||
}
|
||||
Ref<SpineTrackEntry> SpineNewAnimationState::add_animation(const String &anim_name, float delay, bool loop, uint64_t track) {
|
||||
CHECK_X(nullptr);
|
||||
auto skeleton_data = animation_state->getData()->getSkeletonData();
|
||||
auto anim = skeleton_data->findAnimation(anim_name.utf8().ptr());
|
||||
if (!anim) {
|
||||
ERR_PRINT(String("Can not find animation: ") + anim_name);
|
||||
return nullptr;
|
||||
}
|
||||
auto entry = animation_state->addAnimation(track, anim, loop, delay);
|
||||
Ref<SpineTrackEntry> gd_entry(memnew(SpineTrackEntry));
|
||||
gd_entry->set_spine_object(entry);
|
||||
return gd_entry;
|
||||
}
|
||||
|
||||
Ref<SpineTrackEntry> SpineNewAnimationState::set_empty_animation(uint64_t track_id, float mix_duration) {
|
||||
CHECK_X(nullptr);
|
||||
auto entry = animation_state->setEmptyAnimation(track_id, mix_duration);
|
||||
Ref<SpineTrackEntry> gd_entry(memnew(SpineTrackEntry));
|
||||
gd_entry->set_spine_object(entry);
|
||||
return gd_entry;
|
||||
}
|
||||
Ref<SpineTrackEntry> SpineNewAnimationState::add_empty_animation(uint64_t track_id, float mix_duration, float delay) {
|
||||
CHECK_X(nullptr);
|
||||
auto entry = animation_state->addEmptyAnimation(track_id, mix_duration, delay);
|
||||
Ref<SpineTrackEntry> gd_entry(memnew(SpineTrackEntry));
|
||||
gd_entry->set_spine_object(entry);
|
||||
return gd_entry;
|
||||
}
|
||||
void SpineNewAnimationState::set_empty_animations(float mix_duration) {
|
||||
CHECK_V;
|
||||
animation_state->setEmptyAnimations(mix_duration);
|
||||
}
|
||||
|
||||
void SpineNewAnimationState::update(float delta) {
|
||||
CHECK_V;
|
||||
animation_state->update(delta);
|
||||
}
|
||||
bool SpineNewAnimationState::apply(Ref<SpineNewSkeleton> skeleton) {
|
||||
CHECK_X(false);
|
||||
return animation_state->apply(*(skeleton->get_spine_object()));
|
||||
}
|
||||
|
||||
void SpineNewAnimationState::clear_tracks() {
|
||||
CHECK_V;
|
||||
animation_state->clearTracks();
|
||||
}
|
||||
void SpineNewAnimationState::clear_track(uint64_t track_id) {
|
||||
CHECK_V;
|
||||
animation_state->clearTrack(track_id);
|
||||
}
|
||||
|
||||
float SpineNewAnimationState::get_time_scale() {
|
||||
CHECK_X(0);
|
||||
return animation_state->getTimeScale();
|
||||
}
|
||||
void SpineNewAnimationState::set_time_scale(float time_scale) {
|
||||
CHECK_V;
|
||||
animation_state->setTimeScale(time_scale);
|
||||
}
|
||||
|
||||
void SpineNewAnimationState::disable_queue() {
|
||||
CHECK_V;
|
||||
animation_state->disableQueue();
|
||||
}
|
||||
void SpineNewAnimationState::enable_queue() {
|
||||
CHECK_V;
|
||||
animation_state->enableQueue();
|
||||
}
|
||||
|
||||
Ref<SpineTrackEntry> SpineNewAnimationState::get_current(uint64_t track_index) {
|
||||
CHECK_X(nullptr);
|
||||
Ref<SpineTrackEntry> gd_entry(memnew(SpineTrackEntry));
|
||||
auto entry = animation_state->getCurrent(track_index);
|
||||
if (entry == nullptr) return nullptr;
|
||||
gd_entry->set_spine_object(entry);
|
||||
return gd_entry;
|
||||
}
|
||||
|
||||
#undef CHECK_V
|
||||
#undef CHECK_X
|
||||
@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated January 1, 2020. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2020, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef GODOT_SPINENEWANIMATIONSTATE_H
|
||||
#define GODOT_SPINENEWANIMATIONSTATE_H
|
||||
|
||||
#include "SpineNewSkeleton.h"
|
||||
#include "SpineTrackEntry.h"
|
||||
|
||||
class SpineNewAnimationState : public Reference {
|
||||
GDCLASS(SpineNewAnimationState, Reference);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
private:
|
||||
spine::AnimationState *animation_state;
|
||||
Ref<SpineNewSkeletonDataResource> skeleton_data_res;
|
||||
|
||||
public:
|
||||
SpineNewAnimationState();
|
||||
~SpineNewAnimationState();
|
||||
|
||||
void set_skeleton_data_res(Ref<SpineNewSkeletonDataResource> skeleton_data_res);
|
||||
Ref<SpineNewSkeletonDataResource> get_skeleton_data_res() const;
|
||||
|
||||
inline void set_spine_object(spine::AnimationState *animation_state) { this->animation_state = animation_state; }
|
||||
inline spine::AnimationState *get_spine_object() { return animation_state; }
|
||||
|
||||
Ref<SpineTrackEntry> set_animation(const String &anim_name, bool loop, uint64_t track_id);
|
||||
|
||||
Ref<SpineTrackEntry> add_animation(const String &anim_name, float delay, bool loop, uint64_t track_id);
|
||||
|
||||
Ref<SpineTrackEntry> set_empty_animation(uint64_t track_id, float mix_duration);
|
||||
|
||||
Ref<SpineTrackEntry> add_empty_animation(uint64_t track_id, float mix_duration, float delay);
|
||||
void set_empty_animations(float mix_duration);
|
||||
|
||||
float get_time_scale();
|
||||
void set_time_scale(float time_scale);
|
||||
|
||||
void disable_queue();
|
||||
void enable_queue();
|
||||
|
||||
void update(float delta);
|
||||
|
||||
bool apply(Ref<SpineNewSkeleton> skeleton);
|
||||
|
||||
void clear_tracks();
|
||||
|
||||
void clear_track(uint64_t track_id);
|
||||
|
||||
Ref<SpineTrackEntry> get_current(uint64_t track_index);
|
||||
};
|
||||
|
||||
#endif//GODOT_SPINENEWANIMATIONSTATE_H
|
||||
@ -98,9 +98,14 @@ void SpineNewBone::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("apply_world_transform_2d", "node2d"), &SpineNewBone::apply_world_transform_2d);
|
||||
}
|
||||
|
||||
SpineNewBone::SpineNewBone() : bone(NULL), the_sprite(nullptr) {}
|
||||
SpineNewBone::SpineNewBone() : bone(nullptr), sprite(nullptr) {}
|
||||
|
||||
SpineNewBone::~SpineNewBone() {}
|
||||
|
||||
void SpineNewBone::set_spine_sprite(SpineNewSprite* sprite) {
|
||||
this->sprite = sprite;
|
||||
}
|
||||
|
||||
void SpineNewBone::update_world_transform() {
|
||||
bone->updateWorldTransform();
|
||||
}
|
||||
@ -151,7 +156,7 @@ Ref<SpineNewSkeleton> SpineNewBone::get_skeleton() {
|
||||
auto &s = bone->getSkeleton();
|
||||
Ref<SpineNewSkeleton> gd_s(memnew(SpineNewSkeleton));
|
||||
gd_s->set_spine_object(&s);
|
||||
gd_s->set_spine_sprite(the_sprite);
|
||||
gd_s->set_spine_sprite(sprite);
|
||||
return gd_s;
|
||||
}
|
||||
|
||||
@ -160,7 +165,7 @@ Ref<SpineNewBone> SpineNewBone::get_parent() {
|
||||
if (b == NULL) return NULL;
|
||||
Ref<SpineNewBone> gd_b(memnew(SpineNewBone));
|
||||
gd_b->set_spine_object(b);
|
||||
gd_b->set_spine_sprite(the_sprite);
|
||||
gd_b->set_spine_sprite(sprite);
|
||||
return gd_b;
|
||||
}
|
||||
|
||||
@ -173,7 +178,7 @@ Array SpineNewBone::get_children() {
|
||||
if (b == NULL) gd_bs[i] = Ref<SpineNewBone>(NULL);
|
||||
Ref<SpineNewBone> gd_b(memnew(SpineNewBone));
|
||||
gd_b->set_spine_object(b);
|
||||
gd_b->set_spine_sprite(the_sprite);
|
||||
gd_b->set_spine_sprite(sprite);
|
||||
gd_bs[i] = gd_b;
|
||||
}
|
||||
return gd_bs;
|
||||
@ -390,13 +395,13 @@ void SpineNewBone::set_godot_transform(Transform2D trans) {
|
||||
Transform2D SpineNewBone::get_godot_global_transform() {
|
||||
if (get_spine_object() == nullptr)
|
||||
return Transform2D();
|
||||
if (the_sprite == nullptr)
|
||||
if (sprite == nullptr)
|
||||
return get_godot_transform();
|
||||
Transform2D res = the_sprite->get_transform();
|
||||
Transform2D res = sprite->get_transform();
|
||||
res.translate(get_world_x(), -get_world_y());
|
||||
res.rotate(Math::deg2rad(-get_world_rotation_x()));
|
||||
res.scale(Vector2(get_world_scale_x(), get_world_scale_y()));
|
||||
auto p = the_sprite->get_parent() ? Object::cast_to<CanvasItem>(the_sprite->get_parent()) : nullptr;
|
||||
auto p = sprite->get_parent() ? Object::cast_to<CanvasItem>(sprite->get_parent()) : nullptr;
|
||||
if (p) {
|
||||
return p->get_global_transform() * res;
|
||||
}
|
||||
@ -406,9 +411,9 @@ Transform2D SpineNewBone::get_godot_global_transform() {
|
||||
void SpineNewBone::set_godot_global_transform(Transform2D transform) {
|
||||
if (get_spine_object() == nullptr)
|
||||
return;
|
||||
if (the_sprite == nullptr)
|
||||
if (sprite == nullptr)
|
||||
set_godot_transform(transform);
|
||||
transform = the_sprite->get_global_transform().affine_inverse() * transform;
|
||||
transform = sprite->get_global_transform().affine_inverse() * transform;
|
||||
Vector2 position = transform.get_origin();
|
||||
real_t rotation = transform.get_rotation();
|
||||
Vector2 scale = transform.get_scale();
|
||||
@ -433,7 +438,3 @@ void SpineNewBone::set_godot_global_transform(Transform2D transform) {
|
||||
set_scale_x(scale.x);
|
||||
set_scale_y(scale.y);
|
||||
}
|
||||
|
||||
void SpineNewBone::set_spine_sprite(SpineNewSprite *s) {
|
||||
the_sprite = s;
|
||||
}
|
||||
|
||||
@ -46,8 +46,7 @@ protected:
|
||||
|
||||
private:
|
||||
spine::Bone *bone;
|
||||
|
||||
SpineNewSprite *the_sprite;
|
||||
SpineNewSprite* sprite;
|
||||
|
||||
public:
|
||||
SpineNewBone();
|
||||
@ -56,11 +55,12 @@ public:
|
||||
inline void set_spine_object(spine::Bone *b) {
|
||||
bone = b;
|
||||
}
|
||||
|
||||
inline spine::Bone *get_spine_object() {
|
||||
return bone;
|
||||
}
|
||||
|
||||
void set_spine_sprite(SpineNewSprite *s);
|
||||
void set_spine_sprite(SpineNewSprite* sprite);
|
||||
|
||||
void update_world_transform();
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ void SpineNewSkeleton::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("find_path_constraint", "constraint_name"), &SpineNewSkeleton::find_path_constraint);
|
||||
ClassDB::bind_method(D_METHOD("get_bounds"), &SpineNewSkeleton::get_bounds);
|
||||
ClassDB::bind_method(D_METHOD("get_root_bone"), &SpineNewSkeleton::get_root_bone);
|
||||
ClassDB::bind_method(D_METHOD("get_data"), &SpineNewSkeleton::get_data);
|
||||
ClassDB::bind_method(D_METHOD("get_data"), &SpineNewSkeleton::get_skeleton_data_res);
|
||||
ClassDB::bind_method(D_METHOD("get_bones"), &SpineNewSkeleton::get_bones);
|
||||
ClassDB::bind_method(D_METHOD("get_slots"), &SpineNewSkeleton::get_slots);
|
||||
ClassDB::bind_method(D_METHOD("get_draw_orders"), &SpineNewSkeleton::get_draw_orders);
|
||||
@ -77,9 +77,17 @@ SpineNewSkeleton::~SpineNewSkeleton() {
|
||||
void SpineNewSkeleton::set_skeleton_data_res(Ref<SpineNewSkeletonDataResource> data_res) {
|
||||
delete skeleton;
|
||||
skeleton = nullptr;
|
||||
if (!data_res.is_valid()) return;
|
||||
skeleton = new spine::Skeleton(data_res->get_skeleton_data());
|
||||
skeleton_data_res = data_res;
|
||||
if (!data_res.is_valid() || !data_res->is_skeleton_data_loaded()) return;
|
||||
skeleton = new spine::Skeleton(data_res->get_skeleton_data());
|
||||
}
|
||||
|
||||
Ref<SpineNewSkeletonDataResource> SpineNewSkeleton::get_skeleton_data_res() const {
|
||||
return skeleton_data_res;
|
||||
}
|
||||
|
||||
void SpineNewSkeleton::set_spine_sprite(SpineNewSprite* sprite) {
|
||||
this->sprite = sprite;
|
||||
}
|
||||
|
||||
#define S_T(x) (spine::String((x).utf8()))
|
||||
@ -205,10 +213,6 @@ Ref<SpineNewBone> SpineNewSkeleton::get_root_bone() {
|
||||
return gd_b;
|
||||
}
|
||||
|
||||
Ref<SpineNewSkeletonDataResource> SpineNewSkeleton::get_data() const {
|
||||
return skeleton_data_res;
|
||||
}
|
||||
|
||||
Array SpineNewSkeleton::get_bones() {
|
||||
auto &as = skeleton->getBones();
|
||||
Array gd_as;
|
||||
@ -337,7 +341,3 @@ float SpineNewSkeleton::get_scale_y() {
|
||||
void SpineNewSkeleton::set_scale_y(float v) {
|
||||
skeleton->setScaleY(v);
|
||||
}
|
||||
|
||||
void SpineNewSkeleton::set_spine_sprite(SpineNewSprite *s) {
|
||||
sprite = s;
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ public:
|
||||
~SpineNewSkeleton();
|
||||
|
||||
void set_skeleton_data_res(Ref<SpineNewSkeletonDataResource> data_res);
|
||||
Ref<SpineNewSkeletonDataResource> get_skeleton_data_res() const;
|
||||
|
||||
inline void set_spine_object(spine::Skeleton *s) {
|
||||
skeleton = s;
|
||||
@ -64,8 +65,7 @@ public:
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
void set_spine_sprite(SpineNewSprite *s);
|
||||
|
||||
void set_spine_sprite(SpineNewSprite *sprite);
|
||||
|
||||
void update_world_transform();
|
||||
|
||||
@ -95,8 +95,6 @@ public:
|
||||
|
||||
Ref<SpineNewBone> get_root_bone();
|
||||
|
||||
Ref<SpineNewSkeletonDataResource> get_data() const;
|
||||
|
||||
Array get_bones();
|
||||
Array get_slots();
|
||||
Array get_draw_orders();
|
||||
|
||||
@ -29,6 +29,11 @@
|
||||
|
||||
#include "SpineNewSkeletonDataResource.h"
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_inspector.h"
|
||||
#endif
|
||||
|
||||
void SpineNewSkeletonDataResource::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("is_skeleton_data_loaded"), &SpineNewSkeletonDataResource::is_skeleton_data_loaded);
|
||||
ClassDB::bind_method(D_METHOD("set_atlas_res", "atlas_res"), &SpineNewSkeletonDataResource::set_atlas_res);
|
||||
@ -81,13 +86,6 @@ SpineNewSkeletonDataResource::~SpineNewSkeletonDataResource() {
|
||||
}
|
||||
|
||||
void SpineNewSkeletonDataResource::update_skeleton_data() {
|
||||
if (atlas_res.is_valid() && skeleton_file_res.is_valid()) {
|
||||
load_res(atlas_res->get_spine_atlas(), skeleton_file_res->get_json(), skeleton_file_res->get_binary());
|
||||
emit_signal("skeleton_data_changed");
|
||||
}
|
||||
}
|
||||
|
||||
void SpineNewSkeletonDataResource::load_res(spine::Atlas *atlas, const String &json, const Vector<uint8_t> &binary) {
|
||||
if (skeleton_data) {
|
||||
delete skeleton_data;
|
||||
skeleton_data = nullptr;
|
||||
@ -97,6 +95,16 @@ void SpineNewSkeletonDataResource::load_res(spine::Atlas *atlas, const String &j
|
||||
animation_state_data = nullptr;
|
||||
}
|
||||
|
||||
if (atlas_res.is_valid() && skeleton_file_res.is_valid()) {
|
||||
load_res(atlas_res->get_spine_atlas(), skeleton_file_res->get_json(), skeleton_file_res->get_binary());
|
||||
}
|
||||
emit_signal("skeleton_data_changed");
|
||||
#ifdef TOOLS_ENABLED
|
||||
property_list_changed_notify();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpineNewSkeletonDataResource::load_res(spine::Atlas *atlas, const String &json, const Vector<uint8_t> &binary) {
|
||||
if ((json.empty() && binary.empty()) || atlas == nullptr) return;
|
||||
|
||||
spine::SkeletonData *data;
|
||||
|
||||
@ -36,10 +36,9 @@
|
||||
void SpineNewSprite::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_skeleton_data_res", "skeleton_data_res"), &SpineNewSprite::set_skeleton_data_res);
|
||||
ClassDB::bind_method(D_METHOD("get_skeleton_data_res"), &SpineNewSprite::get_skeleton_data_res);
|
||||
ClassDB::bind_method(D_METHOD("_on_animation_data_created"), &SpineNewSprite::_on_animation_data_created);
|
||||
ClassDB::bind_method(D_METHOD("get_skeleton"), &SpineNewSprite::get_skeleton);
|
||||
ClassDB::bind_method(D_METHOD("get_animation_state"), &SpineNewSprite::get_animation_state);
|
||||
ClassDB::bind_method(D_METHOD("_on_animation_data_changed"), &SpineNewSprite::_on_animation_data_changed);
|
||||
ClassDB::bind_method(D_METHOD("_on_skeleton_data_changed"), &SpineNewSprite::_on_skeleton_data_changed);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_bind_slot_nodes"), &SpineNewSprite::get_bind_slot_nodes);
|
||||
ClassDB::bind_method(D_METHOD("set_bind_slot_nodes", "v"), &SpineNewSprite::set_bind_slot_nodes);
|
||||
@ -73,11 +72,10 @@ void SpineNewSprite::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(ProcessMode::ProcessMode_Manual);
|
||||
}
|
||||
|
||||
SpineNewSprite::SpineNewSprite() : overlap(false),
|
||||
skeleton_clipper(nullptr),
|
||||
process_mode(ProcessMode_Process) {
|
||||
SpineNewSprite::SpineNewSprite() : overlap(false), process_mode(ProcessMode_Process), skeleton_clipper(nullptr) {
|
||||
skeleton_clipper = new spine::SkeletonClipping();
|
||||
}
|
||||
|
||||
SpineNewSprite::~SpineNewSprite() {
|
||||
delete skeleton_clipper;
|
||||
}
|
||||
@ -161,9 +159,11 @@ void SpineNewSprite::update_bind_slot_nodes() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpineNewSprite::update_bind_slot_node_transform(Ref<SpineBone> bone, Node2D *node2d) {
|
||||
bone->apply_world_transform_2d(node2d);
|
||||
}
|
||||
|
||||
void SpineNewSprite::update_bind_slot_node_draw_order(const String &slot_name, Node2D *node2d) {
|
||||
auto mesh_ins = find_node(slot_name);
|
||||
if (mesh_ins) {
|
||||
@ -184,55 +184,53 @@ Node *SpineNewSprite::find_child_node_by_node(Node *node) {
|
||||
|
||||
void SpineNewSprite::set_skeleton_data_res(const Ref<SpineNewSkeletonDataResource> &s) {
|
||||
skeleton_data_res = s;
|
||||
_on_animation_data_changed();
|
||||
_on_skeleton_data_changed();
|
||||
}
|
||||
Ref<SpineNewSkeletonDataResource> SpineNewSprite::get_skeleton_data_res() {
|
||||
return skeleton_data_res;
|
||||
}
|
||||
|
||||
void SpineNewSprite::_on_animation_data_created() {
|
||||
skeleton = Ref<SpineNewSkeleton>(memnew(SpineNewSkeleton));
|
||||
skeleton->set_skeleton_data_res(skeleton_data_res);
|
||||
skeleton->set_spine_sprite(this);
|
||||
|
||||
animation_state = Ref<SpineAnimationState>(memnew(SpineAnimationState));
|
||||
animation_state->create_animation_state(skeleton_data_res->get_animation_state_data());
|
||||
animation_state->get_spine_object()->setListener(this);
|
||||
|
||||
animation_state->update(0);
|
||||
animation_state->apply(skeleton);
|
||||
skeleton->update_world_transform();
|
||||
gen_mesh_from_skeleton(skeleton);
|
||||
|
||||
if (process_mode == ProcessMode_Process) {
|
||||
_notification(NOTIFICATION_INTERNAL_PROCESS);
|
||||
} else if (process_mode == ProcessMode_Physics) {
|
||||
_notification(NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
|
||||
}
|
||||
}
|
||||
|
||||
void SpineNewSprite::_on_animation_data_changed() {
|
||||
void SpineNewSprite::_on_skeleton_data_changed() {
|
||||
remove_mesh_instances();
|
||||
skeleton.unref();
|
||||
animation_state.unref();
|
||||
if (skeleton_data_res.is_valid()) {
|
||||
if (!skeleton_data_res->is_connected("skeleton_data_changed", this, "_on_animation_data_created"))
|
||||
skeleton_data_res->connect("skeleton_data_changed", this, "_on_animation_data_created");
|
||||
|
||||
if (skeleton_data_res->is_skeleton_data_loaded()) {
|
||||
_on_animation_data_created();
|
||||
if (skeleton_data_res.is_valid()) {
|
||||
if (!skeleton_data_res->is_connected("skeleton_data_changed", this, "_on_skeleton_data_changed"))
|
||||
skeleton_data_res->connect("skeleton_data_changed", this, "_on_skeleton_data_changed");
|
||||
}
|
||||
|
||||
if (skeleton_data_res.is_valid() && skeleton_data_res->is_skeleton_data_loaded()) {
|
||||
skeleton = Ref<SpineNewSkeleton>(memnew(SpineNewSkeleton));
|
||||
skeleton->set_skeleton_data_res(skeleton_data_res);
|
||||
skeleton->set_spine_sprite(this);
|
||||
|
||||
animation_state = Ref<SpineNewAnimationState>(memnew(SpineNewAnimationState));
|
||||
animation_state->set_skeleton_data_res(skeleton_data_res);
|
||||
if (animation_state->get_spine_object()) animation_state->get_spine_object()->setListener(this);
|
||||
|
||||
animation_state->update(0);
|
||||
animation_state->apply(skeleton);
|
||||
skeleton->update_world_transform();
|
||||
gen_mesh_from_skeleton(skeleton);
|
||||
|
||||
if (process_mode == ProcessMode_Process) {
|
||||
_notification(NOTIFICATION_INTERNAL_PROCESS);
|
||||
} else if (process_mode == ProcessMode_Physics) {
|
||||
_notification(NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<SpineSkeleton> SpineNewSprite::get_skeleton() {
|
||||
Ref<SpineNewSkeleton> SpineNewSprite::get_skeleton() {
|
||||
return skeleton;
|
||||
}
|
||||
Ref<SpineAnimationState> SpineNewSprite::get_animation_state() {
|
||||
|
||||
Ref<SpineNewAnimationState> SpineNewSprite::get_animation_state() {
|
||||
return animation_state;
|
||||
}
|
||||
|
||||
void SpineNewSprite::gen_mesh_from_skeleton(Ref<SpineSkeleton> s) {
|
||||
void SpineNewSprite::gen_mesh_from_skeleton(Ref<SpineNewSkeleton> s) {
|
||||
auto sk = s->get_spine_object();
|
||||
for (size_t i = 0, n = sk->getSlots().size(); i < n; ++i) {
|
||||
auto mesh_ins = memnew(SpineSpriteMeshInstance2D);
|
||||
@ -305,7 +303,7 @@ void SpineNewSprite::remove_redundant_mesh_instances() {
|
||||
} \
|
||||
} while (false);
|
||||
|
||||
void SpineNewSprite::update_mesh_from_skeleton(Ref<SpineSkeleton> s) {
|
||||
void SpineNewSprite::update_mesh_from_skeleton(Ref<SpineNewSkeleton> s) {
|
||||
static const unsigned short VERTEX_STRIDE = 2;
|
||||
static unsigned short quad_indices[] = {0, 1, 2, 2, 3, 0};
|
||||
|
||||
@ -606,7 +604,7 @@ bool SpineNewSprite::_set(const StringName &p_property, const Variant &p_value)
|
||||
if (animation_state.is_valid() && skeleton.is_valid()) {
|
||||
auto animName = p_value.operator String();
|
||||
skeleton->set_to_setup_pose();
|
||||
if (skeleton->get_data()->find_animation(animName).is_valid()) {
|
||||
if (skeleton->get_skeleton_data_res()->find_animation(animName).is_valid()) {
|
||||
animation_state->set_animation(animName, true, 0);
|
||||
} else {
|
||||
animation_state->clear_tracks();
|
||||
@ -617,7 +615,7 @@ bool SpineNewSprite::_set(const StringName &p_property, const Variant &p_value)
|
||||
if (p_property == "Preview skin") {
|
||||
if (animation_state.is_valid() && skeleton.is_valid()) {
|
||||
auto skinName = p_value.operator String();
|
||||
if (skeleton->get_data()->find_skin(skinName).is_valid()) {
|
||||
if (skeleton->get_skeleton_data_res()->find_skin(skinName).is_valid()) {
|
||||
skeleton->set_skin_by_name(skinName);
|
||||
} else {
|
||||
skeleton->set_skin(nullptr);
|
||||
|
||||
@ -32,9 +32,8 @@
|
||||
|
||||
#include <scene/resources/texture.h>
|
||||
|
||||
#include "SpineAnimationState.h"
|
||||
#include "SpineAnimationStateDataResource.h"
|
||||
#include "SpineNewSkeleton.h"
|
||||
#include "SpineNewAnimationState.h"
|
||||
#include "SpineSpriteMeshInstance2D.h"
|
||||
|
||||
class SpineNewSprite : public Node2D, public spine::AnimationStateListenerObject {
|
||||
@ -62,7 +61,7 @@ private:
|
||||
Ref<SpineNewSkeletonDataResource> skeleton_data_res;
|
||||
|
||||
Ref<SpineNewSkeleton> skeleton;
|
||||
Ref<SpineAnimationState> animation_state;
|
||||
Ref<SpineNewAnimationState> animation_state;
|
||||
|
||||
String preview_animation;
|
||||
Array bind_slot_nodes;
|
||||
@ -80,14 +79,14 @@ public:
|
||||
void set_skeleton_data_res(const Ref<SpineNewSkeletonDataResource> &a);
|
||||
Ref<SpineNewSkeletonDataResource> get_skeleton_data_res();
|
||||
|
||||
Ref<SpineSkeleton> get_skeleton();
|
||||
Ref<SpineAnimationState> get_animation_state();
|
||||
Ref<SpineNewSkeleton> get_skeleton();
|
||||
Ref<SpineNewAnimationState> get_animation_state();
|
||||
|
||||
void gen_mesh_from_skeleton(Ref<SpineSkeleton> s);
|
||||
void gen_mesh_from_skeleton(Ref<SpineNewSkeleton> s);
|
||||
void remove_mesh_instances();
|
||||
void remove_redundant_mesh_instances();
|
||||
|
||||
void update_mesh_from_skeleton(Ref<SpineSkeleton> s);
|
||||
void update_mesh_from_skeleton(Ref<SpineNewSkeleton> s);
|
||||
|
||||
void update_bind_slot_nodes();
|
||||
void update_bind_slot_node_transform(Ref<SpineBone> bone, Node2D *node2d);
|
||||
@ -96,8 +95,7 @@ public:
|
||||
|
||||
virtual void callback(spine::AnimationState *state, spine::EventType type, spine::TrackEntry *entry, spine::Event *event);
|
||||
|
||||
void _on_animation_data_created();
|
||||
void _on_animation_data_changed();
|
||||
void _on_skeleton_data_changed();
|
||||
|
||||
void _update_all(float delta);
|
||||
|
||||
|
||||
@ -62,6 +62,8 @@ static Ref<SpineSkeletonFileResourceFormatSaver> skeleton_file_saver;
|
||||
#include "editor/editor_export.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "SpineRuntimeEditorPlugin.h"
|
||||
#include "SpineNewSkeletonDataResource.h"
|
||||
#include "SpineNewSprite.h"
|
||||
|
||||
static void editor_init_callback() {
|
||||
EditorNode::get_singleton()->add_editor_plugin(memnew(SpineRuntimeEditorPlugin(EditorNode::get_singleton())));
|
||||
@ -77,9 +79,12 @@ void register_spine_godot_types() {
|
||||
ClassDB::register_class<SpineAtlasResource>();
|
||||
ClassDB::register_class<SpineSkeletonFileResource>();
|
||||
ClassDB::register_class<SpineSkeletonDataResource>();
|
||||
ClassDB::register_class<SpineNewSkeletonDataResource>();
|
||||
ClassDB::register_class<SpineAnimationStateDataResource>();
|
||||
ClassDB::register_class<SpineSprite>();
|
||||
ClassDB::register_class<SpineNewSprite>();
|
||||
ClassDB::register_class<SpineSkeleton>();
|
||||
ClassDB::register_class<SpineNewSkeleton>();
|
||||
ClassDB::register_class<SpineAnimationState>();
|
||||
ClassDB::register_class<SpineAnimation>();
|
||||
ClassDB::register_class<SpineEventData>();
|
||||
@ -96,6 +101,7 @@ void register_spine_godot_types() {
|
||||
ClassDB::register_class<SpineTransformConstraintData>();
|
||||
ClassDB::register_class<SpinePathConstraintData>();
|
||||
ClassDB::register_class<SpineBone>();
|
||||
ClassDB::register_class<SpineNewBone>();
|
||||
ClassDB::register_class<SpineSlot>();
|
||||
ClassDB::register_class<SpineIkConstraint>();
|
||||
ClassDB::register_class<SpinePathConstraint>();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user