diff options
Diffstat (limited to 'core')
68 files changed, 1493 insertions, 628 deletions
diff --git a/core/SCsub b/core/SCsub index fd3f57dd7c..02abaa2bb6 100644 --- a/core/SCsub +++ b/core/SCsub @@ -18,7 +18,7 @@ gd_cpp = '#include "global_config.h"\n' gd_cpp += gd_inc gd_cpp += "void GlobalConfig::register_global_defaults() {\n" + gd_call + "\n}\n" -f = open("global_defaults.cpp", "wb") +f = open("global_defaults.gen.cpp", "wb") f.write(gd_cpp) f.close() @@ -47,7 +47,7 @@ if ("SCRIPT_AES256_ENCRYPTION_KEY" in os.environ): txt = "0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0" print("Invalid AES256 encryption key, not 64 bits hex: " + e) -f = open("script_encryption_key.cpp", "wb") +f = open("script_encryption_key.gen.cpp", "wb") f.write("#include \"global_config.h\"\nuint8_t script_encryption_key[32]={" + txt + "};\n") f.close() @@ -83,6 +83,25 @@ thirdparty_minizip_sources = [ thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources] env.add_source_files(env.core_sources, thirdparty_minizip_sources) +thirdparty_zstd_dir = "#thirdparty/zstd/" +thirdparty_zstd_sources = [ + "common/entropy_common.c", + "common/error_private.c", + "common/fse_decompress.c", + "common/pool.c", + "common/threading.c", + "common/xxhash.c", + "common/zstd_common.c", + "compress/fse_compress.c", + "compress/huf_compress.c", + "compress/zstd_compress.c", + "compress/zstdmt_compress.c", + "decompress/huf_decompress.c", + "decompress/zstd_decompress.c", +] +thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] +env.add_source_files(env.core_sources, thirdparty_zstd_sources) + # Godot's own sources env.add_source_files(env.core_sources, "*.cpp") @@ -90,7 +109,7 @@ env.add_source_files(env.core_sources, "*.cpp") # Make binders import make_binders -env.Command(['method_bind.inc', 'method_bind_ext.inc'], 'make_binders.py', make_binders.run) +env.Command(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', make_binders.run) # Chain load SCsubs @@ -104,5 +123,5 @@ SConscript('helper/SCsub') # Build it all as a library lib = env.Library("core", env.core_sources) env.Prepend(LIBS=[lib]) - +env.Append(CPPPATH=["#thirdparty/zstd", "#thirdparty/zstd/common"]) Export('env') diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 2752391901..095f058ed9 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -31,6 +31,7 @@ #include "core/global_config.h" #include "geometry.h" +#include "io/file_access_compressed.h" #include "io/file_access_encrypted.h" #include "io/marshalls.h" #include "os/keyboard.h" @@ -1395,6 +1396,24 @@ Error _File::open_encrypted_pass(const String &p_path, int p_mode_flags, const S return OK; } +Error _File::open_compressed(const String &p_path, int p_mode_flags, int p_compress_mode) { + + FileAccessCompressed *fac = memnew(FileAccessCompressed); + Error err = OK; + + fac->configure("GCPF", (Compression::Mode)p_compress_mode); + + err = fac->_open(p_path, p_mode_flags); + + if (err) { + memdelete(fac); + return err; + } + + f = fac; + return OK; +} + Error _File::open(const String &p_path, int p_mode_flags) { close(); @@ -1700,6 +1719,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("open_encrypted", "path", "mode_flags", "key"), &_File::open_encrypted); ClassDB::bind_method(D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &_File::open_encrypted_pass); + ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &_File::open_compressed, DEFVAL(0)); ClassDB::bind_method(D_METHOD("open", "path", "flags"), &_File::open); ClassDB::bind_method(D_METHOD("close"), &_File::close); @@ -1749,6 +1769,10 @@ void _File::_bind_methods() { BIND_CONSTANT(WRITE); BIND_CONSTANT(READ_WRITE); BIND_CONSTANT(WRITE_READ); + + BIND_CONSTANT(COMPRESSION_FASTLZ); + BIND_CONSTANT(COMPRESSION_DEFLATE); + BIND_CONSTANT(COMPRESSION_ZSTD); } _File::_File() { @@ -2532,6 +2556,10 @@ Dictionary _Engine::get_version_info() const { return Engine::get_singleton()->get_version_info(); } +bool _Engine::is_in_fixed_frame() const { + return Engine::get_singleton()->is_in_fixed_frame(); +} + void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_iterations_per_second", "iterations_per_second"), &_Engine::set_iterations_per_second); @@ -2550,6 +2578,8 @@ void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("get_main_loop:MainLoop"), &_Engine::get_main_loop); ClassDB::bind_method(D_METHOD("get_version_info"), &_Engine::get_version_info); + + ClassDB::bind_method(D_METHOD("is_in_fixed_frame"), &_Engine::is_in_fixed_frame); } _Engine *_Engine::singleton = NULL; diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index e48b5c85ad..87d84c0732 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -31,6 +31,7 @@ #define CORE_BIND_H #include "image.h" +#include "io/compression.h" #include "io/resource_loader.h" #include "io/resource_saver.h" #include "os/dir_access.h" @@ -366,8 +367,15 @@ public: WRITE_READ = 7, }; + enum CompressionMode { + COMPRESSION_FASTLZ = Compression::MODE_FASTLZ, + COMPRESSION_DEFLATE = Compression::MODE_DEFLATE, + COMPRESSION_ZSTD = Compression::MODE_ZSTD + }; + Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key); Error open_encrypted_pass(const String &p_path, int p_mode_flags, const String &p_pass); + Error open_compressed(const String &p_path, int p_mode_flags, int p_compress_mode = 0); Error open(const String &p_path, int p_mode_flags); ///< open a file void close(); ///< close a file @@ -634,6 +642,8 @@ public: Dictionary get_version_info() const; + bool is_in_fixed_frame() const; + _Engine(); }; diff --git a/core/class_db.cpp b/core/class_db.cpp index 1fe02c8cd9..6b8c290a99 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -497,7 +497,7 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit } } -void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance) { +void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { OBJTYPE_RLOCK; @@ -528,6 +528,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b minfo.name = E->get(); minfo.id = method->get_method_id(); + if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) + continue; + for (int i = 0; i < method->get_argument_count(); i++) { //Variant::Type t=method->get_argument_type(i); @@ -802,7 +805,14 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons OBJTYPE_WLOCK type->property_list.push_back(p_pinfo); - +#ifdef DEBUG_METHODS_ENABLED + if (mb_get) { + type->methods_in_properties.insert(p_getter); + } + if (mb_set) { + type->methods_in_properties.insert(p_setter); + } +#endif PropertySetGet psg; psg.setter = p_setter; psg.getter = p_getter; diff --git a/core/class_db.h b/core/class_db.h index 547068da5f..4f00a16e91 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -139,6 +139,7 @@ public: #ifdef DEBUG_METHODS_ENABLED List<StringName> constant_order; List<StringName> method_order; + Set<StringName> methods_in_properties; List<MethodInfo> virtual_methods; StringName category; #endif @@ -486,7 +487,7 @@ public: static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false); static void set_method_flags(StringName p_class, StringName p_method, int p_flags); - static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false); + static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false); static MethodBind *get_method(StringName p_class, StringName p_name); static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true); diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index bae8cf7fca..2e0c478108 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -170,6 +170,63 @@ class CommandQueueMT { virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); } }; + template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> + struct Command9 : public CommandBase { + + T *instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + typename GetSimpleTypeT<P9>::type_t p9; + + virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9); } + }; + + template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10> + struct Command10 : public CommandBase { + + T *instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + typename GetSimpleTypeT<P9>::type_t p9; + typename GetSimpleTypeT<P10>::type_t p10; + + virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } + }; + + template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11> + struct Command11 : public CommandBase { + + T *instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + typename GetSimpleTypeT<P9>::type_t p9; + typename GetSimpleTypeT<P10>::type_t p10; + typename GetSimpleTypeT<P11>::type_t p11; + + virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } + }; + /* comands that return */ template <class T, class M, class R> @@ -779,6 +836,76 @@ public: if (sync) sync->post(); } + + template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> + void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) { + + Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> *cmd = allocate_and_lock<Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> >(); + + cmd->instance = p_instance; + cmd->method = p_method; + cmd->p1 = p1; + cmd->p2 = p2; + cmd->p3 = p3; + cmd->p4 = p4; + cmd->p5 = p5; + cmd->p6 = p6; + cmd->p7 = p7; + cmd->p8 = p8; + cmd->p9 = p9; + + unlock(); + + if (sync) sync->post(); + } + + template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10> + void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) { + + Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> *cmd = allocate_and_lock<Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >(); + + cmd->instance = p_instance; + cmd->method = p_method; + cmd->p1 = p1; + cmd->p2 = p2; + cmd->p3 = p3; + cmd->p4 = p4; + cmd->p5 = p5; + cmd->p6 = p6; + cmd->p7 = p7; + cmd->p8 = p8; + cmd->p9 = p9; + cmd->p10 = p10; + + unlock(); + + if (sync) sync->post(); + } + + template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11> + void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) { + + Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> *cmd = allocate_and_lock<Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >(); + + cmd->instance = p_instance; + cmd->method = p_method; + cmd->p1 = p1; + cmd->p2 = p2; + cmd->p3 = p3; + cmd->p4 = p4; + cmd->p5 = p5; + cmd->p6 = p6; + cmd->p7 = p7; + cmd->p8 = p8; + cmd->p9 = p9; + cmd->p10 = p10; + cmd->p11 = p11; + + unlock(); + + if (sync) sync->post(); + } + /*** PUSH AND RET COMMANDS ***/ template <class T, class M, class R> diff --git a/core/core_string_names.cpp b/core/core_string_names.cpp index e35ac2b72c..0ed44b0cb7 100644 --- a/core/core_string_names.cpp +++ b/core/core_string_names.cpp @@ -44,4 +44,7 @@ CoreStringNames::CoreStringNames() { _iter_next = StaticCString::create("_iter_next"); _iter_get = StaticCString::create("_iter_get"); get_rid = StaticCString::create("get_rid"); +#ifdef TOOLS_ENABLED + _sections_unfolded = StaticCString::create("_sections_unfolded"); +#endif } diff --git a/core/core_string_names.h b/core/core_string_names.h index 6672772432..4b4f87a8f0 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -61,6 +61,9 @@ public: StringName _iter_next; StringName _iter_get; StringName get_rid; +#ifdef TOOLS_ENABLED + StringName _sections_unfolded; +#endif }; #endif // SCENE_STRING_NAMES_H diff --git a/core/dvector.h b/core/dvector.h index 2e951b9661..66af42f7e2 100644 --- a/core/dvector.h +++ b/core/dvector.h @@ -92,6 +92,7 @@ class PoolVector { // ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all + // Refcount should not be zero, otherwise it's a misuse of COW if (alloc->refcount.get() == 1) return; //nothing to do @@ -216,7 +217,12 @@ class PoolVector { { int cur_elements = alloc->size / sizeof(T); - Write w = write(); + + // Don't use write() here because it could otherwise provoke COW, + // which is not desirable here because we are destroying the last reference anyways + Write w; + // Reference to still prevent other threads from touching the alloc + w._ref(alloc); for (int i = 0; i < cur_elements; i++) { @@ -403,14 +409,9 @@ public: if (p_to < 0) { p_to = size() + p_to; } - if (p_from < 0 || p_from >= size()) { - PoolVector<T> &aux = *((PoolVector<T> *)0); // nullreturn - ERR_FAIL_COND_V(p_from < 0 || p_from >= size(), aux) - } - if (p_to < 0 || p_to >= size()) { - PoolVector<T> &aux = *((PoolVector<T> *)0); // nullreturn - ERR_FAIL_COND_V(p_to < 0 || p_to >= size(), aux) - } + + CRASH_BAD_INDEX(p_from, size()); + CRASH_BAD_INDEX(p_to, size()); PoolVector<T> slice; int span = 1 + p_to - p_from; @@ -500,13 +501,9 @@ void PoolVector<T>::push_back(const T &p_val) { template <class T> const T PoolVector<T>::operator[](int p_index) const { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); Read r = read(); - return r[p_index]; } diff --git a/core/error_macros.h b/core/error_macros.h index 00fced3586..6c803951a1 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -115,6 +115,19 @@ extern bool _err_error_exists; #define FUNCTION_STR __FUNCTION__ #endif +// Don't use this directly; instead, use any of the CRASH_* macros +#ifdef _MSC_VER +#define GENERATE_TRAP \ + __debugbreak(); \ + /* Avoid warning about control paths */ \ + for (;;) { \ + } +#else +#define GENERATE_TRAP __builtin_trap(); +#endif + +// (*): See https://stackoverflow.com/questions/257418/do-while-0-what-is-it-good-for + #define ERR_FAIL_INDEX(m_index, m_size) \ do { \ if ((m_index) < 0 || (m_index) >= (m_size)) { \ @@ -122,12 +135,12 @@ extern bool _err_error_exists; return; \ } else \ _err_error_exists = false; \ - } while (0); + } while (0); // (*) /** An index has failed if m_index<0 or m_index >=m_size, the function exists. - * This function returns an error value, if returning Error, please select the most - * appropriate error condition from error_macros.h - */ +* This function returns an error value, if returning Error, please select the most +* appropriate error condition from error_macros.h +*/ #define ERR_FAIL_INDEX_V(m_index, m_size, m_retval) \ do { \ @@ -136,7 +149,18 @@ extern bool _err_error_exists; return m_retval; \ } else \ _err_error_exists = false; \ - } while (0); + } while (0); // (*) + +/** Use this one if there is no sensible fallback, that is, the error is unrecoverable. +* We'll return a null reference and try to keep running. +*/ +#define CRASH_BAD_INDEX(m_index, m_size) \ + do { \ + if ((m_index) < 0 || (m_index) >= (m_size)) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Index " _STR(m_index) " out of size (" _STR(m_size) ")."); \ + GENERATE_TRAP \ + } \ + } while (0); // (*) /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). * the function will exit. @@ -173,6 +197,17 @@ extern bool _err_error_exists; _err_error_exists = false; \ } +/** Use this one if there is no sensible fallback, that is, the error is unrecoverable. + */ + +#define CRASH_COND(m_cond) \ + { \ + if (m_cond) { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Condition ' " _STR(m_cond) " ' is true."); \ + GENERATE_TRAP \ + } \ + } + /** An error condition happened (m_cond tested true) (WARNING this is the opposite as assert(). * the function will exit. * This function returns an error value, if returning Error, please select the most @@ -234,6 +269,15 @@ extern bool _err_error_exists; return m_value; \ } +/** Use this one if there is no sensible fallback, that is, the error is unrecoverable. + */ + +#define CRASH_NOW() \ + { \ + _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed."); \ + GENERATE_TRAP \ + } + /** Print an error string. */ diff --git a/core/global_config.cpp b/core/global_config.cpp index 896384d9c8..ba0a7f3e31 100644 --- a/core/global_config.cpp +++ b/core/global_config.cpp @@ -39,6 +39,8 @@ #include "os/os.h" #include "variant_parser.h" +#include <zlib.h> + #define FORMAT_VERSION 3 GlobalConfig *GlobalConfig::singleton = NULL; @@ -967,6 +969,12 @@ GlobalConfig::GlobalConfig() { custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded"); GLOBAL_DEF("debug/profiler/max_functions", 16384); + + GLOBAL_DEF("compression/zstd/compression_level", 3); + custom_prop_info["compression/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1"); + GLOBAL_DEF("compression/zlib/compression_level", Z_DEFAULT_COMPRESSION); + custom_prop_info["compression/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1"); + using_datapack = false; } diff --git a/core/hash_map.h b/core/hash_map.h index 49701188ab..45e7b82d24 100644 --- a/core/hash_map.h +++ b/core/hash_map.h @@ -473,8 +473,7 @@ public: if (!e) { e = create_entry(p_key); - if (!e) - return *(TData *)NULL; /* panic! */ + CRASH_COND(!e); check_hash_table(); // perform mantenience routine } diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp index 2f176fb9bf..5545c2d642 100644 --- a/core/helper/math_fieldwise.cpp +++ b/core/helper/math_fieldwise.cpp @@ -63,8 +63,8 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const SETUP_TYPE(Rect2) - /**/ TRY_TRANSFER_FIELD("x", pos.x) - else TRY_TRANSFER_FIELD("y", pos.y) + /**/ TRY_TRANSFER_FIELD("x", position.x) + else TRY_TRANSFER_FIELD("y", position.y) else TRY_TRANSFER_FIELD("w", size.x) else TRY_TRANSFER_FIELD("h", size.y) @@ -110,9 +110,9 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const SETUP_TYPE(Rect3) - /**/ TRY_TRANSFER_FIELD("px", pos.x) - else TRY_TRANSFER_FIELD("py", pos.y) - else TRY_TRANSFER_FIELD("pz", pos.z) + /**/ TRY_TRANSFER_FIELD("px", position.x) + else TRY_TRANSFER_FIELD("py", position.y) + else TRY_TRANSFER_FIELD("pz", position.z) else TRY_TRANSFER_FIELD("sx", size.x) else TRY_TRANSFER_FIELD("sy", size.y) else TRY_TRANSFER_FIELD("sz", size.z) diff --git a/core/image.cpp b/core/image.cpp index 2640c6be2a..6ab8bb6d46 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -81,21 +81,21 @@ const char *Image::format_names[Image::FORMAT_MAX] = { SavePNGFunc Image::save_png_func = NULL; -void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_dst, const uint8_t *p_src) { +void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) { uint32_t ofs = (p_y * width + p_x) * p_pixelsize; for (uint32_t i = 0; i < p_pixelsize; i++) { - p_dst[ofs + i] = p_src[i]; + p_data[ofs + i] = p_pixel[i]; } } -void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_src, uint8_t *p_dst) { +void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel) { uint32_t ofs = (p_y * width + p_x) * p_pixelsize; for (uint32_t i = 0; i < p_pixelsize; i++) { - p_dst[i] = p_src[ofs + i]; + p_pixel[i] = p_data[ofs + i]; } } @@ -423,7 +423,7 @@ void Image::convert(Format p_new_format) { for (int i = 0; i < width; i++) { for (int j = 0; j < height; j++) { - new_img.put_pixel(i, j, get_pixel(i, j)); + new_img.set_pixel(i, j, get_pixel(i, j)); } } @@ -818,7 +818,7 @@ void Image::flip_y() { uint8_t down[16]; uint32_t pixel_size = get_format_pixel_size(format); - for (int y = 0; y < height; y++) { + for (int y = 0; y < height / 2; y++) { for (int x = 0; x < width; x++) { @@ -854,7 +854,7 @@ void Image::flip_x() { for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { + for (int x = 0; x < width / 2; x++) { _get_pixelb(x, y, pixel_size, w.ptr(), up); _get_pixelb(width - x - 1, y, pixel_size, w.ptr(), down); @@ -1325,19 +1325,19 @@ void Image::create(const char **p_xpm) { line++; } } -#define DETECT_ALPHA_MAX_TRESHOLD 254 -#define DETECT_ALPHA_MIN_TRESHOLD 2 - -#define DETECT_ALPHA(m_value) \ - { \ - uint8_t value = m_value; \ - if (value < DETECT_ALPHA_MIN_TRESHOLD) \ - bit = true; \ - else if (value < DETECT_ALPHA_MAX_TRESHOLD) { \ - \ - detected = true; \ - break; \ - } \ +#define DETECT_ALPHA_MAX_THRESHOLD 254 +#define DETECT_ALPHA_MIN_THRESHOLD 2 + +#define DETECT_ALPHA(m_value) \ + { \ + uint8_t value = m_value; \ + if (value < DETECT_ALPHA_MIN_THRESHOLD) \ + bit = true; \ + else if (value < DETECT_ALPHA_MAX_THRESHOLD) { \ + \ + detected = true; \ + break; \ + } \ } #define DETECT_NON_ALPHA(m_value) \ @@ -1457,7 +1457,7 @@ Error Image::save_png(const String &p_path) const { if (save_png_func == NULL) return ERR_UNAVAILABLE; - return save_png_func(p_path, Ref<Image>(this)); + return save_png_func(p_path, Ref<Image>((Image *)this)); } int Image::get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps) { @@ -1483,23 +1483,23 @@ Error Image::decompress() { _image_decompress_bc(this); else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc) _image_decompress_pvrtc(this); - else if (format == FORMAT_ETC && _image_decompress_etc) - _image_decompress_etc(this); - else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc) + else if (format == FORMAT_ETC && _image_decompress_etc1) + _image_decompress_etc1(this); + else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc1) _image_decompress_etc2(this); else return ERR_UNAVAILABLE; return OK; } -Error Image::compress(CompressMode p_mode, bool p_for_srgb) { +Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_lossy_quality) { switch (p_mode) { case COMPRESS_S3TC: { ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); - _image_compress_bc_func(this, p_for_srgb); + _image_compress_bc_func(this, p_source); } break; case COMPRESS_PVRTC2: { @@ -1513,13 +1513,13 @@ Error Image::compress(CompressMode p_mode, bool p_for_srgb) { } break; case COMPRESS_ETC: { - ERR_FAIL_COND_V(!_image_compress_etc_func, ERR_UNAVAILABLE); - _image_compress_etc_func(this); + ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE); + _image_compress_etc1_func(this, p_lossy_quality); } break; case COMPRESS_ETC2: { - ERR_FAIL_COND_V(!_image_compress_etc_func, ERR_UNAVAILABLE); - _image_compress_etc_func(this); + ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE); + _image_compress_etc2_func(this, p_lossy_quality, p_source); } break; } @@ -1599,7 +1599,7 @@ Rect2 Image::get_used_rect() const { Ref<Image> Image::get_rect(const Rect2 &p_area) const { Ref<Image> img = memnew(Image(p_area.size.x, p_area.size.y, mipmaps, format)); - img->blit_rect(Ref<Image>(this), p_area, Point2(0, 0)); + img->blit_rect(Ref<Image>((Image *)this), p_area, Point2(0, 0)); return img; } @@ -1612,11 +1612,11 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po ERR_FAIL_COND(srcdsize == 0); ERR_FAIL_COND(format != p_src->format); - Rect2i local_src_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest + p_src_rect.pos, p_src_rect.size)); - - if (local_src_rect.size.x <= 0 || local_src_rect.size.y <= 0) + Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); + if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) return; - Rect2i src_rect(p_src_rect.pos + (local_src_rect.pos - p_dest), local_src_rect.size); + + Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size)); PoolVector<uint8_t>::Write wp = data.write(); uint8_t *dst_data_ptr = wp.ptr(); @@ -1626,15 +1626,15 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po int pixel_size = get_format_pixel_size(format); - for (int i = 0; i < src_rect.size.y; i++) { + for (int i = 0; i < dest_rect.size.y; i++) { - for (int j = 0; j < src_rect.size.x; j++) { + for (int j = 0; j < dest_rect.size.x; j++) { - int src_x = src_rect.pos.x + j; - int src_y = src_rect.pos.y + i; + int src_x = clipped_src_rect.position.x + j; + int src_y = clipped_src_rect.position.y + i; - int dst_x = local_src_rect.pos.x + j; - int dst_y = local_src_rect.pos.y + i; + int dst_x = dest_rect.position.x + j; + int dst_y = dest_rect.position.y + i; const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size]; uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size]; @@ -1646,17 +1646,200 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po } } +void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) { + + ERR_FAIL_COND(p_src.is_null()); + ERR_FAIL_COND(p_mask.is_null()); + int dsize = data.size(); + int srcdsize = p_src->data.size(); + int maskdsize = p_mask->data.size(); + ERR_FAIL_COND(dsize == 0); + ERR_FAIL_COND(srcdsize == 0); + ERR_FAIL_COND(maskdsize == 0); + ERR_FAIL_COND(p_src->width != p_mask->width); + ERR_FAIL_COND(p_src->height != p_mask->height); + ERR_FAIL_COND(format != p_src->format); + + Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); + if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) + return; + + Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size)); + + PoolVector<uint8_t>::Write wp = data.write(); + uint8_t *dst_data_ptr = wp.ptr(); + + PoolVector<uint8_t>::Read rp = p_src->data.read(); + const uint8_t *src_data_ptr = rp.ptr(); + + int pixel_size = get_format_pixel_size(format); + + Ref<Image> msk = p_mask; + msk->lock(); + + for (int i = 0; i < dest_rect.size.y; i++) { + + for (int j = 0; j < dest_rect.size.x; j++) { + + int src_x = clipped_src_rect.position.x + j; + int src_y = clipped_src_rect.position.y + i; + + if (msk->get_pixel(src_x, src_y).a != 0) { + + int dst_x = dest_rect.position.x + j; + int dst_y = dest_rect.position.y + i; + + const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size]; + uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size]; + + for (int k = 0; k < pixel_size; k++) { + dst[k] = src[k]; + } + } + } + } + + msk->unlock(); +} + +void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) { + + ERR_FAIL_COND(p_src.is_null()); + int dsize = data.size(); + int srcdsize = p_src->data.size(); + ERR_FAIL_COND(dsize == 0); + ERR_FAIL_COND(srcdsize == 0); + ERR_FAIL_COND(format != p_src->format); + + Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); + if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) + return; + + Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size)); + + lock(); + Ref<Image> img = p_src; + img->lock(); + + for (int i = 0; i < dest_rect.size.y; i++) { + + for (int j = 0; j < dest_rect.size.x; j++) { + + int src_x = clipped_src_rect.position.x + j; + int src_y = clipped_src_rect.position.y + i; + + int dst_x = dest_rect.position.x + j; + int dst_y = dest_rect.position.y + i; + + Color sc = img->get_pixel(src_x, src_y); + Color dc = get_pixel(dst_x, dst_y); + dc.r = (double)(sc.a * sc.r + dc.a * (1.0 - sc.a) * dc.r); + dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g); + dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b); + dc.a = (double)(sc.a + dc.a * (1.0 - sc.a)); + set_pixel(dst_x, dst_y, dc); + } + } + + img->unlock(); + unlock(); +} + +void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) { + + ERR_FAIL_COND(p_src.is_null()); + ERR_FAIL_COND(p_mask.is_null()); + int dsize = data.size(); + int srcdsize = p_src->data.size(); + int maskdsize = p_mask->data.size(); + ERR_FAIL_COND(dsize == 0); + ERR_FAIL_COND(srcdsize == 0); + ERR_FAIL_COND(maskdsize == 0); + ERR_FAIL_COND(p_src->width != p_mask->width); + ERR_FAIL_COND(p_src->height != p_mask->height); + ERR_FAIL_COND(format != p_src->format); + + Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect); + if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) + return; + + Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size)); + + lock(); + Ref<Image> img = p_src; + Ref<Image> msk = p_mask; + img->lock(); + msk->lock(); + + for (int i = 0; i < dest_rect.size.y; i++) { + + for (int j = 0; j < dest_rect.size.x; j++) { + + int src_x = clipped_src_rect.position.x + j; + int src_y = clipped_src_rect.position.y + i; + + // If the mask's pixel is transparent then we skip it + //Color c = msk->get_pixel(src_x, src_y); + //if (c.a == 0) continue; + if (msk->get_pixel(src_x, src_y).a != 0) { + + int dst_x = dest_rect.position.x + j; + int dst_y = dest_rect.position.y + i; + + Color sc = img->get_pixel(src_x, src_y); + Color dc = get_pixel(dst_x, dst_y); + dc.r = (double)(sc.a * sc.r + dc.a * (1.0 - sc.a) * dc.r); + dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g); + dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b); + dc.a = (double)(sc.a + dc.a * (1.0 - sc.a)); + set_pixel(dst_x, dst_y, dc); + } + } + } + + msk->unlock(); + img->unlock(); + unlock(); +} + +void Image::fill(const Color &c) { + + lock(); + + PoolVector<uint8_t>::Write wp = data.write(); + uint8_t *dst_data_ptr = wp.ptr(); + + int pixel_size = get_format_pixel_size(format); + + // put first pixel with the format-aware API + set_pixel(0, 0, c); + + for (int y = 0; y < height; y++) { + + for (int x = 0; x < width; x++) { + + uint8_t *dst = &dst_data_ptr[(y * width + x) * pixel_size]; + + for (int k = 0; k < pixel_size; k++) { + dst[k] = dst_data_ptr[k]; + } + } + } + + unlock(); +} + Ref<Image> (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL; Ref<Image> (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL; -void (*Image::_image_compress_bc_func)(Image *, bool) = NULL; +void (*Image::_image_compress_bc_func)(Image *, Image::CompressSource) = NULL; void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL; void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL; -void (*Image::_image_compress_etc_func)(Image *) = NULL; -void (*Image::_image_compress_etc2_func)(Image *) = NULL; +void (*Image::_image_compress_etc1_func)(Image *, float) = NULL; +void (*Image::_image_compress_etc2_func)(Image *, float, Image::CompressSource) = NULL; void (*Image::_image_decompress_pvrtc)(Image *) = NULL; void (*Image::_image_decompress_bc)(Image *) = NULL; -void (*Image::_image_decompress_etc)(Image *) = NULL; +void (*Image::_image_decompress_etc1)(Image *) = NULL; void (*Image::_image_decompress_etc2)(Image *) = NULL; PoolVector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL; @@ -1712,7 +1895,7 @@ void Image::unlock() { write_lock = PoolVector<uint8_t>::Write(); } -Color Image::get_pixel(int p_x, int p_y) { +Color Image::get_pixel(int p_x, int p_y) const { uint8_t *ptr = write_lock.ptr(); #ifdef DEBUG_ENABLED @@ -1858,12 +2041,12 @@ Color Image::get_pixel(int p_x, int p_y) { return Color(); } -void Image::put_pixel(int p_x, int p_y, const Color &p_color) { +void Image::set_pixel(int p_x, int p_y, const Color &p_color) { uint8_t *ptr = write_lock.ptr(); #ifdef DEBUG_ENABLED if (!ptr) { - ERR_EXPLAIN("Image must be locked with 'lock()' before using put_pixel()"); + ERR_EXPLAIN("Image must be locked with 'lock()' before using set_pixel()"); ERR_FAIL_COND(!ptr); } @@ -1977,7 +2160,7 @@ void Image::put_pixel(int p_x, int p_y, const Color &p_color) { } break; default: { - ERR_EXPLAIN("Can't put_pixel() on compressed image, sorry."); + ERR_EXPLAIN("Can't set_pixel() on compressed image, sorry."); ERR_FAIL(); } } @@ -2040,7 +2223,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("get_mipmap_offset", "mipmap"), &Image::get_mipmap_offset); - ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL("false")); + ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL(false)); ClassDB::bind_method(D_METHOD("resize", "width", "height", "interpolation"), &Image::resize, DEFVAL(INTERPOLATE_BILINEAR)); ClassDB::bind_method(D_METHOD("shrink_x2"), &Image::shrink_x2); ClassDB::bind_method(D_METHOD("expand_x2_hq2x"), &Image::expand_x2_hq2x); @@ -2072,6 +2255,10 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy); ClassDB::bind_method(D_METHOD("blit_rect", "src:Image", "src_rect", "dst"), &Image::blit_rect); + ClassDB::bind_method(D_METHOD("blit_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blit_rect_mask); + ClassDB::bind_method(D_METHOD("blend_rect", "src:Image", "src_rect", "dst"), &Image::blend_rect); + ClassDB::bind_method(D_METHOD("blend_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blend_rect_mask); + ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill); ClassDB::bind_method(D_METHOD("get_used_rect"), &Image::get_used_rect); ClassDB::bind_method(D_METHOD("get_rect:Image", "rect"), &Image::get_rect); @@ -2083,7 +2270,7 @@ void Image::_bind_methods() { ClassDB::bind_method(D_METHOD("lock"), &Image::lock); ClassDB::bind_method(D_METHOD("unlock"), &Image::unlock); - ClassDB::bind_method(D_METHOD("put_pixel", "x", "y", "color"), &Image::put_pixel); + ClassDB::bind_method(D_METHOD("set_pixel", "x", "y", "color"), &Image::set_pixel); ClassDB::bind_method(D_METHOD("get_pixel", "x", "y"), &Image::get_pixel); ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data"); @@ -2140,9 +2327,13 @@ void Image::_bind_methods() { BIND_CONSTANT(COMPRESS_PVRTC4); BIND_CONSTANT(COMPRESS_ETC); BIND_CONSTANT(COMPRESS_ETC2); + + BIND_CONSTANT(COMPRESS_SOURCE_GENERIC); + BIND_CONSTANT(COMPRESS_SOURCE_SRGB); + BIND_CONSTANT(COMPRESS_SOURCE_NORMAL); } -void Image::set_compress_bc_func(void (*p_compress_func)(Image *, bool)) { +void Image::set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)) { _image_compress_bc_func = p_compress_func; } @@ -2243,7 +2434,7 @@ void Image::fix_alpha_edges() { unsigned char *data_ptr = wp.ptr(); const int max_radius = 4; - const int alpha_treshold = 20; + const int alpha_threshold = 20; const int max_dist = 0x7FFFFFFF; for (int i = 0; i < height; i++) { @@ -2252,7 +2443,7 @@ void Image::fix_alpha_edges() { const uint8_t *rptr = &srcptr[(i * width + j) * 4]; uint8_t *wptr = &data_ptr[(i * width + j) * 4]; - if (rptr[3] >= alpha_treshold) + if (rptr[3] >= alpha_threshold) continue; int closest_dist = max_dist; @@ -2274,7 +2465,7 @@ void Image::fix_alpha_edges() { const uint8_t *rp = &srcptr[(k * width + l) << 2]; - if (rp[3] < alpha_treshold) + if (rp[3] < alpha_threshold) continue; closest_color[0] = rp[0]; diff --git a/core/image.h b/core/image.h index 2a78870f53..7acc4744e9 100644 --- a/core/image.h +++ b/core/image.h @@ -109,20 +109,26 @@ public: /* INTERPOLATE GAUSS */ }; + enum CompressSource { + COMPRESS_SOURCE_GENERIC, + COMPRESS_SOURCE_SRGB, + COMPRESS_SOURCE_NORMAL + }; + //some functions provided by something else static Ref<Image> (*_png_mem_loader_func)(const uint8_t *p_png, int p_size); static Ref<Image> (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size); - static void (*_image_compress_bc_func)(Image *, bool p_srgb); + static void (*_image_compress_bc_func)(Image *, CompressSource p_source); static void (*_image_compress_pvrtc2_func)(Image *); static void (*_image_compress_pvrtc4_func)(Image *); - static void (*_image_compress_etc_func)(Image *); - static void (*_image_compress_etc2_func)(Image *); + static void (*_image_compress_etc1_func)(Image *, float); + static void (*_image_compress_etc2_func)(Image *, float, CompressSource p_source); static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); - static void (*_image_decompress_etc)(Image *); + static void (*_image_decompress_etc1)(Image *); static void (*_image_decompress_etc2)(Image *); static PoolVector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality); @@ -162,8 +168,8 @@ private: static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1); bool _can_modify(Format p_format) const; - _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_dst, const uint8_t *p_src); - _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_src, uint8_t *p_dst); + _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel); + _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel); void _set_data(const Dictionary &p_data); Dictionary _get_data() const; @@ -267,7 +273,7 @@ public: COMPRESS_ETC2, }; - Error compress(CompressMode p_mode = COMPRESS_S3TC, bool p_for_srgb = false); + Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7); Error decompress(); bool is_compressed() const; @@ -277,11 +283,15 @@ public: void normalmap_to_xy(); void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); + void blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); + void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest); + void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest); + void fill(const Color &c); Rect2 get_used_rect() const; Ref<Image> get_rect(const Rect2 &p_area) const; - static void set_compress_bc_func(void (*p_compress_func)(Image *, bool)); + static void set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)); static String get_format_name(Format p_format); Image(const uint8_t *p_mem_png_jpg, int p_len = -1); @@ -304,8 +314,8 @@ public: DetectChannels get_detected_channels(); - Color get_pixel(int p_x, int p_y); - void put_pixel(int p_x, int p_y, const Color &p_color); + Color get_pixel(int p_x, int p_y) const; + void set_pixel(int p_x, int p_y, const Color &p_color); void copy_internals_from(const Ref<Image> &p_image) { ERR_FAIL_COND(p_image.is_null()); @@ -322,6 +332,7 @@ public: VARIANT_ENUM_CAST(Image::Format) VARIANT_ENUM_CAST(Image::Interpolation) VARIANT_ENUM_CAST(Image::CompressMode) +VARIANT_ENUM_CAST(Image::CompressSource) VARIANT_ENUM_CAST(Image::AlphaMode) #endif diff --git a/core/io/compression.cpp b/core/io/compression.cpp index 662411a62e..f806c4da6d 100644 --- a/core/io/compression.cpp +++ b/core/io/compression.cpp @@ -28,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "compression.h" - +#include "global_config.h" #include "os/copymem.h" #include "zip_io.h" #include "thirdparty/misc/fastlz.h" +#include "thirdparty/zstd/zstd.h" #include <zlib.h> @@ -57,7 +58,8 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, strm.zalloc = zipio_alloc; strm.zfree = zipio_free; strm.opaque = Z_NULL; - int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION); + int level = GLOBAL_GET("compression/zlib/compression_level"); + int err = deflateInit(&strm, level); if (err != Z_OK) return -1; @@ -76,6 +78,12 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, return aout; } break; + case MODE_ZSTD: { + + int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD); + int level = GLOBAL_GET("compression/zstd/compression_level"); + return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, level); + } break; } ERR_FAIL_V(-1); @@ -105,6 +113,10 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) { deflateEnd(&strm); return aout; } break; + case MODE_ZSTD: { + + return ZSTD_compressBound(p_src_size); + } break; } ERR_FAIL_V(-1); @@ -148,6 +160,10 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p ERR_FAIL_COND_V(err != Z_STREAM_END, -1); return total; } break; + case MODE_ZSTD: { + + return ZSTD_decompress(p_dst, p_dst_max_size, p_src, p_src_size); + } break; } ERR_FAIL_V(-1); diff --git a/core/io/compression.h b/core/io/compression.h index a982a074b1..742f0f4d68 100644 --- a/core/io/compression.h +++ b/core/io/compression.h @@ -36,12 +36,13 @@ class Compression { public: enum Mode { MODE_FASTLZ, - MODE_DEFLATE + MODE_DEFLATE, + MODE_ZSTD }; - static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ); - static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_FASTLZ); - static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ); + static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); + static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD); + static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD); Compression(); }; diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 4c6e8f5507..4e802579c6 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -369,7 +369,7 @@ FileAccessCompressed::FileAccessCompressed() { f = NULL; magic = "GCMP"; block_size = 16384; - cmode = Compression::MODE_DEFLATE; + cmode = Compression::MODE_ZSTD; writing = false; write_ptr = 0; write_buffer_size = 0; diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 6af9d9b6ca..340c298a0f 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -64,7 +64,7 @@ class FileAccessCompressed : public FileAccess { FileAccess *f; public: - void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_FASTLZ, int p_block_size = 4096); + void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, int p_block_size = 4096); Error open_after_magic(FileAccess *p_base); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 899f3b3b2d..0c84a5213f 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -96,7 +96,12 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector }; String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; - request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; + if ((ssl && conn_port == 443) || (!ssl && conn_port == 80)) { + // don't append the standard ports + request += "Host: " + conn_host + "\r\n"; + } else { + request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; + } bool add_clen = p_body.size() > 0; for (int i = 0; i < p_headers.size(); i++) { request += p_headers[i] + "\r\n"; @@ -151,7 +156,12 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str }; String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n"; - request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; + if ((ssl && conn_port == 443) || (!ssl && conn_port == 80)) { + // don't append the standard ports + request += "Host: " + conn_host + "\r\n"; + } else { + request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n"; + } bool add_clen = p_body.length() > 0; for (int i = 0; i < p_headers.size(); i++) { request += p_headers[i] + "\r\n"; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index dccf70ad7a..75dfd563dd 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -139,8 +139,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Rect2 val; - val.pos.x = decode_float(&buf[0]); - val.pos.y = decode_float(&buf[4]); + val.position.x = decode_float(&buf[0]); + val.position.y = decode_float(&buf[4]); val.size.x = decode_float(&buf[8]); val.size.y = decode_float(&buf[12]); r_variant = val; @@ -211,9 +211,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Rect3 val; - val.pos.x = decode_float(&buf[0]); - val.pos.y = decode_float(&buf[4]); - val.pos.z = decode_float(&buf[8]); + val.position.x = decode_float(&buf[0]); + val.position.y = decode_float(&buf[4]); + val.position.z = decode_float(&buf[8]); val.size.x = decode_float(&buf[12]); val.size.y = decode_float(&buf[16]); val.size.z = decode_float(&buf[20]); @@ -861,8 +861,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { if (buf) { Rect2 r2 = p_variant; - encode_float(r2.pos.x, &buf[0]); - encode_float(r2.pos.y, &buf[4]); + encode_float(r2.position.x, &buf[0]); + encode_float(r2.position.y, &buf[4]); encode_float(r2.size.x, &buf[8]); encode_float(r2.size.y, &buf[12]); } @@ -926,9 +926,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) { if (buf) { Rect3 aabb = p_variant; - encode_float(aabb.pos.x, &buf[0]); - encode_float(aabb.pos.y, &buf[4]); - encode_float(aabb.pos.z, &buf[8]); + encode_float(aabb.position.x, &buf[0]); + encode_float(aabb.position.y, &buf[4]); + encode_float(aabb.position.z, &buf[8]); encode_float(aabb.size.x, &buf[12]); encode_float(aabb.size.y, &buf[16]); encode_float(aabb.size.z, &buf[20]); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 26b53c2a31..b474c2e078 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -155,8 +155,8 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { case VARIANT_RECT2: { Rect2 v; - v.pos.x = f->get_real(); - v.pos.y = f->get_real(); + v.position.x = f->get_real(); + v.position.y = f->get_real(); v.size.x = f->get_real(); v.size.y = f->get_real(); r_v = v; @@ -191,9 +191,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { case VARIANT_RECT3: { Rect3 v; - v.pos.x = f->get_real(); - v.pos.y = f->get_real(); - v.pos.z = f->get_real(); + v.position.x = f->get_real(); + v.position.y = f->get_real(); + v.position.z = f->get_real(); v.size.x = f->get_real(); v.size.y = f->get_real(); v.size.z = f->get_real(); @@ -689,6 +689,7 @@ Error ResourceInteractiveLoaderBinary::poll() { f->close(); resource = res; + resource->set_as_translation_remapped(translation_remapped); error = ERR_FILE_EOF; } else { @@ -706,6 +707,11 @@ int ResourceInteractiveLoaderBinary::get_stage_count() const { return external_resources.size() + internal_resources.size(); } +void ResourceInteractiveLoaderBinary::set_translation_remapped(bool p_remapped) { + + translation_remapped = p_remapped; +} + static void save_ustring(FileAccess *f, const String &p_string) { CharString utf8 = p_string.utf8(); @@ -920,6 +926,7 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() { endian_swap = false; use_real64 = false; error = OK; + translation_remapped = false; } ResourceInteractiveLoaderBinary::~ResourceInteractiveLoaderBinary() { @@ -1288,8 +1295,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(VARIANT_RECT2); Rect2 val = p_property; - f->store_real(val.pos.x); - f->store_real(val.pos.y); + f->store_real(val.position.x); + f->store_real(val.position.y); f->store_real(val.size.x); f->store_real(val.size.y); @@ -1327,9 +1334,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(VARIANT_RECT3); Rect3 val = p_property; - f->store_real(val.pos.x); - f->store_real(val.pos.y); - f->store_real(val.pos.z); + f->store_real(val.position.x); + f->store_real(val.position.y); + f->store_real(val.position.z); f->store_real(val.size.x); f->store_real(val.size.y); f->store_real(val.size.z); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 59b9d66d8f..5da5a0fc37 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -36,6 +36,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { + bool translation_remapped; String local_path; String res_path; String type; @@ -87,6 +88,7 @@ public: virtual Error poll(); virtual int get_stage() const; virtual int get_stage_count() const; + virtual void set_translation_remapped(bool p_remapped); void set_remaps(const Map<String, String> &p_remaps) { remaps = p_remaps; } void open(FileAccess *p_f); diff --git a/core/io/resource_import.h b/core/io/resource_import.h index 25b7a534b2..9d2a5180dc 100644 --- a/core/io/resource_import.h +++ b/core/io/resource_import.h @@ -61,6 +61,7 @@ public: String get_internal_resource_path(const String &p_path) const; void add_importer(const Ref<ResourceImporter> &p_importer) { importers.insert(p_importer); } + void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); } Ref<ResourceImporter> get_importer_by_name(const String &p_name); Ref<ResourceImporter> get_importer_by_extension(const String &p_extension); void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers); diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 234d71cb68..bb7be38413 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -29,10 +29,12 @@ /*************************************************************************/ #include "resource_loader.h" #include "global_config.h" +#include "io/resource_import.h" #include "os/file_access.h" #include "os/os.h" #include "path_remap.h" #include "print_string.h" +#include "translation.h" ResourceFormatLoader *ResourceLoader::loader[MAX_LOADERS]; int ResourceLoader::loader_count = 0; @@ -102,6 +104,7 @@ public: virtual Error poll() { return ERR_FILE_EOF; } virtual int get_stage() const { return 1; } virtual int get_stage_count() const { return 1; } + virtual void set_translation_remapped(bool p_remapped) { resource->set_as_translation_remapped(p_remapped); } ResourceInteractiveLoaderDefault() {} }; @@ -165,38 +168,45 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p else local_path = GlobalConfig::get_singleton()->localize_path(p_path); - ERR_FAIL_COND_V(local_path == "", RES()); + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); - if (!p_no_cache && ResourceCache::has(local_path)) { + ERR_FAIL_COND_V(path == "", RES()); + + if (!p_no_cache && ResourceCache::has(path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_line("load resource: " + path + " (cached)"); - return RES(ResourceCache::get(local_path)); + return RES(ResourceCache::get(path)); } if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path); + print_line("load resource: " + path); bool found = false; // Try all loaders and pick the first match for the type hint for (int i = 0; i < loader_count; i++) { - if (!loader[i]->recognize_path(local_path, p_type_hint)) { + if (!loader[i]->recognize_path(path, p_type_hint)) { continue; } found = true; - RES res = loader[i]->load(local_path, local_path, r_error); + RES res = loader[i]->load(path, path, r_error); if (res.is_null()) { continue; } if (!p_no_cache) res->set_path(local_path); + + if (xl_remapped) + res->set_as_translation_remapped(true); + #ifdef TOOLS_ENABLED res->set_edited(false); if (timestamp_on_load) { - uint64_t mt = FileAccess::get_modified_time(local_path); + uint64_t mt = FileAccess::get_modified_time(path); //printf("mt %s: %lli\n",remapped_path.utf8().get_data(),mt); res->set_last_modified_time(mt); } @@ -206,9 +216,9 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p } if (found) { - ERR_EXPLAIN("Failed loading resource: " + p_path); + ERR_EXPLAIN("Failed loading resource: " + path); } else { - ERR_EXPLAIN("No loader found for resource: " + p_path); + ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(RES()); return RES(); @@ -225,14 +235,17 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ else local_path = GlobalConfig::get_singleton()->localize_path(p_path); - ERR_FAIL_COND_V(local_path == "", Ref<ResourceInteractiveLoader>()); + bool xl_remapped = false; + String path = _path_remap(local_path, &xl_remapped); + + ERR_FAIL_COND_V(path == "", Ref<ResourceInteractiveLoader>()); - if (!p_no_cache && ResourceCache::has(local_path)) { + if (!p_no_cache && ResourceCache::has(path)) { if (OS::get_singleton()->is_stdout_verbose()) - print_line("load resource: " + local_path + " (cached)"); + print_line("load resource: " + path + " (cached)"); - Ref<Resource> res_cached = ResourceCache::get(local_path); + Ref<Resource> res_cached = ResourceCache::get(path); Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); ril->resource = res_cached; @@ -246,22 +259,24 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ for (int i = 0; i < loader_count; i++) { - if (!loader[i]->recognize_path(local_path, p_type_hint)) + if (!loader[i]->recognize_path(path, p_type_hint)) continue; found = true; - Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(local_path, r_error); + Ref<ResourceInteractiveLoader> ril = loader[i]->load_interactive(path, r_error); if (ril.is_null()) continue; if (!p_no_cache) ril->set_local_path(local_path); + if (xl_remapped) + ril->set_translation_remapped(true); return ril; } if (found) { - ERR_EXPLAIN("Failed loading resource: " + p_path); + ERR_EXPLAIN("Failed loading resource: " + path); } else { - ERR_EXPLAIN("No loader found for resource: " + p_path); + ERR_EXPLAIN("No loader found for resource: " + path); } ERR_FAIL_V(Ref<ResourceInteractiveLoader>()); return Ref<ResourceInteractiveLoader>(); @@ -283,11 +298,13 @@ void ResourceLoader::add_resource_format_loader(ResourceFormatLoader *p_format_l void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { + String path = _path_remap(p_path); + String local_path; - if (p_path.is_rel_path()) - local_path = "res://" + p_path; + if (path.is_rel_path()) + local_path = "res://" + path; else - local_path = GlobalConfig::get_singleton()->localize_path(p_path); + local_path = GlobalConfig::get_singleton()->localize_path(path); for (int i = 0; i < loader_count; i++) { @@ -304,11 +321,13 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) { + String path = _path_remap(p_path); + String local_path; - if (p_path.is_rel_path()) - local_path = "res://" + p_path; + if (path.is_rel_path()) + local_path = "res://" + path; else - local_path = GlobalConfig::get_singleton()->localize_path(p_path); + local_path = GlobalConfig::get_singleton()->localize_path(path); for (int i = 0; i < loader_count; i++) { @@ -342,6 +361,95 @@ String ResourceLoader::get_resource_type(const String &p_path) { return ""; } + +String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) { + + if (translation_remaps.has(p_path)) { + + Vector<String> &v = *translation_remaps.getptr(p_path); + String locale = TranslationServer::get_singleton()->get_locale(); + if (r_translation_remapped) { + *r_translation_remapped = true; + } + for (int i = 0; i < v.size(); i++) { + + int split = v[i].find_last(":"); + if (split == -1) + continue; + String l = v[i].right(split + 1).strip_edges(); + if (l == String()) + continue; + + if (l.begins_with(locale)) { + return v[i].left(split); + } + } + } + + return p_path; +} + +String ResourceLoader::import_remap(const String &p_path) { + + if (ResourceFormatImporter::get_singleton()->recognize_path(p_path)) { + + return ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_path); + } + + return p_path; +} + +String ResourceLoader::path_remap(const String &p_path) { + return _path_remap(p_path); +} + +void ResourceLoader::reload_translation_remaps() { + + if (ResourceCache::lock) { + ResourceCache::lock->read_lock(); + } + + List<Resource *> to_reload; + SelfList<Resource> *E = remapped_list.first(); + + while (E) { + to_reload.push_back(E->self()); + E = E->next(); + } + + if (ResourceCache::lock) { + ResourceCache::lock->read_unlock(); + } + + //now just make sure to not delete any of these resources while changing locale.. + while (to_reload.front()) { + to_reload.front()->get()->reload_from_file(); + to_reload.pop_front(); + } +} + +void ResourceLoader::load_translation_remaps() { + + Dictionary remaps = GlobalConfig::get_singleton()->get("locale/translation_remaps"); + List<Variant> keys; + remaps.get_key_list(&keys); + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + + Array langs = remaps[E->get()]; + Vector<String> lang_remaps; + lang_remaps.resize(langs.size()); + for (int i = 0; i < langs.size(); i++) { + lang_remaps[i] = langs[i]; + } + + translation_remaps[String(E->get())] = lang_remaps; + } +} + +void ResourceLoader::clear_translation_remaps() { + translation_remaps.clear(); +} + ResourceLoadErrorNotify ResourceLoader::err_notify = NULL; void *ResourceLoader::err_notify_ud = NULL; @@ -350,3 +458,6 @@ void *ResourceLoader::dep_err_notify_ud = NULL; bool ResourceLoader::abort_on_missing_resource = true; bool ResourceLoader::timestamp_on_load = false; + +SelfList<Resource>::List ResourceLoader::remapped_list; +HashMap<String, Vector<String> > ResourceLoader::translation_remaps; diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h index 54b62f6916..e6687800d7 100644 --- a/core/io/resource_loader.h +++ b/core/io/resource_loader.h @@ -49,6 +49,7 @@ public: virtual Error poll() = 0; virtual int get_stage() const = 0; virtual int get_stage_count() const = 0; + virtual void set_translation_remapped(bool p_remapped) = 0; virtual Error wait(); ResourceInteractiveLoader() {} @@ -87,6 +88,12 @@ class ResourceLoader { static void *dep_err_notify_ud; static DependencyErrorNotify dep_err_notify; static bool abort_on_missing_resource; + static HashMap<String, Vector<String> > translation_remaps; + + static String _path_remap(const String &p_path, bool *r_translation_remapped = NULL); + friend class Resource; + + static SelfList<Resource>::List remapped_list; public: static Ref<ResourceInteractiveLoader> load_interactive(const String &p_path, const String &p_type_hint = "", bool p_no_cache = false, Error *r_error = NULL); @@ -118,6 +125,13 @@ public: static void set_abort_on_missing_resources(bool p_abort) { abort_on_missing_resource = p_abort; } static bool get_abort_on_missing_resources() { return abort_on_missing_resource; } + + static String path_remap(const String &p_path); + static String import_remap(const String &p_path); + + static void reload_translation_remaps(); + static void load_translation_remaps(); + static void clear_translation_remaps(); }; #endif diff --git a/core/list.h b/core/list.h index 4390cb65fc..df69b1dc40 100644 --- a/core/list.h +++ b/core/list.h @@ -398,10 +398,7 @@ public: T &operator[](int p_index) { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); Element *I = front(); int c = 0; @@ -415,15 +412,12 @@ public: c++; } - ERR_FAIL_V(*((T *)0)); // bug!! + CRASH_NOW(); // bug!! } const T &operator[](int p_index) const { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); const Element *I = front(); int c = 0; @@ -437,7 +431,7 @@ public: c++; } - ERR_FAIL_V(*((T *)0)); // bug! + CRASH_NOW(); // bug!! } void move_to_back(Element *p_I) { diff --git a/core/map.h b/core/map.h index acf1d608d8..ef0f75fc9b 100644 --- a/core/map.h +++ b/core/map.h @@ -599,9 +599,9 @@ public: const V &operator[](const K &p_key) const { - ERR_FAIL_COND_V(!_data._root, *(V *)NULL); // crash on purpose + CRASH_COND(!_data._root); const Element *e = find(p_key); - ERR_FAIL_COND_V(!e, *(V *)NULL); // crash on purpose + CRASH_COND(!e); return e->_value; } V &operator[](const K &p_key) { @@ -613,7 +613,7 @@ public: if (!e) e = insert(p_key, V()); - ERR_FAIL_COND_V(!e, *(V *)NULL); // crash on purpose + CRASH_COND(!e); return e->_value; } diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 320990cc50..838fec22f0 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -401,7 +401,7 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_weight_scale", "id"), &AStar::get_point_weight_scale); ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point); - ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id"), &AStar::connect_points, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true)); ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected); diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index 9bbce752c0..327a6017c3 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -39,8 +39,8 @@ void BSP_Tree::from_aabb(const Rect3 &p_aabb) { Vector3 n; n[i] = 1; - planes.push_back(Plane(n, p_aabb.pos[i] + p_aabb.size[i])); - planes.push_back(Plane(-n, -p_aabb.pos[i])); + planes.push_back(Plane(n, p_aabb.position[i] + p_aabb.size[i])); + planes.push_back(Plane(-n, -p_aabb.position[i])); } nodes.clear(); @@ -552,7 +552,7 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) { if (first) { - aabb.pos = f.vertex[0]; + aabb.position = f.vertex[0]; first = false; } else { diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 5b072b7c53..33ad522315 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -507,8 +507,8 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { m[9] = 0.0, m[10] = 1.0, m[11] = 0.0, - m[12] = p_rect.pos.x, - m[13] = p_rect.pos.y, + m[12] = p_rect.position.x, + m[13] = p_rect.position.y, m[14] = 0.0, m[15] = 1.0; } @@ -559,8 +559,8 @@ void CameraMatrix::make_scale(const Vector3 &p_scale) { void CameraMatrix::scale_translate_to_fit(const Rect3 &p_aabb) { - Vector3 min = p_aabb.pos; - Vector3 max = p_aabb.pos + p_aabb.size; + Vector3 min = p_aabb.position; + Vector3 max = p_aabb.position + p_aabb.size; matrix[0][0] = 2 / (max.x - min.x); matrix[1][0] = 0; diff --git a/core/math/face3.cpp b/core/math/face3.cpp index 6d772cf08c..0e292500bf 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -197,20 +197,20 @@ bool Face3::intersects_aabb(const Rect3 &p_aabb) const { /** TEST FACE AXIS */ -#define TEST_AXIS(m_ax) \ - { \ - real_t aabb_min = p_aabb.pos.m_ax; \ - real_t aabb_max = p_aabb.pos.m_ax + p_aabb.size.m_ax; \ - real_t tri_min, tri_max; \ - for (int i = 0; i < 3; i++) { \ - if (i == 0 || vertex[i].m_ax > tri_max) \ - tri_max = vertex[i].m_ax; \ - if (i == 0 || vertex[i].m_ax < tri_min) \ - tri_min = vertex[i].m_ax; \ - } \ - \ - if (tri_max < aabb_min || aabb_max < tri_min) \ - return false; \ +#define TEST_AXIS(m_ax) \ + { \ + real_t aabb_min = p_aabb.position.m_ax; \ + real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \ + real_t tri_min, tri_max; \ + for (int i = 0; i < 3; i++) { \ + if (i == 0 || vertex[i].m_ax > tri_max) \ + tri_max = vertex[i].m_ax; \ + if (i == 0 || vertex[i].m_ax < tri_min) \ + tri_min = vertex[i].m_ax; \ + } \ + \ + if (tri_max < aabb_min || aabb_max < tri_min) \ + return false; \ } TEST_AXIS(x); @@ -272,8 +272,8 @@ void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform, void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const { -#define _FACE_IS_VALID_SUPPORT_TRESHOLD 0.98 -#define _EDGE_IS_VALID_SUPPORT_TRESHOLD 0.05 +#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98 +#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05 if (p_max <= 0) return; @@ -281,7 +281,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V Vector3 n = p_transform.basis.xform_inv(p_normal); /** TEST FACE AS SUPPORT **/ - if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_TRESHOLD) { + if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) { *p_count = MIN(3, p_max); @@ -318,7 +318,7 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V // check if edge is valid as a support real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n); dot = ABS(dot); - if (dot < _EDGE_IS_VALID_SUPPORT_TRESHOLD) { + if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) { *p_count = MIN(2, p_max); diff --git a/core/math/face3.h b/core/math/face3.h index 31ab72b925..1cc94321c3 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -101,7 +101,7 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { Vector3 perp = (vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]); Vector3 half_extents = p_aabb.size * 0.5; - Vector3 ofs = p_aabb.pos + half_extents; + Vector3 ofs = p_aabb.position + half_extents; Vector3 sup = Vector3( (perp.x > 0) ? -half_extents.x : half_extents.x, @@ -117,8 +117,8 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { #define TEST_AXIS(m_ax) \ { \ - real_t aabb_min = p_aabb.pos.m_ax; \ - real_t aabb_max = p_aabb.pos.m_ax + p_aabb.size.m_ax; \ + real_t aabb_min = p_aabb.position.m_ax; \ + real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \ real_t tri_min, tri_max; \ for (int i = 0; i < 3; i++) { \ if (i == 0 || vertex[i].m_ax > tri_max) \ @@ -150,68 +150,68 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { case 0: { - from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z); - to = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z); + from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z); + to = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z); } break; case 1: { - from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z); - to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z); + from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z); + to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z); } break; case 2: { - from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z); - to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z); + from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z); + to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z); } break; case 3: { - from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z); - to = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z); + from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z); + to = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z); } break; case 4: { - from = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z); - to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z); + from = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z); + to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z); } break; case 5: { - from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z); - to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z); + from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z); + to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z); } break; case 6: { - from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z); - to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z); + from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z); + to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z); } break; case 7: { - from = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z); - to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z); + from = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z); + to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z); } break; case 8: { - from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z); - to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z); + from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z); + to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z); } break; case 9: { - from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z); - to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z); + from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z); + to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z); } break; case 10: { - from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z); - to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z); + from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z); + to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z); } break; case 11: { - from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z); - to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z); + from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z); + to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z); } break; } diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 618017f8b3..2bea514d37 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -301,7 +301,7 @@ enum _CellFlags { static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, const Vector3 &voxelsize, const Face3 &p_face) { Rect3 aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z)); - aabb.pos = aabb.pos * voxelsize; + aabb.position = aabb.position * voxelsize; aabb.size = aabb.size * voxelsize; if (!p_face.intersects_aabb(aabb)) @@ -640,7 +640,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e Face3 f = faces[i]; for (int j = 0; j < 3; j++) { - f.vertex[j] -= global_aabb.pos; + f.vertex[j] -= global_aabb.position; } _plot_face(cell_status, 0, 0, 0, div_x, div_y, div_z, voxelsize, f); } @@ -707,7 +707,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e Vector3 &v = wrapped_faces_ptr[i].vertex[j]; v = v * voxelsize; - v += global_aabb.pos; + v += global_aabb.position; } } diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp index 962a42acb9..52e240ed47 100644 --- a/core/math/math_2d.cpp +++ b/core/math/math_2d.cpp @@ -308,7 +308,7 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 for (int i = 0; i < 2; i++) { real_t seg_from = p_from[i]; real_t seg_to = p_to[i]; - real_t box_begin = pos[i]; + real_t box_begin = position[i]; real_t box_end = box_begin + size[i]; real_t cmin, cmax; real_t csign; diff --git a/core/math/math_2d.h b/core/math/math_2d.h index 128b74baf6..780bb532d7 100644 --- a/core/math/math_2d.h +++ b/core/math/math_2d.h @@ -207,24 +207,24 @@ struct Transform2D; struct Rect2 { - Point2 pos; + Point2 position; Size2 size; - const Vector2 &get_pos() const { return pos; } - void set_pos(const Vector2 &p_pos) { pos = p_pos; } + const Vector2 &get_position() const { return position; } + void set_position(const Vector2 &p_pos) { position = p_pos; } const Vector2 &get_size() const { return size; } void set_size(const Vector2 &p_size) { size = p_size; } real_t get_area() const { return size.width * size.height; } inline bool intersects(const Rect2 &p_rect) const { - if (pos.x >= (p_rect.pos.x + p_rect.size.width)) + if (position.x >= (p_rect.position.x + p_rect.size.width)) return false; - if ((pos.x + size.width) <= p_rect.pos.x) + if ((position.x + size.width) <= p_rect.position.x) return false; - if (pos.y >= (p_rect.pos.y + p_rect.size.height)) + if (position.y >= (p_rect.position.y + p_rect.size.height)) return false; - if ((pos.y + size.height) <= p_rect.pos.y) + if ((position.y + size.height) <= p_rect.position.y) return false; return true; @@ -234,17 +234,17 @@ struct Rect2 { real_t dist = 1e20; - if (p_point.x < pos.x) { - dist = MIN(dist, pos.x - p_point.x); + if (p_point.x < position.x) { + dist = MIN(dist, position.x - p_point.x); } - if (p_point.y < pos.y) { - dist = MIN(dist, pos.y - p_point.y); + if (p_point.y < position.y) { + dist = MIN(dist, position.y - p_point.y); } - if (p_point.x >= (pos.x + size.x)) { - dist = MIN(p_point.x - (pos.x + size.x), dist); + if (p_point.x >= (position.x + size.x)) { + dist = MIN(p_point.x - (position.x + size.x), dist); } - if (p_point.y >= (pos.y + size.y)) { - dist = MIN(p_point.y - (pos.y + size.y), dist); + if (p_point.y >= (position.y + size.y)) { + dist = MIN(p_point.y - (position.y + size.y), dist); } if (dist == 1e20) @@ -259,9 +259,9 @@ struct Rect2 { inline bool encloses(const Rect2 &p_rect) const { - return (p_rect.pos.x >= pos.x) && (p_rect.pos.y >= pos.y) && - ((p_rect.pos.x + p_rect.size.x) < (pos.x + size.x)) && - ((p_rect.pos.y + p_rect.size.y) < (pos.y + size.y)); + return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && + ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && + ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); } inline bool has_no_area() const { @@ -275,14 +275,14 @@ struct Rect2 { if (!intersects(new_rect)) return Rect2(); - new_rect.pos.x = MAX(p_rect.pos.x, pos.x); - new_rect.pos.y = MAX(p_rect.pos.y, pos.y); + new_rect.position.x = MAX(p_rect.position.x, position.x); + new_rect.position.y = MAX(p_rect.position.y, position.y); - Point2 p_rect_end = p_rect.pos + p_rect.size; - Point2 end = pos + size; + Point2 p_rect_end = p_rect.position + p_rect.size; + Point2 end = position + size; - new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.pos.x; - new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.pos.y; + new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x; + new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y; return new_rect; } @@ -291,25 +291,25 @@ struct Rect2 { Rect2 new_rect; - new_rect.pos.x = MIN(p_rect.pos.x, pos.x); - new_rect.pos.y = MIN(p_rect.pos.y, pos.y); + new_rect.position.x = MIN(p_rect.position.x, position.x); + new_rect.position.y = MIN(p_rect.position.y, position.y); - new_rect.size.x = MAX(p_rect.pos.x + p_rect.size.x, pos.x + size.x); - new_rect.size.y = MAX(p_rect.pos.y + p_rect.size.y, pos.y + size.y); + new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); + new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - new_rect.size = new_rect.size - new_rect.pos; //make relative again + new_rect.size = new_rect.size - new_rect.position; //make relative again return new_rect; }; inline bool has_point(const Point2 &p_point) const { - if (p_point.x < pos.x) + if (p_point.x < position.x) return false; - if (p_point.y < pos.y) + if (p_point.y < position.y) return false; - if (p_point.x >= (pos.x + size.x)) + if (p_point.x >= (position.x + size.x)) return false; - if (p_point.y >= (pos.y + size.y)) + if (p_point.y >= (position.y + size.y)) return false; return true; @@ -317,18 +317,37 @@ struct Rect2 { inline bool no_area() const { return (size.width <= 0 || size.height <= 0); } - bool operator==(const Rect2 &p_rect) const { return pos == p_rect.pos && size == p_rect.size; } - bool operator!=(const Rect2 &p_rect) const { return pos != p_rect.pos || size != p_rect.size; } + bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; } inline Rect2 grow(real_t p_by) const { Rect2 g = *this; - g.pos.x -= p_by; - g.pos.y -= p_by; + g.position.x -= p_by; + g.position.y -= p_by; g.size.width += p_by * 2; g.size.height += p_by * 2; return g; } + inline Rect2 grow_margin(Margin p_margin, real_t p_amount) const { + Rect2 g = *this; + g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0, + (MARGIN_TOP == p_margin) ? p_amount : 0, + (MARGIN_RIGHT == p_margin) ? p_amount : 0, + (MARGIN_BOTTOM == p_margin) ? p_amount : 0); + return g; + } + + inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const { + + Rect2 g = *this; + g.position.x -= p_left; + g.position.y -= p_top; + g.size.width += p_left + p_right; + g.size.height += p_top + p_bottom; + + return g; + } inline Rect2 expand(const Vector2 &p_vector) const { @@ -339,8 +358,8 @@ struct Rect2 { inline void expand_to(const Vector2 &p_vector) { //in place function for speed - Vector2 begin = pos; - Vector2 end = pos + size; + Vector2 begin = position; + Vector2 end = position + size; if (p_vector.x < begin.x) begin.x = p_vector.x; @@ -352,19 +371,19 @@ struct Rect2 { if (p_vector.y > end.y) end.y = p_vector.y; - pos = begin; + position = begin; size = end - begin; } - operator String() const { return String(pos) + ", " + String(size); } + operator String() const { return String(position) + ", " + String(size); } Rect2() {} Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) { - pos = Point2(p_x, p_y); + position = Point2(p_x, p_y); size = Size2(p_width, p_height); } Rect2(const Point2 &p_pos, const Size2 &p_size) { - pos = p_pos; + position = p_pos; size = p_size; } }; @@ -434,24 +453,24 @@ typedef Point2i Size2i; struct Rect2i { - Point2i pos; + Point2i position; Size2i size; - const Point2i &get_pos() const { return pos; } - void set_pos(const Point2i &p_pos) { pos = p_pos; } + const Point2i &get_position() const { return position; } + void set_position(const Point2i &p_pos) { position = p_pos; } const Point2i &get_size() const { return size; } void set_size(const Point2i &p_size) { size = p_size; } int get_area() const { return size.width * size.height; } inline bool intersects(const Rect2i &p_rect) const { - if (pos.x > (p_rect.pos.x + p_rect.size.width)) + if (position.x > (p_rect.position.x + p_rect.size.width)) return false; - if ((pos.x + size.width) < p_rect.pos.x) + if ((position.x + size.width) < p_rect.position.x) return false; - if (pos.y > (p_rect.pos.y + p_rect.size.height)) + if (position.y > (p_rect.position.y + p_rect.size.height)) return false; - if ((pos.y + size.height) < p_rect.pos.y) + if ((position.y + size.height) < p_rect.position.y) return false; return true; @@ -459,9 +478,9 @@ struct Rect2i { inline bool encloses(const Rect2i &p_rect) const { - return (p_rect.pos.x >= pos.x) && (p_rect.pos.y >= pos.y) && - ((p_rect.pos.x + p_rect.size.x) < (pos.x + size.x)) && - ((p_rect.pos.y + p_rect.size.y) < (pos.y + size.y)); + return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) && + ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) && + ((p_rect.position.y + p_rect.size.y) < (position.y + size.y)); } inline bool has_no_area() const { @@ -475,14 +494,14 @@ struct Rect2i { if (!intersects(new_rect)) return Rect2i(); - new_rect.pos.x = MAX(p_rect.pos.x, pos.x); - new_rect.pos.y = MAX(p_rect.pos.y, pos.y); + new_rect.position.x = MAX(p_rect.position.x, position.x); + new_rect.position.y = MAX(p_rect.position.y, position.y); - Point2 p_rect_end = p_rect.pos + p_rect.size; - Point2 end = pos + size; + Point2 p_rect_end = p_rect.position + p_rect.size; + Point2 end = position + size; - new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.pos.x); - new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.pos.y); + new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x); + new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y); return new_rect; } @@ -491,25 +510,25 @@ struct Rect2i { Rect2i new_rect; - new_rect.pos.x = MIN(p_rect.pos.x, pos.x); - new_rect.pos.y = MIN(p_rect.pos.y, pos.y); + new_rect.position.x = MIN(p_rect.position.x, position.x); + new_rect.position.y = MIN(p_rect.position.y, position.y); - new_rect.size.x = MAX(p_rect.pos.x + p_rect.size.x, pos.x + size.x); - new_rect.size.y = MAX(p_rect.pos.y + p_rect.size.y, pos.y + size.y); + new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x); + new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y); - new_rect.size = new_rect.size - new_rect.pos; //make relative again + new_rect.size = new_rect.size - new_rect.position; //make relative again return new_rect; }; bool has_point(const Point2 &p_point) const { - if (p_point.x < pos.x) + if (p_point.x < position.x) return false; - if (p_point.y < pos.y) + if (p_point.y < position.y) return false; - if (p_point.x >= (pos.x + size.x)) + if (p_point.x >= (position.x + size.x)) return false; - if (p_point.y >= (pos.y + size.y)) + if (p_point.y >= (position.y + size.y)) return false; return true; @@ -517,14 +536,14 @@ struct Rect2i { bool no_area() { return (size.width <= 0 || size.height <= 0); } - bool operator==(const Rect2i &p_rect) const { return pos == p_rect.pos && size == p_rect.size; } - bool operator!=(const Rect2i &p_rect) const { return pos != p_rect.pos || size != p_rect.size; } + bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; } + bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; } Rect2i grow(int p_by) const { Rect2i g = *this; - g.pos.x -= p_by; - g.pos.y -= p_by; + g.position.x -= p_by; + g.position.y -= p_by; g.size.width += p_by * 2; g.size.height += p_by * 2; return g; @@ -532,8 +551,8 @@ struct Rect2i { inline void expand_to(const Point2i &p_vector) { - Point2i begin = pos; - Point2i end = pos + size; + Point2i begin = position; + Point2i end = position + size; if (p_vector.x < begin.x) begin.x = p_vector.x; @@ -545,24 +564,24 @@ struct Rect2i { if (p_vector.y > end.y) end.y = p_vector.y; - pos = begin; + position = begin; size = end - begin; } - operator String() const { return String(pos) + ", " + String(size); } + operator String() const { return String(position) + ", " + String(size); } - operator Rect2() const { return Rect2(pos, size); } + operator Rect2() const { return Rect2(position, size); } Rect2i(const Rect2 &p_r2) { - pos = p_r2.pos; + position = p_r2.position; size = p_r2.size; } Rect2i() {} Rect2i(int p_x, int p_y, int p_width, int p_height) { - pos = Point2(p_x, p_y); + position = Point2(p_x, p_y); size = Size2(p_width, p_height); } Rect2i(const Point2 &p_pos, const Size2 &p_size) { - pos = p_pos; + position = p_pos; size = p_size; } }; @@ -668,30 +687,30 @@ bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_re //SAT intersection between local and transformed rect2 Vector2 xf_points[4] = { - p_xform.xform(p_rect.pos), - p_xform.xform(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y)), - p_xform.xform(Vector2(p_rect.pos.x, p_rect.pos.y + p_rect.size.y)), - p_xform.xform(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y + p_rect.size.y)), + p_xform.xform(p_rect.position), + p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)), + p_xform.xform(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), + p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), }; real_t low_limit; //base rect2 first (faster) - if (xf_points[0].y > pos.y) + if (xf_points[0].y > position.y) goto next1; - if (xf_points[1].y > pos.y) + if (xf_points[1].y > position.y) goto next1; - if (xf_points[2].y > pos.y) + if (xf_points[2].y > position.y) goto next1; - if (xf_points[3].y > pos.y) + if (xf_points[3].y > position.y) goto next1; return false; next1: - low_limit = pos.y + size.y; + low_limit = position.y + size.y; if (xf_points[0].y < low_limit) goto next2; @@ -706,20 +725,20 @@ next1: next2: - if (xf_points[0].x > pos.x) + if (xf_points[0].x > position.x) goto next3; - if (xf_points[1].x > pos.x) + if (xf_points[1].x > position.x) goto next3; - if (xf_points[2].x > pos.x) + if (xf_points[2].x > position.x) goto next3; - if (xf_points[3].x > pos.x) + if (xf_points[3].x > position.x) goto next3; return false; next3: - low_limit = pos.x + size.x; + low_limit = position.x + size.x; if (xf_points[0].x < low_limit) goto next4; @@ -735,10 +754,10 @@ next3: next4: Vector2 xf_points2[4] = { - pos, - Vector2(pos.x + size.x, pos.y), - Vector2(pos.x, pos.y + size.y), - Vector2(pos.x + size.x, pos.y + size.y), + position, + Vector2(position.x + size.x, position.y), + Vector2(position.x, position.y + size.y), + Vector2(position.x + size.x, position.y + size.y), }; real_t maxa = p_xform.elements[0].dot(xf_points2[0]); @@ -847,10 +866,10 @@ Rect2 Transform2D::xform(const Rect2 &p_rect) const { Vector2 x = elements[0] * p_rect.size.x; Vector2 y = elements[1] * p_rect.size.y; - Vector2 pos = xform(p_rect.pos); + Vector2 pos = xform(p_rect.position); Rect2 new_rect; - new_rect.pos = pos; + new_rect.position = pos; new_rect.expand_to(pos + x); new_rect.expand_to(pos + y); new_rect.expand_to(pos + x + y); @@ -868,14 +887,14 @@ void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) { Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const { Vector2 ends[4] = { - xform_inv(p_rect.pos), - xform_inv(Vector2(p_rect.pos.x, p_rect.pos.y + p_rect.size.y)), - xform_inv(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y + p_rect.size.y)), - xform_inv(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y)) + xform_inv(p_rect.position), + xform_inv(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)), + xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)), + xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)) }; Rect2 new_rect; - new_rect.pos = ends[0]; + new_rect.position = ends[0]; new_rect.expand_to(ends[1]); new_rect.expand_to(ends[2]); new_rect.expand_to(ends[3]); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 6a5e12c3ce..45509a0808 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -51,9 +51,7 @@ class Math { public: Math() {} // useless to instance - enum { - RANDOM_MAX = 4294967295L - }; + static const uint64_t RANDOM_MAX = 4294967295; static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); } static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); } @@ -112,6 +110,15 @@ public: static _ALWAYS_INLINE_ bool is_inf(double p_val) { #ifdef _MSC_VER return !_finite(p_val); +// use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era +#elif defined(__GNUC__) && __GNUC__ < 6 + union { + uint64_t u; + double f; + } ieee754; + ieee754.f = p_val; + return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 && + ((unsigned)ieee754.u == 0); #else return isinf(p_val); #endif @@ -120,6 +127,14 @@ public: static _ALWAYS_INLINE_ bool is_inf(float p_val) { #ifdef _MSC_VER return !_finite(p_val); +// use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era +#elif defined(__GNUC__) && __GNUC__ < 6 + union { + uint32_t u; + float f; + } ieee754; + ieee754.f = p_val; + return (ieee754.u & 0x7fffffff) == 0x7f800000; #else return isinf(p_val); #endif diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index c733251c3c..b59fecc196 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -451,9 +451,10 @@ Basis::operator String() const { } Basis::operator Quat() const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(is_rotation() == false, Quat()); -#endif + //commenting this check because precision issues cause it to fail when it shouldn't + //#ifdef MATH_CHECKS + //ERR_FAIL_COND_V(is_rotation() == false, Quat()); + //#endif real_t trace = elements[0][0] + elements[1][1] + elements[2][2]; real_t temp[4]; diff --git a/core/math/matrix3.h b/core/math/matrix3.h index c3eeb1f705..8897c692f7 100644 --- a/core/math/matrix3.h +++ b/core/math/matrix3.h @@ -145,6 +145,12 @@ public: elements[2][1] = zy; elements[2][2] = zz; } + _FORCE_INLINE_ void set(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) { + + set_axis(0, p_x); + set_axis(1, p_y); + set_axis(2, p_z); + } _FORCE_INLINE_ Vector3 get_column(int i) const { return Vector3(elements[0][i], elements[1][i], elements[2][i]); diff --git a/core/math/octree.h b/core/math/octree.h index 4cc046ddf4..010c1b18f7 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -483,11 +483,11 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct aabb.size *= 0.5; if (i & 1) - aabb.pos.x += aabb.size.x; + aabb.position.x += aabb.size.x; if (i & 2) - aabb.pos.y += aabb.size.y; + aabb.position.y += aabb.size.y; if (i & 4) - aabb.pos.z += aabb.size.z; + aabb.position.z += aabb.size.z; if (aabb.intersects_inclusive(p_element->aabb)) { /* if actually intersects, create the child */ @@ -544,11 +544,11 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) { while (!base.encloses(p_aabb)) { - if (ABS(base.pos.x + base.size.x) <= ABS(base.pos.x)) { + if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) { /* grow towards positive */ base.size *= 2.0; } else { - base.pos -= base.size; + base.position -= base.size; base.size *= 2.0; } } @@ -576,14 +576,14 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) { octant_count++; root->parent = gp; - if (ABS(base.pos.x + base.size.x) <= ABS(base.pos.x)) { + if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) { /* grow towards positive */ base.size *= 2.0; gp->aabb = base; gp->children[0] = root; root->parent_index = 0; } else { - base.pos -= base.size; + base.position -= base.size; base.size *= 2.0; gp->aabb = base; gp->children[(1 << 0) | (1 << 1) | (1 << 2)] = root; // add at all-positive @@ -797,9 +797,9 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const Rect3 &p_a // check for AABB validity #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V(p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0); - ERR_FAIL_COND_V(p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0); - ERR_FAIL_COND_V(p_aabb.pos.z > 1e15 || p_aabb.pos.z < -1e15, 0); + ERR_FAIL_COND_V(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15, 0); + ERR_FAIL_COND_V(p_aabb.position.y > 1e15 || p_aabb.position.y < -1e15, 0); + ERR_FAIL_COND_V(p_aabb.position.z > 1e15 || p_aabb.position.z < -1e15, 0); ERR_FAIL_COND_V(p_aabb.size.x > 1e15 || p_aabb.size.x < 0.0, 0); ERR_FAIL_COND_V(p_aabb.size.y > 1e15 || p_aabb.size.y < 0.0, 0); ERR_FAIL_COND_V(p_aabb.size.z > 1e15 || p_aabb.size.z < 0.0, 0); @@ -837,9 +837,9 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { #ifdef DEBUG_ENABLED // check for AABB validity - ERR_FAIL_COND(p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15); - ERR_FAIL_COND(p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15); - ERR_FAIL_COND(p_aabb.pos.z > 1e15 || p_aabb.pos.z < -1e15); + ERR_FAIL_COND(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15); + ERR_FAIL_COND(p_aabb.position.y > 1e15 || p_aabb.position.y < -1e15); + ERR_FAIL_COND(p_aabb.position.z > 1e15 || p_aabb.position.z < -1e15); ERR_FAIL_COND(p_aabb.size.x > 1e15 || p_aabb.size.x < 0.0); ERR_FAIL_COND(p_aabb.size.y > 1e15 || p_aabb.size.y < 0.0); ERR_FAIL_COND(p_aabb.size.z > 1e15 || p_aabb.size.z < 0.0); diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index ce93720067..54b97ac38c 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -42,7 +42,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me for (int i = 0; i < p_points.size(); i++) { if (i == 0) { - aabb.pos = p_points[i]; + aabb.position = p_points[i]; } else { aabb.expand_to(p_points[i]); } @@ -58,7 +58,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me for (int i = 0; i < p_points.size(); i++) { - Vector3 sp = p_points[i].snapped(0.0001); + Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001)); if (valid_cache.has(sp)) { valid_points[i] = false; //print_line("INVALIDATED: "+itos(i)); diff --git a/core/math/rect3.cpp b/core/math/rect3.cpp index 39b0beb071..973607f565 100644 --- a/core/math/rect3.cpp +++ b/core/math/rect3.cpp @@ -38,11 +38,11 @@ real_t Rect3::get_area() const { bool Rect3::operator==(const Rect3 &p_rval) const { - return ((pos == p_rval.pos) && (size == p_rval.size)); + return ((position == p_rval.position) && (size == p_rval.size)); } bool Rect3::operator!=(const Rect3 &p_rval) const { - return ((pos != p_rval.pos) || (size != p_rval.size)); + return ((position != p_rval.position) || (size != p_rval.size)); } void Rect3::merge_with(const Rect3 &p_aabb) { @@ -51,8 +51,8 @@ void Rect3::merge_with(const Rect3 &p_aabb) { Vector3 end_1, end_2; Vector3 min, max; - beg_1 = pos; - beg_2 = p_aabb.pos; + beg_1 = position; + beg_2 = p_aabb.position; end_1 = Vector3(size.x, size.y, size.z) + beg_1; end_2 = Vector3(p_aabb.size.x, p_aabb.size.y, p_aabb.size.z) + beg_2; @@ -64,16 +64,16 @@ void Rect3::merge_with(const Rect3 &p_aabb) { max.y = (end_1.y > end_2.y) ? end_1.y : end_2.y; max.z = (end_1.z > end_2.z) ? end_1.z : end_2.z; - pos = min; + position = min; size = max - min; } Rect3 Rect3::intersection(const Rect3 &p_aabb) const { - Vector3 src_min = pos; - Vector3 src_max = pos + size; - Vector3 dst_min = p_aabb.pos; - Vector3 dst_max = p_aabb.pos + p_aabb.size; + Vector3 src_min = position; + Vector3 src_max = position + size; + Vector3 dst_min = p_aabb.position; + Vector3 dst_max = p_aabb.position + p_aabb.size; Vector3 min, max; @@ -107,18 +107,18 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { bool Rect3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { Vector3 c1, c2; - Vector3 end = pos + size; + Vector3 end = position + size; real_t near = -1e20; real_t far = 1e20; int axis = 0; for (int i = 0; i < 3; i++) { if (p_dir[i] == 0) { - if ((p_from[i] < pos[i]) || (p_from[i] > end[i])) { + if ((p_from[i] < position[i]) || (p_from[i] > end[i])) { return false; } } else { // ray not parallel to planes in this direction - c1[i] = (pos[i] - p_from[i]) / p_dir[i]; + c1[i] = (position[i] - p_from[i]) / p_dir[i]; c2[i] = (end[i] - p_from[i]) / p_dir[i]; if (c1[i] > c2[i]) { @@ -156,7 +156,7 @@ bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vecto for (int i = 0; i < 3; i++) { real_t seg_from = p_from[i]; real_t seg_to = p_to[i]; - real_t box_begin = pos[i]; + real_t box_begin = position[i]; real_t box_end = box_begin + size[i]; real_t cmin, cmax; real_t csign; @@ -208,14 +208,14 @@ bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vecto bool Rect3::intersects_plane(const Plane &p_plane) const { Vector3 points[8] = { - Vector3(pos.x, pos.y, pos.z), - Vector3(pos.x, pos.y, pos.z + size.z), - Vector3(pos.x, pos.y + size.y, pos.z), - Vector3(pos.x, pos.y + size.y, pos.z + size.z), - Vector3(pos.x + size.x, pos.y, pos.z), - Vector3(pos.x + size.x, pos.y, pos.z + size.z), - Vector3(pos.x + size.x, pos.y + size.y, pos.z), - Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z), + Vector3(position.x, position.y, position.z), + Vector3(position.x, position.y, position.z + size.z), + Vector3(position.x, position.y + size.y, position.z), + Vector3(position.x, position.y + size.y, position.z + size.z), + Vector3(position.x + size.x, position.y, position.z), + Vector3(position.x + size.x, position.y, position.z + size.z), + Vector3(position.x + size.x, position.y + size.y, position.z), + Vector3(position.x + size.x, position.y + size.y, position.z + size.z), }; bool over = false; @@ -327,68 +327,68 @@ void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { case 0: { - r_from = Vector3(pos.x + size.x, pos.y, pos.z); - r_to = Vector3(pos.x, pos.y, pos.z); + r_from = Vector3(position.x + size.x, position.y, position.z); + r_to = Vector3(position.x, position.y, position.z); } break; case 1: { - r_from = Vector3(pos.x + size.x, pos.y, pos.z + size.z); - r_to = Vector3(pos.x + size.x, pos.y, pos.z); + r_from = Vector3(position.x + size.x, position.y, position.z + size.z); + r_to = Vector3(position.x + size.x, position.y, position.z); } break; case 2: { - r_from = Vector3(pos.x, pos.y, pos.z + size.z); - r_to = Vector3(pos.x + size.x, pos.y, pos.z + size.z); + r_from = Vector3(position.x, position.y, position.z + size.z); + r_to = Vector3(position.x + size.x, position.y, position.z + size.z); } break; case 3: { - r_from = Vector3(pos.x, pos.y, pos.z); - r_to = Vector3(pos.x, pos.y, pos.z + size.z); + r_from = Vector3(position.x, position.y, position.z); + r_to = Vector3(position.x, position.y, position.z + size.z); } break; case 4: { - r_from = Vector3(pos.x, pos.y + size.y, pos.z); - r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z); + r_from = Vector3(position.x, position.y + size.y, position.z); + r_to = Vector3(position.x + size.x, position.y + size.y, position.z); } break; case 5: { - r_from = Vector3(pos.x + size.x, pos.y + size.y, pos.z); - r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z); + r_from = Vector3(position.x + size.x, position.y + size.y, position.z); + r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z); } break; case 6: { - r_from = Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z); - r_to = Vector3(pos.x, pos.y + size.y, pos.z + size.z); + r_from = Vector3(position.x + size.x, position.y + size.y, position.z + size.z); + r_to = Vector3(position.x, position.y + size.y, position.z + size.z); } break; case 7: { - r_from = Vector3(pos.x, pos.y + size.y, pos.z + size.z); - r_to = Vector3(pos.x, pos.y + size.y, pos.z); + r_from = Vector3(position.x, position.y + size.y, position.z + size.z); + r_to = Vector3(position.x, position.y + size.y, position.z); } break; case 8: { - r_from = Vector3(pos.x, pos.y, pos.z + size.z); - r_to = Vector3(pos.x, pos.y + size.y, pos.z + size.z); + r_from = Vector3(position.x, position.y, position.z + size.z); + r_to = Vector3(position.x, position.y + size.y, position.z + size.z); } break; case 9: { - r_from = Vector3(pos.x, pos.y, pos.z); - r_to = Vector3(pos.x, pos.y + size.y, pos.z); + r_from = Vector3(position.x, position.y, position.z); + r_to = Vector3(position.x, position.y + size.y, position.z); } break; case 10: { - r_from = Vector3(pos.x + size.x, pos.y, pos.z); - r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z); + r_from = Vector3(position.x + size.x, position.y, position.z); + r_to = Vector3(position.x + size.x, position.y + size.y, position.z); } break; case 11: { - r_from = Vector3(pos.x + size.x, pos.y, pos.z + size.z); - r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z); + r_from = Vector3(position.x + size.x, position.y, position.z + size.z); + r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z); } break; } @@ -396,5 +396,5 @@ void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { Rect3::operator String() const { - return String() + pos + " - " + size; + return String() + position + " - " + size; } diff --git a/core/math/rect3.h b/core/math/rect3.h index 136a156151..b7c94ad9f7 100644 --- a/core/math/rect3.h +++ b/core/math/rect3.h @@ -36,12 +36,12 @@ /** * AABB / AABB (Axis Aligned Bounding Box) - * This is implemented by a point (pos) and the box size + * This is implemented by a point (position) and the box size */ class Rect3 { public: - Vector3 pos; + Vector3 position; Vector3 size; real_t get_area() const; /// get area @@ -55,8 +55,8 @@ public: return (size.x <= CMP_EPSILON && size.y <= CMP_EPSILON && size.z <= CMP_EPSILON); } - const Vector3 &get_pos() const { return pos; } - void set_pos(const Vector3 &p_pos) { pos = p_pos; } + const Vector3 &get_position() const { return position; } + void set_position(const Vector3 &p_pos) { position = p_pos; } const Vector3 &get_size() const { return size; } void set_size(const Vector3 &p_size) { size = p_size; } @@ -102,24 +102,24 @@ public: _FORCE_INLINE_ Rect3() {} inline Rect3(const Vector3 &p_pos, const Vector3 &p_size) { - pos = p_pos; + position = p_pos; size = p_size; } }; inline bool Rect3::intersects(const Rect3 &p_aabb) const { - if (pos.x >= (p_aabb.pos.x + p_aabb.size.x)) + if (position.x >= (p_aabb.position.x + p_aabb.size.x)) return false; - if ((pos.x + size.x) <= p_aabb.pos.x) + if ((position.x + size.x) <= p_aabb.position.x) return false; - if (pos.y >= (p_aabb.pos.y + p_aabb.size.y)) + if (position.y >= (p_aabb.position.y + p_aabb.size.y)) return false; - if ((pos.y + size.y) <= p_aabb.pos.y) + if ((position.y + size.y) <= p_aabb.position.y) return false; - if (pos.z >= (p_aabb.pos.z + p_aabb.size.z)) + if (position.z >= (p_aabb.position.z + p_aabb.size.z)) return false; - if ((pos.z + size.z) <= p_aabb.pos.z) + if ((position.z + size.z) <= p_aabb.position.z) return false; return true; @@ -127,17 +127,17 @@ inline bool Rect3::intersects(const Rect3 &p_aabb) const { inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const { - if (pos.x > (p_aabb.pos.x + p_aabb.size.x)) + if (position.x > (p_aabb.position.x + p_aabb.size.x)) return false; - if ((pos.x + size.x) < p_aabb.pos.x) + if ((position.x + size.x) < p_aabb.position.x) return false; - if (pos.y > (p_aabb.pos.y + p_aabb.size.y)) + if (position.y > (p_aabb.position.y + p_aabb.size.y)) return false; - if ((pos.y + size.y) < p_aabb.pos.y) + if ((position.y + size.y) < p_aabb.position.y) return false; - if (pos.z > (p_aabb.pos.z + p_aabb.size.z)) + if (position.z > (p_aabb.position.z + p_aabb.size.z)) return false; - if ((pos.z + size.z) < p_aabb.pos.z) + if ((position.z + size.z) < p_aabb.position.z) return false; return true; @@ -145,10 +145,10 @@ inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const { inline bool Rect3::encloses(const Rect3 &p_aabb) const { - Vector3 src_min = pos; - Vector3 src_max = pos + size; - Vector3 dst_min = p_aabb.pos; - Vector3 dst_max = p_aabb.pos + p_aabb.size; + Vector3 src_min = position; + Vector3 src_max = position + size; + Vector3 dst_min = p_aabb.position; + Vector3 dst_max = p_aabb.position + p_aabb.size; return ( (src_min.x <= dst_min.x) && @@ -162,7 +162,7 @@ inline bool Rect3::encloses(const Rect3 &p_aabb) const { Vector3 Rect3::get_support(const Vector3 &p_normal) const { Vector3 half_extents = size * 0.5; - Vector3 ofs = pos + half_extents; + Vector3 ofs = position + half_extents; return Vector3( (p_normal.x > 0) ? -half_extents.x : half_extents.x, @@ -174,14 +174,14 @@ Vector3 Rect3::get_support(const Vector3 &p_normal) const { Vector3 Rect3::get_endpoint(int p_point) const { switch (p_point) { - case 0: return Vector3(pos.x, pos.y, pos.z); - case 1: return Vector3(pos.x, pos.y, pos.z + size.z); - case 2: return Vector3(pos.x, pos.y + size.y, pos.z); - case 3: return Vector3(pos.x, pos.y + size.y, pos.z + size.z); - case 4: return Vector3(pos.x + size.x, pos.y, pos.z); - case 5: return Vector3(pos.x + size.x, pos.y, pos.z + size.z); - case 6: return Vector3(pos.x + size.x, pos.y + size.y, pos.z); - case 7: return Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z); + case 0: return Vector3(position.x, position.y, position.z); + case 1: return Vector3(position.x, position.y, position.z + size.z); + case 2: return Vector3(position.x, position.y + size.y, position.z); + case 3: return Vector3(position.x, position.y + size.y, position.z + size.z); + case 4: return Vector3(position.x + size.x, position.y, position.z); + case 5: return Vector3(position.x + size.x, position.y, position.z + size.z); + case 6: return Vector3(position.x + size.x, position.y + size.y, position.z); + case 7: return Vector3(position.x + size.x, position.y + size.y, position.z + size.z); }; ERR_FAIL_V(Vector3()); @@ -192,7 +192,7 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co #if 1 Vector3 half_extents = size * 0.5; - Vector3 ofs = pos + half_extents; + Vector3 ofs = position + half_extents; for (int i = 0; i < p_plane_count; i++) { const Plane &p = p_planes[i]; @@ -210,14 +210,14 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co //cache all points to check against! // #warning should be easy to optimize, just use the same as when taking the support and use only that point Vector3 points[8] = { - Vector3(pos.x, pos.y, pos.z), - Vector3(pos.x, pos.y, pos.z + size.z), - Vector3(pos.x, pos.y + size.y, pos.z), - Vector3(pos.x, pos.y + size.y, pos.z + size.z), - Vector3(pos.x + size.x, pos.y, pos.z), - Vector3(pos.x + size.x, pos.y, pos.z + size.z), - Vector3(pos.x + size.x, pos.y + size.y, pos.z), - Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z), + Vector3(position.x, position.y, position.z), + Vector3(position.x, position.y, position.z + size.z), + Vector3(position.x, position.y + size.y, position.z), + Vector3(position.x, position.y + size.y, position.z + size.z), + Vector3(position.x + size.x, position.y, position.z), + Vector3(position.x + size.x, position.y, position.z + size.z), + Vector3(position.x + size.x, position.y + size.y, position.z), + Vector3(position.x + size.x, position.y + size.y, position.z + size.z), }; for (int i = 0; i < p_plane_count; i++) { //for each plane @@ -246,17 +246,17 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co bool Rect3::has_point(const Vector3 &p_point) const { - if (p_point.x < pos.x) + if (p_point.x < position.x) return false; - if (p_point.y < pos.y) + if (p_point.y < position.y) return false; - if (p_point.z < pos.z) + if (p_point.z < position.z) return false; - if (p_point.x > pos.x + size.x) + if (p_point.x > position.x + size.x) return false; - if (p_point.y > pos.y + size.y) + if (p_point.y > position.y + size.y) return false; - if (p_point.z > pos.z + size.z) + if (p_point.z > position.z + size.z) return false; return true; @@ -264,8 +264,8 @@ bool Rect3::has_point(const Vector3 &p_point) const { inline void Rect3::expand_to(const Vector3 &p_vector) { - Vector3 begin = pos; - Vector3 end = pos + size; + Vector3 begin = position; + Vector3 end = position + size; if (p_vector.x < begin.x) begin.x = p_vector.x; @@ -281,14 +281,14 @@ inline void Rect3::expand_to(const Vector3 &p_vector) { if (p_vector.z > end.z) end.z = p_vector.z; - pos = begin; + position = begin; size = end - begin; } void Rect3::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5); - Vector3 center(pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z); + Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z); real_t length = p_plane.normal.abs().dot(half_extents); real_t distance = p_plane.distance_to(center); @@ -332,21 +332,21 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t real_t divy = 1.0 / dir.y; real_t divz = 1.0 / dir.z; - Vector3 upbound = pos + size; + Vector3 upbound = position + size; real_t tmin, tmax, tymin, tymax, tzmin, tzmax; if (dir.x >= 0) { - tmin = (pos.x - from.x) * divx; + tmin = (position.x - from.x) * divx; tmax = (upbound.x - from.x) * divx; } else { tmin = (upbound.x - from.x) * divx; - tmax = (pos.x - from.x) * divx; + tmax = (position.x - from.x) * divx; } if (dir.y >= 0) { - tymin = (pos.y - from.y) * divy; + tymin = (position.y - from.y) * divy; tymax = (upbound.y - from.y) * divy; } else { tymin = (upbound.y - from.y) * divy; - tymax = (pos.y - from.y) * divy; + tymax = (position.y - from.y) * divy; } if ((tmin > tymax) || (tymin > tmax)) return false; @@ -355,11 +355,11 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t if (tymax < tmax) tmax = tymax; if (dir.z >= 0) { - tzmin = (pos.z - from.z) * divz; + tzmin = (position.z - from.z) * divz; tzmax = (upbound.z - from.z) * divz; } else { tzmin = (upbound.z - from.z) * divz; - tzmax = (pos.z - from.z) * divz; + tzmax = (position.z - from.z) * divz; } if ((tmin > tzmax) || (tzmin > tmax)) return false; @@ -372,9 +372,9 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t void Rect3::grow_by(real_t p_amount) { - pos.x -= p_amount; - pos.y -= p_amount; - pos.z -= p_amount; + position.x -= p_amount; + position.y -= p_amount; + position.z -= p_amount; size.x += 2.0 * p_amount; size.y += 2.0 * p_amount; size.z += 2.0 * p_amount; diff --git a/core/math/transform.cpp b/core/math/transform.cpp index e53e6cf519..7a50214596 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -82,7 +82,10 @@ Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) co } void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) { - +#ifdef MATH_CHECKS + ERR_FAIL_COND(p_eye == p_target); + ERR_FAIL_COND(p_up.length() == 0); +#endif // Reference: MESA source code Vector3 v_x, v_y, v_z; @@ -96,6 +99,9 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const v_y = p_up; v_x = v_y.cross(v_z); +#ifdef MATH_CHECKS + ERR_FAIL_COND(v_x.length() == 0); +#endif /* Recompute Y = Z cross X */ v_y = v_z.cross(v_x); @@ -103,9 +109,8 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const v_x.normalize(); v_y.normalize(); - basis.set_axis(0, v_x); - basis.set_axis(1, v_y); - basis.set_axis(2, v_z); + basis.set(v_x, v_y, v_z); + origin = p_eye; } diff --git a/core/math/transform.h b/core/math/transform.h index 4731496bf3..48467f2ed7 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -97,15 +97,7 @@ public: void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz) { - basis.elements[0][0] = xx; - basis.elements[0][1] = xy; - basis.elements[0][2] = xz; - basis.elements[1][0] = yx; - basis.elements[1][1] = yy; - basis.elements[1][2] = yz; - basis.elements[2][0] = zx; - basis.elements[2][1] = zy; - basis.elements[2][2] = zz; + basis.set(xx, xy, xz, yx, yy, yz, zx, zy, zz); origin.x = tx; origin.y = ty; origin.z = tz; @@ -167,10 +159,10 @@ _FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const { Vector3 x = basis.get_axis(0) * p_aabb.size.x; Vector3 y = basis.get_axis(1) * p_aabb.size.y; Vector3 z = basis.get_axis(2) * p_aabb.size.z; - Vector3 pos = xform(p_aabb.pos); + Vector3 pos = xform(p_aabb.position); //could be even further optimized Rect3 new_aabb; - new_aabb.pos = pos; + new_aabb.position = pos; new_aabb.expand_to(pos + x); new_aabb.expand_to(pos + y); new_aabb.expand_to(pos + z); @@ -182,14 +174,14 @@ _FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const { #else Vector3 vertices[8] = { - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z), - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z) + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z), + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z), + Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z), + Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z) }; AABB ret; @@ -208,19 +200,19 @@ _FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const { /* define vertices */ Vector3 vertices[8] = { - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z), - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z), - Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z) + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z), + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z), + Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z), + Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z), + Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z) }; Rect3 ret; - ret.pos = xform_inv(vertices[0]); + ret.position = xform_inv(vertices[0]); for (int i = 1; i < 8; i++) { diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 1cf1351646..1df3c8c298 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -79,7 +79,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in int index = max_alloc++; BVH *_new = &p_bvh[index]; _new->aabb = aabb; - _new->center = aabb.pos + aabb.size * 0.5; + _new->center = aabb.position + aabb.size * 0.5; _new->face_index = -1; _new->left = left; _new->right = right; @@ -117,7 +117,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { for (int j = 0; j < 3; j++) { int vidx = -1; - Vector3 vs = v[j].snapped(0.0001); + Vector3 vs = v[j].snapped(Vector3(0.0001, 0.0001, 0.0001)); Map<Vector3, int>::Element *E = db.find(vs); if (E) { vidx = E->get(); @@ -128,7 +128,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { f.indices[j] = vidx; if (j == 0) - bw[i].aabb.pos = vs; + bw[i].aabb.position = vs; else bw[i].aabb.expand_to(vs); } @@ -138,7 +138,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { bw[i].left = -1; bw[i].right = -1; bw[i].face_index = i; - bw[i].center = bw[i].aabb.pos + bw[i].aabb.size * 0.5; + bw[i].center = bw[i].aabb.position + bw[i].aabb.size * 0.5; } vertices.resize(db.size()); diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index e413cc147d..efffacb36e 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -61,13 +61,13 @@ int Vector3::max_axis() const { return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0); } -void Vector3::snap(real_t p_val) { +void Vector3::snap(Vector3 p_val) { - x = Math::stepify(x, p_val); - y = Math::stepify(y, p_val); - z = Math::stepify(z, p_val); + x = Math::stepify(x, p_val.x); + y = Math::stepify(y, p_val.y); + z = Math::stepify(z, p_val.z); } -Vector3 Vector3::snapped(real_t p_val) const { +Vector3 Vector3::snapped(Vector3 p_val) const { Vector3 v = *this; v.snap(p_val); diff --git a/core/math/vector3.h b/core/math/vector3.h index 5f4390fbd1..7dfcedd0da 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -81,8 +81,8 @@ struct Vector3 { _FORCE_INLINE_ void zero(); - void snap(real_t p_val); - Vector3 snapped(real_t p_val) const; + void snap(Vector3 p_val); + Vector3 snapped(Vector3 p_val) const; void rotate(const Vector3 &p_axis, real_t p_phi); Vector3 rotated(const Vector3 &p_axis, real_t p_phi) const; diff --git a/core/method_bind.h b/core/method_bind.h index 8d72c8573a..dbc9cca082 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -343,6 +343,6 @@ MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, i // if you declare an nonexistent class.. class __UnexistingClass; -#include "method_bind.inc" +#include "method_bind.gen.inc" #endif diff --git a/core/object.cpp b/core/object.cpp index 7aee936a2d..3416cd8c5a 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -419,6 +419,16 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid if (r_valid) *r_valid = true; return; +#ifdef TOOLS_ENABLED + } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) { + Array arr = p_value; + for (int i = 0; i < arr.size(); i++) { + editor_section_folding.insert(arr[i]); + } + if (r_valid) + *r_valid = true; + return; +#endif } else { //something inside the object... :| bool success = _setv(p_name, p_value); @@ -464,6 +474,16 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { if (r_valid) *r_valid = true; return ret; +#ifdef TOOLS_ENABLED + } else if (p_name == CoreStringNames::get_singleton()->_sections_unfolded) { + Array array; + for (Set<String>::Element *E = editor_section_folding.front(); E; E = E->next()) { + array.push_back(E->get()); + } + if (r_valid) + *r_valid = true; + return array; +#endif } else { //something inside the object... :| bool success = _getv(p_name, ret); @@ -516,6 +536,11 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons if (!is_class("Script")) // can still be set, but this is for userfriendlyness p_list->push_back(PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NONZERO)); +#ifdef TOOLS_ENABLED + if (editor_section_folding.size()) { + p_list->push_back(PropertyInfo(Variant::ARRAY, CoreStringNames::get_singleton()->_sections_unfolded, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR)); + } +#endif if (!metadata.empty()) p_list->push_back(PropertyInfo(Variant::DICTIONARY, "__meta__", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_STORE_IF_NONZERO)); if (script_instance && !p_reversed) { @@ -1332,6 +1357,21 @@ Array Object::_get_signal_connection_list(const String &p_signal) const { return ret; } +Array Object::_get_incoming_connections() const { + + Array ret; + int connections_amount = connections.size(); + for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) { + Dictionary conn_data; + conn_data["source"] = connections[idx_conn].source; + conn_data["signal_name"] = connections[idx_conn].signal; + conn_data["method_name"] = connections[idx_conn].method; + ret.push_back(conn_data); + } + + return ret; +} + void Object::get_signal_list(List<MethodInfo> *p_signals) const { if (!script.is_null()) { @@ -1571,6 +1611,23 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { } } +#ifdef TOOLS_ENABLED +void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded) { + + set_edited(true); + if (p_unfolded) + editor_section_folding.insert(p_section); + else + editor_section_folding.erase(p_section); +} + +bool Object::editor_is_section_unfolded(const String &p_section) { + + return editor_section_folding.has(p_section); +} + +#endif + void Object::clear_internal_resource_paths() { List<PropertyInfo> pinfo; @@ -1641,6 +1698,7 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("get_signal_list"), &Object::_get_signal_list); ClassDB::bind_method(D_METHOD("get_signal_connection_list", "signal"), &Object::_get_signal_connection_list); + ClassDB::bind_method(D_METHOD("get_incoming_connections"), &Object::_get_incoming_connections); ClassDB::bind_method(D_METHOD("connect", "signal", "target:Object", "method", "binds", "flags"), &Object::connect, DEFVAL(Array()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("disconnect", "signal", "target:Object", "method"), &Object::disconnect); @@ -1831,10 +1889,10 @@ void postinitialize_handler(Object *p_object) { p_object->_postinitialize(); } -HashMap<uint32_t, Object *> ObjectDB::instances; -uint32_t ObjectDB::instance_counter = 1; +HashMap<ObjectID, Object *> ObjectDB::instances; +ObjectID ObjectDB::instance_counter = 1; HashMap<Object *, ObjectID, ObjectDB::ObjectPtrHash> ObjectDB::instance_checks; -uint32_t ObjectDB::add_instance(Object *p_object) { +ObjectID ObjectDB::add_instance(Object *p_object) { ERR_FAIL_COND_V(p_object->get_instance_ID() != 0, 0); @@ -1859,7 +1917,7 @@ void ObjectDB::remove_instance(Object *p_object) { rw_lock->write_unlock(); } -Object *ObjectDB::get_instance(uint32_t p_instance_ID) { +Object *ObjectDB::get_instance(ObjectID p_instance_ID) { rw_lock->read_lock(); Object **obj = instances.getptr(p_instance_ID); @@ -1874,7 +1932,7 @@ void ObjectDB::debug_objects(DebugFunc p_func) { rw_lock->read_lock(); - const uint32_t *K = NULL; + const ObjectID *K = NULL; while ((K = instances.next(K))) { p_func(instances[*K]); @@ -1909,7 +1967,7 @@ void ObjectDB::cleanup() { WARN_PRINT("ObjectDB Instances still exist!"); if (OS::get_singleton()->is_stdout_verbose()) { - const uint32_t *K = NULL; + const ObjectID *K = NULL; while ((K = instances.next(K))) { String node_name; diff --git a/core/object.h b/core/object.h index 3b39224af0..f87705c48b 100644 --- a/core/object.h +++ b/core/object.h @@ -350,7 +350,7 @@ public: \ private: class ScriptInstance; -typedef uint32_t ObjectID; +typedef uint64_t ObjectID; class Object { public: @@ -423,13 +423,14 @@ private: bool _block_signals; int _predelete_ok; Set<Object *> change_receptors; - uint32_t _instance_ID; + ObjectID _instance_ID; bool _predelete(); void _postinitialize(); bool _can_translate; #ifdef TOOLS_ENABLED bool _edited; uint32_t _edited_version; + Set<String> editor_section_folding; #endif ScriptInstance *script_instance; RefPtr script; @@ -442,6 +443,7 @@ private: Variant _emit_signal(const Variant **p_args, int p_argcount, Variant::CallError &r_error); Array _get_signal_list() const; Array _get_signal_connection_list(const String &p_signal) const; + Array _get_incoming_connections() const; void _set_bind(const String &p_set, const Variant &p_value); Variant _get_bind(const String &p_name) const; @@ -531,6 +533,12 @@ public: void add_change_receptor(Object *p_receptor); void remove_change_receptor(Object *p_receptor); +// TODO: ensure 'this' is never NULL since it's UB, but by now, avoid warning flood +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-bool-conversion" +#endif + template <class T> T *cast_to() { @@ -561,6 +569,10 @@ public: #endif } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + enum { NOTIFICATION_POSTINITIALIZE = 0, @@ -666,6 +678,11 @@ public: _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; } _FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; } +#ifdef TOOLS_ENABLED + void editor_set_section_unfold(const String &p_section, bool p_unfolded); + bool editor_is_section_unfolded(const String &p_section); +#endif + void clear_internal_resource_paths(); Object(); @@ -690,16 +707,16 @@ class ObjectDB { } }; - static HashMap<uint32_t, Object *> instances; + static HashMap<ObjectID, Object *> instances; static HashMap<Object *, ObjectID, ObjectPtrHash> instance_checks; - static uint32_t instance_counter; + static ObjectID instance_counter; friend class Object; friend void unregister_core_types(); static RWLock *rw_lock; static void cleanup(); - static uint32_t add_instance(Object *p_object); + static ObjectID add_instance(Object *p_object); static void remove_instance(Object *p_object); friend void register_core_types(); static void setup(); @@ -707,7 +724,7 @@ class ObjectDB { public: typedef void (*DebugFunc)(Object *p_obj); - static Object *get_instance(uint32_t p_instance_ID); + static Object *get_instance(ObjectID p_instance_ID); static void debug_objects(DebugFunc p_func); static int get_object_count(); diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 7ec76c1eed..1c575aa970 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -89,6 +89,11 @@ bool InputEvent::action_match(const Ref<InputEvent> &p_event) const { return false; } +bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const { + + return false; +} + bool InputEvent::is_action_type() const { return false; @@ -130,10 +135,13 @@ void InputEvent::_bind_methods() { ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text); ClassDB::bind_method(D_METHOD("action_match", "event:InputEvent"), &InputEvent::action_match); + ClassDB::bind_method(D_METHOD("shortcut_match", "event:InputEvent"), &InputEvent::shortcut_match); ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type); ClassDB::bind_method(D_METHOD("xformed_by:InputEvent", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2())); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device"); } InputEvent::InputEvent() { @@ -276,13 +284,49 @@ uint32_t InputEventKey::get_scancode_with_modifiers() const { return sc; } +String InputEventKey::as_text() const { + + String kc = keycode_get_string(scancode); + if (kc == String()) + return kc; + + if (get_metakey()) { + kc = "Meta+" + kc; + } + if (get_alt()) { + kc = "Alt+" + kc; + } + if (get_shift()) { + kc = "Shift+" + kc; + } + if (get_control()) { + kc = "Ctrl+" + kc; + } + return kc; +} + bool InputEventKey::action_match(const Ref<InputEvent> &p_event) const { Ref<InputEventKey> key = p_event; if (key.is_null()) return false; - return get_scancode_with_modifiers() == key->get_scancode_with_modifiers(); + uint32_t code = get_scancode_with_modifiers(); + uint32_t event_code = key->get_scancode_with_modifiers(); + + return get_scancode() == key->get_scancode() && (!key->is_pressed() || (code & event_code) == code); +} + +bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const { + + Ref<InputEventKey> key = p_event; + if (key.is_null()) + return false; + + uint32_t code = get_scancode_with_modifiers(); + uint32_t event_code = key->get_scancode_with_modifiers(); + + return code == event_code; } void InputEventKey::_bind_methods() { @@ -324,20 +368,20 @@ int InputEventMouse::get_button_mask() const { return button_mask; } -void InputEventMouse::set_pos(const Vector2 &p_pos) { +void InputEventMouse::set_position(const Vector2 &p_pos) { pos = p_pos; } -Vector2 InputEventMouse::get_pos() const { +Vector2 InputEventMouse::get_position() const { return pos; } -void InputEventMouse::set_global_pos(const Vector2 &p_global_pos) { +void InputEventMouse::set_global_position(const Vector2 &p_global_pos) { global_pos = p_global_pos; } -Vector2 InputEventMouse::get_global_pos() const { +Vector2 InputEventMouse::get_global_position() const { return global_pos; } @@ -347,15 +391,15 @@ void InputEventMouse::_bind_methods() { ClassDB::bind_method(D_METHOD("set_button_mask", "button_mask"), &InputEventMouse::set_button_mask); ClassDB::bind_method(D_METHOD("get_button_mask"), &InputEventMouse::get_button_mask); - ClassDB::bind_method(D_METHOD("set_pos", "pos"), &InputEventMouse::set_pos); - ClassDB::bind_method(D_METHOD("get_pos"), &InputEventMouse::get_pos); + ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventMouse::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &InputEventMouse::get_position); - ClassDB::bind_method(D_METHOD("set_global_pos", "global_pos"), &InputEventMouse::set_global_pos); - ClassDB::bind_method(D_METHOD("get_global_pos"), &InputEventMouse::get_global_pos); + ClassDB::bind_method(D_METHOD("set_global_position", "global_position"), &InputEventMouse::set_global_position); + ClassDB::bind_method(D_METHOD("get_global_position"), &InputEventMouse::get_global_position); ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask"), "set_button_mask", "get_button_mask"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pos"), "set_pos", "get_pos"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_pos"), "set_global_pos", "get_global_pos"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position"), "set_global_position", "get_global_position"); } InputEventMouse::InputEventMouse() { @@ -404,8 +448,8 @@ bool InputEventMouseButton::is_doubleclick() const { Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - Vector2 g = p_xform.xform(get_global_pos()); - Vector2 l = p_xform.xform(get_pos() + p_local_ofs); + Vector2 g = p_xform.xform(get_global_position()); + Vector2 l = p_xform.xform(get_position() + p_local_ofs); Ref<InputEventMouseButton> mb; mb.instance(); @@ -418,8 +462,8 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co mb->set_control(get_control()); mb->set_metakey(get_metakey()); - mb->set_pos(l); - mb->set_global_pos(g); + mb->set_position(l); + mb->set_global_position(g); mb->set_button_mask(get_button_mask()); mb->set_pressed(pressed); @@ -489,8 +533,8 @@ Vector2 InputEventMouseMotion::get_speed() const { Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { - Vector2 g = p_xform.xform(get_global_pos()); - Vector2 l = p_xform.xform(get_pos() + p_local_ofs); + Vector2 g = p_xform.xform(get_global_position()); + Vector2 l = p_xform.xform(get_position() + p_local_ofs); Vector2 r = p_xform.basis_xform(get_relative()); Vector2 s = p_xform.basis_xform(get_speed()); @@ -505,8 +549,8 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co mm->set_control(get_control()); mm->set_metakey(get_metakey()); - mm->set_pos(l); - mm->set_global_pos(g); + mm->set_position(l); + mm->set_global_position(g); mm->set_button_mask(get_button_mask()); mm->set_relative(r); @@ -650,11 +694,11 @@ int InputEventScreenTouch::get_index() const { return index; } -void InputEventScreenTouch::set_pos(const Vector2 &p_pos) { +void InputEventScreenTouch::set_position(const Vector2 &p_pos) { pos = p_pos; } -Vector2 InputEventScreenTouch::get_pos() const { +Vector2 InputEventScreenTouch::get_position() const { return pos; } @@ -675,7 +719,7 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co st->set_id(get_id()); st->set_device(get_device()); st->set_index(index); - st->set_pos(p_xform.xform(pos + p_local_ofs)); + st->set_position(p_xform.xform(pos + p_local_ofs)); st->set_pressed(pressed); return st; @@ -686,14 +730,14 @@ void InputEventScreenTouch::_bind_methods() { ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenTouch::set_index); ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenTouch::get_index); - ClassDB::bind_method(D_METHOD("set_pos", "pos"), &InputEventScreenTouch::set_pos); - ClassDB::bind_method(D_METHOD("get_pos"), &InputEventScreenTouch::get_pos); + ClassDB::bind_method(D_METHOD("set_position", "pos"), &InputEventScreenTouch::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenTouch::get_position); ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventScreenTouch::set_pressed); //ClassDB::bind_method(D_METHOD("is_pressed"),&InputEventScreenTouch::is_pressed); ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pos"), "set_pos", "get_pos"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed"); } @@ -715,11 +759,11 @@ int InputEventScreenDrag::get_index() const { return index; } -void InputEventScreenDrag::set_pos(const Vector2 &p_pos) { +void InputEventScreenDrag::set_position(const Vector2 &p_pos) { pos = p_pos; } -Vector2 InputEventScreenDrag::get_pos() const { +Vector2 InputEventScreenDrag::get_position() const { return pos; } @@ -752,7 +796,7 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con sd->set_device(get_device()); sd->set_index(index); - sd->set_pos(p_xform.xform(pos + p_local_ofs)); + sd->set_position(p_xform.xform(pos + p_local_ofs)); sd->set_relative(p_xform.basis_xform(relative)); sd->set_speed(p_xform.basis_xform(speed)); @@ -764,8 +808,8 @@ void InputEventScreenDrag::_bind_methods() { ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index); ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index); - ClassDB::bind_method(D_METHOD("set_pos", "pos"), &InputEventScreenDrag::set_pos); - ClassDB::bind_method(D_METHOD("get_pos"), &InputEventScreenDrag::get_pos); + ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventScreenDrag::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenDrag::get_position); ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative); ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative); @@ -774,7 +818,7 @@ void InputEventScreenDrag::_bind_methods() { ClassDB::bind_method(D_METHOD("get_speed"), &InputEventScreenDrag::get_speed); ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "pos"), "set_pos", "get_pos"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed"); } diff --git a/core/os/input_event.h b/core/os/input_event.h index 31f88b295b..b120d4b840 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -165,6 +165,7 @@ public: virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; virtual bool action_match(const Ref<InputEvent> &p_event) const; + virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; virtual bool is_action_type() const; InputEvent(); @@ -243,9 +244,12 @@ public: uint32_t get_scancode_with_modifiers() const; virtual bool action_match(const Ref<InputEvent> &p_event) const; + virtual bool shortcut_match(const Ref<InputEvent> &p_event) const; virtual bool is_action_type() const { return true; } + virtual String as_text() const; + InputEventKey(); }; @@ -265,11 +269,11 @@ public: void set_button_mask(int p_mask); int get_button_mask() const; - void set_pos(const Vector2 &p_pos); - Vector2 get_pos() const; + void set_position(const Vector2 &p_pos); + Vector2 get_position() const; - void set_global_pos(const Vector2 &p_global_pos); - Vector2 get_global_pos() const; + void set_global_position(const Vector2 &p_global_pos); + Vector2 get_global_position() const; InputEventMouse(); }; @@ -390,8 +394,8 @@ public: void set_index(int p_index); int get_index() const; - void set_pos(const Vector2 &p_pos); - Vector2 get_pos() const; + void set_position(const Vector2 &p_pos); + Vector2 get_position() const; void set_pressed(bool p_pressed); virtual bool is_pressed() const; @@ -416,8 +420,8 @@ public: void set_index(int p_index); int get_index() const; - void set_pos(const Vector2 &p_pos); - Vector2 get_pos() const; + void set_position(const Vector2 &p_pos); + Vector2 get_position() const; void set_relative(const Vector2 &p_relative); Vector2 get_relative() const; diff --git a/core/reference.h b/core/reference.h index afc097817a..4e2d6c36c0 100644 --- a/core/reference.h +++ b/core/reference.h @@ -344,7 +344,7 @@ struct PtrToArg<const Ref<T> &> { _FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) { - return Ref<T>(reinterpret_cast<const T *>(p_ptr)); + return Ref<T>((T *)p_ptr); } }; diff --git a/core/resource.cpp b/core/resource.cpp index 559d4c1201..a7a5498ef6 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -31,9 +31,9 @@ #include "core_string_names.h" #include "io/resource_loader.h" +#include "io/resource_loader.h" #include "os/file_access.h" #include "script_language.h" - #include <stdio.h> void Resource::emit_changed() { @@ -127,7 +127,7 @@ void Resource::reload_from_file() { if (!path.is_resource_file()) return; - Ref<Resource> s = ResourceLoader::load(path, get_class(), true); + Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true); if (!s.is_valid()) return; @@ -302,6 +302,31 @@ void Resource::setup_local_to_scene() { Node *(*Resource::_get_local_scene_func)() = NULL; +void Resource::set_as_translation_remapped(bool p_remapped) { + + if (remapped_list.in_list() == p_remapped) + return; + + if (ResourceCache::lock) { + ResourceCache::lock->write_lock(); + } + + if (p_remapped) { + ResourceLoader::remapped_list.add(&remapped_list); + } else { + ResourceLoader::remapped_list.remove(&remapped_list); + } + + if (ResourceCache::lock) { + ResourceCache::lock->write_unlock(); + } +} + +bool Resource::is_translation_remapped() const { + + return remapped_list.in_list(); +} + void Resource::_bind_methods() { ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path); @@ -325,7 +350,8 @@ void Resource::_bind_methods() { BIND_VMETHOD(MethodInfo("_setup_local_to_scene")); } -Resource::Resource() { +Resource::Resource() + : remapped_list(this) { #ifdef TOOLS_ENABLED last_modified_time = 0; diff --git a/core/resource.h b/core/resource.h index 903edeff52..5a4e45da36 100644 --- a/core/resource.h +++ b/core/resource.h @@ -35,6 +35,7 @@ #include "ref_ptr.h" #include "reference.h" #include "safe_refcount.h" +#include "self_list.h" /** @author Juan Linietsky <reduzio@gmail.com> @@ -74,6 +75,8 @@ class Resource : public Reference { friend class SceneState; Node *local_scene; + SelfList<Resource> remapped_list; + protected: void emit_changed(); @@ -127,6 +130,9 @@ public: #endif + void set_as_translation_remapped(bool p_remapped); + bool is_translation_remapped() const; + virtual RID get_rid() const; // some resources may offer conversion to RID Resource(); @@ -137,6 +143,7 @@ typedef Ref<Resource> RES; class ResourceCache { friend class Resource; + friend class ResourceLoader; //need the lock static RWLock *lock; static HashMap<String, Resource *> resources; friend void unregister_core_types(); diff --git a/core/script_language.h b/core/script_language.h index 115ab59dca..6e39593a89 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -196,6 +196,8 @@ public: virtual void get_comment_delimiters(List<String> *p_delimiters) const = 0; virtual void get_string_delimiters(List<String> *p_delimiters) const = 0; virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0; + virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {} + virtual bool is_using_templates() { return false; } virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0; virtual Script *create_script() const = 0; virtual bool has_named_classes() const = 0; diff --git a/core/sort.h b/core/sort.h index a45eb8865a..06c427f61e 100644 --- a/core/sort.h +++ b/core/sort.h @@ -46,7 +46,7 @@ class SortArray { enum { - INTROSORT_TRESHOLD = 16 + INTROSORT_THRESHOLD = 16 }; public: @@ -180,7 +180,7 @@ public: inline void introsort(int p_first, int p_last, T *p_array, int p_max_depth) const { - while (p_last - p_first > INTROSORT_TRESHOLD) { + while (p_last - p_first > INTROSORT_THRESHOLD) { if (p_max_depth == 0) { partial_sort(p_first, p_last, p_last, p_array); @@ -273,9 +273,9 @@ public: inline void final_insertion_sort(int p_first, int p_last, T *p_array) const { - if (p_last - p_first > INTROSORT_TRESHOLD) { - insertion_sort(p_first, p_first + INTROSORT_TRESHOLD, p_array); - unguarded_insertion_sort(p_first + INTROSORT_TRESHOLD, p_last, p_array); + if (p_last - p_first > INTROSORT_THRESHOLD) { + insertion_sort(p_first, p_first + INTROSORT_THRESHOLD, p_array); + unguarded_insertion_sort(p_first + INTROSORT_THRESHOLD, p_last, p_array); } else { insertion_sort(p_first, p_last, p_array); diff --git a/core/translation.cpp b/core/translation.cpp index bd670167f9..72231ef295 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -870,6 +870,10 @@ void Translation::set_locale(const String &p_locale) { } else { locale = univ_locale; } + + if (OS::get_singleton()->get_main_loop()) { + OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); + } } void Translation::add_message(const StringName &p_src_text, const StringName &p_xlated_text) { @@ -945,6 +949,8 @@ void TranslationServer::set_locale(const String &p_locale) { if (OS::get_singleton()->get_main_loop()) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); } + + ResourceLoader::reload_translation_remaps(); } String TranslationServer::get_locale() const { diff --git a/core/translation.h b/core/translation.h index 577282b45f..8630b8a478 100644 --- a/core/translation.h +++ b/core/translation.h @@ -36,7 +36,7 @@ class Translation : public Resource { GDCLASS(Translation, Resource); OBJ_SAVE_TYPE(Translation); - RES_BASE_EXTENSION("xl"); + RES_BASE_EXTENSION("translation"); String locale; Map<StringName, StringName> translation_map; diff --git a/core/ustring.cpp b/core/ustring.cpp index 6a93d7789e..ab4528e495 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -65,7 +65,7 @@ bool CharString::operator<(const CharString &p_right) const { } const char *this_str = get_data(); - const char *that_str = get_data(); + const char *that_str = p_right.get_data(); while (true) { if (*that_str == 0 && *this_str == 0) @@ -96,6 +96,12 @@ const char *CharString::get_data() const { void String::copy_from(const char *p_cstr) { + if (!p_cstr) { + + resize(0); + return; + } + int len = 0; const char *ptr = p_cstr; while (*(ptr++) != 0) @@ -119,6 +125,12 @@ void String::copy_from(const char *p_cstr) { void String::copy_from(const CharType *p_cstr, int p_clip_to) { + if (!p_cstr) { + + resize(0); + return; + } + int len = 0; const CharType *ptr = p_cstr; while (*(ptr++) != 0) diff --git a/core/variant.cpp b/core/variant.cpp index ae5141b8bf..0807a33788 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2549,8 +2549,8 @@ uint32_t Variant::hash() const { } break; case RECT2: { - uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->pos.x); - hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->pos.y, hash); + uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.x); + hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.y, hash); hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.x, hash); return hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.y, hash); } break; @@ -2590,7 +2590,7 @@ uint32_t Variant::hash() const { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { - hash = hash_djb2_one_float(_data._rect3->pos[i], hash); + hash = hash_djb2_one_float(_data._rect3->position[i], hash); hash = hash_djb2_one_float(_data._rect3->size[i], hash); } @@ -2820,7 +2820,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { const Rect2 *l = reinterpret_cast<const Rect2 *>(_data._mem); const Rect2 *r = reinterpret_cast<const Rect2 *>(p_variant._data._mem); - return (hash_compare_vector2(l->pos, r->pos)) && + return (hash_compare_vector2(l->position, r->position)) && (hash_compare_vector2(l->size, r->size)); } break; @@ -2855,7 +2855,7 @@ bool Variant::hash_compare(const Variant &p_variant) const { const Rect3 *l = _data._rect3; const Rect3 *r = p_variant._data._rect3; - return (hash_compare_vector3(l->pos, r->pos) && + return (hash_compare_vector3(l->position, r->position) && (hash_compare_vector3(l->size, r->size))); } break; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 6568dc877e..6936a362e1 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -30,6 +30,7 @@ #include "variant.h" #include "core_string_names.h" +#include "io/compression.h" #include "object.h" #include "os/os.h" #include "script_language.h" @@ -354,6 +355,8 @@ struct _VariantCall { VCALL_LOCALMEM1R(Rect2, merge); VCALL_LOCALMEM1R(Rect2, has_point); VCALL_LOCALMEM1R(Rect2, grow); + VCALL_LOCALMEM2R(Rect2, grow_margin); + VCALL_LOCALMEM4R(Rect2, grow_individual); VCALL_LOCALMEM1R(Rect2, expand); VCALL_LOCALMEM0R(Vector3, min_axis); @@ -507,6 +510,44 @@ struct _VariantCall { r_ret = s; } + static void _call_PoolByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) { + + PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); + PoolByteArray compressed; + Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]); + + compressed.resize(Compression::get_max_compressed_buffer_size(ba->size())); + int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode); + + result = result >= 0 ? result : 0; + compressed.resize(result); + + r_ret = compressed; + } + + static void _call_PoolByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) { + + PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem); + PoolByteArray decompressed; + Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]); + + int buffer_size = (int)(*p_args[0]); + + if (buffer_size < 0) { + r_ret = decompressed; + ERR_EXPLAIN("Decompression buffer size is less than zero"); + ERR_FAIL(); + } + + decompressed.resize(buffer_size); + int result = Compression::decompress(decompressed.write().ptr(), buffer_size, ba->read().ptr(), ba->size(), mode); + + result = result >= 0 ? result : 0; + decompressed.resize(result); + + r_ret = decompressed; + } + VCALL_LOCALMEM0R(PoolByteArray, size); VCALL_LOCALMEM2(PoolByteArray, set); VCALL_LOCALMEM1R(PoolByteArray, get); @@ -1433,6 +1474,8 @@ void register_variant_methods() { ADDFUNC1(RECT2, RECT2, Rect2, merge, RECT2, "b", varray()); ADDFUNC1(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray()); ADDFUNC1(RECT2, RECT2, Rect2, grow, REAL, "by", varray()); + ADDFUNC2(RECT2, RECT2, Rect2, grow_margin, INT, "margin", REAL, "by", varray()); + ADDFUNC4(RECT2, RECT2, Rect2, grow_individual, REAL, "left", REAL, "top", REAL, "right", REAL, " bottom", varray()); ADDFUNC1(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray()); ADDFUNC0(VECTOR3, INT, Vector3, min_axis, varray()); @@ -1548,6 +1591,8 @@ void register_variant_methods() { ADDFUNC0(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray()); ADDFUNC0(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray()); + ADDFUNC1(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0)); + ADDFUNC2(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0)); ADDFUNC0(POOL_INT_ARRAY, INT, PoolIntArray, size, varray()); ADDFUNC2(POOL_INT_ARRAY, NIL, PoolIntArray, set, INT, "idx", INT, "integer", varray()); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 7b9b7abd9e..5fda6b1473 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -1109,11 +1109,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) const String *str = reinterpret_cast<const String *>(p_index._data._mem); Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem); - if (*str == "x" || *str == "width") { + if (*str == "x") { valid = true; v->x = p_value; return; - } else if (*str == "y" || *str == "height") { + } else if (*str == "y") { valid = true; v->y = p_value; return; @@ -1131,9 +1131,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) const String *str = reinterpret_cast<const String *>(p_index._data._mem); Rect2 *v = reinterpret_cast<Rect2 *>(_data._mem); - if (*str == "pos") { + if (*str == "position") { valid = true; - v->pos = p_value; + v->position = p_value; return; } else if (*str == "size") { valid = true; @@ -1141,7 +1141,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) return; } else if (*str == "end") { valid = true; - v->size = Vector2(p_value) - v->pos; + v->size = Vector2(p_value) - v->position; return; } } @@ -1177,7 +1177,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) valid = true; v->elements[1] = p_value; return; - } else if (*str == "o") { + } else if (*str == "origin") { valid = true; v->elements[2] = p_value; return; @@ -1304,9 +1304,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) const String *str = reinterpret_cast<const String *>(p_index._data._mem); Rect3 *v = _data._rect3; - if (*str == "pos") { + if (*str == "position") { valid = true; - v->pos = p_value; + v->position = p_value; return; } else if (*str == "size") { valid = true; @@ -1314,7 +1314,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) return; } else if (*str == "end") { valid = true; - v->size = Vector3(p_value) - v->pos; + v->size = Vector3(p_value) - v->position; return; } } @@ -1572,10 +1572,10 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { const String *str = reinterpret_cast<const String *>(p_index._data._mem); const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem); - if (*str == "x" || *str == "width") { + if (*str == "x") { valid = true; return v->x; - } else if (*str == "y" || *str == "height") { + } else if (*str == "y") { valid = true; return v->y; } @@ -1589,15 +1589,15 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { const String *str = reinterpret_cast<const String *>(p_index._data._mem); const Rect2 *v = reinterpret_cast<const Rect2 *>(_data._mem); - if (*str == "pos") { + if (*str == "position") { valid = true; - return v->pos; + return v->position; } else if (*str == "size") { valid = true; return v->size; } else if (*str == "end") { valid = true; - return v->size + v->pos; + return v->size + v->position; } } } break; @@ -1657,7 +1657,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { } else if (*str == "y") { valid = true; return v->elements[1]; - } else if (*str == "o") { + } else if (*str == "origin") { valid = true; return v->elements[2]; } @@ -1718,15 +1718,15 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { const String *str = reinterpret_cast<const String *>(p_index._data._mem); const Rect3 *v = _data._rect3; - if (*str == "pos") { + if (*str == "position") { valid = true; - return v->pos; + return v->position; } else if (*str == "size") { valid = true; return v->size; } else if (*str == "end") { valid = true; - return v->size + v->pos; + return v->size + v->position; } } } break; @@ -2105,13 +2105,11 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::REAL, "x")); p_list->push_back(PropertyInfo(Variant::REAL, "y")); - p_list->push_back(PropertyInfo(Variant::REAL, "width")); - p_list->push_back(PropertyInfo(Variant::REAL, "height")); } break; // 5 case RECT2: { - p_list->push_back(PropertyInfo(Variant::VECTOR2, "pos")); + p_list->push_back(PropertyInfo(Variant::VECTOR2, "position")); p_list->push_back(PropertyInfo(Variant::VECTOR2, "size")); p_list->push_back(PropertyInfo(Variant::VECTOR2, "end")); @@ -2127,7 +2125,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::VECTOR2, "x")); p_list->push_back(PropertyInfo(Variant::VECTOR2, "y")); - p_list->push_back(PropertyInfo(Variant::VECTOR2, "o")); + p_list->push_back(PropertyInfo(Variant::VECTOR2, "origin")); } break; case PLANE: { @@ -2148,7 +2146,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { } break; // 10 case RECT3: { - p_list->push_back(PropertyInfo(Variant::VECTOR3, "pos")); + p_list->push_back(PropertyInfo(Variant::VECTOR3, "position")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "size")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "end")); } break; @@ -2236,30 +2234,30 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const { return _data._int > 0; } break; case REAL: { - r_iter = 0.0; + r_iter = 0; return _data._real > 0.0; } break; case VECTOR2: { - real_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x; - real_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y; + int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y; r_iter = from; return from < to; } break; case VECTOR3: { - real_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x; - real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + int64_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x; + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; r_iter = from; if (from == to) { return false; } else if (from < to) { - return step > 0.0; + return step > 0; } else { - return step < 0.0; + return step < 0; } //return true; } break; @@ -2387,7 +2385,6 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { valid = true; switch (type) { case INT: { - int64_t idx = r_iter; idx++; if (idx >= _data._int) @@ -2396,33 +2393,36 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const { return true; } break; case REAL: { - - double idx = r_iter; - idx += 1.0; + int64_t idx = r_iter; + idx++; if (idx >= _data._real) return false; r_iter = idx; return true; } break; case VECTOR2: { - real_t idx = r_iter; - idx += 1.0; - if (idx >= reinterpret_cast<const Vector2 *>(_data._mem)->y) + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + + int64_t idx = r_iter; + idx++; + + if (idx >= to) return false; + r_iter = idx; return true; } break; case VECTOR3: { - real_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; - real_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; + int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y; + int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z; - real_t idx = r_iter; + int64_t idx = r_iter; idx += step; - if (step < 0.0 && idx <= to) + if (step < 0 && idx <= to) return false; - if (step > 0.0 && idx >= to) + if (step > 0 && idx >= to) return false; r_iter = idx; @@ -2759,7 +2759,7 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) case RECT2: { const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem); const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem); - r_dst = Rect2(ra->pos + rb->pos * c, ra->size + rb->size * c); + r_dst = Rect2(ra->position + rb->position * c, ra->size + rb->size * c); } return; case VECTOR3: { @@ -2769,7 +2769,7 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) case RECT3: { const Rect3 *ra = reinterpret_cast<const Rect3 *>(a._data._mem); const Rect3 *rb = reinterpret_cast<const Rect3 *>(b._data._mem); - r_dst = Rect3(ra->pos + rb->pos * c, ra->size + rb->size * c); + r_dst = Rect3(ra->position + rb->position * c, ra->size + rb->size * c); } return; case QUAT: { @@ -2879,7 +2879,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case RECT2: { - r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->pos.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->pos, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c)); + r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c)); } return; case VECTOR3: { @@ -2899,7 +2899,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & } return; case RECT3: { - r_dst = Rect3(a._data._rect3->pos.linear_interpolate(b._data._rect3->pos, c), a._data._rect3->size.linear_interpolate(b._data._rect3->size, c)); + r_dst = Rect3(a._data._rect3->position.linear_interpolate(b._data._rect3->position, c), a._data._rect3->size.linear_interpolate(b._data._rect3->size, c)); } return; case BASIS: { diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 55e2bb42e3..26a6a05a30 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -744,7 +744,12 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, return err; if (token.type == TK_PARENTHESIS_CLOSE) { - + Reference *reference = obj->cast_to<Reference>(); + if (reference) { + value = REF(reference); + } else { + value = obj; + } return OK; } @@ -760,7 +765,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } } - get_token(p_stream, token, line, r_err_str); if (token.type != TK_STRING) { r_err_str = "Expected property name as string"; return ERR_PARSE_ERROR; @@ -1616,7 +1620,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::RECT2: { Rect2 aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.pos.x) + ", " + rtosfix(aabb.pos.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )"); + p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )"); } break; case Variant::VECTOR3: { @@ -1633,7 +1637,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str case Variant::RECT3: { Rect3 aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect3( " + rtosfix(aabb.pos.x) + ", " + rtosfix(aabb.pos.y) + ", " + rtosfix(aabb.pos.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); + p_store_string_func(p_store_string_ud, "Rect3( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); } break; case Variant::QUAT: { diff --git a/core/vector.h b/core/vector.h index fe1c1b05dd..5eed8dce96 100644 --- a/core/vector.h +++ b/core/vector.h @@ -134,10 +134,7 @@ public: inline T &operator[](int p_index) { - if (p_index < 0 || p_index >= size()) { - T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); _copy_on_write(); // wants to write, so copy on write. @@ -146,10 +143,8 @@ public: inline const T &operator[](int p_index) const { - if (p_index < 0 || p_index >= size()) { - const T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(p_index < 0 || p_index >= size(), aux); - } + CRASH_BAD_INDEX(p_index, size()); + // no cow needed, since it's reading return _get_data()[p_index]; } diff --git a/core/version.h b/core/version.h index 80e50e51b9..43f6f1bbf9 100644 --- a/core/version.h +++ b/core/version.h @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "version_generated.h" +#include "version_generated.gen.h" #ifdef VERSION_PATCH #define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." _MKSTR(VERSION_STATUS) "." _MKSTR(VERSION_REVISION) diff --git a/core/vmap.h b/core/vmap.h index ad07973308..66f935f58d 100644 --- a/core/vmap.h +++ b/core/vmap.h @@ -180,10 +180,8 @@ public: inline const V &operator[](const T &p_key) const { int pos = _find_exact(p_key); - if (pos < 0) { - const T &aux = *((T *)0); //nullreturn - ERR_FAIL_COND_V(pos < 1, aux); - } + + CRASH_COND(pos < 0); return _data[pos].value; } |