[godot] 4.x compatibility.

This commit is contained in:
Mario Zechner 2022-04-21 02:27:17 +02:00
parent 2ec5d44ed3
commit ccc43a3864
37 changed files with 318 additions and 91 deletions

1
.gitignore vendored
View File

@ -171,3 +171,4 @@ spine-godot/spine_godot/__pycache__
spine-godot/example/.import
spine-godot/spine_godot/*.obj
*.bc
spine-godot/example/.godot

View File

@ -1,8 +1,23 @@
#!/bin/bash
set -e
if [ "$#" -eq 0 ]; then
echo "Usage: ./setup.sh <godot_branch_or_tag>"
echo
echo "e.g.:"
echo " ./setup.sh 3.4.4-stable"
echo " ./setup.sh master"
read version
exit 1
fi
branch=${1%/}
rm -rf godot
git clone --depth 1 https://github.com/godotengine/godot.git -b 3.4.4-stable
git clone --depth 1 https://github.com/godotengine/godot.git -b $branch
cp -r .idea godot
cp custom.py godot
cp -r ../spine-cpp/spine-cpp spine_godot
rm -rf example/.import
rm -rf example/.godot
./build.sh

View File

@ -29,7 +29,12 @@
#include "GodotSpineExtension.h"
#include "core/os/memory.h"
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/io/file_access.h"
#else
#include "core/os/file_access.h"
#endif
#include <spine/SpineString.h>
spine::SpineExtension *spine::getDefaultExtension() {

View File

@ -31,8 +31,9 @@
#include "SpineSkeleton.h"
#include "SpineEvent.h"
#include "SpineTimeline.h"
#include "SpineCommon.h"
#if VERSION_MAJOR == 3
#include "core/method_bind_ext.gen.inc"
#endif
void SpineAnimation::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_name"), &SpineAnimation::get_name);

View File

@ -30,16 +30,16 @@
#ifndef GODOT_SPINEANIMATION_H
#define GODOT_SPINEANIMATION_H
#include "SpineCommon.h"
#include "SpineConstant.h"
#include "core/reference.h"
#include <spine/Animation.h>
class SpineEvent;
class SpineSkeleton;
class SpineTimeline;
class SpineAnimation : public Reference {
GDCLASS(SpineAnimation, Reference);
class SpineAnimation : public REFCOUNTED {
GDCLASS(SpineAnimation, REFCOUNTED);
private:
spine::Animation *animation;

View File

@ -28,7 +28,6 @@
*****************************************************************************/
#include "SpineAnimationState.h"
#include "SpineCommon.h"
void SpineAnimationState::_bind_methods() {
ClassDB::bind_method(D_METHOD("update", "delta"), &SpineAnimationState::update, DEFVAL(0));

View File

@ -30,11 +30,12 @@
#ifndef GODOT_SPINEANIMATIONSTATE_H
#define GODOT_SPINEANIMATIONSTATE_H
#include "SpineCommon.h"
#include "SpineSkeleton.h"
#include "SpineTrackEntry.h"
class SpineAnimationState : public Reference {
GDCLASS(SpineAnimationState, Reference)
class SpineAnimationState : public REFCOUNTED {
GDCLASS(SpineAnimationState, REFCOUNTED)
protected:
static void _bind_methods();

View File

@ -51,7 +51,7 @@ public:
if (sub_str_pos < 0) return path;
auto res = path.substr(sub_str_pos);
if (!res.empty()) {
if (!EMPTY(res)) {
if (res[0] != '/') {
return prefix + "/" + res;
} else {
@ -65,8 +65,12 @@ public:
Error error = OK;
auto fixed_path = fix_path(String(path.buffer()));
#if VERSION_MAJOR > 3
Ref<Texture2D> texture = ResourceLoader::load(fixed_path, "", ResourceFormatLoader::CACHE_MODE_REUSE, &error);
#else
Ref<Texture> texture = ResourceLoader::load(fixed_path, "", false, &error);
if (error != OK) {
#endif
if (error != OK || !texture.is_valid()) {
ERR_PRINT(vformat("Can't load texture: \"%s\"", String(path.buffer())));
auto renderer_object = memnew(SpineRendererObject);
renderer_object->texture = Ref<Texture>(nullptr);
@ -162,11 +166,18 @@ Error SpineAtlasResource::load_from_file(const String &path) {
String json_string = FileAccess::get_file_as_string(path, &error);
if (error != OK) return error;
#if VERSION_MAJOR > 3
JSON json;
error = json.parse(json_string);
if (error != OK) return error;
Variant result = json.get_data();
#else
String error_string;
int error_line;
Variant result;
error = JSON::parse(json_string, result, error_string, error_line);
if (error != OK) return error;
#endif
Dictionary content = Dictionary(result);
source_path = content["source_path"];
@ -184,22 +195,37 @@ Error SpineAtlasResource::load_from_file(const String &path) {
Error SpineAtlasResource::save_to_file(const String &path) {
Error err;
#if VERSION_MAJOR > 3
Ref<FileAccess> file = FileAccess::open(path, FileAccess::WRITE, &err);
if (err != OK) return err;
#else
FileAccess *file = FileAccess::open(path, FileAccess::WRITE, &err);
if (err != OK) {
if (file) file->close();
return err;
}
#endif
Dictionary content;
content["source_path"] = source_path;
content["atlas_data"] = atlas_data;
content["normal_texture_prefix"] = normal_map_prefix;
#if VERSION_MAJOR > 3
JSON json;
file->store_string(json.stringify(content));
file->flush();
#else
file->store_string(JSON::print(content));
file->close();
#endif
return OK;
}
#if VERSION_MAJOR > 3
RES SpineAtlasResourceFormatLoader::load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) {
#else
RES SpineAtlasResourceFormatLoader::load(const String &path, const String &original_path, Error *error) {
#endif
Ref<SpineAtlasResource> atlas = memnew(SpineAtlasResource);
atlas->load_from_file(path);
if (error) *error = OK;
@ -221,7 +247,7 @@ bool SpineAtlasResourceFormatLoader::handles_type(const String &type) const {
}
Error SpineAtlasResourceFormatSaver::save(const String &path, const RES &resource, uint32_t flags) {
Ref<SpineAtlasResource> res = resource.get_ref_ptr();
Ref<SpineAtlasResource> res = resource;
return res->save_to_file(path);
}

View File

@ -30,11 +30,13 @@
#ifndef GODOT_SPINEATLASRESOURCE_H
#define GODOT_SPINEATLASRESOURCE_H
#include "SpineCommon.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/io/image_loader.h"
#include <spine/Atlas.h>
class GodotSpineTextureLoader;
class SpineAtlasResource : public Resource {
@ -80,7 +82,11 @@ class SpineAtlasResourceFormatLoader : public ResourceFormatLoader {
GDCLASS(SpineAtlasResourceFormatLoader, ResourceFormatLoader)
public:
#if VERSION_MAJOR > 3
RES load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) override;
#else
RES load(const String &path, const String &original_path, Error *error) override;
#endif
void get_recognized_extensions(List<String> *extensions) const override;

View File

@ -30,11 +30,12 @@
#ifndef GODOT_SPINEATTACHMENT_H
#define GODOT_SPINEATTACHMENT_H
#include "SpineCommon.h"
#include <spine/spine.h>
#include "core/reference.h"
class SpineAttachment : public Reference {
GDCLASS(SpineAttachment, Reference)
class SpineAttachment : public REFCOUNTED {
GDCLASS(SpineAttachment, REFCOUNTED)
protected:
static void _bind_methods();

View File

@ -430,9 +430,8 @@ void SpineBone::set_active(bool v) {
void SpineBone::apply_world_transform_2d(const Variant &o) {
SPINE_CHECK(bone,)
if (o.get_type() == Variant::OBJECT) {
auto node = (Node *) o;
if (node->is_class("Node2D")) {
auto node2d = (Node2D *) node;
auto node2d = Object::cast_to<Node2D>(o.operator Object*());
if (node2d) {
// In godot the y-axis is nag to spine
node2d->set_transform(Transform2D(
get_a(), get_c(),

View File

@ -30,15 +30,16 @@
#ifndef GODOT_SPINEBONE_H
#define GODOT_SPINEBONE_H
#include "SpineCommon.h"
#include "SpineBoneData.h"
#include <scene/2d/node_2d.h>
#include "scene/2d/node_2d.h"
#include <spine/Bone.h>
class SpineSkeleton;
class SpineSprite;
class SpineBone : public Reference {
GDCLASS(SpineBone, Reference)
class SpineBone : public REFCOUNTED {
GDCLASS(SpineBone, REFCOUNTED)
protected:
static void _bind_methods();

View File

@ -30,12 +30,12 @@
#ifndef GODOT_SPINEBONEDATA_H
#define GODOT_SPINEBONEDATA_H
#include "SpineCommon.h"
#include "SpineConstant.h"
#include "core/reference.h"
#include <spine/BoneData.h>
class SpineBoneData : public Reference {
GDCLASS(SpineBoneData, Reference);
class SpineBoneData : public REFCOUNTED {
GDCLASS(SpineBoneData, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -99,7 +99,7 @@ void SpineCollisionShapeProxy::set_slot(const String &slotName) {
spine::Slot *SpineCollisionShapeProxy::get_spine_slot(const String &slotName) const {
auto sprite = get_spine_sprite();
if (sprite == NULL || slot_name.empty()) return NULL;
if (sprite == NULL || EMPTY(slot_name)) return NULL;
if (!sprite->get_skeleton().is_valid()) return NULL;
spine::Skeleton *skeleton = sprite->get_skeleton()->get_spine_object();
spine::Slot *slot = skeleton->findSlot(spine::String(slot_name.utf8()));
@ -155,7 +155,7 @@ void SpineCollisionShapeProxy::_get_property_list(List<PropertyInfo> *p_list) co
p.name = "Slot";
p.type = Variant::STRING;
get_slot_names(slot_names);
if (slot_names.empty())
if (EMPTY(slot_names))
slot_names.push_back("None");
p.hint_string = String(",").join(slot_names);
p.hint = PROPERTY_HINT_ENUM;

View File

@ -30,7 +30,25 @@
#ifndef SPINE_COMMON_H
#define SPINE_COMMON_H
#include "core/version.h"
#if VERSION_MAJOR > 3
#include "core/core_bind.h"
#include "core/error/error_macros.h"
#define REFCOUNTED RefCounted
#define EMPTY(x) ((x).is_empty())
#define EMPTY_PTR(x) ((x)->is_empty())
#define INSTANTIATE(x) (x).instantiate()
#define NOTIFY_PROPERTY_LIST_CHANGED() notify_property_list_changed()
#else
#include "core/object.h"
#include "core/reference.h"
#include "core/error_macros.h"
#define REFCOUNTED Reference
#define EMPTY(x) ((x).empty())
#define EMPTY_PTR(x) ((x)->empty())
#define INSTANTIATE(x) (x).instance()
#define NOTIFY_PROPERTY_LIST_CHANGED() property_list_changed_notify()
#endif
#define SPINE_CHECK(obj, ret) \
if (!(obj)) { \

View File

@ -30,7 +30,7 @@
#ifndef GODOT_SPINECONSTANT_H
#define GODOT_SPINECONSTANT_H
#include "core/object.h"
#include "SpineCommon.h"
class SpineConstant : public Object {
GDCLASS(SpineConstant, Object);

View File

@ -30,14 +30,11 @@
#ifndef GODOT_SPINECONSTRAINTDATA_H
#define GODOT_SPINECONSTRAINTDATA_H
#include "core/reference.h"
#include "SpineCommon.h"
#include <spine/ConstraintData.h>
namespace spine {
class ConstraintData;
}
class SpineConstraintData : public Reference {
GDCLASS(SpineConstraintData, Reference);
class SpineConstraintData : public REFCOUNTED {
GDCLASS(SpineConstraintData, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -42,7 +42,11 @@ Error SpineAtlasResourceImportPlugin::import(const String &source_file, const St
return error;
}
#if VERSION_MAJOR > 3
void SpineAtlasResourceImportPlugin::get_import_options(const String &path, List<ImportOption> *options, int preset) const {
#else
void SpineAtlasResourceImportPlugin::get_import_options(List<ImportOption> *options, int preset) const {
#endif
if (preset == 0) {
ImportOption op;
op.option.name = "normal_map_prefix";
@ -82,8 +86,12 @@ bool SpineSkeletonDataResourceInspectorPlugin::can_handle(Object *object) {
return object->is_class("SpineSkeletonDataResource");
}
#if VERSION_MAJOR > 3
bool SpineSkeletonDataResourceInspectorPlugin:: parse_property(Object *object, const Variant::Type type, const String &path, const PropertyHint hint, const String &hint_text, const uint32_t usage, const bool wide) {
#else
bool SpineSkeletonDataResourceInspectorPlugin::parse_property(Object *object, Variant::Type type, const String &path,
PropertyHint hint, const String &hint_text, int usage) {
#endif
if (path == "animation_mixes") {
Ref<SpineSkeletonDataResource> skeleton_data = Object::cast_to<SpineSkeletonDataResource>(object);
if (!skeleton_data.is_valid() || !skeleton_data->is_skeleton_data_loaded()) return true;
@ -96,7 +104,7 @@ bool SpineSkeletonDataResourceInspectorPlugin::parse_property(Object *object, Va
}
SpineEditorPropertyAnimationMixes::SpineEditorPropertyAnimationMixes(): skeleton_data(nullptr), container(nullptr), updating(false) {
array_object.instance();
INSTANTIATE(array_object);
}
void SpineEditorPropertyAnimationMixes::_bind_methods() {
@ -124,7 +132,11 @@ void SpineEditorPropertyAnimationMixes::delete_mix(int64_t idx) {
if (!skeleton_data.is_valid() || !skeleton_data->is_skeleton_data_loaded() || updating) return;
auto mixes = skeleton_data->get_animation_mixes().duplicate();
#if VERSION_MAJOR > 3
mixes.remove_at((int)idx);
#else
mixes.remove((int)idx);
#endif
emit_changed(get_edited_property(), mixes);
}
@ -180,12 +192,20 @@ void SpineEditorPropertyAnimationMixes::update_property() {
auto delete_button = memnew(Button);
hbox->add_child(delete_button);
delete_button->set_text("Remove");
#if VERSION_MAJOR > 3
delete_button->connect("pressed", callable_mp(this, &SpineEditorPropertyAnimationMixes::delete_mix), varray(i));
#else
delete_button->connect("pressed", this, "delete_mix", varray(i));
#endif
}
auto add_mix_button = memnew(Button);
add_mix_button->set_text("Add mix");
#if VERSION_MAJOR > 3
add_mix_button->connect("pressed", callable_mp(this, &SpineEditorPropertyAnimationMixes::add_mix));
#else
add_mix_button->connect("pressed", this, "add_mix");
#endif
container->add_child(add_mix_button);
updating = false;
@ -256,7 +276,11 @@ void SpineEditorPropertyAnimationMix::update_property() {
from_enum->setup(animation_names);
from_enum->set_object_and_property(mix, "from");
from_enum->update_property();
#if VERSION_MAJOR > 3
from_enum->connect("property_changed", callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
#else
from_enum->connect("property_changed", this, "data_changed");
#endif
container->add_child(from_enum);
auto to_enum = memnew(EditorPropertyTextEnum);
@ -266,7 +290,11 @@ void SpineEditorPropertyAnimationMix::update_property() {
to_enum->setup(animation_names);
to_enum->set_object_and_property(mix, "to");
to_enum->update_property();
#if VERSION_MAJOR > 3
to_enum->connect("property_changed", callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
#else
to_enum->connect("property_changed", this, "data_changed");
#endif
container->add_child(to_enum);
auto mix_float = memnew(EditorPropertyFloat);
@ -276,7 +304,11 @@ void SpineEditorPropertyAnimationMix::update_property() {
mix_float->setup(0, 9999999, 0.001, true, false, false, false);
mix_float->set_object_and_property(mix, "mix");
mix_float->update_property();
#if VERSION_MAJOR > 3
mix_float->connect("property_changed", callable_mp(this, &SpineEditorPropertyAnimationMix::data_changed));
#else
mix_float->connect("property_changed", this, "data_changed");
#endif
container->add_child(mix_float);
updating = false;

View File

@ -29,12 +29,13 @@
#ifndef GODOT_SPINEEDITORPLUGIN_H
#define GODOT_SPINEEDITORPLUGIN_H
#include "editor/editor_properties_array_dict.h"
#ifdef TOOLS_ENABLED
#include "SpineCommon.h"
#include "SpineSprite.h"
#include "editor/editor_node.h"
#include "editor/editor_properties.h"
#include "editor/editor_properties_array_dict.h"
class SpineAtlasResourceImportPlugin : public EditorImportPlugin {
GDCLASS(SpineAtlasResourceImportPlugin, EditorImportPlugin)
@ -54,9 +55,17 @@ public:
String get_resource_type() const override { return "SpineAtlasResource"; }
#if VERSION_MAJOR > 3
int get_import_order() const override { return IMPORT_ORDER_DEFAULT; }
void get_import_options(const String &path, List<ImportOption> *options, int preset) const override;
bool get_option_visibility(const String &path, const String &option, const Map<StringName, Variant> &options) const override { return true; }
#else
void get_import_options(List<ImportOption> *options, int preset) const override;
bool get_option_visibility(const String &option, const Map<StringName, Variant> &options) const override { return true; }
#endif
Error import(const String &source_file, const String &save_path, const Map<StringName, Variant> &options, List<String> *platform_variants, List<String> *gen_files, Variant *metadata) override;
};
@ -79,10 +88,17 @@ public:
String get_resource_type() const override { return "SpineSkeletonFileResource"; }
void get_import_options(List<ImportOption> *options, int preset) const override {}
#if VERSION_MAJOR > 3
int get_import_order() const override { return IMPORT_ORDER_DEFAULT; }
void get_import_options(const String &path, List<ImportOption> *options, int preset) const override { }
bool get_option_visibility(const String &path, const String &option, const Map<StringName, Variant> &options) const override { return true; }
#else
void get_import_options(List<ImportOption> *options, int preset) const override { }
bool get_option_visibility(const String &option, const Map<StringName, Variant> &options) const override { return true; }
#endif
Error import(const String &source_file, const String &save_path, const Map<StringName, Variant> &options, List<String> *platform_variants, List<String> *gen_files, Variant *metadata) override;
};
@ -104,10 +120,17 @@ public:
String get_resource_type() const override { return "SpineSkeletonFileResource"; }
void get_import_options(List<ImportOption> *options, int preset) const override {}
#if VERSION_MAJOR > 3
int get_import_order() const override { return IMPORT_ORDER_DEFAULT; }
void get_import_options(const String &path, List<ImportOption> *options, int preset) const override { }
bool get_option_visibility(const String &path, const String &option, const Map<StringName, Variant> &options) const override { return true; }
#else
void get_import_options(List<ImportOption> *options, int preset) const override { }
bool get_option_visibility(const String &option, const Map<StringName, Variant> &options) const override { return true; }
#endif
Error import(const String &source_file, const String &save_path, const Map<StringName, Variant> &options, List<String> *platform_variants, List<String> *gen_files, Variant *metadata) override;
};
@ -127,7 +150,11 @@ public:
SpineSkeletonDataResourceInspectorPlugin() = default;
bool can_handle(Object *object) override;
#if VERSION_MAJOR > 3
bool parse_property(Object *object, Variant::Type type, const String &path, PropertyHint hint, const String &hint_text, uint32_t usage, bool wide) override;
#else
bool parse_property(Object *object, Variant::Type type, const String &path, PropertyHint hint, const String &hint_text, int usage) override;
#endif
};
class SpineEditorPropertyAnimationMix;

View File

@ -30,12 +30,12 @@
#ifndef GODOT_SPINEEVENT_H
#define GODOT_SPINEEVENT_H
#include "SpineCommon.h"
#include "SpineEventData.h"
#include "core/reference.h"
#include <spine/Event.h>
class SpineEvent : public Reference {
GDCLASS(SpineEvent, Reference)
class SpineEvent : public REFCOUNTED {
GDCLASS(SpineEvent, REFCOUNTED)
protected:
static void _bind_methods();

View File

@ -30,11 +30,11 @@
#ifndef GODOT_SPINEEVENTDATA_H
#define GODOT_SPINEEVENTDATA_H
#include "core/reference.h"
#include "SpineCommon.h"
#include <spine/EventData.h>
class SpineEventData : public Reference {
GDCLASS(SpineEventData, Reference);
class SpineEventData : public REFCOUNTED {
GDCLASS(SpineEventData, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -35,8 +35,8 @@
class SpineBone;
class SpineIkConstraint : public Reference {
GDCLASS(SpineIkConstraint, Reference);
class SpineIkConstraint : public REFCOUNTED {
GDCLASS(SpineIkConstraint, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -34,8 +34,8 @@
#include "SpineSlot.h"
#include <spine/PathConstraint.h>
class SpinePathConstraint : public Reference {
GDCLASS(SpinePathConstraint, Reference);
class SpinePathConstraint : public REFCOUNTED {
GDCLASS(SpinePathConstraint, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -113,7 +113,7 @@ void SpineSkeleton::set_slots_to_setup_pose() {
Ref<SpineBone> SpineSkeleton::find_bone(const String &name) {
SPINE_CHECK(skeleton, nullptr)
if (name.empty()) return nullptr;
if (EMPTY(name)) return nullptr;
auto bone = skeleton->findBone(SPINE_STRING(name));
if (!bone) return nullptr;
Ref<SpineBone> bone_ref(memnew(SpineBone));
@ -124,7 +124,7 @@ Ref<SpineBone> SpineSkeleton::find_bone(const String &name) {
Ref<SpineSlot> SpineSkeleton::find_slot(const String &name) {
SPINE_CHECK(skeleton, nullptr)
if (name.empty()) return nullptr;
if (EMPTY(name)) return nullptr;
auto slot = skeleton->findSlot(SPINE_STRING(name));
if (!slot) return nullptr;
Ref<SpineSlot> slot_ref(memnew(SpineSlot));
@ -162,13 +162,12 @@ Ref<SpineAttachment> SpineSkeleton::get_attachment_by_slot_index(int slot_index,
void SpineSkeleton::set_attachment(const String &slot_name, const String &attachment_name) {
SPINE_CHECK(skeleton,)
ERR_FAIL_COND(slot_name.empty());
skeleton->setAttachment(SPINE_STRING(slot_name), SPINE_STRING(attachment_name));
}
Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (constraint_name.empty()) return nullptr;
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findIkConstraint(SPINE_STRING(constraint_name));
if (!constraint) return nullptr;
Ref<SpineIkConstraint> constraint_ref(memnew(SpineIkConstraint));
@ -178,7 +177,7 @@ Ref<SpineIkConstraint> SpineSkeleton::find_ik_constraint(const String &constrain
Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (constraint_name.empty()) return nullptr;
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findTransformConstraint(SPINE_STRING(constraint_name));
if (!constraint) return nullptr;
Ref<SpineTransformConstraint> constraint_ref(memnew(SpineTransformConstraint));
@ -188,7 +187,7 @@ Ref<SpineTransformConstraint> SpineSkeleton::find_transform_constraint(const Str
Ref<SpinePathConstraint> SpineSkeleton::find_path_constraint(const String &constraint_name) {
SPINE_CHECK(skeleton, nullptr)
if (constraint_name.empty()) return nullptr;
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton->findPathConstraint(SPINE_STRING(constraint_name));
if (!constraint) return nullptr;
Ref<SpinePathConstraint> constraint_ref(memnew(SpinePathConstraint));

View File

@ -30,6 +30,7 @@
#ifndef GODOT_SPINESKELETON_H
#define GODOT_SPINESKELETON_H
#include "SpineCommon.h"
#include "SpineSkeletonDataResource.h"
#include "SpineBone.h"
#include "SpineSlot.h"
@ -39,8 +40,8 @@
class SpineSprite;
class SpineSkeleton : public Reference {
GDCLASS(SpineSkeleton, Reference);
class SpineSkeleton : public REFCOUNTED {
GDCLASS(SpineSkeleton, REFCOUNTED);
friend class SpineBone;
friend class SpineSlot;

View File

@ -41,7 +41,11 @@ void SpineAnimationMix::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "from"), "set_from", "get_from");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "to"), "set_to", "get_to");
#if VERSION_MAJOR > 3
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mix"), "set_mix", "get_mix");
#else
ADD_PROPERTY(PropertyInfo(Variant::REAL, "mix"), "set_mix", "get_mix");
#endif
}
SpineAnimationMix::SpineAnimationMix(): from(""), to(""), mix(0) {
@ -116,7 +120,11 @@ void SpineSkeletonDataResource::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "atlas_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineAtlasResource"), "set_atlas_res", "get_atlas_res");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton_file_res", PropertyHint::PROPERTY_HINT_RESOURCE_TYPE, "SpineSkeletonFileResource"), "set_skeleton_file_res", "get_skeleton_file_res");
#if VERSION_MAJOR > 3
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_mix"), "set_default_mix", "get_default_mix");
#else
ADD_PROPERTY(PropertyInfo(Variant::REAL, "default_mix"), "set_default_mix", "get_default_mix");
#endif
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animation_mixes"), "set_animation_mixes", "get_animation_mixes");
}
@ -143,15 +151,15 @@ void SpineSkeletonDataResource::update_skeleton_data() {
}
emit_signal("skeleton_data_changed");
#ifdef TOOLS_ENABLED
property_list_changed_notify();
NOTIFY_PROPERTY_LIST_CHANGED();
#endif
}
void SpineSkeletonDataResource::load_resources(spine::Atlas *atlas, const String &json, const Vector<uint8_t> &binary) {
if ((json.empty() && binary.empty()) || atlas == nullptr) return;
if ((EMPTY(json) && EMPTY(binary)) || atlas == nullptr) return;
spine::SkeletonData *data;
if (!json.empty()) {
if (!EMPTY(json)) {
spine::SkeletonJson skeletonJson(atlas);
data = skeletonJson.readSkeletonData(json.utf8());
if (!data) {
@ -263,7 +271,7 @@ void SpineSkeletonDataResource::update_mixes() {
Ref<SpineAnimation> SpineSkeletonDataResource::find_animation(const String &animation_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (animation_name.empty()) return nullptr;
if (EMPTY(animation_name)) return nullptr;
auto animation = skeleton_data->findAnimation(SPINE_STRING(animation_name));
if (!animation) return nullptr;
Ref<SpineAnimation> animation_ref(memnew(SpineAnimation));
@ -273,7 +281,7 @@ Ref<SpineAnimation> SpineSkeletonDataResource::find_animation(const String &anim
Ref<SpineBoneData> SpineSkeletonDataResource::find_bone(const String &bone_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (bone_name.empty()) return nullptr;
if (EMPTY(bone_name)) return nullptr;
auto bone = skeleton_data->findBone(SPINE_STRING(bone_name));
if (!bone) return nullptr;
Ref<SpineBoneData> bone_ref(memnew(SpineBoneData));
@ -283,7 +291,7 @@ Ref<SpineBoneData> SpineSkeletonDataResource::find_bone(const String &bone_name)
Ref<SpineSlotData> SpineSkeletonDataResource::find_slot(const String &slot_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (slot_name.empty()) return nullptr;
if (EMPTY(slot_name)) return nullptr;
auto slot = skeleton_data->findSlot(SPINE_STRING(slot_name));
if (!slot) return nullptr;
Ref<SpineSlotData> slot_ref(memnew(SpineSlotData));
@ -293,7 +301,7 @@ Ref<SpineSlotData> SpineSkeletonDataResource::find_slot(const String &slot_name)
Ref<SpineSkin> SpineSkeletonDataResource::find_skin(const String &skin_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (skin_name.empty()) return nullptr;
if (EMPTY(skin_name)) return nullptr;
auto skin = skeleton_data->findSkin(SPINE_STRING(skin_name));
if (!skin) return nullptr;
Ref<SpineSkin> skin_ref(memnew(SpineSkin));
@ -303,7 +311,7 @@ Ref<SpineSkin> SpineSkeletonDataResource::find_skin(const String &skin_name) con
Ref<SpineEventData> SpineSkeletonDataResource::find_event(const String &event_data_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (event_data_name.empty()) return nullptr;
if (EMPTY(event_data_name)) return nullptr;
auto event = skeleton_data->findEvent(SPINE_STRING(event_data_name));
if (!event) return nullptr;
Ref<SpineEventData> event_ref(memnew(SpineEventData));
@ -313,7 +321,7 @@ Ref<SpineEventData> SpineSkeletonDataResource::find_event(const String &event_da
Ref<SpineIkConstraintData> SpineSkeletonDataResource::find_ik_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (constraint_name.empty()) return nullptr;
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findIkConstraint(SPINE_STRING(constraint_name));
if (!constraint) return nullptr;
Ref<SpineIkConstraintData> constraint_ref(memnew(SpineIkConstraintData));
@ -323,7 +331,7 @@ Ref<SpineIkConstraintData> SpineSkeletonDataResource::find_ik_constraint(const S
Ref<SpineTransformConstraintData> SpineSkeletonDataResource::find_transform_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (constraint_name.empty()) return nullptr;
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findTransformConstraint(SPINE_STRING(constraint_name));
if (!constraint) return nullptr;
Ref<SpineTransformConstraintData> constraint_ref(memnew(SpineTransformConstraintData));
@ -332,7 +340,7 @@ Ref<SpineTransformConstraintData> SpineSkeletonDataResource::find_transform_cons
}
Ref<SpinePathConstraintData> SpineSkeletonDataResource::find_path_constraint(const String &constraint_name) const {
SPINE_CHECK(skeleton_data, nullptr)
if (constraint_name.empty()) return nullptr;
if (EMPTY(constraint_name)) return nullptr;
auto constraint = skeleton_data->findPathConstraint(SPINE_STRING(constraint_name));
if (constraint == nullptr) return nullptr;
Ref<SpinePathConstraintData> constraint_ref(memnew(SpinePathConstraintData));

View File

@ -28,7 +28,11 @@
*****************************************************************************/
#include "SpineSkeletonFileResource.h"
#if VERSION_MAJOR > 3
#include "core/io/file_access.h"
#else
#include "core/os/file_access.h"
#endif
void SpineSkeletonFileResource::_bind_methods() {
}
@ -44,20 +48,33 @@ Error SpineSkeletonFileResource::load_from_file(const String &path) {
Error SpineSkeletonFileResource::save_to_file(const String &path) {
Error error;
#if VERSION_MAJOR > 3
Ref<FileAccess> file = FileAccess::open(path, FileAccess::WRITE, &error);
if (error != OK) return error;
#else
FileAccess *file = FileAccess::open(path, FileAccess::WRITE, &error);
if (error != OK) {
if (file) file->close();
return error;
}
#endif
if (!is_binary())
file->store_string(json);
else
file->store_buffer(binary.ptr(), binary.size());
#if VERSION_MAJOR > 3
file->flush();
#else
file->close();
#endif
return OK;
}
#if VERSION_MAJOR > 3
RES SpineSkeletonFileResourceFormatLoader::load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode) {
#else
RES SpineSkeletonFileResourceFormatLoader::load(const String &path, const String &original_path, Error *error) {
#endif
Ref<SpineSkeletonFileResource> skeleton_file = memnew(SpineSkeletonFileResource);
skeleton_file->load_from_file(path);
if (error) *error = OK;
@ -78,7 +95,7 @@ bool SpineSkeletonFileResourceFormatLoader::handles_type(const String &type) con
}
Error SpineSkeletonFileResourceFormatSaver::save(const String &path, const RES &resource, uint32_t flags) {
Ref<SpineSkeletonFileResource> res = resource.get_ref_ptr();
Ref<SpineSkeletonFileResource> res = resource;
Error error = res->save_to_file(path);
return error;
}

View File

@ -30,6 +30,7 @@
#ifndef GODOT_SPINESKELETONFILERESOURCE_H
#define GODOT_SPINESKELETONFILERESOURCE_H
#include "SpineCommon.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
@ -43,7 +44,7 @@ protected:
Vector<uint8_t> binary;
public:
bool is_binary() { return !binary.empty(); }
bool is_binary() { return binary.size() > 0; }
const Vector<uint8_t> &get_binary() { return binary; }
@ -58,7 +59,11 @@ class SpineSkeletonFileResourceFormatLoader : public ResourceFormatLoader {
GDCLASS(SpineSkeletonFileResourceFormatLoader, ResourceFormatLoader);
public:
#if VERSION_MAJOR > 3
RES load(const String &path, const String &original_path, Error *error, bool use_sub_threads, float *progress, CacheMode cache_mode);
#else
RES load(const String &path, const String &original_path, Error *error) override;
#endif
void get_recognized_extensions(List<String> *extensions) const override;

View File

@ -30,10 +30,11 @@
#ifndef GODOT_SPINESKIN_H
#define GODOT_SPINESKIN_H
#include "SpineCommon.h"
#include "SpineAttachment.h"
class SpineSkin : public Reference {
GDCLASS(SpineSkin, Reference);
class SpineSkin : public REFCOUNTED {
GDCLASS(SpineSkin, REFCOUNTED);
protected:
static void _bind_methods();
@ -74,8 +75,8 @@ public:
Array get_constraints();
};
class SpineSkinEntry : public Reference {
GDCLASS(SpineSkinEntry, Reference);
class SpineSkinEntry : public REFCOUNTED {
GDCLASS(SpineSkinEntry, REFCOUNTED);
friend class SpineSkin;

View File

@ -30,6 +30,7 @@
#ifndef GODOT_SPINESLOT_H
#define GODOT_SPINESLOT_H
#include "SpineCommon.h"
#include "SpineSlotData.h"
#include "SpineAttachment.h"
#include "SpineBone.h"
@ -37,8 +38,8 @@
// Breaks cyclic dependency.
class SpineSkeleton;
class SpineSlot : public Reference {
GDCLASS(SpineSlot, Reference);
class SpineSlot : public REFCOUNTED {
GDCLASS(SpineSlot, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -30,12 +30,12 @@
#ifndef GODOT_SPINESLOTDATA_H
#define GODOT_SPINESLOTDATA_H
#include "SpineCommon.h"
#include "SpineBoneData.h"
#include "core/object.h"
#include <spine/SlotData.h>
class SpineSlotData : public Reference {
GDCLASS(SpineSlotData, Reference);
class SpineSlotData : public REFCOUNTED {
GDCLASS(SpineSlotData, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -117,8 +117,13 @@ void SpineSprite::_on_skeleton_data_changed() {
animation_state.unref();
if (skeleton_data_res.is_valid()) {
#if VERSION_MAJOR > 3
if (!skeleton_data_res->is_connected("skeleton_data_changed", callable_mp(this, &SpineSprite::_on_skeleton_data_changed)))
skeleton_data_res->connect("skeleton_data_changed", callable_mp(this, &SpineSprite::_on_skeleton_data_changed));
#else
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");
#endif
}
if (skeleton_data_res.is_valid() && skeleton_data_res->is_skeleton_data_loaded()) {
@ -142,7 +147,7 @@ void SpineSprite::_on_skeleton_data_changed() {
}
}
property_list_changed_notify();
NOTIFY_PROPERTY_LIST_CHANGED();
}
Ref<SpineSkeleton> SpineSprite::get_skeleton() {
@ -176,7 +181,7 @@ void SpineSprite::_notification(int p_what) {
}
void SpineSprite::_update_all(float delta) {
if (!(skeleton.is_valid() && animation_state.is_valid()) || mesh_instances.empty())
if (!(skeleton.is_valid() && animation_state.is_valid()) || EMPTY(mesh_instances))
return;
animation_state->update(delta);
@ -238,6 +243,21 @@ void SpineSprite::update_bind_slot_nodes() {
}
void SpineSprite::update_bind_slot_node_draw_order(const String &slot_name, Node2D *node2d) {
#if VERSION_MAJOR > 3
auto nodes = find_nodes(slot_name);
if (!nodes.is_empty()) {
auto mesh_ins = Object::cast_to<MeshInstance2D>(nodes[0]);
if (mesh_ins) {
auto pos = mesh_ins->get_index();
// get child
auto node = find_child_node_by_node(node2d);
if (node && node->get_index() != pos + 1) {
move_child(node, pos + 1);
}
}
}
#else
auto mesh_ins = find_node(slot_name);
if (mesh_ins) {
auto pos = mesh_ins->get_index();
@ -248,6 +268,7 @@ void SpineSprite::update_bind_slot_node_draw_order(const String &slot_name, Node
move_child(node, pos + 1);
}
}
#endif
}
Node *SpineSprite::find_child_node_by_node(Node *node) {
if (node == nullptr) return nullptr;
@ -368,7 +389,11 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> s) {
}
auto mesh_ins = mesh_instances[i];
#if VERSION_MAJOR > 3
RenderingServer::get_singleton()->canvas_item_clear(mesh_ins->get_canvas_item());
#else
VisualServer::get_singleton()->canvas_item_clear(mesh_ins->get_canvas_item());
#endif
if (skeleton_clipper->isClipping()) {
skeleton_clipper->clipTriangles(vertices, indices, uvs, VERTEX_STRIDE);
@ -400,6 +425,18 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> s) {
p_indices.set(j, clipped_indices[j]);
}
#if VERSION_MAJOR > 3
RenderingServer::get_singleton()->canvas_item_add_triangle_array(mesh_ins->get_canvas_item(),
p_indices,
p_points,
p_colors,
p_uvs,
Vector<int>(),
Vector<float>(),
tex.is_null() ? RID() : tex->get_rid(),
-1
);
#else
VisualServer::get_singleton()->canvas_item_add_triangle_array(mesh_ins->get_canvas_item(),
p_indices,
p_points,
@ -410,6 +447,7 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> s) {
tex.is_null() ? RID() : tex->get_rid(),
-1,
normal_tex.is_null() ? RID() : normal_tex->get_rid());
#endif
}
} else {
if (indices.size() > 0) {
@ -429,6 +467,17 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> s) {
p_indices.set(j, indices[j]);
}
#if VERSION_MAJOR > 3
RenderingServer::get_singleton()->canvas_item_add_triangle_array(mesh_ins->get_canvas_item(),
p_indices,
p_points,
p_colors,
p_uvs,
Vector<int>(),
Vector<float>(),
tex.is_null() ? RID() : tex->get_rid(),
-1);
#else
VisualServer::get_singleton()->canvas_item_add_triangle_array(mesh_ins->get_canvas_item(),
p_indices,
p_points,
@ -439,6 +488,7 @@ void SpineSprite::update_meshes(Ref<SpineSkeleton> s) {
tex.is_null() ? RID() : tex->get_rid(),
-1,
normal_tex.is_null() ? RID() : normal_tex->get_rid());
#endif
}
}
skeleton_clipper->clipEnd(*slot);

View File

@ -30,8 +30,9 @@
#include "SpineTimeline.h"
#include "SpineSkeleton.h"
#include "SpineEvent.h"
#include "SpineCommon.h"
#if VERSION_MAJOR == 3
#include "core/method_bind_ext.gen.inc"
#endif
void SpineTimeline::_bind_methods() {
ClassDB::bind_method(D_METHOD("apply", "skeleton", "last_time", "time", "events", "alpha", "blend", "direction"), &SpineTimeline::apply);

View File

@ -30,15 +30,15 @@
#ifndef GODOT_SPINETIMELINE_H
#define GODOT_SPINETIMELINE_H
#include "SpineCommon.h"
#include "SpineConstant.h"
#include "core/reference.h"
#include <spine/Timeline.h>
class SpineSkeleton;
class SpineEvent;
class SpineTimeline : public Reference {
GDCLASS(SpineTimeline, Reference);
class SpineTimeline : public REFCOUNTED {
GDCLASS(SpineTimeline, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -30,12 +30,13 @@
#ifndef GODOT_SPINETRACKENTRY_H
#define GODOT_SPINETRACKENTRY_H
#include "SpineCommon.h"
#include "SpineAnimation.h"
#include "SpineConstant.h"
#include <spine/AnimationState.h>
class SpineTrackEntry : public Reference {
GDCLASS(SpineTrackEntry, Reference);
class SpineTrackEntry : public REFCOUNTED {
GDCLASS(SpineTrackEntry, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -30,12 +30,13 @@
#ifndef GODOT_SPINETRANSFORMCONSTRAINT_H
#define GODOT_SPINETRANSFORMCONSTRAINT_H
#include "SpineCommon.h"
#include "SpineTransformConstraintData.h"
#include "SpineBone.h"
#include <spine/TransformConstraint.h>
class SpineTransformConstraint : public Reference {
GDCLASS(SpineTransformConstraint, Reference);
class SpineTransformConstraint : public REFCOUNTED {
GDCLASS(SpineTransformConstraint, REFCOUNTED);
protected:
static void _bind_methods();

View File

@ -27,8 +27,8 @@
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*****************************************************************************/
#include "SpineCommon.h"
#include "register_types.h"
#include "core/class_db.h"
#include "SpineAtlasResource.h"
#include "SpineSkeletonFileResource.h"
#include "SpineSkeletonDataResource.h"
@ -56,7 +56,6 @@ static Ref<SpineSkeletonFileResourceFormatLoader> skeleton_file_loader;
static Ref<SpineSkeletonFileResourceFormatSaver> skeleton_file_saver;
#ifdef TOOLS_ENABLED
#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "SpineEditorPlugin.h"
@ -100,6 +99,19 @@ void register_spine_godot_types() {
ClassDB::register_class<SpineConstant>();
ClassDB::register_class<SpineCollisionShapeProxy>();
#if VERSION_MAJOR > 3
atlas_loader.instantiate();
ResourceLoader::add_resource_format_loader(atlas_loader);
atlas_saver.instantiate();
ResourceSaver::add_resource_format_saver(atlas_saver);
skeleton_file_loader.instantiate();
ResourceLoader::add_resource_format_loader(skeleton_file_loader);
skeleton_file_saver.instantiate();
ResourceSaver::add_resource_format_saver(skeleton_file_saver);
#else
atlas_loader.instance();
ResourceLoader::add_resource_format_loader(atlas_loader);
@ -111,6 +123,7 @@ void register_spine_godot_types() {
skeleton_file_saver.instance();
ResourceSaver::add_resource_format_saver(skeleton_file_saver);
#endif
}
void unregister_spine_godot_types() {