diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000000..950311d20c44 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gdextension/godot-cpp"] + path = gdextension/godot-cpp + url = https://github.com/godotengine/godot-cpp diff --git a/gdextension/SConstruct b/gdextension/SConstruct new file mode 100644 index 000000000000..e86df9549961 --- /dev/null +++ b/gdextension/SConstruct @@ -0,0 +1,33 @@ +#!/usr/bin/env python +import os +import sys + +env = SConscript("godot-cpp/SConstruct") + +# For reference: +# - CCFLAGS are compilation flags shared between C and C++ +# - CFLAGS are for C-specific compilation flags +# - CXXFLAGS are for C++-specific compilation flags +# - CPPFLAGS are for pre-processor flags +# - CPPDEFINES are for pre-processor defines +# - LINKFLAGS are for linking flags + +# tweak this if you want to use different folders, or more folders, to store your source code in. +env.Append(CPPPATH=["src"]) +sources = Glob("src/*.cpp") +sources += Glob("src/algorithms/*.cpp") + +if env["platform"] == "macos": + library = env.SharedLibrary( + "lib/bin/pixelorama_lib.{}.{}.framework/pixelorama_lib.{}.{}".format( + env["platform"], env["target"], env["platform"], env["target"] + ), + source=sources, + ) +else: + library = env.SharedLibrary( + "lib/bin/pixelorama_lib{}{}".format(env["suffix"], env["SHLIBSUFFIX"]), + source=sources, + ) + +Default(library) diff --git a/gdextension/godot-cpp b/gdextension/godot-cpp new file mode 160000 index 000000000000..f088bc9b2573 --- /dev/null +++ b/gdextension/godot-cpp @@ -0,0 +1 @@ +Subproject commit f088bc9b257308ed3746a711abdc3f41cefd58f3 diff --git a/gdextension/src/algorithms/drawing_algos.cpp b/gdextension/src/algorithms/drawing_algos.cpp new file mode 100644 index 000000000000..5f5e5a5ea381 --- /dev/null +++ b/gdextension/src/algorithms/drawing_algos.cpp @@ -0,0 +1,87 @@ +#include "drawing_algos.hpp" + +#include + +void DrawingAlgosCpp::_bind_methods() +{ + godot::ClassDB::bind_method(godot::D_METHOD("get_ellipse_points", "pos", "size"), &DrawingAlgosCpp::GetEllipsePoints); +} + +DrawingAlgosCpp::DrawingAlgosCpp() +{ +} + +godot::Array DrawingAlgosCpp::GetEllipsePoints(godot::Vector2i pos, godot::Vector2i size) +{ + godot::Array array; + int x0 = pos.x; + int x1 = pos.x + (size.x - 1); + int y0 = pos.y; + int y1 = pos.y + (size.y - 1); + int a = godot::UtilityFunctions::absi(x1 - x0); + int b = godot::UtilityFunctions::absi(y1 - y0); + int b1 = b & 1; + int dx = 4 * (1 - a) * b * b; + int dy = 4 * (b1 + 1) * a * a; + int err = dx + dy + b1 * a * a; + int e2 = 0; + + if (x0 > x1) + { + x0 = x1; + x1 += a; + } + + if (y0 > y1) + y0 = y1; + + y0 += (b + 1) / 2; + y1 = y0 - b1; + a *= 8 * a; + b1 = 8 * b * b; + + while (x0 <= x1) + { + godot::Vector2i v1 = godot::Vector2i(x1, y0); + godot::Vector2i v2 = godot::Vector2i(x0, y0); + godot::Vector2i v3 = godot::Vector2i(x0, y1); + godot::Vector2i v4 = godot::Vector2i(x1, y1); + array.append(v1); + array.append(v2); + array.append(v3); + array.append(v4); + + e2 = 2 * err; + if (e2 <= dy) + { + y0 += 1; + y1 -= 1; + dy += a; + err += dy; + } + + if (e2 >= dx || 2 * err > dy) + { + x0 += 1; + x1 -= 1; + dx += b1; + err += dx; + } + } + + while (y0 - y1 < b) + { + godot::Vector2i v1 = godot::Vector2i(x0 - 1, y0); + godot::Vector2i v2 = godot::Vector2i(x1 + 1, y0); + godot::Vector2i v3 = godot::Vector2i(x0 - 1, y1); + godot::Vector2i v4 = godot::Vector2i(x1 + 1, y1); + array.append(v1); + array.append(v2); + array.append(v3); + array.append(v4); + y0 += 1; + y1 -= 1; + } + + return array; +} diff --git a/gdextension/src/algorithms/drawing_algos.hpp b/gdextension/src/algorithms/drawing_algos.hpp new file mode 100644 index 000000000000..1542b6aec080 --- /dev/null +++ b/gdextension/src/algorithms/drawing_algos.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include +#include + +class DrawingAlgosCpp : public godot::Node +{ + GDCLASS(DrawingAlgosCpp, Node) + +public: + DrawingAlgosCpp(); + ~DrawingAlgosCpp() = default; + + godot::Array GetEllipsePoints(godot::Vector2i pos, godot::Vector2i size); + +protected: + static void _bind_methods(); +}; diff --git a/gdextension/src/register_types.cpp b/gdextension/src/register_types.cpp new file mode 100644 index 000000000000..0d592fdf8e48 --- /dev/null +++ b/gdextension/src/register_types.cpp @@ -0,0 +1,36 @@ +#include "register_types.hpp" + +#include "algorithms/bucket.hpp" +#include "algorithms/drawing_algos.hpp" + +#include +#include +#include + +void initialize_pixelorama_lib(godot::ModuleInitializationLevel p_level) +{ + if (p_level != godot::MODULE_INITIALIZATION_LEVEL_SCENE) + return; + + godot::ClassDB::register_class(); +} + +void uninitialize_pixelorama_lib(godot::ModuleInitializationLevel p_level) +{ + if (p_level != godot::MODULE_INITIALIZATION_LEVEL_SCENE) + return; +} + +extern "C" +{ + GDExtensionBool GDE_EXPORT pixelorama_lib_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) + { + godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); + + init_obj.register_initializer(initialize_pixelorama_lib); + init_obj.register_terminator(uninitialize_pixelorama_lib); + init_obj.set_minimum_library_initialization_level(godot::MODULE_INITIALIZATION_LEVEL_SCENE); + + return init_obj.init(); + } +} diff --git a/gdextension/src/register_types.hpp b/gdextension/src/register_types.hpp new file mode 100644 index 000000000000..ed87f14fc159 --- /dev/null +++ b/gdextension/src/register_types.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include + +void initialize_pixelorama_lib(godot::ModuleInitializationLevel p_level); +void uninitialize_pixelorama_lib(godot::ModuleInitializationLevel p_level); diff --git a/pixeloramalib.gdextension b/pixeloramalib.gdextension new file mode 100644 index 000000000000..b78c8442cf28 --- /dev/null +++ b/pixeloramalib.gdextension @@ -0,0 +1,34 @@ +[configuration] + +entry_symbol = "pixelorama_lib_init" +compatibility_minimum = "4.1" +reloadable = true + +[libraries] + +macos.debug = "res://gdextension/lib/bin/libpixelorama.macos.template_debug.framework" +macos.release = "res://gdextension/lib/bin/libpixelorama.macos.template_release.framework" +ios.debug = "res://gdextension/lib/bin/libpixelorama.ios.template_debug.xcframework" +ios.release = "res://gdextension/lib/bin/libpixelorama.ios.template^_release.xcframework" +windows.debug.x86_32 = "res://gdextension/lib/bin/libpixelorama.windows.template_debug.x86_32.dll" +windows.release.x86_32 = "res://gdextension/lib/bin/libpixelorama.windows.template_release.x86_32.dll" +windows.debug.x86_64 = "res://gdextension/lib/bin/libpixelorama.windows.template_debug.x86_64.dll" +windows.release.x86_64 = "res://gdextension/lib/bin/libpixelorama.windows.template_release.x86_64.dll" +linux.debug.x86_64 = "res://gdextension/lib/bin/libpixelorama_lib.linux.template_debug.x86_64.so" +linux.release.x86_64 = "res://gdextension/lib/bin/libpixelorama.linux.template_release.x86_64.so" +linux.debug.arm64 = "res://gdextension/lib/bin/libpixelorama.linux.template_debug.arm64.so" +linux.release.arm64 = "res://gdextension/lib/bin/libpixelorama.linux.template_release.arm64.so" +linux.debug.rv64 = "res://gdextension/lib/bin/libpixelorama.linux.template_debug.rv64.so" +linux.release.rv64 = "res://gdextension/lib/bin/libpixelorama.linux.template_release.rv64.so" +android.debug.x86_64 = "res://gdextension/lib/bin/libpixelorama.android.template_debug.x86_64.so" +android.release.x86_64 = "res://gdextension/lib/bin/libpixelorama.android.template_release.x86_64.so" +android.debug.arm64 = "res://gdextension/lib/bin/libpixelorama.android.template_debug.arm64.so" +android.release.arm64 = "res://gdextension/lib/bin/libpixelorama.android.template_release.arm64.so" + +[dependencies] +ios.debug = { + "res://gdextension/lib/bin/libgodot-cpp.ios.template_debug.xcframework": "" +} +ios.release = { + "res://gdextension/lib/bin/libgodot-cpp.ios.template_release.xcframework": "" +} \ No newline at end of file diff --git a/pixeloramalib.gdextension.uid b/pixeloramalib.gdextension.uid new file mode 100644 index 000000000000..0f2c2030cb86 --- /dev/null +++ b/pixeloramalib.gdextension.uid @@ -0,0 +1 @@ +uid://n1mcj5hu1b26 diff --git a/project.godot b/project.godot index 2869edfa2e3c..070620fae4d3 100644 --- a/project.godot +++ b/project.godot @@ -41,6 +41,7 @@ Palettes="*res://src/Autoload/Palettes.gd" Keychain="*res://addons/keychain/Keychain.gd" ExtensionsApi="*res://src/Autoload/ExtensionsApi.gd" Themes="*res://src/Autoload/Themes.gd" +DrawingAlgosCppAutoload="*res://src/Autoload/DrawingAlgosCppAutoload.gd" [debug] diff --git a/src/Autoload/DrawingAlgosCppAutoload.gd b/src/Autoload/DrawingAlgosCppAutoload.gd new file mode 100644 index 000000000000..834f180d964e --- /dev/null +++ b/src/Autoload/DrawingAlgosCppAutoload.gd @@ -0,0 +1,6 @@ +extends Node + +var algo : DrawingAlgosCpp + +func _ready() -> void: + algo = DrawingAlgosCpp.new() diff --git a/src/Autoload/DrawingAlgosCppAutoload.gd.uid b/src/Autoload/DrawingAlgosCppAutoload.gd.uid new file mode 100644 index 000000000000..52c20089dbc4 --- /dev/null +++ b/src/Autoload/DrawingAlgosCppAutoload.gd.uid @@ -0,0 +1 @@ +uid://dm0h5nxjxy5wt diff --git a/src/Tools/SelectionTools/EllipseSelect.gd b/src/Tools/SelectionTools/EllipseSelect.gd index 0b1ecda384bb..498d3e3e6709 100644 --- a/src/Tools/SelectionTools/EllipseSelect.gd +++ b/src/Tools/SelectionTools/EllipseSelect.gd @@ -52,7 +52,10 @@ func draw_preview() -> void: if !_move && _rect.has_area(): var temp_rect := _rect - var points := DrawingAlgos.get_ellipse_points(Vector2.ZERO, temp_rect.size) + var points_untyped := DrawingAlgosCppAutoload.algo.get_ellipse_points(Vector2.ZERO, temp_rect.size) + # necessary conversion from an untyped Array to a Vector2i Array as godot-cpp does not support that type + var points : Array[Vector2i] + points.assign(points_untyped) var image := Image.create( Global.current_project.size.x, Global.current_project.size.y, false, Image.FORMAT_LA8 )