mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-09 16:48:43 +08:00
GDExtension support, heavy WIP
This commit is contained in:
parent
f80ac86bbf
commit
1101e71ec3
1
.gitignore
vendored
1
.gitignore
vendored
@ -204,3 +204,4 @@ spine-flutter/src/spine-cpp-lite
|
||||
spine-sdl/.vs
|
||||
spine-ts/spine-canvaskit/dist
|
||||
spine-ts/output.png
|
||||
spine-godot/godot-cpp
|
||||
|
||||
25
spine-godot/CMakeLists.txt
Normal file
25
spine-godot/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
|
||||
project(spine_godot_extension)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
file(GLOB INCLUDES "spine_godot/**/*.h")
|
||||
file(GLOB SOURCES "spine_godot/*.cpp")
|
||||
string(REPLACE ";" "\n" SOURCES_LIST "${SOURCES}")
|
||||
message(STATUS "Source files:\n${SOURCES_LIST}")
|
||||
|
||||
include_directories(
|
||||
spine_godot
|
||||
spine_godot/spine-cpp/include
|
||||
godot-cpp/gdextension
|
||||
godot-cpp/include
|
||||
godot-cpp/gen/include
|
||||
)
|
||||
|
||||
add_library(spine_godot_extension SHARED ${SOURCES})
|
||||
target_compile_definitions(spine_godot_extension PRIVATE SPINE_GODOT_EXTENSION)
|
||||
|
||||
# Link Godot's GDExtension API
|
||||
target_link_libraries(spine_godot_extension PRIVATE godot-cpp)
|
||||
@ -18,10 +18,13 @@ if [ $# -lt 2 ] || [ $# -gt 4 ]; then
|
||||
fi
|
||||
|
||||
branch=${1%/}
|
||||
godot_version=$(echo "$branch" | grep -o '^[0-9]*\.[0-9]*')
|
||||
dev=${2%/}
|
||||
mono=false
|
||||
repo=https://github.com/godotengine/godot.git
|
||||
|
||||
echo "Godot version: $godot_version"
|
||||
|
||||
if [[ $# -eq 3 && "$branch" != 3* ]]; then
|
||||
mono=${3%/}
|
||||
fi
|
||||
@ -41,6 +44,16 @@ if [ $# -eq 4 ]; then
|
||||
fi
|
||||
|
||||
pushd ..
|
||||
|
||||
echo "--- Cloning GDExtensions"
|
||||
rm -rf godot-cpp
|
||||
git clone https://github.com/godotengine/godot-cpp
|
||||
pushd godot-cpp
|
||||
git submodule update --init
|
||||
git checkout $godot_version
|
||||
popd
|
||||
|
||||
echo "--- Cloning Godot"
|
||||
rm -rf godot
|
||||
git clone --depth 1 $repo -b $branch
|
||||
if [ $dev = "true" ]; then
|
||||
|
||||
@ -28,6 +28,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "GodotSpineExtension.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include "SpineCommon.h"
|
||||
#include <godot_cpp/core/memory.hpp>
|
||||
#include <godot_cpp/classes/file_access.hpp>
|
||||
#else
|
||||
#include "core/os/memory.h"
|
||||
#include "core/version.h"
|
||||
#if VERSION_MAJOR > 3
|
||||
@ -35,6 +40,7 @@
|
||||
#else
|
||||
#include "core/os/file_access.h"
|
||||
#endif
|
||||
#endif
|
||||
#include <spine/SpineString.h>
|
||||
|
||||
spine::SpineExtension *spine::getDefaultExtension() {
|
||||
@ -61,6 +67,10 @@ void GodotSpineExtension::_free(void *mem, const char *file, int line) {
|
||||
|
||||
char *GodotSpineExtension::_readFile(const spine::String &path, int *length) {
|
||||
Error error;
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
// FIXME no error parameter!
|
||||
auto res = FileAccess::get_file_as_bytes(String(path.buffer()));
|
||||
#else
|
||||
#if VERSION_MAJOR > 3
|
||||
auto res = FileAccess::get_file_as_bytes(String(path.buffer()), &error);
|
||||
#else
|
||||
@ -70,6 +80,7 @@ char *GodotSpineExtension::_readFile(const spine::String &path, int *length) {
|
||||
if (length) *length = 0;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
auto r = alloc<char>(res.size(), __FILE__, __LINE__);
|
||||
memcpy(r, res.ptr(), res.size());
|
||||
if (length) *length = res.size();
|
||||
|
||||
@ -30,8 +30,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "SpineSprite.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/classes/animation_player.hpp>
|
||||
#include <godot_cpp/classes/animation.hpp>
|
||||
#else
|
||||
#include "scene/animation/animation_player.h"
|
||||
#include "scene/resources/animation.h"
|
||||
#endif
|
||||
|
||||
class SpineAnimationTrack : public Node {
|
||||
GDCLASS(SpineAnimationTrack, Node)
|
||||
|
||||
@ -29,8 +29,15 @@
|
||||
|
||||
#include "SpineAtlasResource.h"
|
||||
#include "SpineRendererObject.h"
|
||||
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/classes/json.hpp>
|
||||
#include <godot_cpp/classes/texture.hpp>
|
||||
#include <godot_cpp/classes/file_access.hpp>
|
||||
#else
|
||||
#include "core/io/json.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#endif
|
||||
#include <spine/TextureLoader.h>
|
||||
|
||||
class GodotSpineTextureLoader : public spine::TextureLoader {
|
||||
@ -44,16 +51,16 @@ public:
|
||||
}
|
||||
|
||||
static String fix_path(const String &path) {
|
||||
if (path.size() > 5 && path[4] == '/' && path[5] == '/') return path;
|
||||
if (SSIZE(path) > 5 && path[4] == '/' && path[5] == '/') return path;
|
||||
const String prefix = "res:/";
|
||||
auto i = path.find(prefix);
|
||||
auto sub_str_pos = i + prefix.size() - 1;
|
||||
auto sub_str_pos = i + SSIZE(prefix) - 1;
|
||||
if (sub_str_pos < 0) return path;
|
||||
auto res = path.substr(sub_str_pos);
|
||||
|
||||
if (!EMPTY(res)) {
|
||||
if (res[0] != '/') {
|
||||
return prefix + "/" + res;
|
||||
return prefix + String("/") + res;
|
||||
} else {
|
||||
return prefix + res;
|
||||
}
|
||||
@ -65,10 +72,15 @@ public:
|
||||
Error error = OK;
|
||||
auto fixed_path = fix_path(String(path.buffer()));
|
||||
|
||||
#if SPINE_GODOT_EXTENSION
|
||||
// FIXME no error parameter
|
||||
Ref<Texture2D> texture = ResourceLoader::get_singleton()->load(fixed_path, "", ResourceLoader::CACHE_MODE_REUSE);
|
||||
#else
|
||||
#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);
|
||||
#endif
|
||||
#endif
|
||||
if (error != OK || !texture.is_valid()) {
|
||||
ERR_PRINT(vformat("Can't load texture: \"%s\"", String(path.buffer())));
|
||||
@ -85,11 +97,19 @@ public:
|
||||
renderer_object->normal_map = Ref<Texture>(nullptr);
|
||||
|
||||
String new_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), normal_map_prefix, fixed_path.get_file());
|
||||
#if SPINE_GODOT_EXTENSION
|
||||
if (ResourceLoader::get_singleton()->exists(new_path)) {
|
||||
Ref<Texture> normal_map = ResourceLoader::get_singleton()->load(new_path);
|
||||
normal_maps->append(normal_map);
|
||||
renderer_object->normal_map = normal_map;
|
||||
}
|
||||
#else
|
||||
if (ResourceLoader::exists(new_path)) {
|
||||
Ref<Texture> normal_map = ResourceLoader::load(new_path);
|
||||
normal_maps->append(normal_map);
|
||||
renderer_object->normal_map = normal_map;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if VERSION_MAJOR > 3
|
||||
renderer_object->canvas_texture.instantiate();
|
||||
|
||||
@ -30,10 +30,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "SpineCommon.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/classes/resource.hpp>
|
||||
#include <godot_cpp/classes/resource_loader.hpp>
|
||||
#include <godot_cpp/classes/resource_format_loader.hpp>
|
||||
#include <godot_cpp/classes/resource_saver.hpp>
|
||||
#include <godot_cpp/classes/resource_format_saver.hpp>
|
||||
#include <spine/Atlas.h>
|
||||
#else
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
#include "core/io/image_loader.h"
|
||||
#include <spine/Atlas.h>
|
||||
#endif
|
||||
|
||||
class GodotSpineTextureLoader;
|
||||
|
||||
@ -89,6 +98,15 @@ class SpineAtlasResourceFormatLoader : public ResourceFormatLoader {
|
||||
GDCLASS(SpineAtlasResourceFormatLoader, ResourceFormatLoader)
|
||||
|
||||
public:
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
PackedStringArray _get_recognized_extensions();
|
||||
|
||||
bool _handles_type(const StringName &type);
|
||||
|
||||
String _get_resource_type(const String &path);
|
||||
|
||||
Variant _load(const String &path, const String &original_path, bool use_sub_threads, int32_t cache_mode);
|
||||
#else
|
||||
#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
|
||||
@ -100,12 +118,18 @@ public:
|
||||
bool handles_type(const String &type) const override;
|
||||
|
||||
String get_resource_type(const String &path) const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
class SpineAtlasResourceFormatSaver : public ResourceFormatSaver {
|
||||
GDCLASS(SpineAtlasResourceFormatSaver, ResourceFormatSaver)
|
||||
|
||||
public:
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
Error _save(const Ref<Resource> &resource, const String &path, uint32_t flags) override;
|
||||
bool _recognize(const Ref<Resource> &resource);
|
||||
PackedStringArray _get_recognized_extensions(const Ref<Resource> &resource);
|
||||
#else
|
||||
#if VERSION_MAJOR > 3
|
||||
Error save(const RES &resource, const String &path, uint32_t flags) override;
|
||||
#else
|
||||
@ -115,4 +139,5 @@ public:
|
||||
void get_recognized_extensions(const RES &resource, List<String> *extensions) const override;
|
||||
|
||||
bool recognize(const RES &resource) const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -48,7 +48,7 @@ public:
|
||||
|
||||
Ref<SpineAttachment> copy();
|
||||
|
||||
void set_spine_object(const SpineSkeletonDataResource *_owner, spine::Attachment *_object) {
|
||||
void set_spine_object(const SpineSkeletonDataResource *_owner, spine::Attachment *_object) override {
|
||||
if (get_spine_object()) get_spine_object()->dereference();
|
||||
_set_spine_object_internal(_owner, _object);
|
||||
if (_object) _object->reference();
|
||||
|
||||
@ -32,7 +32,11 @@
|
||||
#include "SpineCommon.h"
|
||||
#include "SpineBoneData.h"
|
||||
#include "SpineConstant.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/classes/node2d.hpp>
|
||||
#else
|
||||
#include "scene/2d/node_2d.h"
|
||||
#endif
|
||||
#include <spine/Bone.h>
|
||||
|
||||
class SpineSkeleton;
|
||||
|
||||
@ -30,6 +30,28 @@
|
||||
#ifndef SPINE_COMMON_H
|
||||
#define SPINE_COMMON_H
|
||||
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/core/version.hpp>
|
||||
#include <godot_cpp/classes/ref_counted.hpp>
|
||||
#include <godot_cpp/variant/string_name.hpp>
|
||||
using namespace godot;
|
||||
#define REFCOUNTED RefCounted
|
||||
#define EMPTY(x) ((x).is_empty())
|
||||
#define EMPTY_PTR(x) ((x)->is_empty())
|
||||
#define SSIZE(x) ((x).length())
|
||||
#define INSTANTIATE(x) (x).instantiate()
|
||||
#define NOTIFY_PROPERTY_LIST_CHANGED() notify_property_list_changed()
|
||||
#define VARIANT_FLOAT Variant::FLOAT
|
||||
#define PROPERTY_USAGE_NOEDITOR PROPERTY_USAGE_NO_EDITOR
|
||||
#define RES Ref<Resource>
|
||||
#define REF Ref<RefCounted>
|
||||
#define GEOMETRY2D Geometry2D
|
||||
#define VERSION_MAJOR GODOT_VERSION_MAJOR
|
||||
#define VERSION_MINOR GODOT_VERSION_MINOR
|
||||
// FIXME this doesn't do the same as the engine SNAME in terms of caching
|
||||
#define SNAME(name) StringName(name)
|
||||
#define RS RenderingServer
|
||||
#else
|
||||
#include "core/version.h"
|
||||
#if VERSION_MAJOR > 3
|
||||
#include "core/core_bind.h"
|
||||
@ -37,6 +59,7 @@
|
||||
#define REFCOUNTED RefCounted
|
||||
#define EMPTY(x) ((x).is_empty())
|
||||
#define EMPTY_PTR(x) ((x)->is_empty())
|
||||
#define SSIZE(x) ((x).size())
|
||||
#define INSTANTIATE(x) (x).instantiate()
|
||||
#define NOTIFY_PROPERTY_LIST_CHANGED() notify_property_list_changed()
|
||||
#define VARIANT_FLOAT Variant::FLOAT
|
||||
@ -51,6 +74,7 @@
|
||||
#define REFCOUNTED Reference
|
||||
#define EMPTY(x) ((x).empty())
|
||||
#define EMPTY_PTR(x) ((x)->empty())
|
||||
#define SSIZE(x) ((x).size())
|
||||
#define INSTANTIATE(x) (x).instance()
|
||||
#define NOTIFY_PROPERTY_LIST_CHANGED() property_list_changed_notify()
|
||||
#define VARIANT_FLOAT Variant::REAL
|
||||
@ -60,6 +84,7 @@
|
||||
#define SNAME(m_arg) ([]() -> const StringName & { static StringName sname = _scs_create(m_arg); return sname; })()
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SPINE_CHECK(obj, ret) \
|
||||
if (!(obj)) { \
|
||||
|
||||
@ -30,11 +30,18 @@
|
||||
#ifndef GODOT_SPINERENDEREROBJECT_H
|
||||
#define GODOT_SPINERENDEREROBJECT_H
|
||||
|
||||
#include "SpineCommon.h"
|
||||
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/classes/texture.hpp>
|
||||
#include <godot_cpp/classes/canvas_texture.hpp>
|
||||
#else
|
||||
#include <scene/resources/texture.h>
|
||||
|
||||
#if VERSION_MAJOR > 3
|
||||
#include <scene/main/canvas_item.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct SpineRendererObject {
|
||||
Ref<Texture> texture;
|
||||
|
||||
@ -29,7 +29,6 @@
|
||||
|
||||
#include "SpineSkeletonDataResource.h"
|
||||
#include "SpineCommon.h"
|
||||
#include "core/io/marshalls.h"
|
||||
|
||||
void SpineAnimationMix::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_from", "from"),
|
||||
|
||||
@ -28,6 +28,10 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineSkeletonFileResource.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/core/error_macros.hpp>
|
||||
#include <godot_cpp/classes/file_access.hpp>
|
||||
#else
|
||||
#if VERSION_MAJOR > 3
|
||||
#include "core/error/error_list.h"
|
||||
#include "core/error/error_macros.h"
|
||||
@ -37,6 +41,7 @@
|
||||
#include "core/error_macros.h"
|
||||
#include "core/os/file_access.h"
|
||||
#endif
|
||||
#endif
|
||||
#include <spine/Json.h>
|
||||
#include <spine/Version.h>
|
||||
#include <spine/Extension.h>
|
||||
|
||||
@ -30,8 +30,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "SpineCommon.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include <godot_cpp/classes/resource_loader.hpp>
|
||||
#include <godot_cpp/classes/resource_format_loader.hpp>
|
||||
#include <godot_cpp/classes/resource_saver.hpp>
|
||||
#include <godot_cpp/classes/resource_format_saver.hpp>
|
||||
#include <godot_cpp/classes/resource.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
#else
|
||||
#include "core/io/resource_loader.h"
|
||||
#include "core/io/resource_saver.h"
|
||||
#endif
|
||||
#include <spine/Vector.h>
|
||||
|
||||
class SpineSkeletonFileResource : public Resource {
|
||||
GDCLASS(SpineSkeletonFileResource, Resource);
|
||||
@ -62,6 +72,15 @@ class SpineSkeletonFileResourceFormatLoader : public ResourceFormatLoader {
|
||||
GDCLASS(SpineSkeletonFileResourceFormatLoader, ResourceFormatLoader);
|
||||
|
||||
public:
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
PackedStringArray _get_recognized_extensions();
|
||||
|
||||
bool _handles_type(const StringName &type);
|
||||
|
||||
String _get_resource_type(const String &path);
|
||||
|
||||
Variant _load(const String &path, const String &original_path, bool use_sub_threads, int32_t cache_mode);
|
||||
#else
|
||||
#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
|
||||
@ -73,12 +92,18 @@ public:
|
||||
bool handles_type(const String &type) const override;
|
||||
|
||||
String get_resource_type(const String &path) const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
class SpineSkeletonFileResourceFormatSaver : public ResourceFormatSaver {
|
||||
GDCLASS(SpineSkeletonFileResourceFormatSaver, ResourceFormatSaver);
|
||||
|
||||
public:
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
Error _save(const Ref<Resource> &resource, const String &path, uint32_t flags) override;
|
||||
bool _recognize(const Ref<Resource> &resource);
|
||||
PackedStringArray _get_recognized_extensions(const Ref<Resource> &resource);
|
||||
#else
|
||||
#if VERSION_MAJOR > 3
|
||||
Error save(const RES &resource, const String &path, uint32_t flags) override;
|
||||
#else
|
||||
@ -88,4 +113,5 @@ public:
|
||||
void get_recognized_extensions(const RES &resource, List<String> *p_extensions) const override;
|
||||
|
||||
bool recognize(const RES &p_resource) const override;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -31,7 +31,15 @@
|
||||
|
||||
#include "SpineSkeleton.h"
|
||||
#include "SpineAnimationState.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#include "SpineCommon.h"
|
||||
#include <godot_cpp/classes/node2d.hpp>
|
||||
#include <godot_cpp/templates/vector.hpp>
|
||||
#include <godot_cpp/classes/rendering_server.hpp>
|
||||
#include <godot_cpp/classes/canvas_item_material.hpp>
|
||||
#else
|
||||
#include "scene/2d/node_2d.h"
|
||||
#endif
|
||||
|
||||
class SpineSlotNode;
|
||||
|
||||
@ -84,7 +92,11 @@ public:
|
||||
SpineMesh2D() : renderer_object(nullptr), indices_changed(true), num_vertices(0), num_indices(0), vertex_stride(0), normal_tangent_stride(0), attribute_stride(0){};
|
||||
~SpineMesh2D() {
|
||||
if (mesh.is_valid()) {
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
RS::get_singleton()->free_rid(mesh);
|
||||
#else
|
||||
RS::get_singleton()->free(mesh);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
@ -160,7 +172,7 @@ protected:
|
||||
void draw();
|
||||
void draw_bone(spine::Bone *bone, const Color &color);
|
||||
|
||||
void callback(spine::AnimationState *state, spine::EventType type, spine::TrackEntry *entry, spine::Event *event);
|
||||
void callback(spine::AnimationState *state, spine::EventType type, spine::TrackEntry *entry, spine::Event *event) override;
|
||||
|
||||
public:
|
||||
SpineSprite();
|
||||
|
||||
@ -28,7 +28,10 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include "SpineCommon.h"
|
||||
#ifdef SPINE_GODOT_EXTENSION
|
||||
#else
|
||||
#include "modules/register_module_types.h"
|
||||
#endif
|
||||
#include "register_types.h"
|
||||
#include "SpineAtlasResource.h"
|
||||
#include "SpineSkeletonFileResource.h"
|
||||
|
||||
@ -32,7 +32,9 @@
|
||||
#include "SpineCommon.h"
|
||||
|
||||
#if VERSION_MAJOR > 3
|
||||
#ifndef SPINE_GODOT_EXTENSION
|
||||
#include "modules/register_module_types.h"
|
||||
#endif
|
||||
void initialize_spine_godot_module(ModuleInitializationLevel level);
|
||||
void uninitialize_spine_godot_module(ModuleInitializationLevel level);
|
||||
#else
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user