From b895d3c3264dd52312e65af01e34ed04bbf86222 Mon Sep 17 00:00:00 2001 From: lupoDharkael Date: Wed, 22 May 2019 11:06:01 +0200 Subject: [PATCH] Add missing class methods --- include/core/Array.hpp | 13 ++++ include/core/Basis.hpp | 2 + include/core/Color.hpp | 24 ++++++ include/core/GodotGlobal.hpp | 1 + include/core/NodePath.hpp | 4 + include/core/Quat.hpp | 4 + include/core/String.hpp | 5 ++ src/core/Array.cpp | 29 +++++++ src/core/Basis.cpp | 9 +++ src/core/Color.cpp | 144 +++++++++++++++++++++++++++++++++++ src/core/GodotGlobal.cpp | 12 +++ src/core/NodePath.cpp | 9 +++ src/core/Quat.cpp | 19 +++++ src/core/String.cpp | 30 ++++++++ 14 files changed, 305 insertions(+) diff --git a/include/core/Array.hpp b/include/core/Array.hpp index 988d4c7e..9cb0c120 100644 --- a/include/core/Array.hpp +++ b/include/core/Array.hpp @@ -98,6 +98,19 @@ public: void sort_custom(Object *obj, const String &func); + int bsearch(const Variant &value, const bool before = true); + + int bsearch_custom(const Variant &value, const Object *obj, + const String &func, const bool before = true); + + Array duplicate(const bool deep = false) const; + + Variant max() const; + + Variant min() const; + + void shuffle(); + ~Array(); }; diff --git a/include/core/Basis.hpp b/include/core/Basis.hpp index 3ea9c5d7..24de0f09 100644 --- a/include/core/Basis.hpp +++ b/include/core/Basis.hpp @@ -59,6 +59,8 @@ public: Vector3 get_scale() const; + Basis slerp(Basis b, float t) const; + Vector3 get_euler_xyz() const; void set_euler_xyz(const Vector3 &p_euler); Vector3 get_euler_yxz() const; diff --git a/include/core/Color.hpp b/include/core/Color.hpp index 6d79cc1a..0f93a55d 100644 --- a/include/core/Color.hpp +++ b/include/core/Color.hpp @@ -32,8 +32,26 @@ public: uint32_t to_ARGB32() const; + uint32_t to_ABGR32() const; + + uint64_t to_ABGR64() const; + + uint64_t to_ARGB64() const; + + uint32_t to_RGBA32() const; + + uint64_t to_RGBA64() const; + float gray() const; + uint8_t get_r8() const; + + uint8_t get_g8() const; + + uint8_t get_b8() const; + + uint8_t get_a8() const; + float get_h() const; float get_s() const; @@ -42,6 +60,12 @@ public: void set_hsv(float p_h, float p_s, float p_v, float p_alpha = 1.0); + Color darkened(const float amount) const; + + Color lightened(const float amount) const; + + Color from_hsv(float p_h, float p_s, float p_v, float p_a = 1.0) const; + inline float &operator[](int idx) { return components[idx]; } diff --git a/include/core/GodotGlobal.hpp b/include/core/GodotGlobal.hpp index 71b3cf65..12f8801f 100644 --- a/include/core/GodotGlobal.hpp +++ b/include/core/GodotGlobal.hpp @@ -8,6 +8,7 @@ namespace godot { extern "C" const godot_gdnative_core_api_struct *api; +extern "C" const godot_gdnative_core_1_1_api_struct *core_1_1_api; extern "C" const godot_gdnative_ext_nativescript_api_struct *nativescript_api; extern "C" const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api; diff --git a/include/core/NodePath.hpp b/include/core/NodePath.hpp index aaa6727e..221c5ceb 100644 --- a/include/core/NodePath.hpp +++ b/include/core/NodePath.hpp @@ -31,6 +31,10 @@ public: bool is_empty() const; + NodePath get_as_property_path() const; + + String get_concatenated_subnames() const; + operator String() const; void operator=(const NodePath &other); diff --git a/include/core/Quat.hpp b/include/core/Quat.hpp index 314117d3..f0471784 100644 --- a/include/core/Quat.hpp +++ b/include/core/Quat.hpp @@ -20,6 +20,8 @@ public: Quat normalized() const; + bool is_normalized() const; + Quat inverse() const; void set_euler_xyz(const Vector3 &p_euler); @@ -40,6 +42,8 @@ public: void get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const; + void set_axis_angle(const Vector3 &axis, const float angle); + void operator*=(const Quat &q); Quat operator*(const Quat &q) const; diff --git a/include/core/String.hpp b/include/core/String.hpp index ff5d7234..d448567e 100644 --- a/include/core/String.hpp +++ b/include/core/String.hpp @@ -132,6 +132,11 @@ public: signed char casecmp_to(String p_str) const; signed char nocasecmp_to(String p_str) const; signed char naturalnocasecmp_to(String p_str) const; + String dedent() const; + PoolStringArray rsplit(const String &divisor, const bool allow_empty = true, const int maxsplit = 0) const; + String rstrip(const String &chars) const; + String trim_prefix(const String &prefix) const; + String trim_suffix(const String &suffix) const; }; String operator+(const char *a, const String &b); diff --git a/src/core/Array.cpp b/src/core/Array.cpp index 97372751..676eba5a 100644 --- a/src/core/Array.cpp +++ b/src/core/Array.cpp @@ -158,6 +158,35 @@ void Array::sort_custom(Object *obj, const String &func) { godot::api->godot_array_sort_custom(&_godot_array, (godot_object *)obj, (godot_string *)&func); } +int Array::bsearch(const Variant &value, const bool before) { + return godot::api->godot_array_bsearch(&_godot_array, (godot_variant *)&value, before); +} + +int Array::bsearch_custom(const Variant &value, const Object *obj, + const String &func, const bool before) { + return godot::api->godot_array_bsearch_custom(&_godot_array, (godot_variant *)&value, + (godot_object *)obj, (godot_string *)&func, before); +} + +Array Array::duplicate(const bool deep) const { + godot_array arr = godot::core_1_1_api->godot_array_duplicate(&_godot_array, deep); + return *(Array *)&arr; +} + +Variant Array::max() const { + godot_variant v = godot::core_1_1_api->godot_array_max(&_godot_array); + return *(Variant *)&v; +} + +Variant Array::min() const { + godot_variant v = godot::core_1_1_api->godot_array_min(&_godot_array); + return *(Variant *)&v; +} + +void Array::shuffle() { + godot::core_1_1_api->godot_array_shuffle(&_godot_array); +} + Array::~Array() { godot::api->godot_array_destroy(&_godot_array); } diff --git a/src/core/Basis.cpp b/src/core/Basis.cpp index 73d9cd58..f5bf90fe 100644 --- a/src/core/Basis.cpp +++ b/src/core/Basis.cpp @@ -158,6 +158,15 @@ Vector3 Basis::get_scale() const { Vector3(elements[0][2], elements[1][2], elements[2][2]).length()); } +// TODO: implement this directly without using quaternions to make it more efficient +Basis Basis::slerp(Basis b, float t) const { + ERR_FAIL_COND_V(!is_rotation(), Basis()); + ERR_FAIL_COND_V(!b.is_rotation(), Basis()); + Quat from(*this); + Quat to(b); + return Basis(from.slerp(to, t)); +} + // get_euler_xyz returns a vector containing the Euler angles in the format // (a1,a2,a3), where a3 is the angle of the first rotation, and a1 is the last // (following the convention they are commonly defined in the literature). diff --git a/src/core/Color.cpp b/src/core/Color.cpp index a8e66519..f6a061a0 100644 --- a/src/core/Color.cpp +++ b/src/core/Color.cpp @@ -67,10 +67,86 @@ uint32_t Color::to_ARGB32() const { return c; } +uint32_t Color::to_ABGR32() const { + uint32_t c = (uint8_t)(a * 255); + c <<= 8; + c |= (uint8_t)(b * 255); + c <<= 8; + c |= (uint8_t)(g * 255); + c <<= 8; + c |= (uint8_t)(r * 255); + + return c; +} + +uint64_t Color::to_ABGR64() const { + uint64_t c = (uint16_t)(a * 65535); + c <<= 16; + c |= (uint16_t)(b * 65535); + c <<= 16; + c |= (uint16_t)(g * 65535); + c <<= 16; + c |= (uint16_t)(r * 65535); + + return c; +} + +uint64_t Color::to_ARGB64() const { + uint64_t c = (uint16_t)(a * 65535); + c <<= 16; + c |= (uint16_t)(r * 65535); + c <<= 16; + c |= (uint16_t)(g * 65535); + c <<= 16; + c |= (uint16_t)(b * 65535); + + return c; +} + +uint32_t Color::to_RGBA32() const { + uint32_t c = (uint8_t)(r * 255); + c <<= 8; + c |= (uint8_t)(g * 255); + c <<= 8; + c |= (uint8_t)(b * 255); + c <<= 8; + c |= (uint8_t)(a * 255); + + return c; +} + +uint64_t Color::to_RGBA64() const { + uint64_t c = (uint16_t)(r * 65535); + c <<= 16; + c |= (uint16_t)(g * 65535); + c <<= 16; + c |= (uint16_t)(b * 65535); + c <<= 16; + c |= (uint16_t)(a * 65535); + + return c; +} + float Color::gray() const { return (r + g + b) / 3.0; } +uint8_t Color::get_r8() const { + return (uint8_t)(r * 255.0); +} + +uint8_t Color::get_g8() const { + return (uint8_t)(g * 255.0); +} + +uint8_t Color::get_b8() const { + return (uint8_t)(b * 255.0); +} + +uint8_t Color::get_a8() const { + return (uint8_t)(a * 255.0); +} + float Color::get_h() const { float min = MIN(r, g); @@ -167,6 +243,74 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) { } } +Color Color::darkened(const float p_amount) const { + Color res = *this; + res.r = res.r * (1.0f - p_amount); + res.g = res.g * (1.0f - p_amount); + res.b = res.b * (1.0f - p_amount); + return res; +} + +Color Color::lightened(const float p_amount) const { + Color res = *this; + res.r = res.r + (1.0f - res.r) * p_amount; + res.g = res.g + (1.0f - res.g) * p_amount; + res.b = res.b + (1.0f - res.b) * p_amount; + return res; +} + +Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const { + p_h = ::fmod(p_h * 360.0f, 360.0f); + if (p_h < 0.0) + p_h += 360.0f; + + const float h_ = p_h / 60.0f; + const float c = p_v * p_s; + const float x = c * (1.0f - ::fabs(::fmod(h_, 2.0f) - 1.0f)); + float r, g, b; + + switch ((int)h_) { + case 0: { + r = c; + g = x; + b = 0; + } break; + case 1: { + r = x; + g = c; + b = 0; + } break; + case 2: { + r = 0; + g = c; + b = x; + } break; + case 3: { + r = 0; + g = x; + b = c; + } break; + case 4: { + r = x; + g = 0; + b = c; + } break; + case 5: { + r = c; + g = 0; + b = x; + } break; + default: { + r = 0; + g = 0; + b = 0; + } break; + } + + const float m = p_v - c; + return Color(m + r, m + g, m + b, p_a); +} + void Color::invert() { r = 1.0 - r; g = 1.0 - g; diff --git a/src/core/GodotGlobal.cpp b/src/core/GodotGlobal.cpp index ba984a8e..3e00f19c 100644 --- a/src/core/GodotGlobal.cpp +++ b/src/core/GodotGlobal.cpp @@ -24,7 +24,10 @@ namespace godot { void *_RegisterState::nativescript_handle; int _RegisterState::language_index; + const godot_gdnative_core_api_struct *api = nullptr; +const godot_gdnative_core_1_1_api_struct *core_1_1_api = nullptr; + const godot_gdnative_ext_nativescript_api_struct *nativescript_api = nullptr; const godot_gdnative_ext_nativescript_1_1_api_struct *nativescript_1_1_api = nullptr; @@ -72,6 +75,15 @@ void Godot::gdnative_init(godot_gdnative_init_options *options) { godot::api = options->api_struct; godot::gdnlib = options->gd_native_library; + const godot_gdnative_api_struct *core_extension = godot::api->next; + + while (core_extension) { + if (core_extension->version.major == 1 && core_extension->version.minor == 1) { + godot::core_1_1_api = (const godot_gdnative_core_1_1_api_struct *)core_extension; + } + core_extension = core_extension->next; + } + // now find our extensions for (int i = 0; i < godot::api->num_extensions; i++) { switch (godot::api->extensions[i]->type) { diff --git a/src/core/NodePath.cpp b/src/core/NodePath.cpp index 021bf355..37ab2a3b 100644 --- a/src/core/NodePath.cpp +++ b/src/core/NodePath.cpp @@ -52,6 +52,15 @@ bool NodePath::is_empty() const { return godot::api->godot_node_path_is_empty(&_node_path); } +NodePath NodePath::get_as_property_path() const { + godot_node_path path = godot::core_1_1_api->godot_node_path_get_as_property_path(&_node_path); + return *(NodePath *)&path; +} +String NodePath::get_concatenated_subnames() const { + godot_string str = godot::api->godot_node_path_get_concatenated_subnames(&_node_path); + return *(String *)&str; +} + NodePath::operator String() const { godot_string str = godot::api->godot_node_path_as_string(&_node_path); diff --git a/src/core/Quat.cpp b/src/core/Quat.cpp index abfe0568..7837e412 100644 --- a/src/core/Quat.cpp +++ b/src/core/Quat.cpp @@ -89,6 +89,10 @@ Quat Quat::normalized() const { return *this / length(); } +bool Quat::is_normalized() const { + return std::abs(length_squared() - 1.0) < 0.00001; +} + Quat Quat::inverse() const { return Quat(-x, -y, -z, w); } @@ -171,6 +175,21 @@ void Quat::get_axis_and_angle(Vector3 &r_axis, real_t &r_angle) const { r_axis.z = z / ::sqrt(1 - w * w); } +void Quat::set_axis_angle(const Vector3 &axis, const float angle) { + ERR_FAIL_COND(!axis.is_normalized()); + + real_t d = axis.length(); + if (d == 0) + set(0, 0, 0, 0); + else { + real_t sin_angle = ::sin(angle * 0.5); + real_t cos_angle = ::cos(angle * 0.5); + real_t s = sin_angle / d; + set(axis.x * s, axis.y * s, axis.z * s, + cos_angle); + } +} + Quat Quat::operator*(const Vector3 &v) const { return Quat(w * v.x + y * v.z - z * v.y, w * v.y + z * v.x - x * v.z, diff --git a/src/core/String.cpp b/src/core/String.cpp index 35353220..91d9941b 100644 --- a/src/core/String.cpp +++ b/src/core/String.cpp @@ -555,4 +555,34 @@ signed char String::naturalnocasecmp_to(String p_str) const { return godot::api->godot_string_naturalnocasecmp_to(&_godot_string, &p_str._godot_string); } +String String::dedent() const { + String new_string; + new_string._godot_string = godot::core_1_1_api->godot_string_dedent(&_godot_string); + return new_string; +} + +PoolStringArray String::rsplit(const String &divisor, const bool allow_empty, + const int maxsplit) const { + godot_pool_string_array arr = godot::core_1_1_api->godot_string_rsplit(&_godot_string, &divisor._godot_string, allow_empty, maxsplit); + return *(PoolStringArray *)&arr; +} + +String String::rstrip(const String &chars) const { + String new_string; + new_string._godot_string = godot::core_1_1_api->godot_string_rstrip(&_godot_string, &chars._godot_string); + return new_string; +} + +String String::trim_prefix(const String &prefix) const { + String new_string; + new_string._godot_string = godot::core_1_1_api->godot_string_trim_prefix(&_godot_string, &prefix._godot_string); + return new_string; +} + +String String::trim_suffix(const String &suffix) const { + String new_string; + new_string._godot_string = godot::core_1_1_api->godot_string_trim_suffix(&_godot_string, &suffix._godot_string); + return new_string; +} + } // namespace godot