diff options
-rw-r--r-- | core/image.cpp | 170 | ||||
-rw-r--r-- | editor/editor_run.cpp | 17 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 2 | ||||
-rw-r--r-- | modules/gdnative/gdnative_api.json | 8 | ||||
-rw-r--r-- | modules/gdnative/include/nativescript/godot_nativescript.h | 2 | ||||
-rw-r--r-- | modules/gdnative/nativescript/godot_nativescript.cpp | 4 | ||||
-rw-r--r-- | modules/gdnative/nativescript/nativescript.cpp | 110 | ||||
-rw-r--r-- | modules/gdnative/nativescript/nativescript.h | 18 | ||||
-rw-r--r-- | modules/mono/glue/cs_files/Rect2.cs | 121 |
9 files changed, 357 insertions, 95 deletions
diff --git a/core/image.cpp b/core/image.cpp index e4573c5ebb..b1f0125b43 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -37,6 +37,7 @@ #include "print_string.h" #include "io/resource_loader.h" +#include "math_funcs.h" #include "thirdparty/misc/hq2x.h" #include <stdio.h> @@ -525,7 +526,7 @@ static double _bicubic_interp_kernel(double x) { return bc; } -template <int CC> +template <int CC, class T = uint8_t> static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) { // get source image size @@ -556,7 +557,7 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_ // initial pixel value - uint8_t *__restrict dst = p_dst + (y * p_dst_width + x) * CC; + T *__restrict dst = ((T *)p_dst) + (y * p_dst_width + x) * CC; double color[CC]; for (int i = 0; i < CC; i++) { @@ -584,23 +585,32 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_ ox2 = xmax; // get pixel of original image - const uint8_t *__restrict p = p_src + (oy2 * p_src_width + ox2) * CC; + const T *__restrict p = ((T *)p_src) + (oy2 * p_src_width + ox2) * CC; for (int i = 0; i < CC; i++) { - - color[i] += p[i] * k2; + if (sizeof(T) == 2) { //half float + color[i] = Math::half_to_float(p[i]); + } else { + color[i] += p[i] * k2; + } } } } for (int i = 0; i < CC; i++) { - dst[i] = CLAMP(Math::fast_ftoi(color[i]), 0, 255); + if (sizeof(T) == 1) { //byte + dst[i] = CLAMP(Math::fast_ftoi(color[i]), 0, 255); + } else if (sizeof(T) == 2) { //half float + dst[i] = Math::make_half_float(color[i]); + } else { + dst[i] = color[i]; + } } } } } -template <int CC> +template <int CC, class T = uint8_t> static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) { enum { @@ -640,22 +650,58 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict for (uint32_t l = 0; l < CC; l++) { - uint32_t p00 = p_src[y_ofs_up + src_xofs_left + l] << FRAC_BITS; - uint32_t p10 = p_src[y_ofs_up + src_xofs_right + l] << FRAC_BITS; - uint32_t p01 = p_src[y_ofs_down + src_xofs_left + l] << FRAC_BITS; - uint32_t p11 = p_src[y_ofs_down + src_xofs_right + l] << FRAC_BITS; - - uint32_t interp_up = p00 + (((p10 - p00) * src_xofs_frac) >> FRAC_BITS); - uint32_t interp_down = p01 + (((p11 - p01) * src_xofs_frac) >> FRAC_BITS); - uint32_t interp = interp_up + (((interp_down - interp_up) * src_yofs_frac) >> FRAC_BITS); - interp >>= FRAC_BITS; - p_dst[i * p_dst_width * CC + j * CC + l] = interp; + if (sizeof(T) == 1) { //uint8 + uint32_t p00 = p_src[y_ofs_up + src_xofs_left + l] << FRAC_BITS; + uint32_t p10 = p_src[y_ofs_up + src_xofs_right + l] << FRAC_BITS; + uint32_t p01 = p_src[y_ofs_down + src_xofs_left + l] << FRAC_BITS; + uint32_t p11 = p_src[y_ofs_down + src_xofs_right + l] << FRAC_BITS; + + uint32_t interp_up = p00 + (((p10 - p00) * src_xofs_frac) >> FRAC_BITS); + uint32_t interp_down = p01 + (((p11 - p01) * src_xofs_frac) >> FRAC_BITS); + uint32_t interp = interp_up + (((interp_down - interp_up) * src_yofs_frac) >> FRAC_BITS); + interp >>= FRAC_BITS; + p_dst[i * p_dst_width * CC + j * CC + l] = interp; + } else if (sizeof(T) == 2) { //half float + + float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS); + float yofs_frac = float(src_yofs_frac) / (1 << FRAC_BITS); + const T *src = ((const T *)p_src); + T *dst = ((T *)p_dst); + + float p00 = Math::half_to_float(src[y_ofs_up + src_xofs_left + l]); + float p10 = Math::half_to_float(src[y_ofs_up + src_xofs_right + l]); + float p01 = Math::half_to_float(src[y_ofs_down + src_xofs_left + l]); + float p11 = Math::half_to_float(src[y_ofs_down + src_xofs_right + l]); + + float interp_up = p00 + (p10 - p00) * xofs_frac; + float interp_down = p01 + (p11 - p01) * xofs_frac; + float interp = interp_up + ((interp_down - interp_up) * yofs_frac); + + dst[i * p_dst_width * CC + j * CC + l] = Math::make_half_float(interp); + } else if (sizeof(T) == 4) { //float + + float xofs_frac = float(src_xofs_frac) / (1 << FRAC_BITS); + float yofs_frac = float(src_yofs_frac) / (1 << FRAC_BITS); + const T *src = ((const T *)p_src); + T *dst = ((T *)p_dst); + + float p00 = src[y_ofs_up + src_xofs_left + l]; + float p10 = src[y_ofs_up + src_xofs_right + l]; + float p01 = src[y_ofs_down + src_xofs_left + l]; + float p11 = src[y_ofs_down + src_xofs_right + l]; + + float interp_up = p00 + (p10 - p00) * xofs_frac; + float interp_down = p01 + (p11 - p01) * xofs_frac; + float interp = interp_up + ((interp_down - interp_up) * yofs_frac); + + dst[i * p_dst_width * CC + j * CC + l] = interp; + } } } } } -template <int CC> +template <int CC, class T = uint8_t> static void _scale_nearest(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) { for (uint32_t i = 0; i < p_dst_height; i++) { @@ -670,8 +716,11 @@ static void _scale_nearest(const uint8_t *__restrict p_src, uint8_t *__restrict for (uint32_t l = 0; l < CC; l++) { - uint32_t p = p_src[y_ofs + src_xofs + l]; - p_dst[i * p_dst_width * CC + j * CC + l] = p; + const T *src = ((const T *)p_src); + T *dst = ((T *)p_dst); + + T p = src[y_ofs + src_xofs + l]; + dst[i * p_dst_width * CC + j * CC + l] = p; } } } @@ -766,12 +815,30 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { case INTERPOLATE_NEAREST: { - switch (get_format_pixel_size(format)) { - case 1: _scale_nearest<1>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 2: _scale_nearest<2>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 3: _scale_nearest<3>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 4: _scale_nearest<4>(r_ptr, w_ptr, width, height, p_width, p_height); break; + if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) { + switch (get_format_pixel_size(format)) { + case 1: _scale_nearest<1>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 2: _scale_nearest<2>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 3: _scale_nearest<3>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_nearest<4>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + } else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) { + switch (get_format_pixel_size(format)) { + case 4: _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 12: _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 16: _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + + } else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) { + switch (get_format_pixel_size(format)) { + case 2: _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 6: _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } } + } break; case INTERPOLATE_BILINEAR: case INTERPOLATE_TRILINEAR: { @@ -812,11 +879,27 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } } - switch (get_format_pixel_size(format)) { - case 1: _scale_bilinear<1>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; - case 2: _scale_bilinear<2>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; - case 3: _scale_bilinear<3>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; - case 4: _scale_bilinear<4>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) { + switch (get_format_pixel_size(format)) { + case 1: _scale_bilinear<1>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 2: _scale_bilinear<2>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 3: _scale_bilinear<3>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 4: _scale_bilinear<4>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + } + } else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) { + switch (get_format_pixel_size(format)) { + case 4: _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 8: _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 12: _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 16: _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + } + } else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) { + switch (get_format_pixel_size(format)) { + case 2: _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 4: _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 6: _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + case 8: _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break; + } } } @@ -829,13 +912,28 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } break; case INTERPOLATE_CUBIC: { - switch (get_format_pixel_size(format)) { - case 1: _scale_cubic<1>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 2: _scale_cubic<2>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 3: _scale_cubic<3>(r_ptr, w_ptr, width, height, p_width, p_height); break; - case 4: _scale_cubic<4>(r_ptr, w_ptr, width, height, p_width, p_height); break; + if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) { + switch (get_format_pixel_size(format)) { + case 1: _scale_cubic<1>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 2: _scale_cubic<2>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 3: _scale_cubic<3>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_cubic<4>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + } else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) { + switch (get_format_pixel_size(format)) { + case 4: _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 12: _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 16: _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } + } else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) { + switch (get_format_pixel_size(format)) { + case 2: _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 4: _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 6: _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + case 8: _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break; + } } - } break; } diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 072bd948e1..bbd18306a2 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -68,9 +68,24 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li int screen = EditorSettings::get_singleton()->get("run/window_placement/screen"); if (screen == 0) { + // Same as editor screen = OS::get_singleton()->get_current_screen(); + } else if (screen == 1) { + // Previous monitor (wrap to the other end if needed) + screen = Math::wrapi( + OS::get_singleton()->get_current_screen() - 1, + 0, + OS::get_singleton()->get_screen_count()); + } else if (screen == 2) { + // Next monitor (wrap to the other end if needed) + screen = Math::wrapi( + OS::get_singleton()->get_current_screen() + 1, + 0, + OS::get_singleton()->get_screen_count()); } else { - screen--; + // Fixed monitor ID + // There are 3 special options, so decrement the option ID by 3 to get the monitor ID + screen -= 3; } if (OS::get_singleton()->is_disable_crash_handler()) { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 85186440ab..9278d7676a 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -494,7 +494,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("run/window_placement/rect", 1); hints["run/window_placement/rect"] = PropertyInfo(Variant::INT, "run/window_placement/rect", PROPERTY_HINT_ENUM, "Top Left,Centered,Custom Position,Force Maximized,Force Fullscreen"); - String screen_hints = TTR("Default (Same as Editor)"); + String screen_hints = "Same as Editor,Previous Monitor,Next Monitor"; for (int i = 0; i < OS::get_singleton()->get_screen_count(); i++) { screen_hints += ",Monitor " + itos(i + 1); } diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 217fd87c3e..e326d11a84 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -5876,6 +5876,14 @@ ["int", "p_idx"], ["godot_object *", "p_object"] ] + }, + { + "name": "godot_nativescript_profiling_add_data", + "return_type": "void", + "arguments": [ + ["const char *", "p_signature"], + ["uint64_t", "p_line"] + ] } ] }, diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index 1c5422d723..29bd9eec5a 100644 --- a/modules/gdnative/include/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -238,6 +238,8 @@ void GDAPI godot_nativescript_unregister_instance_binding_data_functions(int p_i void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object *p_object); +void GDAPI godot_nativescript_profiling_add_data(const char *p_signature, uint64_t p_time); + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index ace2ecac5c..72606c8340 100644 --- a/modules/gdnative/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -365,6 +365,10 @@ void GDAPI *godot_nativescript_get_instance_binding_data(int p_idx, godot_object return NativeScriptLanguage::get_singleton()->get_instance_binding_data(p_idx, (Object *)p_object); } +void GDAPI godot_nativescript_profiling_add_data(const char *p_signature, uint64_t p_time) { + NativeScriptLanguage::get_singleton()->profiling_add_data(StringName(p_signature), p_time); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index 24264c4256..608c7aa4a5 100644 --- a/modules/gdnative/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -1010,6 +1010,10 @@ NativeScriptLanguage::NativeScriptLanguage() { has_objects_to_register = false; mutex = Mutex::create(); #endif + +#ifdef DEBUG_ENABLED + profiling = false; +#endif } NativeScriptLanguage::~NativeScriptLanguage() { @@ -1152,17 +1156,105 @@ void NativeScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_ } void NativeScriptLanguage::profiling_start() { +#ifdef DEBUG_ENABLED +#ifndef NO_THREADS + MutexLock lock(mutex); +#endif + + profile_data.clear(); + profiling = true; +#endif } void NativeScriptLanguage::profiling_stop() { +#ifdef DEBUG_ENABLED +#ifndef NO_THREADS + MutexLock lock(mutex); +#endif + + profiling = false; +#endif } int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) { +#ifdef DEBUG_ENABLED +#ifndef NO_THREADS + MutexLock lock(mutex); +#endif + int current = 0; + + for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { + if (current >= p_info_max) + break; + + p_info_arr[current].call_count = d->get().call_count; + p_info_arr[current].self_time = d->get().self_time; + p_info_arr[current].total_time = d->get().total_time; + p_info_arr[current].signature = d->get().signature; + current++; + } + + return current; +#else return 0; +#endif } int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) { +#ifdef DEBUG_ENABLED +#ifndef NO_THREADS + MutexLock lock(mutex); +#endif + int current = 0; + + for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { + if (current >= p_info_max) + break; + + if (d->get().last_frame_call_count) { + p_info_arr[current].call_count = d->get().last_frame_call_count; + p_info_arr[current].self_time = d->get().last_frame_self_time; + p_info_arr[current].total_time = d->get().last_frame_total_time; + p_info_arr[current].signature = d->get().signature; + current++; + } + } + + return current; +#else return 0; +#endif +} + +void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p_time) { +#ifdef DEBUG_ENABLED +#ifndef NO_THREADS + MutexLock lock(mutex); +#endif + + Map<StringName, ProfileData>::Element *d = profile_data.find(p_signature); + if (d) { + d->get().call_count += 1; + d->get().total_time += p_time; + d->get().frame_call_count += 1; + d->get().frame_total_time += p_time; + } else { + ProfileData data; + + data.signature = p_signature; + data.call_count = 1; + data.self_time = 0; + data.total_time = p_time; + data.frame_call_count = 1; + data.frame_self_time = 0; + data.frame_total_time = p_time; + data.last_frame_call_count = 0; + data.last_frame_self_time = 0; + data.last_frame_total_time = 0; + + profile_data.insert(p_signature, data); + } +#endif } int NativeScriptLanguage::register_binding_functions(godot_instance_binding_functions p_binding_functions) { @@ -1405,6 +1497,24 @@ void NativeScriptLanguage::frame() { has_objects_to_register = false; } #endif + +#ifdef DEBUG_ENABLED + { +#ifndef NO_THREADS + MutexLock lock(mutex); +#endif + + for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) { + d->get().last_frame_call_count = d->get().frame_call_count; + d->get().last_frame_self_time = d->get().frame_self_time; + d->get().last_frame_total_time = d->get().frame_total_time; + d->get().frame_call_count = 0; + d->get().frame_self_time = 0; + d->get().frame_total_time = 0; + } + } +#endif + call_libraries_cb(_frame_call_name); } diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index c1f11646b0..6f18e2db27 100644 --- a/modules/gdnative/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -254,6 +254,22 @@ private: Map<int, HashMap<StringName, const void *> > global_type_tags; + struct ProfileData { + StringName signature; + uint64_t call_count; + uint64_t self_time; + uint64_t total_time; + uint64_t frame_call_count; + uint64_t frame_self_time; + uint64_t frame_total_time; + uint64_t last_frame_call_count; + uint64_t last_frame_self_time; + uint64_t last_frame_total_time; + }; + + Map<StringName, ProfileData> profile_data; + bool profiling; + public: // These two maps must only be touched on the main thread Map<String, Map<StringName, NativeScriptDesc> > library_classes; @@ -343,6 +359,8 @@ public: virtual bool handles_global_class_type(const String &p_type) const; virtual String get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const; + + void profiling_add_data(StringName p_signature, uint64_t p_time); }; inline NativeScriptDesc *NativeScript::get_script_desc() const { diff --git a/modules/mono/glue/cs_files/Rect2.cs b/modules/mono/glue/cs_files/Rect2.cs index 6f16656573..e772665009 100644 --- a/modules/mono/glue/cs_files/Rect2.cs +++ b/modules/mono/glue/cs_files/Rect2.cs @@ -11,24 +11,24 @@ namespace Godot [StructLayout(LayoutKind.Sequential)] public struct Rect2 : IEquatable<Rect2> { - private Vector2 position; - private Vector2 size; + private Vector2 _position; + private Vector2 _size; public Vector2 Position { - get { return position; } - set { position = value; } + get { return _position; } + set { _position = value; } } public Vector2 Size { - get { return size; } - set { size = value; } + get { return _size; } + set { _size = value; } } public Vector2 End { - get { return position + size; } + get { return _position + _size; } } public real_t Area @@ -36,6 +36,13 @@ namespace Godot get { return GetArea(); } } + public Rect2 Abs() + { + Vector2 end = End; + Vector2 topLeft = new Vector2(Mathf.Min(_position.x, end.x), Mathf.Min(_position.y, end.y)); + return new Rect2(topLeft, _size.Abs()); + } + public Rect2 Clip(Rect2 b) { var newRect = b; @@ -43,31 +50,31 @@ namespace Godot if (!Intersects(newRect)) return new Rect2(); - newRect.position.x = Mathf.Max(b.position.x, position.x); - newRect.position.y = Mathf.Max(b.position.y, position.y); + newRect._position.x = Mathf.Max(b._position.x, _position.x); + newRect._position.y = Mathf.Max(b._position.y, _position.y); - Vector2 bEnd = b.position + b.size; - Vector2 end = position + size; + Vector2 bEnd = b._position + b._size; + Vector2 end = _position + _size; - newRect.size.x = Mathf.Min(bEnd.x, end.x) - newRect.position.x; - newRect.size.y = Mathf.Min(bEnd.y, end.y) - newRect.position.y; + newRect._size.x = Mathf.Min(bEnd.x, end.x) - newRect._position.x; + newRect._size.y = Mathf.Min(bEnd.y, end.y) - newRect._position.y; return newRect; } public bool Encloses(Rect2 b) { - return b.position.x >= position.x && b.position.y >= position.y && - b.position.x + b.size.x < position.x + size.x && - b.position.y + b.size.y < position.y + size.y; + return b._position.x >= _position.x && b._position.y >= _position.y && + b._position.x + b._size.x < _position.x + _size.x && + b._position.y + b._size.y < _position.y + _size.y; } public Rect2 Expand(Vector2 to) { var expanded = this; - Vector2 begin = expanded.position; - Vector2 end = expanded.position + expanded.size; + Vector2 begin = expanded._position; + Vector2 end = expanded._position + expanded._size; if (to.x < begin.x) begin.x = to.x; @@ -79,25 +86,25 @@ namespace Godot if (to.y > end.y) end.y = to.y; - expanded.position = begin; - expanded.size = end - begin; + expanded._position = begin; + expanded._size = end - begin; return expanded; } public real_t GetArea() { - return size.x * size.y; + return _size.x * _size.y; } public Rect2 Grow(real_t by) { var g = this; - g.position.x -= by; - g.position.y -= by; - g.size.x += by * 2; - g.size.y += by * 2; + g._position.x -= by; + g._position.y -= by; + g._size.x += by * 2; + g._size.y += by * 2; return g; } @@ -106,10 +113,10 @@ namespace Godot { var g = this; - g.position.x -= left; - g.position.y -= top; - g.size.x += left + right; - g.size.y += top + bottom; + g._position.x -= left; + g._position.y -= top; + g._size.x += left + right; + g._size.y += top + bottom; return g; } @@ -128,19 +135,19 @@ namespace Godot public bool HasNoArea() { - return size.x <= 0 || size.y <= 0; + return _size.x <= 0 || _size.y <= 0; } public bool HasPoint(Vector2 point) { - if (point.x < position.x) + if (point.x < _position.x) return false; - if (point.y < position.y) + if (point.y < _position.y) return false; - if (point.x >= position.x + size.x) + if (point.x >= _position.x + _size.x) return false; - if (point.y >= position.y + size.y) + if (point.y >= _position.y + _size.y) return false; return true; @@ -148,13 +155,13 @@ namespace Godot public bool Intersects(Rect2 b) { - if (position.x > b.position.x + b.size.x) + if (_position.x > b._position.x + b._size.x) return false; - if (position.x + size.x < b.position.x) + if (_position.x + _size.x < b._position.x) return false; - if (position.y > b.position.y + b.size.y) + if (_position.y > b._position.y + b._size.y) return false; - if (position.y + size.y < b.position.y) + if (_position.y + _size.y < b._position.y) return false; return true; @@ -164,13 +171,13 @@ namespace Godot { Rect2 newRect; - newRect.position.x = Mathf.Min(b.position.x, position.x); - newRect.position.y = Mathf.Min(b.position.y, position.y); + newRect._position.x = Mathf.Min(b._position.x, _position.x); + newRect._position.y = Mathf.Min(b._position.y, _position.y); - newRect.size.x = Mathf.Max(b.position.x + b.size.x, position.x + size.x); - newRect.size.y = Mathf.Max(b.position.y + b.size.y, position.y + size.y); + newRect._size.x = Mathf.Max(b._position.x + b._size.x, _position.x + _size.x); + newRect._size.y = Mathf.Max(b._position.y + b._size.y, _position.y + _size.y); - newRect.size = newRect.size - newRect.position; // Make relative again + newRect._size = newRect._size - newRect._position; // Make relative again return newRect; } @@ -178,23 +185,23 @@ namespace Godot // Constructors public Rect2(Vector2 position, Vector2 size) { - this.position = position; - this.size = size; + _position = position; + _size = size; } public Rect2(Vector2 position, real_t width, real_t height) { - this.position = position; - size = new Vector2(width, height); + _position = position; + _size = new Vector2(width, height); } public Rect2(real_t x, real_t y, Vector2 size) { - position = new Vector2(x, y); - this.size = size; + _position = new Vector2(x, y); + _size = size; } public Rect2(real_t x, real_t y, real_t width, real_t height) { - position = new Vector2(x, y); - size = new Vector2(width, height); + _position = new Vector2(x, y); + _size = new Vector2(width, height); } public static bool operator ==(Rect2 left, Rect2 right) @@ -219,20 +226,20 @@ namespace Godot public bool Equals(Rect2 other) { - return position.Equals(other.position) && size.Equals(other.size); + return _position.Equals(other._position) && _size.Equals(other._size); } public override int GetHashCode() { - return position.GetHashCode() ^ size.GetHashCode(); + return _position.GetHashCode() ^ _size.GetHashCode(); } public override string ToString() { return String.Format("({0}, {1})", new object[] { - position.ToString(), - size.ToString() + _position.ToString(), + _size.ToString() }); } @@ -240,8 +247,8 @@ namespace Godot { return String.Format("({0}, {1})", new object[] { - position.ToString(format), - size.ToString(format) + _position.ToString(format), + _size.ToString(format) }); } } |