diff options
123 files changed, 1400 insertions, 631 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 63238e3029..b8c448dc82 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -1272,9 +1272,9 @@ uint64_t _File::get_position() const { return f->get_position(); } -uint64_t _File::get_len() const { +uint64_t _File::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); - return f->get_len(); + return f->get_length(); } bool _File::eof_reached() const { @@ -1536,7 +1536,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("seek", "position"), &_File::seek); ClassDB::bind_method(D_METHOD("seek_end", "position"), &_File::seek_end, DEFVAL(0)); ClassDB::bind_method(D_METHOD("get_position"), &_File::get_position); - ClassDB::bind_method(D_METHOD("get_len"), &_File::get_len); + ClassDB::bind_method(D_METHOD("get_length"), &_File::get_length); ClassDB::bind_method(D_METHOD("eof_reached"), &_File::eof_reached); ClassDB::bind_method(D_METHOD("get_8"), &_File::get_8); ClassDB::bind_method(D_METHOD("get_16"), &_File::get_16); @@ -1545,7 +1545,7 @@ void _File::_bind_methods() { ClassDB::bind_method(D_METHOD("get_float"), &_File::get_float); ClassDB::bind_method(D_METHOD("get_double"), &_File::get_double); ClassDB::bind_method(D_METHOD("get_real"), &_File::get_real); - ClassDB::bind_method(D_METHOD("get_buffer", "len"), &_File::get_buffer); + ClassDB::bind_method(D_METHOD("get_buffer", "length"), &_File::get_buffer); ClassDB::bind_method(D_METHOD("get_line"), &_File::get_line); ClassDB::bind_method(D_METHOD("get_csv_line", "delim"), &_File::get_csv_line, DEFVAL(",")); ClassDB::bind_method(D_METHOD("get_as_text"), &_File::get_as_text); diff --git a/core/core_bind.h b/core/core_bind.h index 8bd96d8268..be8b30b38d 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -391,7 +391,7 @@ public: void seek(int64_t p_position); // Seek to a given position. void seek_end(int64_t p_position = 0); // Seek from the end of file. uint64_t get_position() const; // Get position in the file. - uint64_t get_len() const; // Get size of the file. + uint64_t get_length() const; // Get size of the file. bool eof_reached() const; // Reading passed EOF. diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index efcaa80fc5..e54c947340 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -237,7 +237,7 @@ uint64_t FileAccessCompressed::get_position() const { } } -uint64_t FileAccessCompressed::get_len() const { +uint64_t FileAccessCompressed::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); if (writing) { return write_max; diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index d8a81c2417..19e4f241dd 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -75,7 +75,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 9a6bee7348..b9514c8c8b 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -69,7 +69,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 } base = p_base->get_position(); - ERR_FAIL_COND_V(p_base->get_len() < base + length, ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(p_base->get_length() < base + length, ERR_FILE_CORRUPT); uint64_t ds = length; if (ds % 16) { ds += 16 - (ds % 16); @@ -199,8 +199,8 @@ String FileAccessEncrypted::get_path_absolute() const { } void FileAccessEncrypted::seek(uint64_t p_position) { - if (p_position > get_len()) { - p_position = get_len(); + if (p_position > get_length()) { + p_position = get_length(); } pos = p_position; @@ -208,14 +208,14 @@ void FileAccessEncrypted::seek(uint64_t p_position) { } void FileAccessEncrypted::seek_end(int64_t p_position) { - seek(get_len() + p_position); + seek(get_length() + p_position); } uint64_t FileAccessEncrypted::get_position() const { return pos; } -uint64_t FileAccessEncrypted::get_len() const { +uint64_t FileAccessEncrypted::get_length() const { return data.size(); } @@ -225,7 +225,7 @@ bool FileAccessEncrypted::eof_reached() const { uint8_t FileAccessEncrypted::get_8() const { ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode."); - if (pos >= get_len()) { + if (pos >= get_length()) { eofed = true; return 0; } @@ -239,7 +239,7 @@ uint64_t FileAccessEncrypted::get_buffer(uint8_t *p_dst, uint64_t p_length) cons ERR_FAIL_COND_V(!p_dst && p_length > 0, -1); ERR_FAIL_COND_V_MSG(writing, -1, "File has not been opened in read mode."); - uint64_t to_copy = MIN(p_length, get_len() - pos); + uint64_t to_copy = MIN(p_length, get_length() - pos); for (uint64_t i = 0; i < to_copy; i++) { p_dst[i] = data[pos++]; } @@ -258,11 +258,11 @@ Error FileAccessEncrypted::get_error() const { void FileAccessEncrypted::store_buffer(const uint8_t *p_src, uint64_t p_length) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); - if (pos < get_len()) { + if (pos < get_length()) { for (uint64_t i = 0; i < p_length; i++) { store_8(p_src[i]); } - } else if (pos == get_len()) { + } else if (pos == get_length()) { data.resize(pos + p_length); for (uint64_t i = 0; i < p_length; i++) { data.write[pos + i] = p_src[i]; @@ -280,10 +280,10 @@ void FileAccessEncrypted::flush() { void FileAccessEncrypted::store_8(uint8_t p_dest) { ERR_FAIL_COND_MSG(!writing, "File has not been opened in write mode."); - if (pos < get_len()) { + if (pos < get_length()) { data.write[pos] = p_dest; pos++; - } else if (pos == get_len()) { + } else if (pos == get_length()) { data.push_back(p_dest); pos++; } diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 8bea8c2585..00f14099f9 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -71,7 +71,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 14e24d6668..0114ab1765 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -117,7 +117,7 @@ uint64_t FileAccessMemory::get_position() const { return pos; } -uint64_t FileAccessMemory::get_len() const { +uint64_t FileAccessMemory::get_length() const { ERR_FAIL_COND_V(!data, 0); return length; } diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index cc589dc259..4157531d01 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -52,7 +52,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index dedd5523ed..63a8f9c5b6 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -328,7 +328,7 @@ uint64_t FileAccessNetwork::get_position() const { return pos; } -uint64_t FileAccessNetwork::get_len() const { +uint64_t FileAccessNetwork::get_length() const { ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use."); return total_size; } diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h index 4810cca195..94b66c2480 100644 --- a/core/io/file_access_network.h +++ b/core/io/file_access_network.h @@ -137,7 +137,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 3e1c51b733..e9983ece47 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -279,7 +279,7 @@ uint64_t FileAccessPack::get_position() const { return pos; } -uint64_t FileAccessPack::get_len() const { +uint64_t FileAccessPack::get_length() const { return pf.size; } diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 763c0fb327..9747e865c8 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -163,7 +163,7 @@ public: virtual void seek(uint64_t p_position); virtual void seek_end(int64_t p_position = 0); virtual uint64_t get_position() const; - virtual uint64_t get_len() const; + virtual uint64_t get_length() const; virtual bool eof_reached() const; diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index d7ff1b7e00..b8383fd865 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -73,7 +73,7 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { pos = f->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: - pos = f->get_len() + offset; + pos = f->get_length() + offset; break; default: break; @@ -270,7 +270,7 @@ void FileAccessZip::seek(uint64_t p_position) { void FileAccessZip::seek_end(int64_t p_position) { ERR_FAIL_COND(!zfile); - unzSeekCurrentFile(zfile, get_len() + p_position); + unzSeekCurrentFile(zfile, get_length() + p_position); } uint64_t FileAccessZip::get_position() const { @@ -278,7 +278,7 @@ uint64_t FileAccessZip::get_position() const { return unztell(zfile); } -uint64_t FileAccessZip::get_len() const { +uint64_t FileAccessZip::get_length() const { ERR_FAIL_COND_V(!zfile, 0); return file_info.uncompressed_size; } diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 91bdaafb68..cca14ded62 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -90,7 +90,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index 4fe22e57d8..cadb02b5dd 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -120,7 +120,7 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src, bool p_encr pf.path = p_file; pf.src_path = p_src; pf.ofs = ofs; - pf.size = f->get_len(); + pf.size = f->get_length(); Vector<uint8_t> data = FileAccess::get_file_as_array(p_src); { diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index f3ce2319e3..938d93a01b 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -476,7 +476,7 @@ Error XMLParser::open(const String &p_path) { ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); - length = file->get_len(); + length = file->get_length(); ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT); if (data) { diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index e0e491dc85..fb4c76aa7a 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -74,7 +74,7 @@ long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { pos = f->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: - pos = f->get_len() + offset; + pos = f->get_length() + offset; break; default: break; diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index d00d0ac5bb..d1b940190a 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -380,7 +380,7 @@ uint64_t FileAccess::get_buffer(uint8_t *p_dst, uint64_t p_length) const { String FileAccess::get_as_utf8_string() const { Vector<uint8_t> sourcef; - uint64_t len = get_len(); + uint64_t len = get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); @@ -565,7 +565,7 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_err ERR_FAIL_V_MSG(Vector<uint8_t>(), "Can't open file from path '" + String(p_path) + "'."); } Vector<uint8_t> data; - data.resize(f->get_len()); + data.resize(f->get_length()); f->get_buffer(data.ptrw(), data.size()); memdelete(f); return data; diff --git a/core/os/file_access.h b/core/os/file_access.h index f9749c0fd1..1b9fb2f422 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -96,7 +96,7 @@ public: virtual void seek(uint64_t p_position) = 0; ///< seek to a given position virtual void seek_end(int64_t p_position = 0) = 0; ///< seek from the end of file with negative offset virtual uint64_t get_position() const = 0; ///< get position in the file - virtual uint64_t get_len() const = 0; ///< get size of the file + virtual uint64_t get_length() const = 0; ///< get size of the file virtual bool eof_reached() const = 0; ///< reading passed EOF diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index efaaa8cd19..063611d415 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -611,6 +611,9 @@ struct _VariantCall { if (buffer_size <= 0) { ERR_FAIL_V_MSG(decompressed, "Decompression buffer size must be greater than zero."); } + if (p_instance->size() == 0) { + ERR_FAIL_V_MSG(decompressed, "Compressed buffer size must be greater than zero."); + } decompressed.resize(buffer_size); int result = Compression::decompress(decompressed.ptrw(), buffer_size, p_instance->ptr(), p_instance->size(), mode); diff --git a/doc/classes/EditorSpinSlider.xml b/doc/classes/EditorSpinSlider.xml index f2c5a00640..935335943f 100644 --- a/doc/classes/EditorSpinSlider.xml +++ b/doc/classes/EditorSpinSlider.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="EditorSpinSlider" inherits="Range" version="4.0"> <brief_description> - Godot editor's control for editing numertic values. + Godot editor's control for editing numeric values. </brief_description> <description> This [Control] node is used in the editor's Inspector dock to allow editing of numeric values. Can be used with [EditorInspectorPlugin] to recreate the same behavior. diff --git a/doc/classes/File.xml b/doc/classes/File.xml index f0b9156b89..2206730523 100644 --- a/doc/classes/File.xml +++ b/doc/classes/File.xml @@ -61,7 +61,7 @@ </return> <description> Returns [code]true[/code] if the file cursor has read past the end of the file. - [b]Note:[/b] This function will still return [code]false[/code] while at the end of the file and only activates when reading past it. This can be confusing but it conforms to how low-level file access works in all operating systems. There is always [method get_len] and [method get_position] to implement a custom logic. + [b]Note:[/b] This function will still return [code]false[/code] while at the end of the file and only activates when reading past it. This can be confusing but it conforms to how low-level file access works in all operating systems. There is always [method get_length] and [method get_position] to implement a custom logic. </description> </method> <method name="file_exists" qualifiers="const"> @@ -121,10 +121,10 @@ <method name="get_buffer" qualifiers="const"> <return type="PackedByteArray"> </return> - <argument index="0" name="len" type="int"> + <argument index="0" name="length" type="int"> </argument> <description> - Returns next [code]len[/code] bytes of the file as a [PackedByteArray]. + Returns next [code]length[/code] bytes of the file as a [PackedByteArray]. </description> </method> <method name="get_csv_line" qualifiers="const"> @@ -158,7 +158,7 @@ Returns the next 32 bits from the file as a floating-point number. </description> </method> - <method name="get_len" qualifiers="const"> + <method name="get_length" qualifiers="const"> <return type="int"> </return> <description> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 27b26801f3..c31467c67e 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -533,6 +533,12 @@ <theme_item name="checked" type="Texture2D"> The check icon to display when the [constant TreeItem.CELL_MODE_CHECK] mode cell is checked. </theme_item> + <theme_item name="children_hl_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> + The [Color] of the relationship lines between the selected [TreeItem] and its children. + </theme_item> + <theme_item name="children_hl_line_width" type="int" default="1"> + The width of the relationship lines between the selected [TreeItem] and its children. + </theme_item> <theme_item name="cursor" type="StyleBox"> [StyleBox] used for the cursor, when the [Tree] is being focused. </theme_item> @@ -587,8 +593,20 @@ <theme_item name="outline_size" type="int" default="0"> The size of the text outline. </theme_item> + <theme_item name="parent_hl_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> + The [Color] of the relationship lines between the selected [TreeItem] and its parents. + </theme_item> + <theme_item name="parent_hl_line_margin" type="int" default="0"> + The space between the parent relationship lines for the selected [TreeItem] and the relationship lines to its siblings that are not selected. + </theme_item> + <theme_item name="parent_hl_line_width" type="int" default="1"> + The width of the relationship lines between the selected [TreeItem] and its parents. + </theme_item> <theme_item name="relationship_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> - [Color] of the relationship lines. + The default [Color] of the relationship lines. + </theme_item> + <theme_item name="relationship_line_width" type="int" default="1"> + The default width of the relationship lines. </theme_item> <theme_item name="scroll_border" type="int" default="4"> The maximum distance between the mouse cursor and the control's border to trigger border scrolling when dragging. diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp index 41554bc93f..8b2e786146 100644 --- a/drivers/png/image_loader_png.cpp +++ b/drivers/png/image_loader_png.cpp @@ -37,7 +37,7 @@ #include <string.h> Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { - const uint64_t buffer_size = f->get_len(); + const uint64_t buffer_size = f->get_length(); Vector<uint8_t> file_buffer; Error err = file_buffer.resize(buffer_size); if (err) { diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index de9a7867ee..ec23df62d0 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -212,7 +212,7 @@ uint64_t FileAccessUnix::get_position() const { return pos; } -uint64_t FileAccessUnix::get_len() const { +uint64_t FileAccessUnix::get_length() const { ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use."); int64_t pos = ftello(f); diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 6aa3e1529f..5b1599c67f 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -64,7 +64,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 0f52c70482..1f46b44f5e 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -219,7 +219,7 @@ uint64_t FileAccessWindows::get_position() const { return aux_position; } -uint64_t FileAccessWindows::get_len() const { +uint64_t FileAccessWindows::get_length() const { ERR_FAIL_COND_V(!f, 0); uint64_t pos = get_position(); diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 008c69de66..95f3a75548 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -59,7 +59,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 086afde07c..d1a0bfeded 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -224,6 +224,13 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { valid_extensions.insert(E->get()); } + if (!file_dialog) { + file_dialog = memnew(EditorFileDialog); + file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); + add_child(file_dialog); + file_dialog->connect("file_selected", callable_mp(this, &EditorResourcePicker::_file_selected)); + } + file_dialog->clear_filters(); for (Set<String>::Element *E = valid_extensions.front(); E; E = E->next()) { file_dialog->add_filter("*." + E->get() + " ; " + E->get().to_upper()); @@ -781,10 +788,11 @@ EditorResourcePicker::EditorResourcePicker() { assign_button->set_flat(true); assign_button->set_h_size_flags(SIZE_EXPAND_FILL); assign_button->set_clip_text(true); - assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected)); assign_button->set_drag_forwarding(this); - assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw)); add_child(assign_button); + assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected)); + assign_button->connect("draw", callable_mp(this, &EditorResourcePicker::_button_draw)); + assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); preview_rect = memnew(TextureRect); preview_rect->set_expand(true); @@ -793,23 +801,17 @@ EditorResourcePicker::EditorResourcePicker() { preview_rect->set_offset(SIDE_BOTTOM, -1); preview_rect->set_offset(SIDE_RIGHT, -1); assign_button->add_child(preview_rect); - assign_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); - edit_menu = memnew(PopupMenu); - add_child(edit_menu); edit_button = memnew(Button); edit_button->set_flat(true); edit_button->set_toggle_mode(true); - edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); - edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); edit_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_update_menu)); add_child(edit_button); edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); - - file_dialog = memnew(EditorFileDialog); - file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE); - add_child(file_dialog); - file_dialog->connect("file_selected", callable_mp(this, &EditorResourcePicker::_file_selected)); + edit_menu = memnew(PopupMenu); + add_child(edit_menu); + edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk)); + edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false)); } void EditorScriptPicker::set_create_options(Object *p_menu_node) { diff --git a/editor/editor_resource_picker.h b/editor/editor_resource_picker.h index 20fafe1780..9a4b945bc7 100644 --- a/editor/editor_resource_picker.h +++ b/editor/editor_resource_picker.h @@ -51,7 +51,7 @@ class EditorResourcePicker : public HBoxContainer { Button *assign_button; TextureRect *preview_rect; Button *edit_button; - EditorFileDialog *file_dialog; + EditorFileDialog *file_dialog = nullptr; enum MenuOption { OBJ_MENU_LOAD, diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 0868c31c45..eb8ad9bac4 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -704,6 +704,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/scroll_to_pan", false); _initial_set("editors/2d/pan_speed", 20); + // Tiles editor + _initial_set("editors/tiles_editor/display_grid", true); + _initial_set("editors/tiles_editor/grid_color", Color(1.0, 0.5, 0.2, 0.5)); + // Polygon editor _initial_set("editors/poly_editor/point_grab_radius", 8); _initial_set("editors/poly_editor/show_previous_outline", true); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 81f6096abf..978714f719 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -799,8 +799,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tree_bg->set_border_color(dark_color_3); theme->set_stylebox("bg", "Tree", style_tree_bg); - const Color guide_color = mono_color * Color(1, 1, 1, 0.05); - Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); // Tree theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons")); @@ -817,19 +815,33 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_color", "Tree", font_color); theme->set_color("font_selected_color", "Tree", mono_color); theme->set_color("title_button_color", "Tree", font_color); - theme->set_color("guide_color", "Tree", guide_color); - theme->set_color("relationship_line_color", "Tree", relationship_line_color); theme->set_color("drop_position_color", "Tree", accent_color); theme->set_constant("vseparation", "Tree", widget_default_margin.y - EDSCALE); theme->set_constant("hseparation", "Tree", 6 * EDSCALE); theme->set_constant("guide_width", "Tree", border_width); theme->set_constant("item_margin", "Tree", 3 * default_margin_size * EDSCALE); theme->set_constant("button_margin", "Tree", default_margin_size * EDSCALE); - theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01); - theme->set_constant("draw_guides", "Tree", relationship_line_opacity < 0.01); theme->set_constant("scroll_border", "Tree", 40 * EDSCALE); theme->set_constant("scroll_speed", "Tree", 12); + const Color guide_color = mono_color * Color(1, 1, 1, 0.05); + Color relationship_line_color = mono_color * Color(1, 1, 1, relationship_line_opacity); + + theme->set_constant("draw_guides", "Tree", relationship_line_opacity < 0.01); + theme->set_color("guide_color", "Tree", guide_color); + + int relationship_line_width = 1; + Color parent_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.45, 0.0, 1.0)); + Color children_line_color = mono_color * Color(1, 1, 1, CLAMP(relationship_line_opacity + 0.25, 0.0, 1.0)); + theme->set_constant("draw_relationship_lines", "Tree", relationship_line_opacity >= 0.01); + theme->set_constant("relationship_line_width", "Tree", relationship_line_width); + theme->set_constant("parent_hl_line_width", "Tree", relationship_line_width * 2); + theme->set_constant("children_hl_line_width", "Tree", relationship_line_width); + theme->set_constant("parent_hl_line_margin", "Tree", relationship_line_width * 3); + theme->set_color("relationship_line_color", "Tree", relationship_line_color); + theme->set_color("parent_hl_line_color", "Tree", parent_line_color); + theme->set_color("children_hl_line_color", "Tree", children_line_color); + Ref<StyleBoxFlat> style_tree_btn = style_default->duplicate(); style_tree_btn->set_bg_color(highlight_color); style_tree_btn->set_border_width_all(0); diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index b04e518b0b..654915e3e5 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -200,7 +200,7 @@ void EditorFileServer::_subthread_start(void *s) { cd->connection->put_data(buf4, 4); encode_uint32(OK, buf4); cd->connection->put_data(buf4, 4); - encode_uint64(fa->get_len(), buf4); + encode_uint64(fa->get_length(), buf4); cd->connection->put_data(buf4, 8); cd->files[id] = fa; diff --git a/editor/icons/Grid.svg b/editor/icons/Grid.svg index b80a9d6525..3b63bfb051 100644 --- a/editor/icons/Grid.svg +++ b/editor/icons/Grid.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v2 10 2h2 12v-2-12h-12zm2 2h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm-8 4h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2z" fill="#8da5f3" fill-opacity=".98824"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm1.9999999 2h2v2h-2zm4 0h2v2h-2zm4.0000001 0h2v2h-2zm-8.0000001 4.0000004h2v2h-2zm4 0h2v2h-2zm4.0000001 0h2v2h-2zm-8.0000001 3.9999996h2v2h-2zm4 0h2v2h-2zm4.0000001 0h2v2h-2z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/RibbonTrailMesh.svg b/editor/icons/RibbonTrailMesh.svg new file mode 100644 index 0000000000..3f6cf0bfef --- /dev/null +++ b/editor/icons/RibbonTrailMesh.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f" stroke-width=".25" transform="rotate(90)"><path d="m6.5625-14.062499h1.875v13.124999h-1.875z"/><path d="m.9375-11.249999h1.875v7.499999h-1.875z"/><path d="m12.187499-11.249999h1.875v7.5h-1.875z"/></g></svg> diff --git a/editor/icons/TubeTrailMesh.svg b/editor/icons/TubeTrailMesh.svg new file mode 100644 index 0000000000..3ca524226f --- /dev/null +++ b/editor/icons/TubeTrailMesh.svg @@ -0,0 +1 @@ +<svg height="16" viewBox="0 0 14.999999 14.999999" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="#ffca5f"><path d="m14.0625 7.5c0-1.6377-.2123-3.12-.5969-4.2737-.1923-.57682-.4237-1.0754-.7508-1.4905-.3271-.41505-.8259-.79834-1.4648-.79834h-7.5c-.6389 0-1.1396.38329-1.4667.79834s-.5585.91366-.7507 1.4905c-.3846 1.1536-.5951 2.6359-.5951 4.2737s.2105 3.12.5951 4.2737c.1922.57682.4236 1.0754.7507 1.4905.3271.41505.8278.79834 1.4667.79834h7.5c.6389 0 1.1377-.38329 1.4648-.79834s.5585-.91366.7508-1.4905c.3846-1.1536.5969-2.6359.5969-4.2737zm-2.8125-4.6875002c.4358 1.0052002 0 0 .4358 1.0052002.2941.88221.5017 2.2134.5017 3.6823s-.2076 2.8-.5017 3.6823c-.1449.4347 0 0-.4358 1.005199l-7.5.000041c-.1212-.15705-.2929-.57092-.4376-1.0052-.2941-.88221-.4999-2.2134-.4999-3.6823s.2058-2.8.4999-3.6823c.1447-.43433.3164-.8482.4376-1.0052"/><path d="m6.5625-11.25h1.875v7.5h-1.875z" stroke-width=".25" transform="rotate(90)"/></g></svg> diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp index fa6ce5fc89..c5b2a8dc3a 100644 --- a/editor/import/resource_importer_image.cpp +++ b/editor/import/resource_importer_image.cpp @@ -75,7 +75,7 @@ Error ResourceImporterImage::import(const String &p_source_file, const String &p ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open file from path '" + p_source_file + "'."); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); Vector<uint8_t> data; data.resize(len); diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 6e82951d3d..78f181e321 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -39,6 +39,7 @@ #include "scene/gui/texture_rect.h" #include "editor/editor_scale.h" +#include "editor/editor_settings.h" void TileAtlasView::_gui_input(const Ref<InputEvent> &p_event) { bool ctrl = Input::get_singleton()->is_key_pressed(KEY_CTRL); @@ -316,6 +317,7 @@ void TileAtlasView::_draw_base_tiles_dark() { void TileAtlasView::_draw_base_tiles_shape_grid() { // Draw the shapes. + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); Vector2i tile_shape_size = tile_set->get_tile_size(); for (int i = 0; i < tile_set_atlas_source->get_tiles_count(); i++) { Vector2i tile_id = tile_set_atlas_source->get_tile_id(i); @@ -324,7 +326,7 @@ void TileAtlasView::_draw_base_tiles_shape_grid() { Vector2 origin = texture_region.position + (texture_region.size - tile_shape_size) / 2 + in_tile_base_offset; // Draw only if the tile shape fits in the texture region - tile_set->draw_tile_shape(base_tiles_shape_grid, Rect2(origin, tile_shape_size), Color(1.0, 0.5, 0.2, 0.8)); + tile_set->draw_tile_shape(base_tiles_shape_grid, Rect2(origin, tile_shape_size), grid_color); } } diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 80ba396936..ef13d8ea12 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -56,10 +56,18 @@ void TileMapEditorTilesPlugin::_notification(int p_what) { picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons")); erase_button->set_icon(get_theme_icon("Eraser", "EditorIcons")); + toggle_grid_button->set_icon(get_theme_icon("Grid", "EditorIcons")); + missing_atlas_texture_icon = get_theme_icon("TileSet", "EditorIcons"); + + toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); break; case NOTIFICATION_VISIBILITY_CHANGED: _stop_dragging(); + break; + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: + toggle_grid_button->set_pressed(EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid")); + break; } } @@ -77,6 +85,10 @@ void TileMapEditorTilesPlugin::_on_scattering_spinbox_changed(double p_value) { scattering = p_value; } +void TileMapEditorTilesPlugin::_on_grid_toggled(bool p_pressed) { + EditorSettings::get_singleton()->set("editors/tiles_editor/display_grid", p_pressed); +} + void TileMapEditorTilesPlugin::_update_toolbar() { // Stop draggig if needed. _stop_dragging(); @@ -604,7 +616,9 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over if (drag_type == DRAG_TYPE_MOVE || (drag_type == DRAG_TYPE_SELECT && !Input::get_singleton()->is_key_pressed(KEY_CTRL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT))) { // Do nothing } else { - tile_map->draw_cells_outline(p_overlay, tile_map_selection, Color(0.0, 0.0, 1.0), xform); + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); + tile_map->draw_cells_outline(p_overlay, tile_map_selection, selection_color, xform); } } @@ -703,21 +717,27 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over const int fading = 5; // Draw the lines of the grid behind the preview. - if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) { - drawn_grid_rect = drawn_grid_rect.grow(fading); - for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) { - for (int y = drawn_grid_rect.position.y; y < (drawn_grid_rect.position.y + drawn_grid_rect.size.y); y++) { - Vector2i pos_in_rect = Vector2i(x, y) - drawn_grid_rect.position; - - // Fade out the border of the grid. - float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); - float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); - float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); - - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 0.5, 0.2, 0.5 * opacity), false); + bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + if (display_grid) { + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + if (drawn_grid_rect.size.x > 0 && drawn_grid_rect.size.y > 0) { + drawn_grid_rect = drawn_grid_rect.grow(fading); + for (int x = drawn_grid_rect.position.x; x < (drawn_grid_rect.position.x + drawn_grid_rect.size.x); x++) { + for (int y = drawn_grid_rect.position.y; y < (drawn_grid_rect.position.y + drawn_grid_rect.size.y); y++) { + Vector2i pos_in_rect = Vector2i(x, y) - drawn_grid_rect.position; + + // Fade out the border of the grid. + float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.x, (float)(drawn_grid_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)drawn_grid_rect.size.y, (float)(drawn_grid_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); + + Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); + Color color = grid_color; + color.a = color.a * opacity; + tile_set->draw_tile_shape(p_overlay, cell_region, color, false); + } } } } @@ -1417,9 +1437,11 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { } // Draw the selection. + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); for (Set<TileMapCell>::Element *E = tile_set_selection.front(); E; E = E->next()) { if (E->get().source_id == source_id && E->get().alternative_tile == 0) { - tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get().get_atlas_coords()), Color(0.0, 0.0, 1.0), false); + tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get().get_atlas_coords()), selection_color, false); } } @@ -1445,9 +1467,9 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { } } } - + Color selection_rect_color = selection_color.lightened(0.2); for (Set<Vector2i>::Element *E = to_draw.front(); E; E = E->next()) { - tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get()), Color(0.8, 0.8, 1.0), false); + tile_atlas_control->draw_rect(atlas->get_tile_texture_region(E->get()), selection_rect_color, false); } } } @@ -1730,6 +1752,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { // --- Toolbar --- toolbar = memnew(HBoxContainer); + toolbar->set_h_size_flags(SIZE_EXPAND_FILL); HBoxContainer *tilemap_tiles_tools_buttons = memnew(HBoxContainer); @@ -1774,7 +1797,6 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { bucket_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/bucket_tool", "Bucket", KEY_B)); bucket_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar)); tilemap_tiles_tools_buttons->add_child(bucket_tool_button); - toolbar->add_child(tilemap_tiles_tools_buttons); // -- TileMap tool settings -- @@ -1834,6 +1856,18 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() { _on_random_tile_checkbox_toggled(false); + // Wide empty separation control. + Control *h_empty_space = memnew(Control); + h_empty_space->set_h_size_flags(SIZE_EXPAND_FILL); + toolbar->add_child(h_empty_space); + + // Grid toggle. + toggle_grid_button = memnew(Button); + toggle_grid_button->set_flat(true); + toggle_grid_button->set_toggle_mode(true); + toggle_grid_button->connect("toggled", callable_mp(this, &TileMapEditorTilesPlugin::_on_grid_toggled)); + toolbar->add_child(toggle_grid_button); + // Default tool. paint_tool_button->set_pressed(true); _update_toolbar(); @@ -3426,19 +3460,25 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) { } // Draw the grid. - for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) { - for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) { - Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position; + bool display_grid = EditorSettings::get_singleton()->get("editors/tiles_editor/display_grid"); + if (display_grid) { + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + for (int x = displayed_rect.position.x; x < (displayed_rect.position.x + displayed_rect.size.x); x++) { + for (int y = displayed_rect.position.y; y < (displayed_rect.position.y + displayed_rect.size.y); y++) { + Vector2i pos_in_rect = Vector2i(x, y) - displayed_rect.position; - // Fade out the border of the grid. - float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); - float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); - float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); - float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); - float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); + // Fade out the border of the grid. + float left_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.x), 0.0f, 1.0f); + float right_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.x, (float)(displayed_rect.size.x - fading), (float)pos_in_rect.x), 0.0f, 1.0f); + float top_opacity = CLAMP(Math::inverse_lerp(0.0f, (float)fading, (float)pos_in_rect.y), 0.0f, 1.0f); + float bottom_opacity = CLAMP(Math::inverse_lerp((float)displayed_rect.size.y, (float)(displayed_rect.size.y - fading), (float)pos_in_rect.y), 0.0f, 1.0f); + float opacity = CLAMP(MIN(left_opacity, MIN(right_opacity, MIN(top_opacity, bottom_opacity))) + 0.1, 0.0f, 1.0f); - Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); - tile_set->draw_tile_shape(p_overlay, cell_region, Color(1.0, 0.5, 0.2, 0.5 * opacity), false); + Rect2 cell_region = xform.xform(Rect2(tile_map->map_to_world(Vector2(x, y)) - tile_shape_size / 2, tile_shape_size)); + Color color = grid_color; + color.a = color.a * opacity; + tile_set->draw_tile_shape(p_overlay, cell_region, color, false); + } } } @@ -3500,9 +3540,8 @@ TileMapEditor::TileMapEditor() { // --- TileMap toolbar --- tilemap_toolbar = memnew(HBoxContainer); - //tilemap_toolbar->add_child(memnew(VSeparator)); + tilemap_toolbar->set_h_size_flags(SIZE_EXPAND_FILL); tilemap_toolbar->add_child(tabs); - //tilemap_toolbar->add_child(memnew(VSeparator)); for (int i = 0; i < tile_map_editor_plugins.size(); i++) { tile_map_editor_plugins[i]->get_toolbar()->hide(); tilemap_toolbar->add_child(tile_map_editor_plugins[i]->get_toolbar()); diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h index a1fb9af3ef..a6f4ec3021 100644 --- a/editor/plugins/tiles/tile_map_editor.h +++ b/editor/plugins/tiles/tile_map_editor.h @@ -82,6 +82,9 @@ private: void _on_random_tile_checkbox_toggled(bool p_pressed); void _on_scattering_spinbox_changed(double p_value); + Button *toggle_grid_button; + void _on_grid_toggled(bool p_pressed); + void _update_toolbar(); ///// Tilemap editing. ///// diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index b6e1a318cb..8e7d613027 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -1178,6 +1178,10 @@ Array TileSetAtlasSourceEditor::_get_selection_as_array() { } void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { + // Colors. + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); + // Draw the selected tile. if (tools_button_group->get_pressed_button() == tool_select_button) { for (Set<TileSelection>::Element *E = selection.front(); E; E = E->next()) { @@ -1185,7 +1189,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { if (selected.alternative == 0) { // Draw the rect. Rect2 region = tile_set_atlas_source->get_tile_texture_region(selected.tile); - tile_atlas_control->draw_rect(region, Color(0.2, 0.2, 1.0), false); + tile_atlas_control->draw_rect(region, selection_color, false); } } @@ -1234,7 +1238,7 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { Color color = Color(0.0, 0.0, 0.0); if (drag_type == DRAG_TYPE_RECT_SELECT) { - color = Color(0.5, 0.5, 1.0); + color = selection_color.lightened(0.2); } Set<Vector2i> to_paint; @@ -1393,6 +1397,9 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_mouse_exited() { } void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() { + Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color"); + Color selection_color = Color().from_hsv(Math::fposmod(grid_color.get_h() + 0.5, 1.0), grid_color.get_s(), grid_color.get_v(), 1.0); + // Update the hovered alternative tile. if (tools_button_group->get_pressed_button() == tool_select_button) { // Draw hovered tile. @@ -1410,7 +1417,7 @@ void TileSetAtlasSourceEditor::_tile_alternatives_control_draw() { if (selected.alternative >= 1) { Rect2i rect = tile_atlas_view->get_alternative_tile_rect(selected.tile, selected.alternative); if (rect != Rect2i()) { - alternative_tiles_control->draw_rect(rect, Color(0.2, 0.2, 1.0), false); + alternative_tiles_control->draw_rect(rect, selection_color, false); } } } diff --git a/editor/plugins/tiles/tiles_editor_plugin.cpp b/editor/plugins/tiles/tiles_editor_plugin.cpp index 971ff15073..fb111efc17 100644 --- a/editor/plugins/tiles/tiles_editor_plugin.cpp +++ b/editor/plugins/tiles/tiles_editor_plugin.cpp @@ -202,6 +202,7 @@ TilesEditor::TilesEditor(EditorNode *p_editor) { // Toolbar. HBoxContainer *toolbar = memnew(HBoxContainer); + toolbar->set_h_size_flags(SIZE_EXPAND_FILL); add_child(toolbar); // Switch button. diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme b/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme index b6beeb012f..d61a53d5c2 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme @@ -23,7 +23,7 @@ </BuildActionEntries> </BuildAction> <TestAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> @@ -42,7 +42,7 @@ </AdditionalOptions> </TestAction> <LaunchAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle = "0" @@ -67,7 +67,7 @@ </AdditionalOptions> </LaunchAction> <ProfileAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" shouldUseLaunchSchemeArgsEnv = "YES" savedToolIdentifier = "" useCustomWorkingDirectory = "NO" @@ -84,10 +84,10 @@ </BuildableProductRunnable> </ProfileAction> <AnalyzeAction - buildConfiguration = "Debug"> + buildConfiguration = "$default_build_config"> </AnalyzeAction> <ArchiveAction - buildConfiguration = "Debug" + buildConfiguration = "$default_build_config" revealArchiveInOrganizer = "YES"> </ArchiveAction> </Scheme> diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index f22e74cafb..27b49a6609 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -205,7 +205,7 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, // A valid bmp file should always at least have a // file header and a minimal info header - if (f->get_len() > BITMAP_FILE_HEADER_SIZE + BITMAP_INFO_HEADER_MIN_SIZE) { + if (f->get_length() > BITMAP_FILE_HEADER_SIZE + BITMAP_INFO_HEADER_MIN_SIZE) { // File Header bmp_header.bmp_file_header.bmp_signature = f->get_16(); if (bmp_header.bmp_file_header.bmp_signature == BITMAP_SIGNATURE) { diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index 58bc450e9d..f60277f60a 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -102,7 +102,7 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl FBXDocParser::TokenList tokens; bool is_binary = false; - data.resize(f->get_len()); + data.resize(f->get_length()); ERR_FAIL_COND_V(data.size() < 64, nullptr); diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp index a0d7fbf726..93fe3b3992 100644 --- a/modules/gdnative/pluginscript/pluginscript_script.cpp +++ b/modules/gdnative/pluginscript/pluginscript_script.cpp @@ -441,7 +441,7 @@ Error PluginScript::load_source_code(const String &p_path) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V_MSG(err, err, "Cannot open file '" + p_path + "'."); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); uint64_t r = f->get_buffer(w, len); diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp index 1b7838846f..8b0434c7dd 100644 --- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp +++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp @@ -58,7 +58,7 @@ int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) { FileAccess *file = reinterpret_cast<FileAccess *>(ptr); if (file) { - int64_t len = file->get_len(); + int64_t len = file->get_length(); switch (whence) { case SEEK_SET: { if (pos > len) { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 2896420239..d7814e85b0 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1045,7 +1045,7 @@ Error GDScript::load_source_code(const String &p_path) { ERR_FAIL_COND_V(err, err); } - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); uint64_t r = f->get_buffer(w, len); diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index 6aa76703f1..601cdb4080 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -153,7 +153,7 @@ String GDScriptCache::get_source_code(const String &p_path) { ERR_FAIL_COND_V(err, ""); } - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); source_file.resize(len + 1); uint64_t r = f->get_buffer(source_file.ptrw(), len); f->close(); diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index 8ad5cdacad..fc73b5bb72 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -215,8 +215,8 @@ void test(TestType p_type) { init_language(fa->get_path_absolute().get_base_dir()); Vector<uint8_t> buf; - uint64_t flen = fa->get_len(); - buf.resize(fa->get_len() + 1); + uint64_t flen = fa->get_length(); + buf.resize(flen + 1); fa->get_buffer(buf.ptrw(), flen); buf.write[flen] = 0; diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index b3fa17bfb5..ac76506b87 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -233,7 +233,7 @@ Error GLTFDocument::_parse_json(const String &p_path, Ref<GLTFState> state) { } Vector<uint8_t> array; - array.resize(f->get_len()); + array.resize(f->get_length()); f->get_buffer(array.ptrw(), array.size()); String text; text.parse_utf8((const char *)array.ptr(), array.size()); diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index 18beff41d8..d237544d66 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -105,7 +105,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - uint64_t src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp index 4a42e9af0d..c389609984 100644 --- a/modules/mbedtls/crypto_mbedtls.cpp +++ b/modules/mbedtls/crypto_mbedtls.cpp @@ -58,7 +58,7 @@ Error CryptoKeyMbedTLS::load(String p_path, bool p_public_only) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_INVALID_PARAMETER, "Cannot open CryptoKeyMbedTLS file '" + p_path + "'."); - uint64_t flen = f->get_len(); + uint64_t flen = f->get_length(); out.resize(flen + 1); f->get_buffer(out.ptrw(), flen); out.write[flen] = 0; // string terminator @@ -146,7 +146,7 @@ Error X509CertificateMbedTLS::load(String p_path) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(!f, ERR_INVALID_PARAMETER, "Cannot open X509CertificateMbedTLS file '" + p_path + "'."); - uint64_t flen = f->get_len(); + uint64_t flen = f->get_length(); out.resize(flen + 1); f->get_buffer(out.ptrw(), flen); out.write[flen] = 0; // string terminator diff --git a/modules/minimp3/resource_importer_mp3.cpp b/modules/minimp3/resource_importer_mp3.cpp index 96cce49c86..f5137965da 100644 --- a/modules/minimp3/resource_importer_mp3.cpp +++ b/modules/minimp3/resource_importer_mp3.cpp @@ -79,7 +79,7 @@ Error ResourceImporterMP3::import(const String &p_source_file, const String &p_s ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); Vector<uint8_t> data; data.resize(len); diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp index 5d53394658..ee68458268 100644 --- a/modules/mono/utils/string_utils.cpp +++ b/modules/mono/utils/string_utils.cpp @@ -170,7 +170,7 @@ Error read_all_file_utf8(const String &p_path, String &r_content) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); uint64_t r = f->get_buffer(w, len); diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp index 17380001f5..e3aa630cef 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp @@ -79,7 +79,7 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open file '" + p_source_file + "'."); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); Vector<uint8_t> data; data.resize(len); diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 24fe654946..4911346b96 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -140,7 +140,7 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p } Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { - uint64_t size = f->get_len(); + uint64_t size = f->get_length(); Vector<uint8_t> src_image; src_image.resize(size + 1); uint8_t *src_w = src_image.ptrw(); diff --git a/modules/text_server_adv/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp index faeb83f920..c29aac05bb 100644 --- a/modules/text_server_adv/dynamic_font_adv.cpp +++ b/modules/text_server_adv/dynamic_font_adv.cpp @@ -66,7 +66,7 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size( ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'."); } - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); font_mem_cache.resize(len); f->get_buffer(font_mem_cache.ptrw(), len); font_mem = font_mem_cache.ptr(); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 361852547f..7eff3f8dee 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -181,7 +181,7 @@ bool TextServerAdvanced::load_support_data(const String &p_filename) { UErrorCode err = U_ZERO_ERROR; // ICU data found. - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); icu_data = (uint8_t *)memalloc(len); f->get_buffer(icu_data, len); f->close(); diff --git a/modules/text_server_fb/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp index 406f60b6f5..a261ba8f37 100644 --- a/modules/text_server_fb/dynamic_font_fb.cpp +++ b/modules/text_server_fb/dynamic_font_fb.cpp @@ -65,7 +65,7 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size( ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'."); } - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); font_mem_cache.resize(len); f->get_buffer(font_mem_cache.ptrw(), len); font_mem = font_mem_cache.ptr(); diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index 52b92ee930..3cfd4ff36a 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -226,7 +226,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - uint64_t src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); ERR_FAIL_COND_V(src_image_len < (int64_t)sizeof(tga_header_s), ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index cfb75fb93b..eb7a8597e6 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -37,7 +37,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - uint64_t src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp index 15bf9dbf2d..34addb5c9f 100644 --- a/modules/webm/video_stream_webm.cpp +++ b/modules/webm/video_stream_webm.cpp @@ -74,7 +74,7 @@ public: virtual int Length(long long *total, long long *available) { if (file) { - const uint64_t len = file->get_len(); + const uint64_t len = file->get_length(); if (total) { *total = len; } diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index d7e88d76b1..1f2a456619 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -147,7 +147,7 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) { Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) { Vector<uint8_t> src_image; - uint64_t src_image_len = f->get_len(); + uint64_t src_image_len = f->get_length(); ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT); src_image.resize(src_image_len); diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index f46dcf58dc..ff61eeaee1 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -196,7 +196,7 @@ void DisplayServerAndroid::window_set_input_text_callback(const Callable &p_call } void DisplayServerAndroid::window_set_rect_changed_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { - // Not supported on Android. + rect_changed_callback = p_callable; } void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_callable, DisplayServer::WindowID p_window) { @@ -389,6 +389,19 @@ void DisplayServerAndroid::reset_window() { #endif } +void DisplayServerAndroid::notify_surface_changed(int p_width, int p_height) { + if (rect_changed_callback.is_null()) { + return; + } + + const Variant size = Rect2i(0, 0, p_width, p_height); + const Variant *sizep = &size; + Variant ret; + Callable::CallError ce; + + rect_changed_callback.call(reinterpret_cast<const Variant **>(&sizep), 1, ret, ce); +} + DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) { rendering_driver = p_rendering_driver; diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 53c768f406..1379baf154 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -112,6 +112,7 @@ private: Callable window_event_callback; Callable input_event_callback; Callable input_text_callback; + Callable rect_changed_callback; void _window_callback(const Callable &p_callable, const Variant &p_arg) const; @@ -215,6 +216,7 @@ public: static void register_android_driver(); void reset_window(); + void notify_surface_changed(int p_width, int p_height); virtual Point2i mouse_get_position() const; virtual int mouse_get_button_state() const; diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index ec2618a3d5..073c9dc6ef 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -857,6 +857,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int xr_mode_index = p_preset->get("xr_features/xr_mode"); + bool backup_allowed = p_preset->get("user_data_backup/allow"); + Vector<String> perms; // Write permissions into the perms variable. _get_permissions(p_preset, p_give_internet, perms); @@ -949,6 +951,10 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } } + if (tname == "application" && attrname == "allowBackup") { + encode_uint32(backup_allowed, &p_manifest.write[iofs + 16]); + } + if (tname == "instrumentation" && attrname == "targetPackage") { string_table.write[attr_value] = get_package_name(package_name); } @@ -1684,6 +1690,8 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data_backup/allow"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false)); diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 48e7fd46ac..0bb94dcc97 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -258,10 +258,11 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { } String _get_application_tag(const Ref<EditorExportPreset> &p_preset) { - String manifest_application_text = + String manifest_application_text = vformat( " <application android:label=\"@string/godot_project_name_string\"\n" - " android:allowBackup=\"false\" tools:ignore=\"GoogleAppIndexingWarning\"\n" - " android:icon=\"@mipmap/icon\">\n\n"; + " android:allowBackup=\"%s\" tools:ignore=\"GoogleAppIndexingWarning\"\n" + " android:icon=\"@mipmap/icon\">\n\n", + bool_to_string(p_preset->get("user_data_backup/allow"))); manifest_application_text += _get_activity_tag(p_preset); manifest_application_text += " </application>\n"; diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index 900d4d9b20..90370878b7 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -94,7 +94,7 @@ uint64_t FileAccessAndroid::get_position() const { return pos; } -uint64_t FileAccessAndroid::get_len() const { +uint64_t FileAccessAndroid::get_length() const { return len; } diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index 9b0f85089d..8890e0f645 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -54,7 +54,7 @@ public: virtual void seek(uint64_t p_position); ///< seek to a given position virtual void seek_end(int64_t p_position = 0); ///< seek from the end of file virtual uint64_t get_position() const; ///< get position in the file - virtual uint64_t get_len() const; ///< get size of the file + virtual uint64_t get_length() const; ///< get size of the file virtual bool eof_reached() const; ///< reading passed EOF diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt index b967fd5f24..6e59268076 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkThread.kt @@ -61,6 +61,7 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk private var rendererInitialized = false private var rendererResumed = false private var resumed = false + private var surfaceChanged = false private var hasSurface = false private var width = 0 private var height = 0 @@ -141,8 +142,10 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk fun onSurfaceChanged(width: Int, height: Int) { lock.withLock { hasSurface = true + surfaceChanged = true; this.width = width this.height = height + lockCondition.signalAll() } } @@ -188,8 +191,11 @@ internal class VkThread(private val vkSurfaceView: VkSurfaceView, private val vk rendererInitialized = true vkRenderer.onVkSurfaceCreated(vkSurfaceView.holder.surface) } + } + if (surfaceChanged) { vkRenderer.onVkSurfaceChanged(vkSurfaceView.holder.surface, width, height) + surfaceChanged = false } // Break out of the loop so drawing can occur without holding onto the lock. diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 0c342dc280..c7ff6cb2c0 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -173,6 +173,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j os_android->set_native_window(native_window); DisplayServerAndroid::get_singleton()->reset_window(); + DisplayServerAndroid::get_singleton()->notify_surface_changed(p_width, p_height); } } } diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 36566dffbf..08ad77e940 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -448,6 +448,8 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n"; } else if (lines[i].find("$team_id") != -1) { strnew += lines[i].replace("$team_id", p_preset->get("application/app_store_team_id")) + "\n"; + } else if (lines[i].find("$default_build_config") != -1) { + strnew += lines[i].replace("$default_build_config", p_debug ? "Debug" : "Release") + "\n"; } else if (lines[i].find("$export_method") != -1) { int export_method = p_preset->get(p_debug ? "application/export_method_debug" : "application/export_method_release"); strnew += lines[i].replace("$export_method", export_method_string[export_method]) + "\n"; diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp index ac4e6a1256..b35ccd087f 100644 --- a/platform/javascript/api/javascript_tools_editor_plugin.cpp +++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp @@ -72,7 +72,7 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) { FileAccess *f = FileAccess::open("/tmp/project.zip", FileAccess::READ); ERR_FAIL_COND_MSG(!f, "Unable to create zip file"); Vector<uint8_t> buf; - buf.resize(f->get_len()); + buf.resize(f->get_length()); f->get_buffer(buf.ptrw(), buf.size()); godot_js_os_download_buffer(buf.ptr(), buf.size(), "project.zip", "application/zip"); } @@ -84,7 +84,7 @@ void JavaScriptToolsEditorPlugin::_zip_file(String p_path, String p_base_path, z return; } Vector<uint8_t> data; - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); data.resize(len); f->get_buffer(data.ptrw(), len); f->close(); diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index e398072312..5096285e33 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -547,7 +547,7 @@ Error EditorExportPlatformJavaScript::_build_pwa(const Ref<EditorExportPreset> & EditorNode::get_singleton()->show_warning(TTR("Could not read file:") + "\n" + sw_path); return ERR_FILE_CANT_READ; } - sw.resize(f->get_len()); + sw.resize(f->get_length()); f->get_buffer(sw.ptrw(), sw.size()); memdelete(f); f = nullptr; @@ -651,7 +651,7 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "html/experimental_virtual_keyboard"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "progressive_web_app/enabled"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/offline_page", PROPERTY_HINT_FILE, "*.html"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/display", PROPERTY_HINT_ENUM, "Fullscreen,Standalone,Minimal Ui,Browser"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/display", PROPERTY_HINT_ENUM, "Fullscreen,Standalone,Minimal UI,Browser"), 1)); r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "progressive_web_app/orientation", PROPERTY_HINT_ENUM, "Any,Landscape,Portrait"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_144x144", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg,*.svgz"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_180x180", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg,*.svgz"), "")); @@ -781,13 +781,13 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese FileAccess *f = nullptr; f = FileAccess::open(pck_path, FileAccess::READ); if (f) { - file_sizes[pck_path.get_file()] = (uint64_t)f->get_len(); + file_sizes[pck_path.get_file()] = (uint64_t)f->get_length(); memdelete(f); f = nullptr; } f = FileAccess::open(base_path + ".wasm", FileAccess::READ); if (f) { - file_sizes[base_name + ".wasm"] = (uint64_t)f->get_len(); + file_sizes[base_name + ".wasm"] = (uint64_t)f->get_length(); memdelete(f); f = nullptr; } @@ -800,7 +800,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese EditorNode::get_singleton()->show_warning(TTR("Could not read HTML shell:") + "\n" + html_path); return ERR_FILE_CANT_READ; } - html.resize(f->get_len()); + html.resize(f->get_length()); f->get_buffer(html.ptrw(), html.size()); memdelete(f); f = nullptr; diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 4c761e77b5..f53b60891f 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -3479,7 +3479,7 @@ void DisplayServerOSX::set_native_icon(const String &p_filename) { ERR_FAIL_COND(!f); Vector<uint8_t> data; - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); data.resize(len); f->get_buffer((uint8_t *)&data.write[0], len); memdelete(f); diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index b2f881a8a8..3a6a5333dd 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -312,7 +312,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ } int ofs = data.size(); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); data.resize(data.size() + len + 8); f->get_buffer(&data.write[ofs + 8], len); memdelete(f); @@ -689,8 +689,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (iconpath.get_extension() == "icns") { FileAccess *icon = FileAccess::open(iconpath, FileAccess::READ); if (icon) { - data.resize(icon->get_len()); - icon->get_buffer(&data.write[0], icon->get_len()); + data.resize(icon->get_length()); + icon->get_buffer(&data.write[0], icon->get_length()); icon->close(); memdelete(icon); } diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 217c119978..f1a857d414 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -572,7 +572,7 @@ void AppxPackager::finish() { FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ); Vector<uint8_t> blockmap_buffer; - blockmap_buffer.resize(blockmap_file->get_len()); + blockmap_buffer.resize(blockmap_file->get_length()); blockmap_file->get_buffer(blockmap_buffer.ptrw(), blockmap_buffer.size()); @@ -590,7 +590,7 @@ void AppxPackager::finish() { FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ); Vector<uint8_t> types_buffer; - types_buffer.resize(types_file->get_len()); + types_buffer.resize(types_file->get_length()); types_file->get_buffer(types_buffer.ptrw(), types_buffer.size()); @@ -900,7 +900,7 @@ class EditorExportPlatformUWP : public EditorExportPlatform { ERR_FAIL_V_MSG(data, err_string); } - data.resize(f->get_len()); + data.resize(f->get_length()); f->get_buffer(data.ptrw(), data.size()); f->close(); diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 8fb765f16b..ce57895341 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -281,7 +281,7 @@ void Light2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Sub,Mix"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Add,Subtract,Mix"), "set_blend_mode", "get_blend_mode"); ADD_GROUP("Range", "range_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_min", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_min", "get_z_range_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "range_z_max", PROPERTY_HINT_RANGE, itos(RS::CANVAS_ITEM_Z_MIN) + "," + itos(RS::CANVAS_ITEM_Z_MAX) + ",1"), "set_z_range_max", "get_z_range_max"); @@ -292,7 +292,7 @@ void Light2D::_bind_methods() { ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow_enabled", "is_shadow_enabled"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13"), "set_shadow_filter", "get_shadow_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_filter", PROPERTY_HINT_ENUM, "None (Fast),PCF5 (Average),PCF13 (Slow)"), "set_shadow_filter", "get_shadow_filter"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask"); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 72392be5bd..55b26bc9fb 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -962,7 +962,7 @@ void AudioStreamPlayer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_stream_playback"), &AudioStreamPlayer3D::get_stream_playback); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,InverseSquare,Log,Disabled"), "set_attenuation_model", "get_attenuation_model"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,Inverse Square,Log,Disabled"), "set_attenuation_model", "get_attenuation_model"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index ad24f39bce..7762156b4a 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -230,7 +230,7 @@ void ReflectionProbe::_bind_methods() { ClassDB::bind_method(D_METHOD("set_update_mode", "mode"), &ReflectionProbe::set_update_mode); ClassDB::bind_method(D_METHOD("get_update_mode"), &ReflectionProbe::get_update_mode); - ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once,Always"), "set_update_mode", "get_update_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "update_mode", PROPERTY_HINT_ENUM, "Once (Fast),Always (Slow)"), "set_update_mode", "get_update_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "intensity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_intensity", "get_intensity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_distance", PROPERTY_HINT_EXP_RANGE, "0,16384,0.1,or_greater"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents"), "set_extents", "get_extents"); @@ -242,7 +242,7 @@ void ReflectionProbe::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); ADD_GROUP("Ambient", "ambient_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_mode", PROPERTY_HINT_ENUM, "Disabled,Environment,ConstantColor"), "set_ambient_mode", "get_ambient_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "ambient_mode", PROPERTY_HINT_ENUM, "Disabled,Environment,Constant Color"), "set_ambient_mode", "get_ambient_mode"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_ambient_color", "get_ambient_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ambient_color_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_color_energy", "get_ambient_color_energy"); diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index bd1c202205..294e313300 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -129,7 +129,7 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain return true; } -void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) { +void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet, Vector3 p_origin_pos) { real_t distance_to_goal(1e4); real_t previous_distance_to_goal(0); int can_solve(p_task->max_iterations); @@ -138,7 +138,7 @@ void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) { --can_solve; solve_simple_backwards(p_task->chain, p_solve_magnet); - solve_simple_forwards(p_task->chain, p_solve_magnet); + solve_simple_forwards(p_task->chain, p_solve_magnet, p_origin_pos); distance_to_goal = (p_task->chain.tips[0].chain_item->current_pos - p_task->chain.tips[0].end_effector->goal_transform.origin).length(); } @@ -176,13 +176,13 @@ void FabrikInverseKinematic::solve_simple_backwards(Chain &r_chain, bool p_solve } } -void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet) { +void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet, Vector3 p_origin_pos) { if (p_solve_magnet && !r_chain.middle_chain_item) { return; } ChainItem *sub_chain_root(&r_chain.chain_root); - Vector3 origin(r_chain.chain_root.initial_transform.origin); + Vector3 origin = p_origin_pos; while (sub_chain_root) { // Reach the tip sub_chain_root->current_pos = origin; @@ -273,13 +273,16 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove // Update the initial root transform so its synced with any animation changes _update_chain(p_task->skeleton, &p_task->chain.chain_root); + p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, false); + Vector3 origin_pos = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone).origin; + make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta); if (p_use_magnet && p_task->chain.middle_chain_item) { p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); - solve_simple(p_task, true); + solve_simple(p_task, true, origin_pos); } - solve_simple(p_task, false); + solve_simple(p_task, false, origin_pos); // Assign new bone position. ChainItem *ci(&p_task->chain.chain_root); diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index 9255e18b72..9b5ae240f6 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -106,10 +106,10 @@ private: /// Init a chain that starts from the root to tip static bool build_chain(Task *p_task, bool p_force_simple_chain = true); - static void solve_simple(Task *p_task, bool p_solve_magnet); + static void solve_simple(Task *p_task, bool p_solve_magnet, Vector3 p_origin_pos); /// Special solvers that solve only chains with one end effector static void solve_simple_backwards(Chain &r_chain, bool p_solve_magnet); - static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet); + static void solve_simple_forwards(Chain &r_chain, bool p_solve_magnet, Vector3 p_origin_pos); public: static Task *create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform); diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index 246fff6d57..65918a2989 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -115,7 +115,7 @@ void AnimationNodeStateMachineTransition::_bind_methods() { ClassDB::bind_method(D_METHOD("set_priority", "priority"), &AnimationNodeStateMachineTransition::set_priority); ClassDB::bind_method(D_METHOD("get_priority"), &AnimationNodeStateMachineTransition::get_priority); - ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,AtEnd"), "set_switch_mode", "get_switch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "switch_mode", PROPERTY_HINT_ENUM, "Immediate,Sync,At End"), "set_switch_mode", "get_switch_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_advance"), "set_auto_advance", "has_auto_advance"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "advance_condition"), "set_advance_condition", "get_advance_condition"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,240,0.01"), "set_xfade_time", "get_xfade_time"); diff --git a/scene/gui/aspect_ratio_container.cpp b/scene/gui/aspect_ratio_container.cpp index c7f6c0e2da..fb6fa9dec9 100644 --- a/scene/gui/aspect_ratio_container.cpp +++ b/scene/gui/aspect_ratio_container.cpp @@ -155,7 +155,7 @@ void AspectRatioContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_alignment_vertical"), &AspectRatioContainer::get_alignment_vertical); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ratio"), "set_ratio", "get_ratio"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width controls height,Height controls width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_mode", PROPERTY_HINT_ENUM, "Width Controls Height,Height Controls Width,Fit,Cover"), "set_stretch_mode", "get_stretch_mode"); ADD_GROUP("Alignment", "alignment_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alignment_horizontal", PROPERTY_HINT_ENUM, "Begin,Center,End"), "set_alignment_horizontal", "get_alignment_horizontal"); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index b0bcde8865..c0df5271b4 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -533,7 +533,7 @@ void Button::_bind_methods() { BIND_ENUM_CONSTANT(ALIGN_RIGHT); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_button_icon", "get_button_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 9ccb2886e1..c0b4563615 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -91,7 +91,6 @@ void ColorPicker::init_shaders() { wheel_shader.instance(); wheel_shader->set_code( "shader_type canvas_item;" - "const float TAU = 6.28318530718;" "void fragment() {" " float x = UV.x - 0.5;" " float y = UV.y - 0.5;" @@ -111,7 +110,6 @@ void ColorPicker::init_shaders() { circle_shader.instance(); circle_shader->set_code( "shader_type canvas_item;" - "const float TAU = 6.28318530718;" "uniform float v = 1.0;" "void fragment() {" " float x = UV.x - 0.5;" diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 83abd02b40..0ae1dec46d 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2801,7 +2801,7 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "grow_vertical", PROPERTY_HINT_ENUM, "Begin,End,Both"), "set_v_grow_direction", "get_v_grow_direction"); ADD_GROUP("Layout Direction", "layout_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-right,Right-to-left"), "set_layout_direction", "get_layout_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction"); ADD_GROUP("Rect", "rect_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "rect_position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_position", "get_position"); @@ -2828,7 +2828,7 @@ void Control::_bind_methods() { ADD_GROUP("Mouse", "mouse_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,Ibeam,Pointing hand,Cross,Wait,Busy,Drag,Can drop,Forbidden,Vertical resize,Horizontal resize,Secondary diagonal resize,Main diagonal resize,Move,Vertical split,Horizontal split,Help"), "set_default_cursor_shape", "get_default_cursor_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_default_cursor_shape", PROPERTY_HINT_ENUM, "Arrow,I-Beam,Pointing Hand,Cross,Wait,Busy,Drag,Can Drop,Forbidden,Vertical Resize,Horizontal Resize,Secondary Diagonal Resize,Main Diagonal Resize,Move,Vertical Split,Horizontal Split,Help"), "set_default_cursor_shape", "get_default_cursor_shape"); ADD_GROUP("Size Flags", "size_flags_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 1ca54a16ae..77c502cf8d 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -999,7 +999,7 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("get_overlay"), &GraphNode::get_overlay); ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position_offset"), "set_position_offset", "get_position_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible"); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index be73fd8f51..de0ee626b9 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -695,7 +695,7 @@ void Label::_bind_methods() { BIND_ENUM_CONSTANT(VALIGN_FILL); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_DEFAULT_INTL), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::INT, "align", PROPERTY_HINT_ENUM, "Left,Center,Right,Fill"), "set_align", "get_align"); ADD_PROPERTY(PropertyInfo(Variant::INT, "valign", PROPERTY_HINT_ENUM, "Top,Center,Bottom,Fill"), "set_valign", "get_valign"); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 98dd9f624b..c2ed9c1a3c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2209,7 +2209,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp index 1f7b61e3d1..d45ffde715 100644 --- a/scene/gui/link_button.cpp +++ b/scene/gui/link_button.cpp @@ -292,7 +292,7 @@ void LinkButton::_bind_methods() { BIND_ENUM_CONSTANT(UNDERLINE_MODE_NEVER); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::INT, "underline", PROPERTY_HINT_ENUM, "Always,On Hover,Never"), "set_underline_mode", "get_underline_mode"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 2800ab0442..9ed4c937f4 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -3935,7 +3935,7 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_ARRAY_TYPE, "RichTextEffect", (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE)), "set_effects", "get_effects"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_GROUP("Structured Text", "structured_text_"); diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp index 13ff2c5b86..df4cf9a740 100644 --- a/scene/gui/split_container.cpp +++ b/scene/gui/split_container.cpp @@ -353,7 +353,7 @@ void SplitContainer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "split_offset"), "set_split_offset", "get_split_offset"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collapsed"), "set_collapsed", "is_collapsed"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden & Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "dragger_visibility", PROPERTY_HINT_ENUM, "Visible,Hidden,Hidden and Collapsed"), "set_dragger_visibility", "get_dragger_visibility"); BIND_ENUM_CONSTANT(DRAGGER_VISIBLE); BIND_ENUM_CONSTANT(DRAGGER_HIDDEN); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index d19d95f6f4..4b199d1441 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -7055,7 +7055,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_minimap_width"), &TextEdit::get_minimap_width); ADD_PROPERTY(PropertyInfo(Variant::STRING, "text", PROPERTY_HINT_MULTILINE_TEXT), "set_text", "get_text"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,LTR,RTL,Inherited"), "set_text_direction", "get_text_direction"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "text_direction", PROPERTY_HINT_ENUM, "Auto,Left-to-Right,Right-to-Left,Inherited"), "set_text_direction", "get_text_direction"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "language"), "set_language", "get_language"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "readonly"), "set_readonly", "is_readonly"); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 2f78736a12..d2b98eb0fa 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1184,15 +1184,23 @@ void Tree::update_cache() { cache.font_color = get_theme_color("font_color"); cache.font_selected_color = get_theme_color("font_selected_color"); - cache.guide_color = get_theme_color("guide_color"); cache.drop_position_color = get_theme_color("drop_position_color"); cache.hseparation = get_theme_constant("hseparation"); cache.vseparation = get_theme_constant("vseparation"); cache.item_margin = get_theme_constant("item_margin"); cache.button_margin = get_theme_constant("button_margin"); + cache.draw_guides = get_theme_constant("draw_guides"); + cache.guide_color = get_theme_color("guide_color"); cache.draw_relationship_lines = get_theme_constant("draw_relationship_lines"); + cache.relationship_line_width = get_theme_constant("relationship_line_width"); + cache.parent_hl_line_width = get_theme_constant("parent_hl_line_width"); + cache.children_hl_line_width = get_theme_constant("children_hl_line_width"); + cache.parent_hl_line_margin = get_theme_constant("parent_hl_line_margin"); cache.relationship_line_color = get_theme_color("relationship_line_color"); + cache.parent_hl_line_color = get_theme_color("parent_hl_line_color"); + cache.children_hl_line_color = get_theme_color("children_hl_line_color"); + cache.scroll_border = get_theme_constant("scroll_border"); cache.scroll_speed = get_theme_constant("scroll_speed"); @@ -1813,38 +1821,79 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 TreeItem *c = p_item->first_child; - int prev_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int base_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y; + int prev_ofs = base_ofs; + int prev_hl_ofs = base_ofs; while (c) { if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) { int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); - int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin); + int parent_ofs = p_pos.x + cache.item_margin; Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs; if (c->get_first_child() != nullptr) { root_pos -= Point2i(cache.arrow->get_width(), 0); } - float line_width = 1.0; + float line_width = cache.relationship_line_width; + float parent_line_width = cache.parent_hl_line_width; + float children_line_width = cache.children_hl_line_width; + #ifdef TOOLS_ENABLED line_width *= Math::round(EDSCALE); + parent_line_width *= Math::round(EDSCALE); + children_line_width *= Math::round(EDSCALE); #endif Point2i parent_pos = Point2i(parent_ofs - cache.arrow->get_width() / 2, p_pos.y + label_h / 2 + cache.arrow->get_height() / 2) - cache.offset + p_draw_ofs; + int more_prev_ofs = 0; + if (root_pos.y + line_width >= 0) { if (rtl) { root_pos.x = get_size().width - root_pos.x; parent_pos.x = get_size().width - parent_pos.x; } - RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x - Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); - RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y), Point2i(parent_pos.x, prev_ofs), cache.relationship_line_color, line_width); + + // Order of parts on this bend: the horizontal line first, then the vertical line. + if (_is_branch_selected(c)) { + // If this item or one of its children is selected, we draw the line using parent highlight style. + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.parent_hl_line_color, parent_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + more_prev_ofs = cache.parent_hl_line_margin; + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else if (p_item->is_selected(0)) { + // If parent item is selected (but this item is not), we draw the line using children highlight style. + // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. + if (_is_sibling_branch_selected(c)) { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(parent_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(children_line_width / 2), root_pos.y), cache.children_hl_line_color, children_line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(children_line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(children_line_width / 2)), cache.children_hl_line_color, children_line_width); + } + } else { + // If nothing of the above is true, we draw the line using normal style. + // Siblings of the selected branch can be drawn with a slight offset and their vertical line must appear as highlighted. + if (_is_sibling_branch_selected(c)) { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + cache.parent_hl_line_margin, root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(parent_line_width / 2)), Point2i(parent_pos.x, prev_hl_ofs), cache.parent_hl_line_color, parent_line_width); + + prev_hl_ofs = root_pos.y + Math::floor(parent_line_width / 2); + } else { + RenderingServer::get_singleton()->canvas_item_add_line(ci, root_pos, Point2i(parent_pos.x + Math::floor(line_width / 2), root_pos.y), cache.relationship_line_color, line_width); + RenderingServer::get_singleton()->canvas_item_add_line(ci, Point2i(parent_pos.x, root_pos.y + Math::floor(line_width / 2)), Point2i(parent_pos.x, prev_ofs + Math::floor(line_width / 2)), cache.relationship_line_color, line_width); + } + } } if (htotal < 0) { return -1; } - prev_ofs = root_pos.y; + prev_ofs = root_pos.y + more_prev_ofs; } if (htotal >= 0) { @@ -1853,10 +1902,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (child_h < 0) { if (cache.draw_relationship_lines == 0) { return -1; // break, stop drawing, no need to anymore - } else { - htotal = -1; - children_pos.y = cache.offset.y + p_draw_size.height; } + + htotal = -1; + children_pos.y = cache.offset.y + p_draw_size.height; } else { htotal += child_h; children_pos.y += child_h; @@ -1889,6 +1938,36 @@ int Tree::_count_selected_items(TreeItem *p_from) const { return count; } +bool Tree::_is_branch_selected(TreeItem *p_from) const { + for (int i = 0; i < columns.size(); i++) { + if (p_from->is_selected(i)) { + return true; + } + } + + TreeItem *child_item = p_from->get_first_child(); + while (child_item) { + if (_is_branch_selected(child_item)) { + return true; + } + child_item = child_item->get_next(); + } + + return false; +} + +bool Tree::_is_sibling_branch_selected(TreeItem *p_from) const { + TreeItem *sibling_item = p_from->get_next(); + while (sibling_item) { + if (_is_branch_selected(sibling_item)) { + return true; + } + sibling_item = sibling_item->get_next(); + } + + return false; +} + void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev, bool *r_in_range, bool p_force_deselect) { TreeItem::Cell &selected_cell = p_selected->cells.write[p_col]; @@ -4386,7 +4465,7 @@ void Tree::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_folding"), "set_hide_folding", "is_folding_hidden"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hide_root"), "set_hide_root", "is_root_hidden"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In between"), "set_drop_mode_flags", "get_drop_mode_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "drop_mode_flags", PROPERTY_HINT_FLAGS, "On Item,In Between"), "set_drop_mode_flags", "get_drop_mode_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Row,Multi"), "set_select_mode", "get_select_mode"); ADD_SIGNAL(MethodInfo("item_selected")); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 9dbfd93082..c0948f1b80 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -494,6 +494,8 @@ private: Color guide_color; Color drop_position_color; Color relationship_line_color; + Color parent_hl_line_color; + Color children_hl_line_color; Color custom_button_font_highlight; int hseparation = 0; @@ -502,6 +504,10 @@ private: int button_margin = 0; Point2 offset; int draw_relationship_lines = 0; + int relationship_line_width = 0; + int parent_hl_line_width = 0; + int children_hl_line_width = 0; + int parent_hl_line_margin = 0; int draw_guides = 0; int scroll_border = 0; int scroll_speed = 0; @@ -574,6 +580,8 @@ private: bool hide_folding = false; int _count_selected_items(TreeItem *p_from) const; + bool _is_branch_selected(TreeItem *p_from) const; + bool _is_sibling_branch_selected(TreeItem *p_from) const; void _go_left(); void _go_right(); void _go_down(); diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index d594c6c8b6..181fe606c8 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -271,7 +271,7 @@ void CanvasItemMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "loop"), &CanvasItemMaterial::set_particles_anim_loop); ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &CanvasItemMaterial::get_particles_anim_loop); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,Premult Alpha"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply,Premultiplied Alpha"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_mode", PROPERTY_HINT_ENUM, "Normal,Unshaded,Light Only"), "set_light_mode", "get_light_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "particles_animation"), "set_particles_animation", "get_particles_animation"); @@ -1554,7 +1554,7 @@ void CanvasTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular_color", "get_specular_color"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "specular_shininess", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular_shininess", "get_specular_shininess"); ADD_GROUP("Texture", "texture_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Inherit,Nearest,Linear,MipmapNearest,MipmapLinear,MipmapNearestAniso,MipmapLinearAniso"), "set_texture_filter", "get_texture_filter"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_filter", PROPERTY_HINT_ENUM, "Inherit,Nearest,Linear,Nearest Mipmap,Linear Mipmap,Nearest Mipmap Aniso.,Linear Mipmap Aniso."), "set_texture_filter", "get_texture_filter"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_repeat", PROPERTY_HINT_ENUM, "Inherit,Disabled,Enabled,Mirror"), "set_texture_repeat", "get_texture_repeat"); } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index c90d3e4a32..dc7057f339 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2872,7 +2872,7 @@ void Node::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "custom_multiplayer", PROPERTY_HINT_RESOURCE_TYPE, "MultiplayerAPI", 0), "set_custom_multiplayer", "get_custom_multiplayer"); ADD_GROUP("Process", "process_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,WhenPaused,Always,Disabled"), "set_process_mode", "get_process_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,When Paused,Always,Disabled"), "set_process_mode", "get_process_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority"); ADD_GROUP("Editor Description", "editor_"); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 62e1223fb0..77667cf188 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -3601,8 +3601,8 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled"); ADD_GROUP("Rendering", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"), "set_screen_space_aa", "get_screen_space_aa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"), "set_msaa", "get_msaa"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lod_threshold", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_lod_threshold", "get_lod_threshold"); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index b7bc2a83c5..d793be1869 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -1444,7 +1444,7 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "position"), "set_position", "get_position"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,FullScreen"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_screen"), "set_current_screen", "get_current_screen"); ADD_GROUP("Flags", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); @@ -1461,8 +1461,8 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "max_size"), "set_max_size", "get_max_size"); ADD_GROUP("Content Scale", "content_scale_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,CanvasItems,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,KeepWidth,KeepHeight,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_custom_type"), "set_theme_custom_type", "get_theme_custom_type"); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 6e67daf15f..3a5b3534c6 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -719,6 +719,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1)); theme->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2)); theme->set_color("relationship_line_color", "Tree", Color(0.27, 0.27, 0.27)); + theme->set_color("parent_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); + theme->set_color("children_hl_line_color", "Tree", Color(0.27, 0.27, 0.27)); theme->set_color("custom_button_font_highlight", "Tree", control_font_hover_color); theme->set_constant("hseparation", "Tree", 4 * scale); @@ -726,6 +728,10 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("item_margin", "Tree", 12 * scale); theme->set_constant("button_margin", "Tree", 4 * scale); theme->set_constant("draw_relationship_lines", "Tree", 0); + theme->set_constant("relationship_line_width", "Tree", 1); + theme->set_constant("parent_hl_line_width", "Tree", 1); + theme->set_constant("children_hl_line_width", "Tree", 1); + theme->set_constant("parent_hl_line_margin", "Tree", 0); theme->set_constant("draw_guides", "Tree", 1); theme->set_constant("scroll_border", "Tree", 4); theme->set_constant("scroll_speed", "Tree", 12); diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 75dd417f7f..100fccc783 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1760,7 +1760,8 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const { if (orm) { if (property.name == "shading_mode") { - property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness. + // Vertex not supported in ORM mode, since no individual roughness. + property.hint_string = "Unshaded,Per-Pixel"; } if (property.name.begins_with("roughness") || property.name.begins_with("metallic") || property.name.begins_with("ao_texture")) { property.usage = 0; @@ -2387,18 +2388,18 @@ void BaseMaterial3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_distance_fade_min_distance"), &BaseMaterial3D::get_distance_fade_min_distance); ADD_GROUP("Transparency", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth PrePass"), "set_transparency", "get_transparency"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "transparency", PROPERTY_HINT_ENUM, "Disabled,Alpha,Alpha Scissor,Alpha Hash,Depth Pre-Pass"), "set_transparency", "get_transparency"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_scissor_threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_scissor_threshold", "get_alpha_scissor_threshold"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_hash_scale", PROPERTY_HINT_RANGE, "0,2,0.01"), "set_alpha_hash_scale", "get_alpha_hash_scale"); ADD_PROPERTY(PropertyInfo(Variant::INT, "alpha_antialiasing_mode", PROPERTY_HINT_ENUM, "Disabled,Alpha Edge Blend,Alpha Edge Clip"), "set_alpha_antialiasing", "get_alpha_antialiasing"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "alpha_antialiasing_edge", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_alpha_antialiasing_edge", "get_alpha_antialiasing_edge"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_blend_mode", "get_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply"), "set_blend_mode", "get_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cull_mode", PROPERTY_HINT_ENUM, "Back,Front,Disabled"), "set_cull_mode", "get_cull_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_draw_mode", PROPERTY_HINT_ENUM, "Opaque Only,Always,Never"), "set_depth_draw_mode", "get_depth_draw_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "no_depth_test"), "set_flag", "get_flag", FLAG_DISABLE_DEPTH_TEST); ADD_GROUP("Shading", ""); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,PerPixel,PerVertex"), "set_shading_mode", "get_shading_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shading_mode", PROPERTY_HINT_ENUM, "Unshaded,Per-Pixel,Per-Vertex"), "set_shading_mode", "get_shading_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Oren Nayar,Toon"), "set_diffuse_mode", "get_diffuse_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Blinn,Phong,Toon,Disabled"), "set_specular_mode", "get_specular_mode"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT); @@ -2502,7 +2503,7 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Detail", "detail_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "detail_enabled"), "set_feature", "get_feature", FEATURE_DETAIL); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_mask", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_MASK); - ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul"), "set_detail_blend_mode", "get_detail_blend_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_blend_mode", PROPERTY_HINT_ENUM, "Mix,Add,Subtract,Multiply"), "set_detail_blend_mode", "get_detail_blend_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "detail_uv_layer", PROPERTY_HINT_ENUM, "UV1,UV2"), "set_detail_uv", "get_detail_uv"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_ALBEDO); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "detail_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_DETAIL_NORMAL); diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index a965317c81..60d5566f08 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -1316,7 +1316,7 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); ADD_GROUP("Sub Emitter", "sub_emitter_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,AtEnd,AtCollision"), "set_sub_emitter_mode", "get_sub_emitter_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,At End,At Collision"), "set_sub_emitter_mode", "get_sub_emitter_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sub_emitter_frequency", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_sub_emitter_frequency", "get_sub_emitter_frequency"); ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_end", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_end", "get_sub_emitter_amount_at_end"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sub_emitter_keep_velocity"), "set_sub_emitter_keep_velocity", "get_sub_emitter_keep_velocity"); diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index f50ee9c4c8..9d79c22159 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -193,7 +193,6 @@ ProceduralSkyMaterial::ProceduralSkyMaterial() { code += "uniform float ground_energy = 1.0;\n\n"; code += "uniform float sun_angle_max = 1.74;\n"; code += "uniform float sun_curve : hint_range(0, 1) = 0.05;\n\n"; - code += "const float PI = 3.1415926535897932384626433833;\n\n"; code += "void sky() {\n"; code += "\tfloat v_angle = acos(clamp(EYEDIR.y, -1.0, 1.0));\n"; code += "\tfloat c = (1.0 - v_angle / (PI * 0.5));\n"; @@ -499,7 +498,6 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "uniform sampler2D night_sky : hint_black;"; - code += "const float PI = 3.141592653589793238462643383279502884197169;\n"; code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n"; code += "// Sun constants\n"; diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index b71909b6bb..564c65adb9 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -55,7 +55,7 @@ Error TextFile::load_text(const String &p_path) { ERR_FAIL_COND_V_MSG(err, err, "Cannot open TextFile '" + p_path + "'."); - uint64_t len = f->get_len(); + uint64_t len = f->get_length(); sourcef.resize(len + 1); uint8_t *w = sourcef.ptrw(); uint64_t r = f->get_buffer(w, len); diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 925867a1f2..f1eff6e84f 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -74,7 +74,7 @@ void TextLine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextLine::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &TextLine::get_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida justification,Word justification,Trim edge spaces after justification,Justification only after last tab"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justify,Word Justify,Trim Edge Spaces After Justify,Justify Only After Last Tab"), "set_flags", "get_flags"); ClassDB::bind_method(D_METHOD("get_objects"), &TextLine::get_objects); ClassDB::bind_method(D_METHOD("get_object_rect", "key"), &TextLine::get_object_rect); diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 341f5abd80..958c94fe31 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -72,7 +72,7 @@ void TextParagraph::_bind_methods() { ClassDB::bind_method(D_METHOD("set_flags", "flags"), &TextParagraph::set_flags); ClassDB::bind_method(D_METHOD("get_flags"), &TextParagraph::get_flags); - ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida justification,Word justification,Trim edge spaces after justification,Justification only after last tab,Break mandatory,Break words,Break graphemes"), "set_flags", "get_flags"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Kashida Justify,Word Justify,Trim Edge Spaces After Justify,Justify Only After Last Tab,Break Mandatory,Break Words,Break Graphemes"), "set_flags", "get_flags"); ClassDB::bind_method(D_METHOD("set_width", "width"), &TextParagraph::set_width); ClassDB::bind_method(D_METHOD("get_width"), &TextParagraph::get_width); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 9db7acb263..308f219a8d 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -1290,7 +1290,7 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tile_skew", "skew"), &TileSet::set_tile_skew); ClassDB::bind_method(D_METHOD("get_tile_skew"), &TileSet::get_tile_skew); - ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_shape", PROPERTY_HINT_ENUM, "Square,Isometric,Half-offset square,Hexagon"), "set_tile_shape", "get_tile_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_shape", PROPERTY_HINT_ENUM, "Square,Isometric,Half-Offset Square,Hexagon"), "set_tile_shape", "get_tile_shape"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_layout", PROPERTY_HINT_ENUM, "Stacked,Stacked Offset,Stairs Right,Stairs Down,Diamond Right,Diamond Down"), "set_tile_layout", "get_tile_layout"); ADD_PROPERTY(PropertyInfo(Variant::INT, "tile_offset_axis", PROPERTY_HINT_ENUM, "Horizontal Offset,Vertical Offset"), "set_tile_offset_axis", "get_tile_offset_axis"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "tile_size"), "set_tile_size", "get_tile_size"); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a8e71bcc4b..314333158c 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -789,7 +789,7 @@ void VisualShaderNodeTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_SCREEN); @@ -1336,7 +1336,7 @@ void VisualShaderNodeCubemap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "Cubemap"), "set_cube_map", "get_cube_map"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map"), "set_texture_type", "get_texture_type"); BIND_ENUM_CONSTANT(SOURCE_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_PORT); @@ -1437,7 +1437,7 @@ void VisualShaderNodeFloatOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Atan2,Step"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,ATan2,Step"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1534,7 +1534,7 @@ void VisualShaderNodeIntOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1643,7 +1643,7 @@ void VisualShaderNodeVectorOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Sub,Multiply,Divide,Remainder,Power,Max,Min,Cross,Atan2,Reflect,Step"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Power,Max,Min,Cross,ATan2,Reflect,Step"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_ADD); BIND_ENUM_CONSTANT(OP_SUB); @@ -1813,7 +1813,7 @@ void VisualShaderNodeColorOp::_bind_methods() { ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator); ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator); - ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,SoftLight,HardLight"), "set_operator", "get_operator"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Screen,Difference,Darken,Lighten,Overlay,Dodge,Burn,Soft Light,Hard Light"), "set_operator", "get_operator"); BIND_ENUM_CONSTANT(OP_SCREEN); BIND_ENUM_CONSTANT(OP_DIFFERENCE); @@ -3927,7 +3927,7 @@ void VisualShaderNodeIntUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value); ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value); - ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range + Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step"); @@ -4515,7 +4515,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_default", "type"), &VisualShaderNodeTextureUniform::set_color_default); ClassDB::bind_method(D_METHOD("get_color_default"), &VisualShaderNodeTextureUniform::get_color_default); - ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap,Aniso"), "set_texture_type", "get_texture_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normal Map,Anisotropic"), "set_texture_type", "get_texture_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "color_default", PROPERTY_HINT_ENUM, "White Default,Black Default"), "set_color_default", "get_color_default"); BIND_ENUM_CONSTANT(TYPE_DATA); diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index 06d51776a3..5c076ca3fe 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -159,7 +159,7 @@ void AudioEffectDistortion::_bind_methods() { ClassDB::bind_method(D_METHOD("set_post_gain", "post_gain"), &AudioEffectDistortion::set_post_gain); ClassDB::bind_method(D_METHOD("get_post_gain"), &AudioEffectDistortion::get_post_gain); - ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,WaveShape"), "set_mode", "get_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,Wave Shape"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pre_gain", PROPERTY_HINT_RANGE, "-60,60,0.01"), "set_pre_gain", "get_pre_gain"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_keep_hf_hz", "get_keep_hf_hz"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drive", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drive", "get_drive"); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index c96c541461..5a26b5abbb 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -30,6 +30,7 @@ #include "scene_shader_forward_clustered.h" #include "core/config/project_settings.h" +#include "core/math/math_defs.h" #include "render_forward_clustered.h" using namespace RendererSceneRenderImplementation; @@ -608,6 +609,9 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin //builtins actions.renames["TIME"] = "scene_data.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index b9220cc514..883273c8a5 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -30,6 +30,7 @@ #include "scene_shader_forward_mobile.h" #include "core/config/project_settings.h" +#include "core/math/math_defs.h" #include "render_forward_mobile.h" using namespace RendererSceneRenderImplementation; @@ -625,6 +626,9 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p //builtins actions.renames["TIME"] = "scene_data.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size"; actions.renames["FRAGCOORD"] = "gl_FragCoord"; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 1f27dd54ec..70c1705bff 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -31,6 +31,7 @@ #include "renderer_canvas_render_rd.h" #include "core/config/project_settings.h" #include "core/math/geometry_2d.h" +#include "core/math/math_defs.h" #include "core/math/math_funcs.h" #include "renderer_compositor_rd.h" #include "servers/rendering/rendering_server_default.h" @@ -2408,6 +2409,9 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { actions.renames["CANVAS_MATRIX"] = "canvas_data.canvas_transform"; actions.renames["SCREEN_MATRIX"] = "canvas_data.screen_transform"; actions.renames["TIME"] = "canvas_data.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["AT_LIGHT_PASS"] = "false"; actions.renames["INSTANCE_CUSTOM"] = "instance_custom"; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 54c6e81110..966a1c6815 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -30,6 +30,7 @@ #include "renderer_scene_sky_rd.h" #include "core/config/project_settings.h" +#include "core/math/math_defs.h" #include "renderer_scene_render_rd.h" #include "servers/rendering/rendering_server_default.h" @@ -710,6 +711,9 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { actions.renames["SKY_COORDS"] = "panorama_coords"; actions.renames["SCREEN_UV"] = "uv"; actions.renames["TIME"] = "params.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["HALF_RES_COLOR"] = "half_res_color"; actions.renames["QUARTER_RES_COLOR"] = "quarter_res_color"; actions.renames["RADIANCE"] = "radiance"; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 26ddd74a80..7a26e40c0a 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/config/project_settings.h" #include "core/io/resource_loader.h" +#include "core/math/math_defs.h" #include "renderer_compositor_rd.h" #include "servers/rendering/shader_language.h" @@ -9225,6 +9226,9 @@ RendererStorageRD::RendererStorageRD() { actions.renames["CUSTOM"] = "PARTICLE.custom"; actions.renames["TRANSFORM"] = "PARTICLE.xform"; actions.renames["TIME"] = "FRAME.time"; + actions.renames["PI"] = _MKSTR(Math_PI); + actions.renames["TAU"] = _MKSTR(Math_TAU); + actions.renames["E"] = _MKSTR(Math_E); actions.renames["LIFETIME"] = "params.lifetime"; actions.renames["DELTA"] = "local_delta"; actions.renames["NUMBER"] = "particle_number"; diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 3a000bd06e..056c8113a7 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -391,10 +391,21 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S String header; if (fnode->return_type == SL::TYPE_STRUCT) { - header = _mkid(fnode->return_struct_name) + " " + _mkid(fnode->name) + "("; + header = _mkid(fnode->return_struct_name); } else { - header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "("; + header = _typestr(fnode->return_type); } + + if (fnode->return_array_size > 0) { + header += "["; + header += itos(fnode->return_array_size); + header += "]"; + } + + header += " "; + header += _mkid(fnode->name); + header += "("; + for (int i = 0; i < fnode->arguments.size(); i++) { if (i > 0) { header += ", "; @@ -407,6 +418,11 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S } else { header += _qualstr(fnode->arguments[i].qualifier) + _prestr(fnode->arguments[i].precision) + _typestr(fnode->arguments[i].type) + " " + _mkid(fnode->arguments[i].name); } + if (fnode->arguments[i].array_size > 0) { + header += "["; + header += itos(fnode->arguments[i].array_size); + header += "]"; + } } header += ")\n"; @@ -959,25 +975,30 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge declaration += itos(adnode->declarations[i].size); } declaration += "]"; - int sz = adnode->declarations[i].initializer.size(); - if (sz > 0) { + if (adnode->declarations[i].single_expression) { declaration += "="; - if (adnode->datatype == SL::TYPE_STRUCT) { - declaration += _mkid(adnode->struct_name); - } else { - declaration += _typestr(adnode->datatype); - } - declaration += "["; - declaration += itos(sz); - declaration += "]"; - declaration += "("; - for (int j = 0; j < sz; j++) { - declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (j != sz - 1) { - declaration += ", "; + declaration += _dump_node_code(adnode->declarations[i].initializer[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } else { + int sz = adnode->declarations[i].initializer.size(); + if (sz > 0) { + declaration += "="; + if (adnode->datatype == SL::TYPE_STRUCT) { + declaration += _mkid(adnode->struct_name); + } else { + declaration += _typestr(adnode->datatype); + } + declaration += "["; + declaration += itos(sz); + declaration += "]"; + declaration += "("; + for (int j = 0; j < sz; j++) { + declaration += _dump_node_code(adnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + if (j != sz - 1) { + declaration += ", "; + } } + declaration += ")"; } - declaration += ")"; } } @@ -988,7 +1009,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge bool use_fragment_varying = false; if (!(p_actions.entry_point_stages.has(current_func_name) && p_actions.entry_point_stages[current_func_name] == STAGE_VERTEX)) { - if (anode->assign_expression != nullptr) { + if (anode->assign_expression != nullptr && shader->varyings.has(anode->name)) { use_fragment_varying = true; } else { if (p_assigning) { diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 2ce7707257..14b21e1f42 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -926,6 +926,8 @@ void ShaderLanguage::clear() { char_idx = 0; error_set = false; error_str = ""; + last_const = false; + pass_array = false; while (nodes) { Node *n = nodes; nodes = nodes->next; @@ -973,7 +975,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_type) { *r_type = IDENTIFIER_BUILTIN_VAR; } - return true; } @@ -987,7 +988,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_type) { *r_type = IDENTIFIER_FUNCTION; } - return true; } @@ -1004,16 +1004,15 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_array_size) { *r_array_size = p_block->variables[p_identifier].array_size; } - if (r_type) { - *r_type = IDENTIFIER_LOCAL_VAR; - } if (r_struct_name) { *r_struct_name = p_block->variables[p_identifier].struct_name; } if (r_constant_value) { *r_constant_value = p_block->variables[p_identifier].value; } - + if (r_type) { + *r_type = IDENTIFIER_LOCAL_VAR; + } return true; } @@ -1035,15 +1034,18 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_data_type) { *r_data_type = function->arguments[i].type; } - if (r_type) { - *r_type = IDENTIFIER_FUNCTION_ARGUMENT; - } if (r_struct_name) { *r_struct_name = function->arguments[i].type_str; } + if (r_array_size) { + *r_array_size = function->arguments[i].array_size; + } if (r_is_const) { *r_is_const = function->arguments[i].is_const; } + if (r_type) { + *r_type = IDENTIFIER_FUNCTION_ARGUMENT; + } return true; } } @@ -1082,9 +1084,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_array_size) { *r_array_size = shader->constants[p_identifier].array_size; } - if (r_type) { - *r_type = IDENTIFIER_CONSTANT; - } if (r_struct_name) { *r_struct_name = shader->constants[p_identifier].type_str; } @@ -1093,6 +1092,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea *r_constant_value = shader->constants[p_identifier].initializer->values[0]; } } + if (r_type) { + *r_type = IDENTIFIER_CONSTANT; + } return true; } @@ -1105,6 +1107,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea if (r_data_type) { *r_data_type = shader->functions[i].function->return_type; } + if (r_array_size) { + *r_array_size = shader->functions[i].function->return_array_size; + } if (r_type) { *r_type = IDENTIFIER_FUNCTION; } @@ -1115,13 +1120,18 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea return false; } -bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) { +bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type, int *r_ret_size) { bool valid = false; DataType ret_type = TYPE_VOID; + int ret_size = 0; switch (p_op->op) { case OP_EQUAL: case OP_NOT_EQUAL: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); valid = na == nb; @@ -1131,6 +1141,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_LESS_EQUAL: case OP_GREATER: case OP_GREATER_EQUAL: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1140,6 +1154,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } break; case OP_AND: case OP_OR: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1148,6 +1166,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } break; case OP_NOT: { + if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); valid = na == TYPE_BOOL; ret_type = TYPE_BOOL; @@ -1158,6 +1180,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_POST_INCREMENT: case OP_POST_DECREMENT: case OP_NEGATE: { + if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); valid = na > TYPE_BOOL && na < TYPE_MAT2; ret_type = na; @@ -1166,6 +1192,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_SUB: case OP_MUL: case OP_DIV: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1234,6 +1264,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type * component-wise. */ + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1286,6 +1320,10 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type case OP_ASSIGN_SHIFT_RIGHT: case OP_SHIFT_LEFT: case OP_SHIFT_RIGHT: { + if ((!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) || (!p_op->arguments[1]->is_indexed() && p_op->arguments[1]->get_array_size() > 0)) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1334,6 +1372,18 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } break; case OP_ASSIGN: { + int sa = 0; + int sb = 0; + if (!p_op->arguments[0]->is_indexed()) { + sa = p_op->arguments[0]->get_array_size(); + } + if (!p_op->arguments[1]->is_indexed()) { + sb = p_op->arguments[1]->get_array_size(); + } + if (sa != sb) { + break; // don't accept arrays if their sizes are not equal + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); if (na == TYPE_STRUCT || nb == TYPE_STRUCT) { @@ -1342,11 +1392,24 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type valid = na == nb; } ret_type = na; + ret_size = sa; } break; case OP_ASSIGN_ADD: case OP_ASSIGN_SUB: case OP_ASSIGN_MUL: case OP_ASSIGN_DIV: { + int sa = 0; + int sb = 0; + if (!p_op->arguments[0]->is_indexed()) { + sa = p_op->arguments[0]->get_array_size(); + } + if (!p_op->arguments[1]->is_indexed()) { + sb = p_op->arguments[1]->get_array_size(); + } + if (sa > 0 || sb > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1414,6 +1477,18 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type * must match. */ + int sa = 0; + int sb = 0; + if (!p_op->arguments[0]->is_indexed()) { + sa = p_op->arguments[0]->get_array_size(); + } + if (!p_op->arguments[1]->is_indexed()) { + sb = p_op->arguments[1]->get_array_size(); + } + if (sa > 0 || sb > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); @@ -1468,17 +1543,34 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type } } break; case OP_BIT_INVERT: { //unaries + if (!p_op->arguments[0]->is_indexed() && p_op->arguments[0]->get_array_size() > 0) { + break; // don't accept arrays + } + DataType na = p_op->arguments[0]->get_datatype(); valid = na >= TYPE_INT && na < TYPE_FLOAT; ret_type = na; } break; case OP_SELECT_IF: { + int sa = 0; + int sb = 0; + if (!p_op->arguments[1]->is_indexed()) { + sa = p_op->arguments[1]->get_array_size(); + } + if (!p_op->arguments[2]->is_indexed()) { + sb = p_op->arguments[2]->get_array_size(); + } + if (sa != sb) { + break; // don't accept arrays if their sizes are not equal + } + DataType na = p_op->arguments[0]->get_datatype(); DataType nb = p_op->arguments[1]->get_datatype(); DataType nc = p_op->arguments[2]->get_datatype(); valid = na == TYPE_BOOL && (nb == nc); ret_type = nb; + ret_size = sa; } break; default: { ERR_FAIL_V(false); @@ -1488,6 +1580,9 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type if (r_ret_type) { *r_ret_type = ret_type; } + if (r_ret_size) { + *r_ret_size = ret_size; + } return valid; } @@ -2223,6 +2318,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI Vector<DataType> args; Vector<StringName> args2; + Vector<int> args3; ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::TYPE_VARIABLE, false); @@ -2231,6 +2327,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI for (int i = 1; i < p_func->arguments.size(); i++) { args.push_back(p_func->arguments[i]->get_datatype()); args2.push_back(p_func->arguments[i]->get_datatype_name()); + args3.push_back(p_func->arguments[i]->get_array_size()); } int argcount = args.size(); @@ -2498,6 +2595,11 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI } else { func_arg_name = get_datatype_name(pfunc->arguments[j].type); } + if (pfunc->arguments[j].array_size > 0) { + func_arg_name += "["; + func_arg_name += itos(pfunc->arguments[j].array_size); + func_arg_name += "]"; + } arg_list += func_arg_name; } } @@ -2510,21 +2612,32 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI bool fail = false; for (int j = 0; j < args.size(); j++) { - if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { + if (get_scalar_type(args[j]) == args[j] && p_func->arguments[j + 1]->type == Node::TYPE_CONSTANT && args3[j] == 0 && convert_constant(static_cast<ConstantNode *>(p_func->arguments[j + 1]), pfunc->arguments[j].type)) { //all good, but it needs implicit conversion later - } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str)) { + } else if (args[j] != pfunc->arguments[j].type || (args[j] == TYPE_STRUCT && args2[j] != pfunc->arguments[j].type_str) || args3[j] != pfunc->arguments[j].array_size) { String func_arg_name; if (pfunc->arguments[j].type == TYPE_STRUCT) { func_arg_name = pfunc->arguments[j].type_str; } else { func_arg_name = get_datatype_name(pfunc->arguments[j].type); } + if (pfunc->arguments[j].array_size > 0) { + func_arg_name += "["; + func_arg_name += itos(pfunc->arguments[j].array_size); + func_arg_name += "]"; + } String arg_name; if (args[j] == TYPE_STRUCT) { arg_name = args2[j]; } else { arg_name = get_datatype_name(args[j]); } + if (args3[j] > 0) { + arg_name += "["; + arg_name += itos(args3[j]); + arg_name += "]"; + } + _set_error(vformat("Invalid argument for \"%s(%s)\" function: argument %s should be %s but is %s.", String(name), arg_list, j + 1, func_arg_name, arg_name)); fail = true; break; @@ -2570,16 +2683,45 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI return false; } -bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const { - if (a->get_datatype() != b->get_datatype()) { - return false; +bool ShaderLanguage::_compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b) { + bool result = true; + + if (p_datatype_a == TYPE_STRUCT || p_datatype_b == TYPE_STRUCT) { + if (p_datatype_name_a != p_datatype_name_b) { + result = false; + } + } else { + if (p_datatype_a != p_datatype_b) { + result = false; + } } - if (a->get_datatype() == TYPE_STRUCT || b->get_datatype() == TYPE_STRUCT) { - if (a->get_datatype_name() != b->get_datatype_name()) { - return false; + + if (p_array_size_a != p_array_size_b) { + result = false; + } + + if (!result) { + String type_name = p_datatype_a == TYPE_STRUCT ? p_datatype_name_a : get_datatype_name(p_datatype_a); + if (p_array_size_a > 0) { + type_name += "["; + type_name += itos(p_array_size_a); + type_name += "]"; } + + String type_name2 = p_datatype_b == TYPE_STRUCT ? p_datatype_name_b : get_datatype_name(p_datatype_b); + if (p_array_size_b > 0) { + type_name2 += "["; + type_name2 += itos(p_array_size_b); + type_name2 += "]"; + } + + _set_error("Invalid assignment of '" + type_name2 + "' to '" + type_name + "'"); } - return true; + return result; +} + +bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) { + return _compare_datatypes(a->get_datatype(), a->get_datatype_name(), a->get_array_size(), b->get_datatype(), b->get_datatype_name(), b->get_array_size()); } bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg) { @@ -3390,11 +3532,12 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa ERR_FAIL_V(false); //bug? function not found } -ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) { +ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info) { DataType type = TYPE_VOID; String struct_name = ""; int array_size = 0; bool auto_size = false; + bool undefined_size = false; Token tk = _get_token(); if (tk.type == TK_CURLY_BRACKET_OPEN) { @@ -3415,6 +3558,137 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc TkPos pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_BRACKET_CLOSE) { + undefined_size = true; + tk = _get_token(); + } else { + _set_tkpos(pos); + + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { + _set_error("Expected single integer constant > 0"); + return nullptr; + } + + ConstantNode *cnode = (ConstantNode *)n; + if (cnode->values.size() == 1) { + array_size = cnode->values[0].sint; + if (array_size <= 0) { + _set_error("Expected single integer constant > 0"); + return nullptr; + } + } else { + _set_error("Expected single integer constant > 0"); + return nullptr; + } + + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return nullptr; + } else { + tk = _get_token(); + } + } + } else { + _set_error("Expected '['"); + return nullptr; + } + } + + ArrayConstructNode *an = alloc_node<ArrayConstructNode>(); + + if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization + int idx = 0; + while (true) { + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n) { + return nullptr; + } + + // define type by using the first member + if (auto_size && idx == 0) { + type = n->get_datatype(); + if (type == TYPE_STRUCT) { + struct_name = n->get_datatype_name(); + } + } else { + if (!_compare_datatypes(type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { + return nullptr; + } + } + + tk = _get_token(); + if (tk.type == TK_COMMA) { + an->initializer.push_back(n); + } else if (!auto_size && tk.type == TK_PARENTHESIS_CLOSE) { + an->initializer.push_back(n); + break; + } else if (auto_size && tk.type == TK_CURLY_BRACKET_CLOSE) { + an->initializer.push_back(n); + break; + } else { + if (auto_size) { + _set_error("Expected '}' or ','"); + } else { + _set_error("Expected ')' or ','"); + } + return nullptr; + } + idx++; + } + if (!auto_size && !undefined_size && an->initializer.size() != array_size) { + _set_error("Array size mismatch"); + return nullptr; + } + } else { + _set_error("Expected array initialization!"); + return nullptr; + } + + an->datatype = type; + an->struct_name = struct_name; + return an; +} + +ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size) { + DataType type = TYPE_VOID; + String struct_name = ""; + int array_size = 0; + bool auto_size = false; + TkPos prev_pos = _get_tkpos(); + Token tk = _get_token(); + + if (tk.type == TK_CURLY_BRACKET_OPEN) { + auto_size = true; + } else { + if (shader->structs.has(tk.text)) { + type = TYPE_STRUCT; + struct_name = tk.text; + } else { + if (!is_token_variable_datatype(tk.type)) { + _set_tkpos(prev_pos); + + pass_array = true; + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + pass_array = false; + + if (!n) { + _set_error("Invalid data type for array"); + return nullptr; + } + + if (!_compare_datatypes(p_type, p_struct_name, p_array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { + return nullptr; + } + return n; + } + type = get_token_datatype(tk.type); + } + tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + TkPos pos = _get_tkpos(); + tk = _get_token(); + if (tk.type == TK_BRACKET_CLOSE) { array_size = p_array_size; tk = _get_token(); } else { @@ -3486,8 +3760,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc return nullptr; } - if (p_type != n->get_datatype() || p_struct_name != n->get_datatype_name()) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (type == TYPE_STRUCT ? struct_name : get_datatype_name(type)) + "'"); + if (!_compare_datatypes(p_type, p_struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { return nullptr; } @@ -3587,50 +3860,73 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //make sure void is not used in expression _set_error("Void value not allowed in Expression"); return nullptr; - } else if (is_token_nonvoid_datatype(tk.type)) { - //basic type constructor + } else if (is_token_nonvoid_datatype(tk.type) || tk.type == TK_CURLY_BRACKET_OPEN) { + if (tk.type == TK_CURLY_BRACKET_OPEN) { + //array constructor - OperatorNode *func = alloc_node<OperatorNode>(); - func->op = OP_CONSTRUCT; + _set_tkpos(prepos); + expr = _parse_array_constructor(p_block, p_function_info); + } else { + DataType datatype; + DataPrecision precision; + bool precision_defined = false; - if (is_token_precision(tk.type)) { - func->return_precision_cache = get_token_precision(tk.type); + if (is_token_precision(tk.type)) { + precision = get_token_precision(tk.type); + precision_defined = true; + tk = _get_token(); + } + + datatype = get_token_datatype(tk.type); tk = _get_token(); - } - VariableNode *funcname = alloc_node<VariableNode>(); - funcname->name = get_datatype_name(get_token_datatype(tk.type)); - func->arguments.push_back(funcname); + if (tk.type == TK_BRACKET_OPEN) { + //array constructor - tk = _get_token(); - if (tk.type != TK_PARENTHESIS_OPEN) { - _set_error("Expected '(' after type name"); - return nullptr; - } + _set_tkpos(prepos); + expr = _parse_array_constructor(p_block, p_function_info); + } else { + if (tk.type != TK_PARENTHESIS_OPEN) { + _set_error("Expected '(' after type name"); + return nullptr; + } + //basic type constructor - int carg = -1; + OperatorNode *func = alloc_node<OperatorNode>(); + func->op = OP_CONSTRUCT; - bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); + if (precision_defined) { + func->return_precision_cache = precision; + } - if (carg >= 0) { - completion_type = COMPLETION_CALL_ARGUMENTS; - completion_line = tk_line; - completion_block = p_block; - completion_function = funcname->name; - completion_argument = carg; - } + VariableNode *funcname = alloc_node<VariableNode>(); + funcname->name = get_datatype_name(datatype); + func->arguments.push_back(funcname); - if (!ok) { - return nullptr; - } + int carg = -1; - if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) { - _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); - return nullptr; - } + bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); + + if (carg >= 0) { + completion_type = COMPLETION_CALL_ARGUMENTS; + completion_line = tk_line; + completion_block = p_block; + completion_function = funcname->name; + completion_argument = carg; + } - expr = _reduce_expression(p_block, func); + if (!ok) { + return nullptr; + } + + if (!_validate_function_call(p_block, p_function_info, func, &func->return_cache, &func->struct_name)) { + _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); + return nullptr; + } + expr = _reduce_expression(p_block, func); + } + } } else if (tk.type == TK_IDENTIFIER) { _set_tkpos(prepos); @@ -3678,11 +3974,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (!nexpr) { return nullptr; } - Node *node = pstruct->members[i]; if (!_compare_datatypes_in_nodes(pstruct->members[i], nexpr)) { - String type_name = nexpr->get_datatype() == TYPE_STRUCT ? nexpr->get_datatype_name() : get_datatype_name(nexpr->get_datatype()); - String type_name2 = node->get_datatype() == TYPE_STRUCT ? node->get_datatype_name() : get_datatype_name(node->get_datatype()); - _set_error("Invalid assignment of '" + type_name + "' to '" + type_name2 + "'"); return nullptr; } } @@ -3704,7 +3996,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expr = func; - } else { //a function + } else { //a function call const StringName &name = identifier; @@ -3716,7 +4008,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons int carg = -1; + pass_array = true; bool ok = _parse_function_arguments(p_block, p_function_info, func, &carg); + pass_array = false; // Check if block has a variable with the same name as function to prevent shader crash. ShaderLanguage::BlockNode *bnode = p_block; @@ -3769,6 +4063,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons FunctionNode *call_function = shader->functions[function_index].function; if (call_function) { + func->return_cache = call_function->get_datatype(); + func->struct_name = call_function->get_datatype_name(); + func->return_array_size = call_function->get_array_size(); + //get current base function FunctionNode *base_function = nullptr; { @@ -3943,60 +4241,61 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons Node *assign_expression = nullptr; if (array_size > 0) { - tk = _get_token(); - - if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) { - _set_error("Expected '[','.' or '='"); - return nullptr; - } + if (!pass_array) { + tk = _get_token(); - if (tk.type == TK_OP_ASSIGN) { - if (is_const) { - _set_error("Constants cannot be modified."); + if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD && tk.type != TK_OP_ASSIGN) { + _set_error("Expected '[','.' or '='"); return nullptr; } - assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); - if (!assign_expression) { - return nullptr; - } - } else if (tk.type == TK_PERIOD) { - completion_class = TAG_ARRAY; - p_block->block_tag = SubClassTag::TAG_ARRAY; - call_expression = _parse_and_reduce_expression(p_block, p_function_info); - p_block->block_tag = SubClassTag::TAG_GLOBAL; - if (!call_expression) { - return nullptr; - } - data_type = call_expression->get_datatype(); - } else { // indexing - index_expression = _parse_and_reduce_expression(p_block, p_function_info); - if (!index_expression) { - return nullptr; - } + if (tk.type == TK_OP_ASSIGN) { + if (is_const) { + _set_error("Constants cannot be modified."); + return nullptr; + } + assign_expression = _parse_array_constructor(p_block, p_function_info, data_type, struct_name, array_size); + if (!assign_expression) { + return nullptr; + } + } else if (tk.type == TK_PERIOD) { + completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; + call_expression = _parse_and_reduce_expression(p_block, p_function_info); + p_block->block_tag = SubClassTag::TAG_GLOBAL; + if (!call_expression) { + return nullptr; + } + data_type = call_expression->get_datatype(); + } else { // indexing + index_expression = _parse_and_reduce_expression(p_block, p_function_info); + if (!index_expression) { + return nullptr; + } - if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { - _set_error("Only integer expressions are allowed for indexing"); - return nullptr; - } + if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { + _set_error("Only integer expressions are allowed for indexing"); + return nullptr; + } - if (index_expression->type == Node::TYPE_CONSTANT) { - ConstantNode *cnode = (ConstantNode *)index_expression; - if (cnode) { - if (!cnode->values.is_empty()) { - int value = cnode->values[0].sint; - if (value < 0 || value >= array_size) { - _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); - return nullptr; + if (index_expression->type == Node::TYPE_CONSTANT) { + ConstantNode *cnode = (ConstantNode *)index_expression; + if (cnode) { + if (!cnode->values.is_empty()) { + int value = cnode->values[0].sint; + if (value < 0 || value >= array_size) { + _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); + return nullptr; + } } } } - } - tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return nullptr; + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return nullptr; + } } } @@ -4008,6 +4307,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons arrname->call_expression = call_expression; arrname->assign_expression = assign_expression; arrname->is_const = is_const; + arrname->array_size = array_size; expr = arrname; } else { VariableNode *varname = alloc_node<VariableNode>(); @@ -4072,6 +4372,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons DataType dt = expr->get_datatype(); String st = expr->get_datatype_name(); + if (!expr->is_indexed() && expr->get_array_size() > 0) { + completion_class = TAG_ARRAY; + p_block->block_tag = SubClassTag::TAG_ARRAY; + Node *call_expression = _parse_and_reduce_expression(p_block, p_function_info); + p_block->block_tag = SubClassTag::TAG_GLOBAL; + if (!call_expression) { + return nullptr; + } + expr = call_expression; + break; + } + StringName identifier; if (_get_completable_identifier(p_block, dt == TYPE_STRUCT ? COMPLETION_STRUCT : COMPLETION_INDEX, identifier)) { if (dt == TYPE_STRUCT) { @@ -4348,6 +4660,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons mn->has_swizzling_duplicates = repeated; if (array_size > 0) { + TkPos prev_pos = _get_tkpos(); tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { if (last_type == IDENTIFIER_CONSTANT) { @@ -4399,13 +4712,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons return nullptr; } mn->index_expression = index_expression; - } else { - _set_error("Expected '[','.' or '='"); - return nullptr; + if (!pass_array) { + _set_error("Expected '[','.' or '='"); + return nullptr; + } + _set_tkpos(prev_pos); } } - expr = mn; //todo @@ -4430,117 +4744,130 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } DataType member_type = TYPE_VOID; + String member_struct_name; - switch (expr->get_datatype()) { - case TYPE_BVEC2: - case TYPE_VEC2: - case TYPE_IVEC2: - case TYPE_UVEC2: - case TYPE_MAT2: - if (index->type == Node::TYPE_CONSTANT) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= 2) { - _set_error("Index out of range (0-1)"); - return nullptr; + if (expr->get_array_size() > 0) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= (uint32_t)expr->get_array_size()) { + _set_error(vformat("Index [%s] out of range [%s..%s]", index_constant, 0, expr->get_array_size() - 1)); + return nullptr; + } + member_type = expr->get_datatype(); + if (member_type == TYPE_STRUCT) { + member_struct_name = expr->get_datatype_name(); + } + } else { + switch (expr->get_datatype()) { + case TYPE_BVEC2: + case TYPE_VEC2: + case TYPE_IVEC2: + case TYPE_UVEC2: + case TYPE_MAT2: + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= 2) { + _set_error("Index out of range (0-1)"); + return nullptr; + } } - } - switch (expr->get_datatype()) { - case TYPE_BVEC2: - member_type = TYPE_BOOL; - break; - case TYPE_VEC2: - member_type = TYPE_FLOAT; - break; - case TYPE_IVEC2: - member_type = TYPE_INT; - break; - case TYPE_UVEC2: - member_type = TYPE_UINT; - break; - case TYPE_MAT2: - member_type = TYPE_VEC2; - break; - default: - break; - } + switch (expr->get_datatype()) { + case TYPE_BVEC2: + member_type = TYPE_BOOL; + break; + case TYPE_VEC2: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC2: + member_type = TYPE_INT; + break; + case TYPE_UVEC2: + member_type = TYPE_UINT; + break; + case TYPE_MAT2: + member_type = TYPE_VEC2; + break; + default: + break; + } - break; - case TYPE_BVEC3: - case TYPE_VEC3: - case TYPE_IVEC3: - case TYPE_UVEC3: - case TYPE_MAT3: - if (index->type == Node::TYPE_CONSTANT) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= 3) { - _set_error("Index out of range (0-2)"); - return nullptr; + break; + case TYPE_BVEC3: + case TYPE_VEC3: + case TYPE_IVEC3: + case TYPE_UVEC3: + case TYPE_MAT3: + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= 3) { + _set_error("Index out of range (0-2)"); + return nullptr; + } } - } - switch (expr->get_datatype()) { - case TYPE_BVEC3: - member_type = TYPE_BOOL; - break; - case TYPE_VEC3: - member_type = TYPE_FLOAT; - break; - case TYPE_IVEC3: - member_type = TYPE_INT; - break; - case TYPE_UVEC3: - member_type = TYPE_UINT; - break; - case TYPE_MAT3: - member_type = TYPE_VEC3; - break; - default: - break; - } - break; - case TYPE_BVEC4: - case TYPE_VEC4: - case TYPE_IVEC4: - case TYPE_UVEC4: - case TYPE_MAT4: - if (index->type == Node::TYPE_CONSTANT) { - uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; - if (index_constant >= 4) { - _set_error("Index out of range (0-3)"); - return nullptr; + switch (expr->get_datatype()) { + case TYPE_BVEC3: + member_type = TYPE_BOOL; + break; + case TYPE_VEC3: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC3: + member_type = TYPE_INT; + break; + case TYPE_UVEC3: + member_type = TYPE_UINT; + break; + case TYPE_MAT3: + member_type = TYPE_VEC3; + break; + default: + break; + } + break; + case TYPE_BVEC4: + case TYPE_VEC4: + case TYPE_IVEC4: + case TYPE_UVEC4: + case TYPE_MAT4: + if (index->type == Node::TYPE_CONSTANT) { + uint32_t index_constant = static_cast<ConstantNode *>(index)->values[0].uint; + if (index_constant >= 4) { + _set_error("Index out of range (0-3)"); + return nullptr; + } } - } - switch (expr->get_datatype()) { - case TYPE_BVEC4: - member_type = TYPE_BOOL; - break; - case TYPE_VEC4: - member_type = TYPE_FLOAT; - break; - case TYPE_IVEC4: - member_type = TYPE_INT; - break; - case TYPE_UVEC4: - member_type = TYPE_UINT; - break; - case TYPE_MAT4: - member_type = TYPE_VEC4; - break; - default: - break; + switch (expr->get_datatype()) { + case TYPE_BVEC4: + member_type = TYPE_BOOL; + break; + case TYPE_VEC4: + member_type = TYPE_FLOAT; + break; + case TYPE_IVEC4: + member_type = TYPE_INT; + break; + case TYPE_UVEC4: + member_type = TYPE_UINT; + break; + case TYPE_MAT4: + member_type = TYPE_VEC4; + break; + default: + break; + } + break; + default: { + _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed"); + return nullptr; } - break; - default: { - _set_error("Object of type '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' can't be indexed"); - return nullptr; } } - OperatorNode *op = alloc_node<OperatorNode>(); op->op = OP_INDEX; op->return_cache = member_type; + op->struct_name = member_struct_name; op->arguments.push_back(expr); op->arguments.push_back(index); expr = op; @@ -4556,7 +4883,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT; op->arguments.push_back(expr); - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { _set_error("Invalid base type for increment/decrement operator"); return nullptr; } @@ -4874,13 +5201,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[i].is_op = false; expression.write[i].node = op; - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { String at; for (int j = 0; j < op->arguments.size(); j++) { if (j > 0) { at += " and "; } at += get_datatype_name(op->arguments[j]->get_datatype()); + if (!op->arguments[j]->is_indexed() && op->arguments[j]->get_array_size() > 0) { + at += "["; + at += itos(op->arguments[j]->get_array_size()); + at += "]"; + } } _set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at); return nullptr; @@ -4907,13 +5239,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.write[next_op - 1].is_op = false; expression.write[next_op - 1].node = op; - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { String at; for (int i = 0; i < op->arguments.size(); i++) { if (i > 0) { at += " and "; } at += get_datatype_name(op->arguments[i]->get_datatype()); + if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) { + at += "["; + at += itos(op->arguments[i]->get_array_size()); + at += "]"; + } } _set_error("Invalid argument to ternary ?: operator: " + at); return nullptr; @@ -4960,7 +5297,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons //replace all 3 nodes by this operator and make it an expression - if (!_validate_operator(op, &op->return_cache)) { + if (!_validate_operator(op, &op->return_cache, &op->return_array_size)) { String at; for (int i = 0; i < op->arguments.size(); i++) { if (i > 0) { @@ -4971,6 +5308,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } else { at += get_datatype_name(op->arguments[i]->get_datatype()); } + if (!op->arguments[i]->is_indexed() && op->arguments[i]->get_array_size() > 0) { + at += "["; + at += itos(op->arguments[i]->get_array_size()); + at += "]"; + } } _set_error("Invalid arguments to operator '" + get_operator_text(op->op) + "' :" + at); return nullptr; @@ -5227,6 +5569,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun ArrayDeclarationNode::Declaration decl; decl.name = name; decl.size = 0U; + decl.single_expression = false; pos = _get_tkpos(); tk = _get_token(); @@ -5293,179 +5636,205 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } + TkPos prev_pos = _get_tkpos(); tk = _get_token(); - if (tk.type != TK_CURLY_BRACKET_OPEN) { - if (unknown_size) { - _set_error("Expected '{'"); - return ERR_PARSE_ERROR; - } - - full_def = true; + if (tk.type == TK_IDENTIFIER) { // a function call array initialization + _set_tkpos(prev_pos); + pass_array = true; + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + pass_array = false; - DataPrecision precision2 = PRECISION_DEFAULT; - if (is_token_precision(tk.type)) { - precision2 = get_token_precision(tk.type); - tk = _get_token(); - if (shader->structs.has(tk.text)) { - _set_error("Precision modifier cannot be used on structs."); - return ERR_PARSE_ERROR; + if (!n) { + _set_error("Expected correct array initializer!"); + return ERR_PARSE_ERROR; + } else { + if (unknown_size) { + decl.size = n->get_array_size(); + var.array_size = n->get_array_size(); } - if (!is_token_nonvoid_datatype(tk.type)) { - _set_error("Expected datatype after precision"); + + if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { return ERR_PARSE_ERROR; } - } - DataType type2; - StringName struct_name2 = ""; + decl.single_expression = true; + decl.initializer.push_back(n); + } - if (shader->structs.has(tk.text)) { - type2 = TYPE_STRUCT; - struct_name2 = tk.text; - } else { - if (!is_token_variable_datatype(tk.type)) { - _set_error("Invalid data type for array"); + tk = _get_token(); + } else { + if (tk.type != TK_CURLY_BRACKET_OPEN) { + if (unknown_size) { + _set_error("Expected '{'"); return ERR_PARSE_ERROR; } - type2 = get_token_datatype(tk.type); - } - int array_size2 = 0; + full_def = true; - tk = _get_token(); - if (tk.type == TK_BRACKET_OPEN) { - TkPos pos2 = _get_tkpos(); - tk = _get_token(); - if (tk.type == TK_BRACKET_CLOSE) { - array_size2 = var.array_size; + DataPrecision precision2 = PRECISION_DEFAULT; + if (is_token_precision(tk.type)) { + precision2 = get_token_precision(tk.type); tk = _get_token(); - } else { - _set_tkpos(pos2); - - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { - _set_error("Expected single integer constant > 0"); + if (shader->structs.has(tk.text)) { + _set_error("Precision modifier cannot be used on structs."); + return ERR_PARSE_ERROR; + } + if (!is_token_nonvoid_datatype(tk.type)) { + _set_error("Expected datatype after precision"); return ERR_PARSE_ERROR; } + } - ConstantNode *cnode = (ConstantNode *)n; - if (cnode->values.size() == 1) { - array_size2 = cnode->values[0].sint; - if (array_size2 <= 0) { - _set_error("Expected single integer constant > 0"); - return ERR_PARSE_ERROR; - } - } else { - _set_error("Expected single integer constant > 0"); + DataType type2; + StringName struct_name2 = ""; + + if (shader->structs.has(tk.text)) { + type2 = TYPE_STRUCT; + struct_name2 = tk.text; + } else { + if (!is_token_variable_datatype(tk.type)) { + _set_error("Invalid data type for array"); return ERR_PARSE_ERROR; } + type2 = get_token_datatype(tk.type); + } + int array_size2 = 0; + + tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + TkPos pos2 = _get_tkpos(); tk = _get_token(); - if (tk.type != TK_BRACKET_CLOSE) { - _set_error("Expected ']'"); - return ERR_PARSE_ERROR; + if (tk.type == TK_BRACKET_CLOSE) { + array_size2 = var.array_size; + tk = _get_token(); } else { + _set_tkpos(pos2); + + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + + ConstantNode *cnode = (ConstantNode *)n; + if (cnode->values.size() == 1) { + array_size2 = cnode->values[0].sint; + if (array_size2 <= 0) { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + } else { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } else { + tk = _get_token(); + } } - } - } else { - _set_error("Expected '['"); - return ERR_PARSE_ERROR; - } - - if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) { - String error_str = "Cannot convert from '"; - if (precision2 != PRECISION_DEFAULT) { - error_str += get_precision_name(precision2); - error_str += " "; - } - if (type2 == TYPE_STRUCT) { - error_str += struct_name2; } else { - error_str += get_datatype_name(type2); - } - error_str += "["; - error_str += itos(array_size2); - error_str += "]'"; - error_str += " to '"; - if (precision != PRECISION_DEFAULT) { - error_str += get_precision_name(precision); - error_str += " "; + _set_error("Expected '['"); + return ERR_PARSE_ERROR; } - if (type == TYPE_STRUCT) { - error_str += struct_name; - } else { - error_str += get_datatype_name(type); + + if (precision != precision2 || type != type2 || struct_name != struct_name2 || var.array_size != array_size2) { + String error_str = "Cannot convert from '"; + if (precision2 != PRECISION_DEFAULT) { + error_str += get_precision_name(precision2); + error_str += " "; + } + if (type2 == TYPE_STRUCT) { + error_str += struct_name2; + } else { + error_str += get_datatype_name(type2); + } + error_str += "["; + error_str += itos(array_size2); + error_str += "]'"; + error_str += " to '"; + if (precision != PRECISION_DEFAULT) { + error_str += get_precision_name(precision); + error_str += " "; + } + if (type == TYPE_STRUCT) { + error_str += struct_name; + } else { + error_str += get_datatype_name(type); + } + error_str += "["; + error_str += itos(var.array_size); + error_str += "]'"; + _set_error(error_str); + return ERR_PARSE_ERROR; } - error_str += "["; - error_str += itos(var.array_size); - error_str += "]'"; - _set_error(error_str); - return ERR_PARSE_ERROR; } - } - bool curly = tk.type == TK_CURLY_BRACKET_OPEN; + bool curly = tk.type == TK_CURLY_BRACKET_OPEN; - if (unknown_size) { - if (!curly) { - _set_error("Expected '{'"); - return ERR_PARSE_ERROR; - } - } else { - if (full_def) { - if (curly) { - _set_error("Expected '('"); + if (unknown_size) { + if (!curly) { + _set_error("Expected '{'"); return ERR_PARSE_ERROR; } + } else { + if (full_def) { + if (curly) { + _set_error("Expected '('"); + return ERR_PARSE_ERROR; + } + } } - } - if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization - while (true) { - Node *n = _parse_and_reduce_expression(p_block, p_function_info); - if (!n) { - return ERR_PARSE_ERROR; - } + if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization + while (true) { + Node *n = _parse_and_reduce_expression(p_block, p_function_info); + if (!n) { + return ERR_PARSE_ERROR; + } - if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { - _set_error("Expected constant expression"); - return ERR_PARSE_ERROR; - } + if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) { + _set_error("Expected constant expression"); + return ERR_PARSE_ERROR; + } - if (var.type != n->get_datatype() || struct_name != n->get_datatype_name()) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (var.type == TYPE_STRUCT ? struct_name : get_datatype_name(var.type)) + "'"); - return ERR_PARSE_ERROR; - } + if (!_compare_datatypes(var.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { + return ERR_PARSE_ERROR; + } - tk = _get_token(); - if (tk.type == TK_COMMA) { - decl.initializer.push_back(n); - continue; - } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) { - decl.initializer.push_back(n); - break; - } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) { - decl.initializer.push_back(n); - break; - } else { - if (curly) { - _set_error("Expected '}' or ','"); + tk = _get_token(); + if (tk.type == TK_COMMA) { + decl.initializer.push_back(n); + continue; + } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) { + decl.initializer.push_back(n); + break; + } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) { + decl.initializer.push_back(n); + break; } else { - _set_error("Expected ')' or ','"); + if (curly) { + _set_error("Expected '}' or ','"); + } else { + _set_error("Expected ')' or ','"); + } + return ERR_PARSE_ERROR; } + } + if (unknown_size) { + decl.size = decl.initializer.size(); + var.array_size = decl.initializer.size(); + } else if (decl.initializer.size() != var.array_size) { + _set_error("Array size mismatch"); return ERR_PARSE_ERROR; } + tk = _get_token(); } - if (unknown_size) { - decl.size = decl.initializer.size(); - var.array_size = decl.initializer.size(); - } else if (decl.initializer.size() != var.array_size) { - _set_error("Array size mismatch"); - return ERR_PARSE_ERROR; - } - tk = _get_token(); } } else { if (unknown_size) { @@ -5518,8 +5887,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } } - if (var.type == TYPE_STRUCT ? (var.struct_name != n->get_datatype_name()) : (var.type != n->get_datatype())) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (var.type == TYPE_STRUCT ? String(var.struct_name) : get_datatype_name(var.type)) + "'"); + if (!_compare_datatypes(var.type, var.struct_name, var.array_size, n->get_datatype(), n->get_datatype_name(), n->get_array_size())) { return ERR_PARSE_ERROR; } tk = _get_token(); @@ -5980,6 +6348,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun } String return_struct_name = String(b->parent_function->return_struct_name); + String array_size_string; + + if (b->parent_function->return_array_size > 0) { + array_size_string = "[" + itos(b->parent_function->return_array_size) + "]"; + } ControlFlowNode *flow = alloc_node<ControlFlowNode>(); flow->flow_op = FLOW_OP_RETURN; @@ -5989,18 +6362,27 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun if (tk.type == TK_SEMICOLON) { //all is good if (b->parent_function->return_type != TYPE_VOID) { - _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'"); + _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'"); return ERR_PARSE_ERROR; } } else { _set_tkpos(pos); //rollback, wants expression + + pass_array = true; Node *expr = _parse_and_reduce_expression(p_block, p_function_info); if (!expr) { return ERR_PARSE_ERROR; } + pass_array = false; + + bool array_size_incorrect = false; + + if (b->parent_function->return_array_size > 0 && b->parent_function->return_array_size != expr->get_array_size()) { + array_size_incorrect = true; + } - if (b->parent_function->return_type != expr->get_datatype() || return_struct_name != expr->get_datatype_name()) { - _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + "'"); + if (b->parent_function->return_type != expr->get_datatype() || array_size_incorrect || return_struct_name != expr->get_datatype_name()) { + _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'"); return ERR_PARSE_ERROR; } @@ -6795,6 +7177,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct DataPrecision precision = PRECISION_DEFAULT; DataType type; StringName name; + int return_array_size = 0; if (tk.type == TK_CONST) { is_constant = true; @@ -6832,10 +7215,33 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct } TkPos prev_pos = _get_tkpos(); tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { - _set_error("Cannot use arrays as return types"); - return ERR_PARSE_ERROR; + bool error = false; + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT) { + return_array_size = (int)tk.constant; + if (return_array_size > 0) { + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + error = true; + } + } else { + error = true; + } + if (error) { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + + prev_pos = _get_tkpos(); } + _set_tkpos(prev_pos); _get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name); @@ -7049,8 +7455,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return ERR_PARSE_ERROR; } - if (constant.type != n->get_datatype() || n->get_datatype_name() != struct_name) { - _set_error("Invalid assignment of '" + (n->get_datatype() == TYPE_STRUCT ? n->get_datatype_name() : get_datatype_name(n->get_datatype())) + "' to '" + (is_struct ? String(struct_name) : get_datatype_name(constant.type)) + "'"); + if (!_compare_datatypes(constant.type, struct_name, 0, n->get_datatype(), n->get_datatype_name(), 0)) { return ERR_PARSE_ERROR; } @@ -7111,8 +7516,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct constant.initializer = static_cast<ConstantNode *>(expr); - if (type != expr->get_datatype() || expr->get_datatype_name() != struct_name) { - _set_error("Invalid assignment of '" + (expr->get_datatype() == TYPE_STRUCT ? expr->get_datatype_name() : get_datatype_name(expr->get_datatype())) + "' to '" + (is_struct ? String(struct_name) : get_datatype_name(type)) + "'"); + if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), 0)) { return ERR_PARSE_ERROR; } } @@ -7192,6 +7596,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct func_node->return_type = type; func_node->return_struct_name = struct_name; func_node->return_precision = precision; + func_node->return_array_size = return_array_size; if (p_functions.has(name)) { func_node->can_discard = p_functions[name].can_discard; @@ -7245,6 +7650,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct StringName param_struct_name; DataPrecision pprecision = PRECISION_DEFAULT; bool use_precision = false; + int array_size = 0; if (is_token_precision(tk.type)) { pprecision = get_token_precision(tk.type); @@ -7291,8 +7697,29 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - _set_error("Arrays as parameters are not implemented yet"); - return ERR_PARSE_ERROR; + bool error = false; + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT) { + array_size = (int)tk.constant; + + if (array_size > 0) { + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + error = true; + } + } else { + error = true; + } + if (error) { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); } if (tk.type != TK_IDENTIFIER) { _set_error("Expected identifier for argument name"); @@ -7326,14 +7753,41 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct arg.tex_argument_repeat = REPEAT_DEFAULT; arg.is_const = is_const; - func_node->arguments.push_back(arg); - tk = _get_token(); if (tk.type == TK_BRACKET_OPEN) { - _set_error("Arrays as parameters are not implemented yet"); - return ERR_PARSE_ERROR; + if (array_size > 0) { + _set_error("Array size is already defined!"); + return ERR_PARSE_ERROR; + } + bool error = false; + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT) { + array_size = (int)tk.constant; + + if (array_size > 0) { + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + error = true; + } + } else { + error = true; + } + + if (error) { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); } + arg.array_size = array_size; + func_node->arguments.push_back(arg); + if (tk.type == TK_COMMA) { tk = _get_token(); //do none and go on @@ -7756,6 +8210,13 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct String calltip; calltip += get_datatype_name(shader->functions[i].function->return_type); + + if (shader->functions[i].function->return_array_size > 0) { + calltip += "["; + calltip += itos(shader->functions[i].function->return_array_size); + calltip += "]"; + } + calltip += " "; calltip += shader->functions[i].name; calltip += "("; @@ -7787,6 +8248,12 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct calltip += " "; calltip += shader->functions[i].function->arguments[j].name; + if (shader->functions[i].function->arguments[j].array_size > 0) { + calltip += "["; + calltip += itos(shader->functions[i].function->arguments[j].array_size); + calltip += "]"; + } + if (j == completion_argument) { calltip += char32_t(0xFFFF); } diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index c8c5bb1fa7..af66e32e06 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -369,6 +369,8 @@ public: virtual DataType get_datatype() const { return TYPE_VOID; } virtual String get_datatype_name() const { return ""; } + virtual int get_array_size() const { return 0; } + virtual bool is_indexed() const { return false; } Node(Type t) : type(t) {} @@ -388,11 +390,15 @@ public: struct OperatorNode : public Node { DataType return_cache = TYPE_VOID; DataPrecision return_precision_cache = PRECISION_DEFAULT; + int return_array_size = 0; Operator op = OP_EQUAL; StringName struct_name; Vector<Node *> arguments; - virtual DataType get_datatype() const { return return_cache; } - virtual String get_datatype_name() const { return String(struct_name); } + + virtual DataType get_datatype() const override { return return_cache; } + virtual String get_datatype_name() const override { return String(struct_name); } + virtual int get_array_size() const override { return return_array_size; } + virtual bool is_indexed() const override { return op == OP_INDEX; } OperatorNode() : Node(TYPE_OPERATOR) {} @@ -402,10 +408,11 @@ public: DataType datatype_cache = TYPE_VOID; StringName name; StringName struct_name; - virtual DataType get_datatype() const { return datatype_cache; } - virtual String get_datatype_name() const { return String(struct_name); } bool is_const = false; + virtual DataType get_datatype() const override { return datatype_cache; } + virtual String get_datatype_name() const override { return String(struct_name); } + VariableNode() : Node(TYPE_VARIABLE) {} }; @@ -420,9 +427,9 @@ public: StringName name; Node *initializer; }; - Vector<Declaration> declarations; - virtual DataType get_datatype() const { return datatype; } + + virtual DataType get_datatype() const override { return datatype; } VariableDeclarationNode() : Node(TYPE_VARIABLE_DECLARATION) {} @@ -436,9 +443,12 @@ public: Node *call_expression = nullptr; Node *assign_expression = nullptr; bool is_const = false; + int array_size = 0; - virtual DataType get_datatype() const { return datatype_cache; } - virtual String get_datatype_name() const { return String(struct_name); } + virtual DataType get_datatype() const override { return datatype_cache; } + virtual String get_datatype_name() const override { return String(struct_name); } + virtual int get_array_size() const override { return array_size; } + virtual bool is_indexed() const override { return index_expression != nullptr; } ArrayNode() : Node(TYPE_ARRAY) {} @@ -449,6 +459,10 @@ public: String struct_name; Vector<Node *> initializer; + virtual DataType get_datatype() const override { return datatype; } + virtual String get_datatype_name() const override { return struct_name; } + virtual int get_array_size() const override { return initializer.size(); } + ArrayConstructNode() : Node(TYPE_ARRAY_CONSTRUCT) {} }; @@ -464,10 +478,11 @@ public: StringName name; uint32_t size; Vector<Node *> initializer; + bool single_expression; }; - Vector<Declaration> declarations; - virtual DataType get_datatype() const { return datatype; } + + virtual DataType get_datatype() const override { return datatype; } ArrayDeclarationNode() : Node(TYPE_ARRAY_DECLARATION) {} @@ -487,8 +502,10 @@ public: Vector<Value> values; Vector<ArrayDeclarationNode::Declaration> array_declarations; - virtual DataType get_datatype() const { return datatype; } - virtual String get_datatype_name() const { return struct_name; } + + virtual DataType get_datatype() const override { return datatype; } + virtual String get_datatype_name() const override { return struct_name; } + virtual int get_array_size() const override { return array_size; } ConstantNode() : Node(TYPE_CONSTANT) {} @@ -553,8 +570,10 @@ public: Node *call_expression = nullptr; bool has_swizzling_duplicates = false; - virtual DataType get_datatype() const { return datatype; } - virtual String get_datatype_name() const { return String(struct_name); } + virtual DataType get_datatype() const override { return datatype; } + virtual String get_datatype_name() const override { return String(struct_name); } + virtual int get_array_size() const override { return array_size; } + virtual bool is_indexed() const override { return index_expression != nullptr || call_expression != nullptr; } MemberNode() : Node(TYPE_MEMBER) {} @@ -580,6 +599,7 @@ public: bool tex_builtin_check; StringName tex_builtin; bool is_const; + int array_size; Map<StringName, Set<int>> tex_argument_connect; }; @@ -588,10 +608,15 @@ public: DataType return_type = TYPE_VOID; StringName return_struct_name; DataPrecision return_precision = PRECISION_DEFAULT; + int return_array_size = 0; Vector<Argument> arguments; BlockNode *body = nullptr; bool can_discard = false; + virtual DataType get_datatype() const override { return return_type; } + virtual String get_datatype_name() const override { return String(return_struct_name); } + virtual int get_array_size() const override { return return_array_size; } + FunctionNode() : Node(TYPE_FUNCTION) {} }; @@ -842,6 +867,8 @@ private: int tk_line; StringName current_function; + bool last_const = false; + bool pass_array = false; StringName last_name; VaryingFunctionNames varying_function_names; @@ -894,7 +921,7 @@ private: #endif // DEBUG_ENABLED bool _is_operator_assign(Operator p_op) const; bool _validate_assign(Node *p_node, const FunctionInfo &p_function_info, String *r_message = nullptr); - bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr); + bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = nullptr, int *r_ret_size = nullptr); struct BuiltinFuncDef { enum { MAX_ARGS = 5 }; @@ -925,7 +952,8 @@ private: static const BuiltinFuncOutArgs builtin_func_out_args[]; Error _validate_datatype(DataType p_type); - bool _compare_datatypes_in_nodes(Node *a, Node *b) const; + bool _compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b); + bool _compare_datatypes_in_nodes(Node *a, Node *b); bool _validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str); bool _parse_function_arguments(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, int *r_complete_arg = nullptr); @@ -936,6 +964,7 @@ private: bool _check_node_constness(const Node *p_node) const; Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info); + Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info); Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size); ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node); diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 0bf68b9e0f..1a5e277f46 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "shader_types.h" +#include "core/math/math_defs.h" const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) { return shader_modes[p_mode].functions; @@ -54,6 +55,9 @@ ShaderTypes::ShaderTypes() { /*************** SPATIAL ***********************/ shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3; @@ -227,6 +231,9 @@ ShaderTypes::ShaderTypes() { /************ CANVAS ITEM **************************/ shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2; @@ -317,6 +324,9 @@ ShaderTypes::ShaderTypes() { /************ PARTICLES **************************/ shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3; @@ -381,6 +391,9 @@ ShaderTypes::ShaderTypes() { /************ SKY **************************/ shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT); + shader_modes[RS::SHADER_SKY].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE); shader_modes[RS::SHADER_SKY].functions["global"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL); diff --git a/tests/test_image.h b/tests/test_image.h index d73717f5b7..99c2a9380d 100644 --- a/tests/test_image.h +++ b/tests/test_image.h @@ -101,8 +101,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_bmp = memnew(Image()); FileAccessRef f_bmp = FileAccess::open(TestUtils::get_data_path("images/icon.bmp"), FileAccess::READ, &err); PackedByteArray data_bmp; - data_bmp.resize(f_bmp->get_len() + 1); - f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_len()); + data_bmp.resize(f_bmp->get_length() + 1); + f_bmp->get_buffer(data_bmp.ptrw(), f_bmp->get_length()); CHECK_MESSAGE( image_bmp->load_bmp_from_buffer(data_bmp) == OK, "The BMP image should load successfully."); @@ -111,8 +111,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_jpg = memnew(Image()); FileAccessRef f_jpg = FileAccess::open(TestUtils::get_data_path("images/icon.jpg"), FileAccess::READ, &err); PackedByteArray data_jpg; - data_jpg.resize(f_jpg->get_len() + 1); - f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_len()); + data_jpg.resize(f_jpg->get_length() + 1); + f_jpg->get_buffer(data_jpg.ptrw(), f_jpg->get_length()); CHECK_MESSAGE( image_jpg->load_jpg_from_buffer(data_jpg) == OK, "The JPG image should load successfully."); @@ -121,8 +121,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_webp = memnew(Image()); FileAccessRef f_webp = FileAccess::open(TestUtils::get_data_path("images/icon.webp"), FileAccess::READ, &err); PackedByteArray data_webp; - data_webp.resize(f_webp->get_len() + 1); - f_webp->get_buffer(data_webp.ptrw(), f_webp->get_len()); + data_webp.resize(f_webp->get_length() + 1); + f_webp->get_buffer(data_webp.ptrw(), f_webp->get_length()); CHECK_MESSAGE( image_webp->load_webp_from_buffer(data_webp) == OK, "The WEBP image should load successfully."); @@ -131,8 +131,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_png = memnew(Image()); FileAccessRef f_png = FileAccess::open(TestUtils::get_data_path("images/icon.png"), FileAccess::READ, &err); PackedByteArray data_png; - data_png.resize(f_png->get_len() + 1); - f_png->get_buffer(data_png.ptrw(), f_png->get_len()); + data_png.resize(f_png->get_length() + 1); + f_png->get_buffer(data_png.ptrw(), f_png->get_length()); CHECK_MESSAGE( image_png->load_png_from_buffer(data_png) == OK, "The PNG image should load successfully."); @@ -141,8 +141,8 @@ TEST_CASE("[Image] Saving and loading") { Ref<Image> image_tga = memnew(Image()); FileAccessRef f_tga = FileAccess::open(TestUtils::get_data_path("images/icon.tga"), FileAccess::READ, &err); PackedByteArray data_tga; - data_tga.resize(f_tga->get_len() + 1); - f_tga->get_buffer(data_tga.ptrw(), f_tga->get_len()); + data_tga.resize(f_tga->get_length() + 1); + f_tga->get_buffer(data_tga.ptrw(), f_tga->get_length()); CHECK_MESSAGE( image_tga->load_tga_from_buffer(data_tga) == OK, "The TGA image should load successfully."); diff --git a/tests/test_math.cpp b/tests/test_math.cpp index 85cfdf7d2c..88c32713ed 100644 --- a/tests/test_math.cpp +++ b/tests/test_math.cpp @@ -529,8 +529,8 @@ MainLoop *test() { ERR_FAIL_COND_V_MSG(!fa, nullptr, "Could not open file: " + test); Vector<uint8_t> buf; - uint64_t flen = fa->get_len(); - buf.resize(fa->get_len() + 1); + uint64_t flen = fa->get_length(); + buf.resize(fa->get_length() + 1); fa->get_buffer(buf.ptrw(), flen); buf.write[flen] = 0; diff --git a/tests/test_pck_packer.h b/tests/test_pck_packer.h index 8e4721b821..06e4e64963 100644 --- a/tests/test_pck_packer.h +++ b/tests/test_pck_packer.h @@ -62,10 +62,10 @@ TEST_CASE("[PCKPacker] Pack an empty PCK file") { err == OK, "The generated empty PCK file should be opened successfully."); CHECK_MESSAGE( - f->get_len() >= 100, + f->get_length() >= 100, "The generated empty PCK file shouldn't be too small (it should have the PCK header)."); CHECK_MESSAGE( - f->get_len() <= 500, + f->get_length() <= 500, "The generated empty PCK file shouldn't be too large."); } @@ -103,10 +103,10 @@ TEST_CASE("[PCKPacker] Pack a PCK file with some files and directories") { err == OK, "The generated non-empty PCK file should be opened successfully."); CHECK_MESSAGE( - f->get_len() >= 25000, + f->get_length() >= 25000, "The generated non-empty PCK file should be large enough to actually hold the contents specified above."); CHECK_MESSAGE( - f->get_len() <= 35000, + f->get_length() <= 35000, "The generated non-empty PCK file shouldn't be too large."); } } // namespace TestPCKPacker |