From b0890856cd76384a3b337c2ca77aaa8a8ae0147c Mon Sep 17 00:00:00 2001 From: Luke Ingram Date: Wed, 28 May 2025 23:23:56 -0400 Subject: [PATCH] [godot] Port of 6a08383 Adds specular map support to spine-godot on the Spine Runtimes 4.2 branch. This was tested by porting the changes and compiling the spine-godot editor (version 4.3-stable) from source. --- .../spine_godot/SpineAtlasResource.cpp | 41 +++++++++++++++++-- spine-godot/spine_godot/SpineAtlasResource.h | 6 +++ spine-godot/spine_godot/SpineEditorPlugin.cpp | 39 ++++++++++++------ spine-godot/spine_godot/SpineRendererObject.h | 1 + spine-godot/spine_godot/SpineSprite.cpp | 7 +++- .../spine_godot/docs/SpineAtlasResource.xml | 2 + 6 files changed, 78 insertions(+), 18 deletions(-) diff --git a/spine-godot/spine_godot/SpineAtlasResource.cpp b/spine-godot/spine_godot/SpineAtlasResource.cpp index da06afa4e..58be6da1f 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.cpp +++ b/spine-godot/spine_godot/SpineAtlasResource.cpp @@ -61,10 +61,12 @@ class GodotSpineTextureLoader : public spine::TextureLoader { Array *textures; Array *normal_maps; + Array *specular_maps; String normal_map_prefix; + String specular_map_prefix; public: - GodotSpineTextureLoader(Array *_textures, Array *_normal_maps, const String &normal_map_prefix, bool is_importing) : textures(_textures), normal_maps(_normal_maps), normal_map_prefix(normal_map_prefix) { + GodotSpineTextureLoader(Array *_textures, Array *_normal_maps, Array *_specular_maps, const String &normal_map_prefix, const String &specular_map_prefix, bool is_importing) : textures(_textures), normal_maps(_normal_maps), specular_maps(_specular_maps), normal_map_prefix(normal_map_prefix), specular_map_prefix(specular_map_prefix) { } static bool fix_path(String &path) { @@ -156,6 +158,7 @@ public: auto renderer_object = memnew(SpineRendererObject); renderer_object->texture = Ref(nullptr); renderer_object->normal_map = Ref(nullptr); + renderer_object->specular_map = Ref(nullptr); page.texture = (void *) renderer_object; return; } @@ -164,9 +167,12 @@ public: auto renderer_object = memnew(SpineRendererObject); renderer_object->texture = texture; renderer_object->normal_map = Ref(nullptr); + renderer_object->specular_map = Ref(nullptr); String normal_map_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), normal_map_prefix, fixed_path.get_file()); + String specular_map_path = vformat("%s/%s_%s", fixed_path.get_base_dir(), specular_map_prefix, fixed_path.get_file()); is_resource = fix_path(normal_map_path); + is_resource = fix_path(specular_map_path); #if SPINE_GODOT_EXTENSION if (ResourceLoader::get_singleton()->exists(normal_map_path)) { import_image_resource(normal_map_path); @@ -174,6 +180,13 @@ public: normal_maps->append(normal_map); renderer_object->normal_map = normal_map; } + + if (ResourceLoader::get_singleton()->exists(specular_map_path)) { + import_image_resource(specular_map_path); + Ref specular_map = get_texture_from_image(specular_map_path, is_resource); + specular_maps->append(specular_map); + renderer_object->specular_map = specular_map; + } #else if (ResourceLoader::exists(normal_map_path)) { import_image_resource(normal_map_path); @@ -181,12 +194,20 @@ public: normal_maps->append(normal_map); renderer_object->normal_map = normal_map; } + + if (ResourceLoader::exists(specular_map_path)) { + import_image_resource(specular_map_path); + Ref specular_map = get_texture_from_image(specular_map_path, is_resource); + specular_maps->append(specular_map); + renderer_object->specular_map = specular_map; + } #endif #if VERSION_MAJOR > 3 renderer_object->canvas_texture.instantiate(); renderer_object->canvas_texture->set_diffuse_texture(renderer_object->texture); renderer_object->canvas_texture->set_normal_texture(renderer_object->normal_map); + renderer_object->canvas_texture->set_specular_texture(renderer_object->specular_map); #endif page.texture = (void *) renderer_object; @@ -198,6 +219,7 @@ public: auto renderer_object = (SpineRendererObject *) data; if (renderer_object->texture.is_valid()) renderer_object->texture.unref(); if (renderer_object->normal_map.is_valid()) renderer_object->normal_map.unref(); + if (renderer_object->specular_map.is_valid()) renderer_object->specular_map.unref(); #if VERSION_MAJOR > 3 if (renderer_object->canvas_texture.is_valid()) renderer_object->canvas_texture.unref(); #endif @@ -210,13 +232,15 @@ void SpineAtlasResource::_bind_methods() { ClassDB::bind_method(D_METHOD("get_source_path"), &SpineAtlasResource::get_source_path); ClassDB::bind_method(D_METHOD("get_textures"), &SpineAtlasResource::get_textures); ClassDB::bind_method(D_METHOD("get_normal_maps"), &SpineAtlasResource::get_normal_maps); + ClassDB::bind_method(D_METHOD("get_specular_maps"), &SpineAtlasResource::get_specular_maps); ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_path"), "", "get_source_path"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "textures"), "", "get_textures"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "normal_maps"), "", "get_normal_maps"); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "specular_maps"), "", "get_specular_maps"); } -SpineAtlasResource::SpineAtlasResource() : atlas(nullptr), texture_loader(nullptr), normal_map_prefix("n") { +SpineAtlasResource::SpineAtlasResource() : atlas(nullptr), texture_loader(nullptr), normal_map_prefix("n"), specular_map_prefix("s") { } SpineAtlasResource::~SpineAtlasResource() { @@ -231,6 +255,7 @@ void SpineAtlasResource::clear() { texture_loader = nullptr; textures.clear(); normal_maps.clear(); + specular_maps.clear(); } Array SpineAtlasResource::get_textures() { @@ -241,6 +266,10 @@ Array SpineAtlasResource::get_normal_maps() { return normal_maps; } +Array SpineAtlasResource::get_specular_maps() { + return specular_maps; +} + String SpineAtlasResource::get_source_path() { return source_path; } @@ -261,7 +290,7 @@ Error SpineAtlasResource::load_from_atlas_file_internal(const String &path, bool #endif clear(); - texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, normal_map_prefix, is_importing); + texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, &specular_maps, normal_map_prefix, specular_map_prefix, is_importing); auto atlas_utf8 = atlas_data.utf8(); atlas = new spine::Atlas(atlas_utf8, atlas_utf8.length(), source_path.get_base_dir().utf8(), texture_loader); if (atlas) return OK; @@ -301,9 +330,10 @@ Error SpineAtlasResource::load_from_file(const String &path) { source_path = content["source_path"]; atlas_data = content["atlas_data"]; normal_map_prefix = content["normal_texture_prefix"]; + specular_map_prefix = content["specular_texture_prefix"]; clear(); - texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, normal_map_prefix, false); + texture_loader = new GodotSpineTextureLoader(&textures, &normal_maps, &specular_maps, normal_map_prefix, specular_map_prefix, false); auto utf8 = atlas_data.utf8(); atlas = new spine::Atlas(utf8.ptr(), utf8.size(), source_path.get_base_dir().utf8(), texture_loader); if (atlas) return OK; @@ -334,6 +364,7 @@ Error SpineAtlasResource::save_to_file(const String &path) { content["source_path"] = source_path; content["atlas_data"] = atlas_data; content["normal_texture_prefix"] = normal_map_prefix; + content["specular_texture_prefix"] = specular_map_prefix; #if VERSION_MAJOR > 3 JSON *json = memnew(JSON); file->store_string(json->stringify(content)); @@ -361,8 +392,10 @@ Error SpineAtlasResource::copy_from(const Ref &p_resource) { this->source_path = spineAtlas->source_path; this->atlas_data = spineAtlas->atlas_data; this->normal_map_prefix = spineAtlas->normal_map_prefix; + this->specular_map_prefix = spineAtlas->specular_map_prefix; this->textures = spineAtlas->textures; this->normal_maps = spineAtlas->normal_maps; + this->specular_maps = spineAtlas->specular_maps; emit_signal(SNAME("skeleton_file_changed")); return OK; diff --git a/spine-godot/spine_godot/SpineAtlasResource.h b/spine-godot/spine_godot/SpineAtlasResource.h index 916c45f20..4635654e2 100644 --- a/spine-godot/spine_godot/SpineAtlasResource.h +++ b/spine-godot/spine_godot/SpineAtlasResource.h @@ -60,9 +60,11 @@ protected: String source_path; String atlas_data; String normal_map_prefix; + String specular_map_prefix; Array textures; Array normal_maps; + Array specular_maps; public: SpineAtlasResource(); @@ -72,6 +74,8 @@ public: void set_normal_texture_prefix(const String &prefix) { normal_map_prefix = prefix; } + void set_specular_texture_prefix(const String &prefix) { specular_map_prefix = prefix; } + Error load_from_atlas_file(const String &path);// .atlas Error load_from_atlas_file_internal(const String &path, bool is_importing);// .atlas @@ -92,6 +96,8 @@ public: Array get_normal_maps(); + Array get_specular_maps(); + void clear_native_data() const { this->atlas = nullptr; this->texture_loader = nullptr; diff --git a/spine-godot/spine_godot/SpineEditorPlugin.cpp b/spine-godot/spine_godot/SpineEditorPlugin.cpp index a46cfc191..36050faea 100644 --- a/spine-godot/spine_godot/SpineEditorPlugin.cpp +++ b/spine-godot/spine_godot/SpineEditorPlugin.cpp @@ -54,6 +54,7 @@ Error SpineAtlasResourceImportPlugin::import(const String &source_file, const St #endif Ref atlas(memnew(SpineAtlasResource)); atlas->set_normal_texture_prefix(options["normal_map_prefix"]); + atlas->set_specular_texture_prefix(options["specular_map_prefix"]); atlas->load_from_atlas_file_internal(source_file, true); #if VERSION_MAJOR > 3 @@ -74,12 +75,19 @@ Error SpineAtlasResourceImportPlugin::import(const String &source_file, const St #ifdef SPINE_GODOT_EXTENSION TypedArray SpineAtlasResourceImportPlugin::_get_import_options(const String &p_path, int32_t p_preset_index) const { TypedArray options; - Dictionary dictionary; - dictionary["name"] = "normal_map_prefix"; - dictionary["type"] = Variant::STRING; - dictionary["hint_string"] = "String"; - dictionary["default_value"] = String("n"); - options.push_back(dictionary); + Dictionary normal_map_dictionary; + normal_map_dictionary["name"] = "normal_map_prefix"; + normal_map_dictionary["type"] = Variant::STRING; + normal_map_dictionary["hint_string"] = "String"; + normal_map_dictionary["default_value"] = String("n"); + options.push_back(normal_map_dictionary); + + Dictionary specular_map_dictionary; + specular_map_dictionary["name"] = "specular_map_prefix"; + specular_map_dictionary["type"] = Variant::STRING; + specular_map_dictionary["hint_string"] = "String"; + specular_map_dictionary["default_value"] = String("s"); + options.push_back(specular_map_dictionary); return options; } #else @@ -89,12 +97,19 @@ void SpineAtlasResourceImportPlugin::get_import_options(const String &path, List void SpineAtlasResourceImportPlugin::get_import_options(List *options, int preset) const { #endif if (preset == 0) { - ImportOption op; - op.option.name = "normal_map_prefix"; - op.option.type = Variant::STRING; - op.option.hint_string = "String"; - op.default_value = String("n"); - options->push_back(op); + ImportOption normal_map_op; + normal_map_op.option.name = "normal_map_prefix"; + normal_map_op.option.type = Variant::STRING; + normal_map_op.option.hint_string = "String"; + normal_map_op.default_value = String("n"); + options->push_back(normal_map_op); + + ImportOption specular_map_op; + specular_map_op.option.name = "specular_map_prefix"; + specular_map_op.option.type = Variant::STRING; + specular_map_op.option.hint_string = "String"; + specular_map_op.default_value = String("s"); + options->push_back(specular_map_op); } } #endif diff --git a/spine-godot/spine_godot/SpineRendererObject.h b/spine-godot/spine_godot/SpineRendererObject.h index bfd623afa..e27170d2e 100644 --- a/spine-godot/spine_godot/SpineRendererObject.h +++ b/spine-godot/spine_godot/SpineRendererObject.h @@ -46,6 +46,7 @@ struct SpineRendererObject { Ref texture; Ref normal_map; + Ref specular_map; #if VERSION_MAJOR > 3 Ref canvas_texture; #endif diff --git a/spine-godot/spine_godot/SpineSprite.cpp b/spine-godot/spine_godot/SpineSprite.cpp index c29e250bf..a728031d6 100644 --- a/spine-godot/spine_godot/SpineSprite.cpp +++ b/spine-godot/spine_godot/SpineSprite.cpp @@ -179,6 +179,7 @@ static void add_triangles(SpineMesh2D *mesh_instance, #else auto texture = renderer_object->texture; auto normal_map = renderer_object->normal_map; + auto specular_map = renderer_object->specular_map; VisualServer::get_singleton()->canvas_item_add_triangle_array(mesh_instance->get_canvas_item(), indices, vertices, @@ -188,7 +189,8 @@ static void add_triangles(SpineMesh2D *mesh_instance, Vector(), texture.is_null() ? RID() : texture->get_rid(), -1, - normal_map.is_null() ? RID() : normal_map->get_rid()); + normal_map.is_null() ? RID() : normal_map->get_rid(), + specular_map.is_null() ? RID() : specular_map->get_rid()); #endif #endif } @@ -403,7 +405,8 @@ void SpineMesh2D::update_mesh(const Vector &vertices, Transform2D(), Color(1, 1, 1, 1), renderer_object->texture.is_null() ? RID() : renderer_object->texture->get_rid(), - renderer_object->normal_map.is_null() ? RID() : renderer_object->normal_map->get_rid()); + renderer_object->normal_map.is_null() ? RID() : renderer_object->normal_map->get_rid(), + renderer_object->specular_map.is_null() ? RID() : renderer_object->specular_map->get_rid()); #endif } #endif diff --git a/spine-godot/spine_godot/docs/SpineAtlasResource.xml b/spine-godot/spine_godot/docs/SpineAtlasResource.xml index 6cbdc689e..4e5016da7 100644 --- a/spine-godot/spine_godot/docs/SpineAtlasResource.xml +++ b/spine-godot/spine_godot/docs/SpineAtlasResource.xml @@ -19,6 +19,8 @@ + +