diff options
341 files changed, 4788 insertions, 3166 deletions
diff --git a/.gitignore b/.gitignore index b347b348a5..0de1e682a0 100644 --- a/.gitignore +++ b/.gitignore @@ -88,6 +88,9 @@ bld/ [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* +# Hints for improving IntelliSense, created together with VS project +cpp.hint + #NUNIT *.VisualState.xml TestResult.xml diff --git a/AUTHORS.md b/AUTHORS.md index 3fd8227fa7..588ce97322 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -30,16 +30,20 @@ name is available. Alexander Holland (AlexHolly) Alexey Velikiy (jonyrock) Alket Rexhepi (alketii) + Andrea Catania (AndreaCatania) Andreas Haas (Hinsbart) Anton Yabchinskiy (a12n) Aren Villanueva (kurikaesu) Ariel Manzur (punto-) Bastiaan Olij (BastiaanOlij) + Ben Brookshire (sheepandshepherd) + Bernard Liebl (poke1024) Bojidar Marinov (bojidar-bg) Błażej Szczygieł (zaps166) Carl Olsson (not-surt) Dana Olson (adolson) Daniel J. Ramirez (djrm) + Дмитрий Сальников (DmitriySalnikov) Emmanuel Leblond (touilleMan) Fabio Alessandrelli (Faless) Ferenc Arn (tagcup) @@ -54,6 +58,7 @@ name is available. Hiroshi Ogawa (hi-ogawa) Hubert Jarosz (Marqin) Hugo Locurcio (Calinou) + Ian (ianb96) Ignacio Etcheverry (neikeq) Indah Sylvia (ISylvox) J08nY @@ -69,6 +74,8 @@ name is available. Mariano Javier Suligoy (MarianoGnu) Mario Schlack (hurikhan) Masoud BH (masoudbh3) + Matthias Hölzl (hoelzl) + Max Hilbrunner (mhilbrunner) Nathan Warden (NathanWarden) Nuno Donato (nunodonato) Ovnuniarchos @@ -77,6 +84,7 @@ name is available. Pawel Kowal (pkowal1982) Pedro J. Estébanez (RandomShaper) Poommetee Ketson (Noshyaar) + Przemysław Gołąb (n-pigeon) Ralf Hölzemer (rollenrolm) Ramesh Ravone (RameshRavone) Ray Koopa (RayKoopa) @@ -17,32 +17,35 @@ None so far, but your company could be the first! :) ## Gold sponsors Gamblify <https://www.gamblify.com> + GameDev.TV <https://www.gamedev.tv> ## Mini sponsors Andreas Andreas Hirschauer Christian Uldall Pedersen + Christoph Woinke E Hewert Hein-Pieter van Braam Matthieu Huvé Nathan Warden Neal Gompa (Conan Kudo) Olimpiu Metiu + Pascal Julien Ruslan Mustakov Slobodan Milnovic ## Gold donors + 3Dexplorer Alexander Otto + Andy Meier Asdf - Blair Allen cheese65536 Jake Bo Javier Manuele Finocchiaro Officine Pixel S.n.c. - Ranoller Rémi Verschelde Stephan Lanfermann @@ -50,8 +53,10 @@ None so far, but your company could be the first! :) Austen McRae Bernhard Liebl Gerald E Butler + Jahn Johansen Jordan M Lucas Kris Michael + Ranoller BanjoNode2D Chris Serino @@ -63,7 +68,6 @@ None so far, but your company could be the first! :) Henrique Alves Laurence Bannister Leo - mhilbrunner Przemysław Gołąb (n-pigeon) Robert Willes Robin Arys @@ -72,9 +76,12 @@ None so far, but your company could be the first! :) Testus Maximus Thomas Bjarnelöf Xavier Tan + Zaq Poi Amanda Haldy Andreas Haas + Andres Cuevas + Arnaud Verstuyf Bryanna M Chris Brown Cody Parker @@ -82,16 +89,16 @@ None so far, but your company could be the first! :) Ezra Theunissen flesk François Cantin + Giovanni Solimeno Hendrik Mans Jeppe Zapp Justin Arnold Justo Delgado Baudà Leandro Voltolino Lucien Boudy - Myles Noah + Ryan Estes Trent McPheron - x1212 ## Silver donors @@ -102,23 +109,36 @@ None so far, but your company could be the first! :) Avencherus Bastian Böhm Ben Vercammen + Blair Allen Bryan Stevenson Christian Baune Christian Winter Collin Shooltz + Daniel Kaplan + David Cravens + David May + Diego Moreira Guimarães Dominik Wetzel + Eric Martini Fabian Becker fengjiongmax - Fredy Romero Sam + Frank C. Simmons Geequlim Gerrit Großkopf Guldoman + Gustav Dahlström + HardRound hatniX HeartBeast Heribert Hirth Hunter Jones + Jaime Ruiz-Borau Vizárraga + Jeff Hungerford + Jesse Liles + joe513 Jonathon Josh 'Cheeseness' Bush + Juan Negrier JuDelCo Julian Murgia Juraj Móza @@ -127,6 +147,7 @@ None so far, but your company could be the first! :) Kevin Kamper Meejach Petersen Klavdij Voncina Kobi Malul + Linus Lind Lundgren Lisandro Lorea magodev Martin Novák @@ -134,7 +155,9 @@ None so far, but your company could be the first! :) Matthew Valancy Matthias Hölzl Max R.R. Collada + mhilbrunner Michael Gringauz + Michael Tintiuc Mikael Olsson MoM Moritz Laass @@ -142,9 +165,10 @@ None so far, but your company could be the first! :) Neil Blakey-Milner Nik Lee Niko Leopold - nvgrod + Oleg Tyshchenko Pablo Seibelt Pan Ip + Pat LaBine Patrick Nafarrete Paul Mason Paweł Kowal @@ -153,17 +177,15 @@ None so far, but your company could be the first! :) rayos Richman Stewart Roger Smith - Ryan Estes + Roman Tinkov Sam Van Campenhout - Sam Vila Sasori Olkof Scott D. Yelich Sootstone - Tavo Tell TheHappieCat Theo Cranmore + Thomas Norman Tom Larrow - Troy Bonneau UltyX Wout Standaert Xananax & karroffel diff --git a/SConstruct b/SConstruct index 10982211ac..856994ef15 100644 --- a/SConstruct +++ b/SConstruct @@ -22,6 +22,7 @@ platform_flags = {} # flags for each platform active_platforms = [] active_platform_ids = [] platform_exporters = [] +platform_apis = [] global_defaults = [] for x in glob.glob("platform/*"): @@ -34,6 +35,8 @@ for x in glob.glob("platform/*"): if (os.path.exists(x + "/export/export.cpp")): platform_exporters.append(x[9:]) + if (os.path.exists(x + "/api/api.cpp")): + platform_apis.append(x[9:]) if (os.path.exists(x + "/globals/global_defaults.cpp")): global_defaults.append(x[9:]) if (detect.is_active()): @@ -215,6 +218,7 @@ env_base.Append(CPPPATH=['#core', '#core/math', '#editor', '#drivers', '#']) # configure ENV for platform env_base.platform_exporters = platform_exporters +env_base.platform_apis = platform_apis """ sys.path.append("./platform/"+env_base["platform"]) @@ -438,6 +442,7 @@ if selected_platform in platform_list: SConscript("editor/SCsub") SConscript("drivers/SCsub") + SConscript("platform/SCsub") SConscript("modules/SCsub") SConscript("main/SCsub") @@ -447,6 +452,7 @@ if selected_platform in platform_list: if env['vsproj']: env['CPPPATH'] = [Dir(path) for path in env['CPPPATH']] methods.generate_vs_project(env, GetOption("num_jobs")) + methods.generate_cpp_hint_file("cpp.hint") # Check for the existence of headers conf = Configure(env) diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index e1adb250e7..999befaf67 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -888,9 +888,9 @@ void _OS::dump_resources_to_file(const String &p_file) { OS::get_singleton()->dump_resources_to_file(p_file.utf8().get_data()); } -String _OS::get_data_dir() const { +String _OS::get_user_data_dir() const { - return OS::get_singleton()->get_data_dir(); + return OS::get_singleton()->get_user_data_dir(); }; Error _OS::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { @@ -1088,7 +1088,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_static_memory_peak_usage"), &_OS::get_static_memory_peak_usage); ClassDB::bind_method(D_METHOD("get_dynamic_memory_usage"), &_OS::get_dynamic_memory_usage); - ClassDB::bind_method(D_METHOD("get_data_dir"), &_OS::get_data_dir); + ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir); ClassDB::bind_method(D_METHOD("get_system_dir", "dir"), &_OS::get_system_dir); ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id); diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 9be8895443..8163b08d76 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -297,7 +297,7 @@ public: String get_system_dir(SystemDir p_dir) const; - String get_data_dir() const; + String get_user_data_dir() const; void alert(const String &p_alert, const String &p_title = "ALERT!"); diff --git a/core/engine.cpp b/core/engine.cpp index 31abcd62ef..53c7a73b43 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -84,17 +84,17 @@ Dictionary Engine::get_version_info() const { #else dict["patch"] = 0; #endif - dict["status"] = _MKSTR(VERSION_STATUS); - dict["revision"] = _MKSTR(VERSION_REVISION); + dict["status"] = VERSION_STATUS; + dict["build"] = VERSION_BUILD; dict["year"] = VERSION_YEAR; - String hash = String(VERSION_HASH); + String hash = VERSION_HASH; dict["hash"] = hash.length() == 0 ? String("unknown") : hash; String stringver = String(dict["major"]) + "." + String(dict["minor"]); if ((int)dict["patch"] != 0) stringver += "." + String(dict["patch"]); - stringver += "-" + String(dict["status"]) + " (" + String(dict["revision"]) + ")"; + stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")"; dict["string"] = stringver; return dict; diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 7854f342b0..48101c8cf1 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -557,7 +557,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT); // 10 - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RECT3", Variant::RECT3); + BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM", Variant::TRANSFORM); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp index 228611f8b3..2cd8a4f392 100644 --- a/core/helper/math_fieldwise.cpp +++ b/core/helper/math_fieldwise.cpp @@ -46,8 +46,8 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const switch (p_source.get_type()) { - /* clang-format makes a mess of this macro usage */ - /* clang-format off */ + /* clang-format makes a mess of this macro usage */ + /* clang-format off */ case Variant::VECTOR2: { @@ -106,9 +106,9 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } - case Variant::RECT3: { + case Variant::AABB: { - SETUP_TYPE(Rect3) + SETUP_TYPE(AABB) /**/ TRY_TRANSFER_FIELD("px", position.x) else TRY_TRANSFER_FIELD("py", position.y) diff --git a/core/image.cpp b/core/image.cpp index 42684e7ea7..422c0e407b 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -757,22 +757,24 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { _copy_internals_from(dst); } -void Image::crop(int p_width, int p_height) { +void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) { if (!_can_modify(format)) { ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats."); ERR_FAIL(); } + ERR_FAIL_COND(p_x < 0); + ERR_FAIL_COND(p_y < 0); ERR_FAIL_COND(p_width <= 0); ERR_FAIL_COND(p_height <= 0); - ERR_FAIL_COND(p_width > MAX_WIDTH); - ERR_FAIL_COND(p_height > MAX_HEIGHT); + ERR_FAIL_COND(p_x + p_width > MAX_WIDTH); + ERR_FAIL_COND(p_y + p_height > MAX_HEIGHT); /* to save memory, cropping should be done in-place, however, since this function will most likely either not be used much, or in critical areas, for now it wont, because it's a waste of time. */ - if (p_width == width && p_height == height) + if (p_width == width && p_height == height && p_x == 0 && p_y == 0) return; uint8_t pdata[16]; //largest is 16 @@ -784,9 +786,11 @@ void Image::crop(int p_width, int p_height) { PoolVector<uint8_t>::Read r = data.read(); PoolVector<uint8_t>::Write w = dst.data.write(); - for (int y = 0; y < p_height; y++) { + int m_h = p_y + p_height; + int m_w = p_x + p_width; + for (int y = p_y; y < m_h; y++) { - for (int x = 0; x < p_width; x++) { + for (int x = p_x; x < m_w; x++) { if ((x >= width || y >= height)) { for (uint32_t i = 0; i < pixel_size; i++) @@ -795,7 +799,7 @@ void Image::crop(int p_width, int p_height) { _get_pixelb(x, y, pixel_size, r.ptr(), pdata); } - dst._put_pixelb(x, y, pixel_size, w.ptr(), pdata); + dst._put_pixelb(x - p_x, y - p_y, pixel_size, w.ptr(), pdata); } } } @@ -805,6 +809,11 @@ void Image::crop(int p_width, int p_height) { _copy_internals_from(dst); } +void Image::crop(int p_width, int p_height) { + + crop_from_point(0, 0, p_width, p_height); +} + void Image::flip_y() { if (!_can_modify(format)) { diff --git a/core/image.h b/core/image.h index 27df65a898..24693aa706 100644 --- a/core/image.h +++ b/core/image.h @@ -207,6 +207,7 @@ public: /** * Crop the image to a specific size, if larger, then the image is filled by black */ + void crop_from_point(int p_x, int p_y, int p_width, int p_height); void crop(int p_width, int p_height); void flip_x(); diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index d388a622de..1d9d2dd959 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -159,7 +159,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = str; } break; - // math types + // math types case Variant::VECTOR2: { @@ -245,10 +245,10 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += 4 * 4; } break; - case Variant::RECT3: { + case Variant::AABB: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); - Rect3 val; + AABB val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.position.z = decode_float(&buf[8]); @@ -967,7 +967,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo _encode_string(p_variant, buf, r_len); } break; - // math types + // math types case Variant::VECTOR2: { @@ -1045,10 +1045,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 * 4; } break; - case Variant::RECT3: { + case Variant::AABB: { if (buf) { - Rect3 aabb = p_variant; + AABB aabb = p_variant; encode_float(aabb.position.x, &buf[0]); encode_float(aabb.position.y, &buf[4]); encode_float(aabb.position.z, &buf[8]); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 03c3c5f615..8dc396c362 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -52,7 +52,7 @@ enum { VARIANT_VECTOR3 = 12, VARIANT_PLANE = 13, VARIANT_QUAT = 14, - VARIANT_RECT3 = 15, + VARIANT_AABB = 15, VARIANT_MATRIX3 = 16, VARIANT_TRANSFORM = 17, VARIANT_MATRIX32 = 18, @@ -196,9 +196,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_RECT3: { + case VARIANT_AABB: { - Rect3 v; + AABB v; v.position.x = f->get_real(); v.position.y = f->get_real(); v.position.z = f->get_real(); @@ -1374,10 +1374,10 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_real(val.w); } break; - case Variant::RECT3: { + case Variant::AABB: { - f->store_32(VARIANT_RECT3); - Rect3 val = p_property; + f->store_32(VARIANT_AABB); + AABB val = p_property; f->store_real(val.position.x); f->store_real(val.position.y); f->store_real(val.position.z); diff --git a/core/math/rect3.cpp b/core/math/aabb.cpp index 6f01000f61..737a42b337 100644 --- a/core/math/rect3.cpp +++ b/core/math/aabb.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rect3.cpp */ +/* aabb.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,25 +27,25 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rect3.h" +#include "aabb.h" #include "print_string.h" -real_t Rect3::get_area() const { +real_t AABB::get_area() const { return size.x * size.y * size.z; } -bool Rect3::operator==(const Rect3 &p_rval) const { +bool AABB::operator==(const AABB &p_rval) const { return ((position == p_rval.position) && (size == p_rval.size)); } -bool Rect3::operator!=(const Rect3 &p_rval) const { +bool AABB::operator!=(const AABB &p_rval) const { return ((position != p_rval.position) || (size != p_rval.size)); } -void Rect3::merge_with(const Rect3 &p_aabb) { +void AABB::merge_with(const AABB &p_aabb) { Vector3 beg_1, beg_2; Vector3 end_1, end_2; @@ -68,7 +68,7 @@ void Rect3::merge_with(const Rect3 &p_aabb) { size = max - min; } -Rect3 Rect3::intersection(const Rect3 &p_aabb) const { +AABB AABB::intersection(const AABB &p_aabb) const { Vector3 src_min = position; Vector3 src_max = position + size; @@ -78,7 +78,7 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { Vector3 min, max; if (src_min.x > dst_max.x || src_max.x < dst_min.x) - return Rect3(); + return AABB(); else { min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x; @@ -86,7 +86,7 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { } if (src_min.y > dst_max.y || src_max.y < dst_min.y) - return Rect3(); + return AABB(); else { min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y; @@ -94,17 +94,17 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { } if (src_min.z > dst_max.z || src_max.z < dst_min.z) - return Rect3(); + return AABB(); else { min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z; max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z; } - return Rect3(min, max - min); + return AABB(min, max - min); } -bool Rect3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { +bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { Vector3 c1, c2; Vector3 end = position + size; @@ -147,7 +147,7 @@ bool Rect3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 return true; } -bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { +bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { real_t min = 0, max = 1; int axis = 0; @@ -205,7 +205,7 @@ bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vecto return true; } -bool Rect3::intersects_plane(const Plane &p_plane) const { +bool AABB::intersects_plane(const Plane &p_plane) const { Vector3 points[8] = { Vector3(position.x, position.y, position.z), @@ -232,7 +232,7 @@ bool Rect3::intersects_plane(const Plane &p_plane) const { return under && over; } -Vector3 Rect3::get_longest_axis() const { +Vector3 AABB::get_longest_axis() const { Vector3 axis(1, 0, 0); real_t max_size = size.x; @@ -249,7 +249,7 @@ Vector3 Rect3::get_longest_axis() const { return axis; } -int Rect3::get_longest_axis_index() const { +int AABB::get_longest_axis_index() const { int axis = 0; real_t max_size = size.x; @@ -267,7 +267,7 @@ int Rect3::get_longest_axis_index() const { return axis; } -Vector3 Rect3::get_shortest_axis() const { +Vector3 AABB::get_shortest_axis() const { Vector3 axis(1, 0, 0); real_t max_size = size.x; @@ -284,7 +284,7 @@ Vector3 Rect3::get_shortest_axis() const { return axis; } -int Rect3::get_shortest_axis_index() const { +int AABB::get_shortest_axis_index() const { int axis = 0; real_t max_size = size.x; @@ -302,25 +302,25 @@ int Rect3::get_shortest_axis_index() const { return axis; } -Rect3 Rect3::merge(const Rect3 &p_with) const { +AABB AABB::merge(const AABB &p_with) const { - Rect3 aabb = *this; + AABB aabb = *this; aabb.merge_with(p_with); return aabb; } -Rect3 Rect3::expand(const Vector3 &p_vector) const { - Rect3 aabb = *this; +AABB AABB::expand(const Vector3 &p_vector) const { + AABB aabb = *this; aabb.expand_to(p_vector); return aabb; } -Rect3 Rect3::grow(real_t p_by) const { +AABB AABB::grow(real_t p_by) const { - Rect3 aabb = *this; + AABB aabb = *this; aabb.grow_by(p_by); return aabb; } -void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { +void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { ERR_FAIL_INDEX(p_edge, 12); switch (p_edge) { @@ -394,7 +394,7 @@ void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { } } -Rect3::operator String() const { +AABB::operator String() const { return String() + position + " - " + size; } diff --git a/core/math/rect3.h b/core/math/aabb.h index c3a2f5fbfb..c60213496a 100644 --- a/core/math/rect3.h +++ b/core/math/aabb.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rect3.h */ +/* aabb.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -39,7 +39,7 @@ * This is implemented by a point (position) and the box size */ -class Rect3 { +class AABB { public: Vector3 position; Vector3 size; @@ -60,16 +60,16 @@ public: const Vector3 &get_size() const { return size; } void set_size(const Vector3 &p_size) { size = p_size; } - bool operator==(const Rect3 &p_rval) const; - bool operator!=(const Rect3 &p_rval) const; + bool operator==(const AABB &p_rval) const; + bool operator!=(const AABB &p_rval) const; - _FORCE_INLINE_ bool intersects(const Rect3 &p_aabb) const; /// Both AABBs overlap - _FORCE_INLINE_ bool intersects_inclusive(const Rect3 &p_aabb) const; /// Both AABBs (or their faces) overlap - _FORCE_INLINE_ bool encloses(const Rect3 &p_aabb) const; /// p_aabb is completely inside this + _FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap + _FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap + _FORCE_INLINE_ bool encloses(const AABB &p_aabb) const; /// p_aabb is completely inside this - Rect3 merge(const Rect3 &p_with) const; - void merge_with(const Rect3 &p_aabb); ///merge with another AABB - Rect3 intersection(const Rect3 &p_aabb) const; ///get box where two intersect, empty if no intersection occurs + AABB merge(const AABB &p_with) const; + void merge_with(const AABB &p_aabb); ///merge with another AABB + AABB intersection(const AABB &p_aabb) const; ///get box where two intersect, empty if no intersection occurs bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const; bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const; _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const; @@ -88,26 +88,26 @@ public: int get_shortest_axis_index() const; _FORCE_INLINE_ real_t get_shortest_axis_size() const; - Rect3 grow(real_t p_by) const; + AABB grow(real_t p_by) const; _FORCE_INLINE_ void grow_by(real_t p_amount); void get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const; _FORCE_INLINE_ Vector3 get_endpoint(int p_point) const; - Rect3 expand(const Vector3 &p_vector) const; + AABB expand(const Vector3 &p_vector) const; _FORCE_INLINE_ void project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const; _FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */ operator String() const; - _FORCE_INLINE_ Rect3() {} - inline Rect3(const Vector3 &p_pos, const Vector3 &p_size) + _FORCE_INLINE_ AABB() {} + inline AABB(const Vector3 &p_pos, const Vector3 &p_size) : position(p_pos), size(p_size) { } }; -inline bool Rect3::intersects(const Rect3 &p_aabb) const { +inline bool AABB::intersects(const AABB &p_aabb) const { if (position.x >= (p_aabb.position.x + p_aabb.size.x)) return false; @@ -125,7 +125,7 @@ inline bool Rect3::intersects(const Rect3 &p_aabb) const { return true; } -inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const { +inline bool AABB::intersects_inclusive(const AABB &p_aabb) const { if (position.x > (p_aabb.position.x + p_aabb.size.x)) return false; @@ -143,7 +143,7 @@ inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const { return true; } -inline bool Rect3::encloses(const Rect3 &p_aabb) const { +inline bool AABB::encloses(const AABB &p_aabb) const { Vector3 src_min = position; Vector3 src_max = position + size; @@ -159,7 +159,7 @@ inline bool Rect3::encloses(const Rect3 &p_aabb) const { (src_max.z > dst_max.z)); } -Vector3 Rect3::get_support(const Vector3 &p_normal) const { +Vector3 AABB::get_support(const Vector3 &p_normal) const { Vector3 half_extents = size * 0.5; Vector3 ofs = position + half_extents; @@ -171,7 +171,7 @@ Vector3 Rect3::get_support(const Vector3 &p_normal) const { ofs; } -Vector3 Rect3::get_endpoint(int p_point) const { +Vector3 AABB::get_endpoint(int p_point) const { switch (p_point) { case 0: return Vector3(position.x, position.y, position.z); @@ -187,7 +187,7 @@ Vector3 Rect3::get_endpoint(int p_point) const { ERR_FAIL_V(Vector3()); } -bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) const { +bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count) const { Vector3 half_extents = size * 0.5; Vector3 ofs = position + half_extents; @@ -206,7 +206,7 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co return true; } -bool Rect3::has_point(const Vector3 &p_point) const { +bool AABB::has_point(const Vector3 &p_point) const { if (p_point.x < position.x) return false; @@ -224,7 +224,7 @@ bool Rect3::has_point(const Vector3 &p_point) const { return true; } -inline void Rect3::expand_to(const Vector3 &p_vector) { +inline void AABB::expand_to(const Vector3 &p_vector) { Vector3 begin = position; Vector3 end = position + size; @@ -247,7 +247,7 @@ inline void Rect3::expand_to(const Vector3 &p_vector) { size = end - begin; } -void Rect3::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { +void AABB::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5); Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z); @@ -258,7 +258,7 @@ void Rect3::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t & r_max = distance + length; } -inline real_t Rect3::get_longest_axis_size() const { +inline real_t AABB::get_longest_axis_size() const { real_t max_size = size.x; @@ -273,7 +273,7 @@ inline real_t Rect3::get_longest_axis_size() const { return max_size; } -inline real_t Rect3::get_shortest_axis_size() const { +inline real_t AABB::get_shortest_axis_size() const { real_t max_size = size.x; @@ -288,7 +288,7 @@ inline real_t Rect3::get_shortest_axis_size() const { return max_size; } -bool Rect3::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const { +bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const { real_t divx = 1.0 / p_dir.x; real_t divy = 1.0 / p_dir.y; @@ -332,7 +332,7 @@ bool Rect3::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, rea return ((tmin < t1) && (tmax > t0)); } -void Rect3::grow_by(real_t p_amount) { +void AABB::grow_by(real_t p_amount) { position.x -= p_amount; position.y -= p_amount; diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index be950568cf..bdc040160f 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -31,7 +31,7 @@ #include "error_macros.h" #include "print_string.h" -void BSP_Tree::from_aabb(const Rect3 &p_aabb) { +void BSP_Tree::from_aabb(const AABB &p_aabb) { planes.clear(); @@ -67,7 +67,7 @@ Vector<Plane> BSP_Tree::get_planes() const { return planes; } -Rect3 BSP_Tree::get_aabb() const { +AABB BSP_Tree::get_aabb() const { return aabb; } @@ -577,7 +577,7 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) { error_radius = p_error_radius; } -BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const Rect3 &p_aabb, real_t p_error_radius) +BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius) : nodes(p_nodes), planes(p_planes), aabb(p_aabb), diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h index 2e762ba4de..f64a13ce39 100644 --- a/core/math/bsp_tree.h +++ b/core/math/bsp_tree.h @@ -30,11 +30,11 @@ #ifndef BSP_TREE_H #define BSP_TREE_H +#include "aabb.h" #include "dvector.h" #include "face3.h" #include "method_ptrcall.h" #include "plane.h" -#include "rect3.h" #include "variant.h" #include "vector.h" /** @@ -64,7 +64,7 @@ private: Vector<Node> nodes; Vector<Plane> planes; - Rect3 aabb; + AABB aabb; real_t error_radius; int _get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const; @@ -76,7 +76,7 @@ public: bool is_empty() const { return nodes.size() == 0; } Vector<Node> get_nodes() const; Vector<Plane> get_planes() const; - Rect3 get_aabb() const; + AABB get_aabb() const; bool point_is_inside(const Vector3 &p_point) const; int get_points_inside(const Vector3 *p_points, int p_point_count) const; @@ -85,12 +85,12 @@ public: operator Variant() const; - void from_aabb(const Rect3 &p_aabb); + void from_aabb(const AABB &p_aabb); BSP_Tree(); BSP_Tree(const Variant &p_variant); BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius = 0); - BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const Rect3 &p_aabb, real_t p_error_radius = 0); + BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius = 0); ~BSP_Tree(); }; diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 2c587762e8..c5f1d57441 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -596,7 +596,7 @@ void CameraMatrix::make_scale(const Vector3 &p_scale) { matrix[2][2] = p_scale.z; } -void CameraMatrix::scale_translate_to_fit(const Rect3 &p_aabb) { +void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 3145d73356..15d6b8128e 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -86,7 +86,7 @@ struct CameraMatrix { operator String() const; - void scale_translate_to_fit(const Rect3 &p_aabb); + void scale_translate_to_fit(const AABB &p_aabb); void make_scale(const Vector3 &p_scale); int get_pixels_per_meter(int p_for_pixel_width) const; operator Transform() const; diff --git a/core/math/face3.cpp b/core/math/face3.cpp index e1b172e491..070ce77db4 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -189,13 +189,13 @@ ClockDirection Face3::get_clock_dir() const { return (normal.dot(vertex[0]) >= 0) ? CLOCKWISE : COUNTERCLOCKWISE; } -bool Face3::intersects_aabb(const Rect3 &p_aabb) const { +bool Face3::intersects_aabb(const AABB &p_aabb) const { /** TEST PLANE **/ if (!p_aabb.intersects_plane(get_plane())) return false; -/** TEST FACE AXIS */ + /** TEST FACE AXIS */ #define TEST_AXIS(m_ax) \ { \ diff --git a/core/math/face3.h b/core/math/face3.h index 8e4a25fb7a..561fa31238 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -30,8 +30,8 @@ #ifndef FACE3_H #define FACE3_H +#include "aabb.h" #include "plane.h" -#include "rect3.h" #include "transform.h" #include "vector3.h" @@ -76,16 +76,16 @@ public: void get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const; void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; - Rect3 get_aabb() const { + AABB get_aabb() const { - Rect3 aabb(vertex[0], Vector3()); + AABB aabb(vertex[0], Vector3()); aabb.expand_to(vertex[1]); aabb.expand_to(vertex[2]); return aabb; } - bool intersects_aabb(const Rect3 &p_aabb) const; - _FORCE_INLINE_ bool intersects_aabb2(const Rect3 &p_aabb) const; + bool intersects_aabb(const AABB &p_aabb) const; + _FORCE_INLINE_ bool intersects_aabb2(const AABB &p_aabb) const; operator String() const; inline Face3() {} @@ -96,7 +96,7 @@ public: } }; -bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { +bool Face3::intersects_aabb2(const AABB &p_aabb) const { Vector3 perp = (vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]); @@ -256,6 +256,6 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { return true; } -//this sucks... + //this sucks... #endif // FACE3_H diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 7c8fb6f17d..39bd34f03c 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -300,7 +300,7 @@ enum _CellFlags { static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, const Vector3 &voxelsize, const Face3 &p_face) { - Rect3 aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z)); + AABB aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z)); aabb.position = aabb.position * voxelsize; aabb.size = aabb.size * voxelsize; @@ -575,7 +575,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e PoolVector<Face3>::Read facesr = p_array.read(); const Face3 *faces = facesr.ptr(); - Rect3 global_aabb; + AABB global_aabb; for (int i = 0; i < face_count; i++) { diff --git a/core/math/octree.h b/core/math/octree.h index 95a67943fd..6acd4c5f75 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -30,10 +30,10 @@ #ifndef OCTREE_H #define OCTREE_H +#include "aabb.h" #include "list.h" #include "map.h" #include "print_string.h" -#include "rect3.h" #include "variant.h" #include "vector3.h" @@ -106,7 +106,7 @@ private: struct Octant { // cached for FAST plane check - Rect3 aabb; + AABB aabb; uint64_t last_pass; Octant *parent; @@ -152,8 +152,8 @@ private: OctreeElementID _id; Octant *common_parent; - Rect3 aabb; - Rect3 container_aabb; + AABB aabb; + AABB container_aabb; List<PairData *, AL> pair_list; @@ -334,7 +334,7 @@ private: } void _insert_element(Element *p_element, Octant *p_octant); - void _ensure_valid_root(const Rect3 &p_aabb); + void _ensure_valid_root(const AABB &p_aabb); bool _remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit = NULL); void _remove_element(Element *p_element); void _pair_element(Element *p_element, Octant *p_octant); @@ -351,7 +351,7 @@ private: }; void _cull_convex(Octant *p_octant, _CullConvexData *p_cull); - void _cull_aabb(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); + void _cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); void _cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); @@ -370,8 +370,8 @@ private: } public: - OctreeElementID create(T *p_userdata, const Rect3 &p_aabb = Rect3(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1); - void move(OctreeElementID p_id, const Rect3 &p_aabb); + OctreeElementID create(T *p_userdata, const AABB &p_aabb = AABB(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1); + void move(OctreeElementID p_id, const AABB &p_aabb); void set_pairable(OctreeElementID p_id, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1); void erase(OctreeElementID p_id); @@ -380,7 +380,7 @@ public: int get_subindex(OctreeElementID p_id) const; int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF); - int cull_aabb(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); + int cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); int cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); int cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); @@ -479,7 +479,7 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct } else { /* check againt AABB where child should be */ - Rect3 aabb = p_octant->aabb; + AABB aabb = p_octant->aabb; aabb.size *= 0.5; if (i & 1) @@ -535,12 +535,12 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct } template <class T, bool use_pairs, class AL> -void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) { +void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) { if (!root) { // octre is empty - Rect3 base(Vector3(), Vector3(1.0, 1.0, 1.0) * unit_size); + AABB base(Vector3(), Vector3(1.0, 1.0, 1.0) * unit_size); while (!base.encloses(p_aabb)) { @@ -563,7 +563,7 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) { } else { - Rect3 base = root->aabb; + AABB base = root->aabb; while (!base.encloses(p_aabb)) { @@ -793,7 +793,7 @@ void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) { } template <class T, bool use_pairs, class AL> -OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const Rect3 &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) { +OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) { // check for AABB validity #ifdef DEBUG_ENABLED @@ -833,7 +833,7 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const Rect3 &p_a } template <class T, bool use_pairs, class AL> -void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { +void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) { #ifdef DEBUG_ENABLED // check for AABB validity @@ -859,7 +859,7 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { if (old_has_surf) { _remove_element(&e); // removing e.common_parent = NULL; - e.aabb = Rect3(); + e.aabb = AABB(); _optimize(); } else { _ensure_valid_root(p_aabb); // inserting @@ -886,7 +886,7 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { return; } - Rect3 combined = e.aabb; + AABB combined = e.aabb; combined.merge_with(p_aabb); _ensure_valid_root(combined); @@ -1072,7 +1072,7 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p } template <class T, bool use_pairs, class AL> -void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { +void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { if (*p_result_idx == p_result_max) return; //pointless @@ -1313,7 +1313,7 @@ int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_r } template <class T, bool use_pairs, class AL> -int Octree<T, use_pairs, AL>::cull_aabb(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { +int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { if (!root) return 0; diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index e0137b6921..946d9f6b79 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -38,7 +38,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me /* CREATE AABB VOLUME */ - Rect3 aabb; + AABB aabb; for (int i = 0; i < p_points.size(); i++) { if (i == 0) { diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h index 47ed22615b..f014d0decc 100644 --- a/core/math/quick_hull.h +++ b/core/math/quick_hull.h @@ -30,9 +30,9 @@ #ifndef QUICK_HULL_H #define QUICK_HULL_H +#include "aabb.h" #include "geometry.h" #include "list.h" -#include "rect3.h" #include "set.h" class QuickHull { diff --git a/core/math/transform.h b/core/math/transform.h index 566bf482a9..4d91869121 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -30,9 +30,9 @@ #ifndef TRANSFORM_H #define TRANSFORM_H +#include "aabb.h" #include "matrix3.h" #include "plane.h" -#include "rect3.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -80,8 +80,8 @@ public: _FORCE_INLINE_ Plane xform(const Plane &p_plane) const; _FORCE_INLINE_ Plane xform_inv(const Plane &p_plane) const; - _FORCE_INLINE_ Rect3 xform(const Rect3 &p_aabb) const; - _FORCE_INLINE_ Rect3 xform_inv(const Rect3 &p_aabb) const; + _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; + _FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const; void operator*=(const Transform &p_transform); Transform operator*(const Transform &p_transform) const; @@ -153,14 +153,14 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const { return Plane(normal, d); } -_FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const { +_FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const { /* define vertices */ Vector3 x = basis.get_axis(0) * p_aabb.size.x; Vector3 y = basis.get_axis(1) * p_aabb.size.y; Vector3 z = basis.get_axis(2) * p_aabb.size.z; Vector3 pos = xform(p_aabb.position); //could be even further optimized - Rect3 new_aabb; + AABB new_aabb; new_aabb.position = pos; new_aabb.expand_to(pos + x); new_aabb.expand_to(pos + y); @@ -172,7 +172,7 @@ _FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const { return new_aabb; } -_FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const { +_FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const { /* define vertices */ Vector3 vertices[8] = { @@ -186,7 +186,7 @@ _FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const { Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z) }; - Rect3 ret; + AABB ret; ret.position = xform_inv(vertices[0]); diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 3b246cb183..5f57c7c26a 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -44,7 +44,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in return -1; } - Rect3 aabb; + AABB aabb; aabb = p_bb[p_from]->aabb; for (int i = 1; i < p_size; i++) { @@ -166,7 +166,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { valid = true; } -Vector3 TriangleMesh::get_area_normal(const Rect3 &p_aabb) const { +Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 2bf67fffcb..4bd9fecf37 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -47,7 +47,7 @@ class TriangleMesh : public Reference { struct BVH { - Rect3 aabb; + AABB aabb; Vector3 center; //used for sorting int left; int right; @@ -88,7 +88,7 @@ public: bool is_valid() const; bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const; bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const; - Vector3 get_area_normal(const Rect3 &p_aabb) const; + Vector3 get_area_normal(const AABB &p_aabb) const; PoolVector<Face3> get_faces() const; void create(const PoolVector<Vector3> &p_faces); diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index 2875eb912f..d819dfbc27 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -119,7 +119,7 @@ MAKE_PTRARG_BY_REFERENCE(Vector3); MAKE_PTRARG(Transform2D); MAKE_PTRARG_BY_REFERENCE(Plane); MAKE_PTRARG(Quat); -MAKE_PTRARG_BY_REFERENCE(Rect3); +MAKE_PTRARG_BY_REFERENCE(AABB); MAKE_PTRARG_BY_REFERENCE(Basis); MAKE_PTRARG_BY_REFERENCE(Transform); MAKE_PTRARG_BY_REFERENCE(Color); diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 0875f78478..35e4443f2a 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -38,7 +38,7 @@ String DirAccess::_get_root_path() const { switch (_access_type) { case ACCESS_RESOURCES: return ProjectSettings::get_singleton()->get_resource_path(); - case ACCESS_USERDATA: return OS::get_singleton()->get_data_dir(); + case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir(); default: return ""; } @@ -217,7 +217,7 @@ String DirAccess::fix_path(String p_path) const { if (p_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_data_dir(); + String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { return p_path.replace_first("user:/", data_dir); diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index fcb3b58fed..5fdd2b9135 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -152,7 +152,7 @@ String FileAccess::fix_path(const String &p_path) const { if (r_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_data_dir(); + String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { return r_path.replace("user:/", data_dir); diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 74d5cbbea1..439951f711 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -44,6 +44,26 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) { return p_allocfunc(p_size); } +#ifdef _MSC_VER +void operator delete(void *p_mem, const char *p_description) { + + ERR_EXPLAINC("Call to placement delete should not happen."); + CRASH_NOW(); +} + +void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) { + + ERR_EXPLAINC("Call to placement delete should not happen."); + CRASH_NOW(); +} + +void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) { + + ERR_EXPLAINC("Call to placement delete should not happen."); + CRASH_NOW(); +} +#endif + #ifdef DEBUG_ENABLED uint64_t Memory::mem_usage = 0; uint64_t Memory::max_usage = 0; diff --git a/core/os/memory.h b/core/os/memory.h index f8b3da579b..7801d56837 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -72,6 +72,14 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< ope void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory +#ifdef _MSC_VER +// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291). +// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete. +void operator delete(void *p_mem, const char *p_description); +void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)); +void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description); +#endif + #define memalloc(m_size) Memory::alloc_static(m_size) #define memrealloc(m_mem, m_size) Memory::realloc_static(m_mem, m_size) #define memfree(m_size) Memory::free_static(m_size) diff --git a/core/os/os.cpp b/core/os/os.cpp index eb5d5be33d..65d0b2e05d 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -33,6 +33,7 @@ #include "input.h" #include "os/file_access.h" #include "project_settings.h" +#include "version_generated.gen.h" #include <stdarg.h> @@ -262,16 +263,7 @@ String OS::get_locale() const { return "en"; } -String OS::get_resource_dir() const { - - return ProjectSettings::get_singleton()->get_resource_path(); -} - -String OS::get_system_dir(SystemDir p_dir) const { - - return "."; -} - +// Helper function used by OS_Unix and OS_Windows String OS::get_safe_application_name() const { String an = ProjectSettings::get_singleton()->get("application/config/name"); Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" "); @@ -281,11 +273,51 @@ String OS::get_safe_application_name() const { return an; } -String OS::get_data_dir() const { +// Path to data, config, cache, etc. OS-specific folders + +// Get properly capitalized engine name for system paths +String OS::get_godot_dir_name() const { + + // Default to lowercase, so only override when different case is needed + return String(VERSION_SHORT_NAME).to_lower(); +} + +// OS equivalent of XDG_DATA_HOME +String OS::get_data_path() const { + + return "."; +} + +// OS equivalent of XDG_CONFIG_HOME +String OS::get_config_path() const { + + return "."; +} + +// OS equivalent of XDG_CACHE_HOME +String OS::get_cache_path() const { + + return "."; +} + +// OS specific path for user:// +String OS::get_user_data_dir() const { return "."; }; +// Absolute path to res:// +String OS::get_resource_dir() const { + + return ProjectSettings::get_singleton()->get_resource_path(); +} + +// Access system-specific dirs like Documents, Downloads, etc. +String OS::get_system_dir(SystemDir p_dir) const { + + return "."; +} + Error OS::shell_open(String p_uri) { return ERR_UNAVAILABLE; }; @@ -374,9 +406,9 @@ OS::ScreenOrientation OS::get_screen_orientation() const { return (OS::ScreenOrientation)_orientation; } -void OS::_ensure_data_dir() { +void OS::_ensure_user_data_dir() { - String dd = get_data_dir(); + String dd = get_user_data_dir(); DirAccess *da = DirAccess::open(dd); if (da) { memdelete(da); diff --git a/core/os/os.h b/core/os/os.h index faecdb0e07..e48e5c6d70 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -90,13 +90,15 @@ public: bool fullscreen; bool resizable; bool borderless_window; + bool maximized; float get_aspect() const { return (float)width / (float)height; } - VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false) { + VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false) { width = p_width; height = p_height; fullscreen = p_fullscreen; resizable = p_resizable; borderless_window = p_borderless_window; + maximized = p_maximized; } }; @@ -124,7 +126,7 @@ protected: virtual void set_cmdline(const char *p_execpath, const List<String> &p_args); - void _ensure_data_dir(); + void _ensure_user_data_dir(); virtual bool _check_internal_feature_support(const String &p_feature) = 0; public: @@ -200,7 +202,6 @@ public: virtual void set_low_processor_usage_mode(bool p_enabled); virtual bool is_in_low_processor_usage_mode() const; - virtual String get_installed_templates_path() const { return ""; } virtual String get_executable_path() const; virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false) = 0; virtual Error kill(const ProcessID &p_pid) = 0; @@ -334,10 +335,14 @@ public: virtual String get_locale() const; String get_safe_application_name() const; - virtual String get_data_dir() const; - virtual String get_resource_dir() const; + virtual String get_godot_dir_name() const; - virtual Error move_to_trash(const String &p_path) { return FAILED; } + virtual String get_data_path() const; + virtual String get_config_path() const; + virtual String get_cache_path() const; + + virtual String get_user_data_dir() const; + virtual String get_resource_dir() const; enum SystemDir { SYSTEM_DIR_DESKTOP, @@ -352,6 +357,8 @@ public: virtual String get_system_dir(SystemDir p_dir) const; + virtual Error move_to_trash(const String &p_path) { return FAILED; } + virtual void set_no_window_mode(bool p_enable); virtual bool is_no_window_mode_enabled() const; diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp index ad8438e416..3748df12f7 100644 --- a/core/packed_data_container.cpp +++ b/core/packed_data_container.cpp @@ -234,7 +234,7 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd case Variant::TRANSFORM2D: case Variant::PLANE: case Variant::QUAT: - case Variant::RECT3: + case Variant::AABB: case Variant::BASIS: case Variant::TRANSFORM: case Variant::POOL_BYTE_ARRAY: diff --git a/core/print_string.cpp b/core/print_string.cpp index 92a04cbf0b..520fb3daec 100644 --- a/core/print_string.cpp +++ b/core/print_string.cpp @@ -82,7 +82,25 @@ void print_line(String p_string) { PrintHandlerList *l = print_handler_list; while (l) { - l->printfunc(l->userdata, p_string); + l->printfunc(l->userdata, p_string, false); + l = l->next; + } + + _global_unlock(); +} + +void print_error(String p_string) { + + if (!_print_error_enabled) + return; + + OS::get_singleton()->printerr("%s\n", p_string.utf8().get_data()); + + _global_lock(); + PrintHandlerList *l = print_handler_list; + while (l) { + + l->printfunc(l->userdata, p_string, true); l = l->next; } diff --git a/core/print_string.h b/core/print_string.h index 9f8420c31a..6b68380b9d 100644 --- a/core/print_string.h +++ b/core/print_string.h @@ -34,7 +34,7 @@ extern void (*_print_func)(String); -typedef void (*PrintHandlerFunc)(void *, const String &p_string); +typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error); struct PrintHandlerList { @@ -56,5 +56,6 @@ void remove_print_handler(PrintHandlerList *p_handler); extern bool _print_line_enabled; extern bool _print_error_enabled; extern void print_line(String p_string); +extern void print_error(String p_string); #endif diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 65a6f2b83c..361464ee1f 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -116,7 +116,7 @@ String ProjectSettings::globalize_path(const String &p_path) const { return p_path.replace("res://", ""); } else if (p_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_data_dir(); + String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { return p_path.replace("user:/", data_dir); diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 56056268f2..5e06339b9e 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -889,7 +889,7 @@ void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_ mutex->unlock(); } -void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string) { +void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) { ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote *)p_this; diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index 22137d1350..90d2daf1f8 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -94,7 +94,7 @@ class ScriptDebuggerRemote : public ScriptDebugger { uint64_t msec_count; bool locking; //hack to avoid a deadloop - static void _print_handler(void *p_this, const String &p_string); + static void _print_handler(void *p_this, const String &p_string, bool p_error); PrintHandlerList phl; diff --git a/core/type_info.h b/core/type_info.h index 9fb80af0eb..24d96c51e8 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -82,7 +82,7 @@ MAKE_TYPE_INFO(Vector3, Variant::VECTOR3) MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D) MAKE_TYPE_INFO(Plane, Variant::PLANE) MAKE_TYPE_INFO(Quat, Variant::QUAT) -MAKE_TYPE_INFO(Rect3, Variant::RECT3) +MAKE_TYPE_INFO(AABB, Variant::AABB) MAKE_TYPE_INFO(Basis, Variant::BASIS) MAKE_TYPE_INFO(Transform, Variant::TRANSFORM) MAKE_TYPE_INFO(Color, Variant::COLOR) diff --git a/core/variant.cpp b/core/variant.cpp index f70e4a5218..d4143b8d84 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -66,7 +66,7 @@ String Variant::get_type_name(Variant::Type p_type) { return "String"; } break; - // math types + // math types case VECTOR2: { @@ -94,9 +94,9 @@ String Variant::get_type_name(Variant::Type p_type) { } break;*/ - case RECT3: { + case AABB: { - return "Rect3"; + return "AABB"; } break; case QUAT: { @@ -267,6 +267,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { static const Type valid[] = { QUAT, + VECTOR3, NIL }; @@ -722,7 +723,7 @@ bool Variant::is_zero() const { } break; - // math types + // math types case VECTOR2: { @@ -754,9 +755,9 @@ bool Variant::is_zero() const { } break;*/ - case RECT3: { + case AABB: { - return *_data._rect3 == Rect3(); + return *_data._aabb == ::AABB(); } break; case QUAT: { @@ -931,7 +932,7 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem))); } break; - // math types + // math types case VECTOR2: { @@ -954,9 +955,9 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); } break; - case RECT3: { + case AABB: { - _data._rect3 = memnew(Rect3(*p_variant._data._rect3)); + _data._aabb = memnew(::AABB(*p_variant._data._aabb)); } break; case QUAT: { @@ -1079,9 +1080,9 @@ void Variant::clear() { memdelete(_data._transform2d); } break; - case RECT3: { + case AABB: { - memdelete(_data._rect3); + memdelete(_data._aabb); } break; case BASIS: { @@ -1426,7 +1427,7 @@ Variant::operator String() const { case PLANE: return operator Plane(); //case QUAT: - case RECT3: return operator Rect3(); + case AABB: return operator ::AABB(); case QUAT: return "(" + operator Quat() + ")"; case BASIS: { @@ -1617,12 +1618,12 @@ Variant::operator Plane() const { else return Plane(); } -Variant::operator Rect3() const { +Variant::operator ::AABB() const { - if (type == RECT3) - return *_data._rect3; + if (type == AABB) + return *_data._aabb; else - return Rect3(); + return ::AABB(); } Variant::operator Basis() const { @@ -2188,10 +2189,10 @@ Variant::Variant(const Plane &p_plane) { type = PLANE; memnew_placement(_data._mem, Plane(p_plane)); } -Variant::Variant(const Rect3 &p_aabb) { +Variant::Variant(const ::AABB &p_aabb) { - type = RECT3; - _data._rect3 = memnew(Rect3(p_aabb)); + type = AABB; + _data._aabb = memnew(::AABB(p_aabb)); } Variant::Variant(const Basis &p_matrix) { @@ -2501,7 +2502,7 @@ void Variant::operator=(const Variant &p_variant) { *reinterpret_cast<String *>(_data._mem) = *reinterpret_cast<const String *>(p_variant._data._mem); } break; - // math types + // math types case VECTOR2: { @@ -2524,9 +2525,9 @@ void Variant::operator=(const Variant &p_variant) { *reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem); } break; - case RECT3: { + case AABB: { - *_data._rect3 = *(p_variant._data._rect3); + *_data._aabb = *(p_variant._data._aabb); } break; case QUAT: { @@ -2641,7 +2642,7 @@ uint32_t Variant::hash() const { return reinterpret_cast<const String *>(_data._mem)->hash(); } break; - // math types + // math types case VECTOR2: { @@ -2686,13 +2687,13 @@ uint32_t Variant::hash() const { } break;*/ - case RECT3: { + case AABB: { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { - hash = hash_djb2_one_float(_data._rect3->position[i], hash); - hash = hash_djb2_one_float(_data._rect3->size[i], hash); + hash = hash_djb2_one_float(_data._aabb->position[i], hash); + hash = hash_djb2_one_float(_data._aabb->size[i], hash); } return hash; @@ -2952,9 +2953,9 @@ bool Variant::hash_compare(const Variant &p_variant) const { (hash_compare_scalar(l->d, r->d)); } break; - case RECT3: { - const Rect3 *l = _data._rect3; - const Rect3 *r = p_variant._data._rect3; + case AABB: { + const ::AABB *l = _data._aabb; + const ::AABB *r = p_variant._data._aabb; return (hash_compare_vector3(l->position, r->position) && (hash_compare_vector3(l->size, r->size))); diff --git a/core/variant.h b/core/variant.h index 45066af401..8ba4d576cf 100644 --- a/core/variant.h +++ b/core/variant.h @@ -34,6 +34,7 @@ @author Juan Linietsky <reduzio@gmail.com> */ +#include "aabb.h" #include "array.h" #include "color.h" #include "dictionary.h" @@ -45,7 +46,6 @@ #include "node_path.h" #include "plane.h" #include "quat.h" -#include "rect3.h" #include "ref_ptr.h" #include "rid.h" #include "transform.h" @@ -89,7 +89,7 @@ public: TRANSFORM2D, PLANE, QUAT, // 10 - RECT3, + AABB, BASIS, TRANSFORM, @@ -136,7 +136,7 @@ private: int64_t _int; double _real; Transform2D *_transform2d; - Rect3 *_rect3; + ::AABB *_aabb; Basis *_basis; Transform *_transform; RefPtr *_resource; @@ -184,7 +184,7 @@ public: operator Rect2() const; operator Vector3() const; operator Plane() const; - operator Rect3() const; + operator ::AABB() const; operator Quat() const; operator Basis() const; operator Transform() const; @@ -253,7 +253,7 @@ public: Variant(const Rect2 &p_rect2); Variant(const Vector3 &p_vector3); Variant(const Plane &p_plane); - Variant(const Rect3 &p_aabb); + Variant(const ::AABB &p_aabb); Variant(const Quat &p_quat); Variant(const Basis &p_transform); Variant(const Transform2D &p_transform); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 05f0478003..9e6aaeb911 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -655,26 +655,26 @@ struct _VariantCall { #define VCALL_PTR5R(m_type, m_method) \ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = reinterpret_cast<m_type *>(p_self._data._ptr)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); } - VCALL_PTR0R(Rect3, get_area); - VCALL_PTR0R(Rect3, has_no_area); - VCALL_PTR0R(Rect3, has_no_surface); - VCALL_PTR1R(Rect3, intersects); - VCALL_PTR1R(Rect3, encloses); - VCALL_PTR1R(Rect3, merge); - VCALL_PTR1R(Rect3, intersection); - VCALL_PTR1R(Rect3, intersects_plane); - VCALL_PTR2R(Rect3, intersects_segment); - VCALL_PTR1R(Rect3, has_point); - VCALL_PTR1R(Rect3, get_support); - VCALL_PTR0R(Rect3, get_longest_axis); - VCALL_PTR0R(Rect3, get_longest_axis_index); - VCALL_PTR0R(Rect3, get_longest_axis_size); - VCALL_PTR0R(Rect3, get_shortest_axis); - VCALL_PTR0R(Rect3, get_shortest_axis_index); - VCALL_PTR0R(Rect3, get_shortest_axis_size); - VCALL_PTR1R(Rect3, expand); - VCALL_PTR1R(Rect3, grow); - VCALL_PTR1R(Rect3, get_endpoint); + VCALL_PTR0R(AABB, get_area); + VCALL_PTR0R(AABB, has_no_area); + VCALL_PTR0R(AABB, has_no_surface); + VCALL_PTR1R(AABB, intersects); + VCALL_PTR1R(AABB, encloses); + VCALL_PTR1R(AABB, merge); + VCALL_PTR1R(AABB, intersection); + VCALL_PTR1R(AABB, intersects_plane); + VCALL_PTR2R(AABB, intersects_segment); + VCALL_PTR1R(AABB, has_point); + VCALL_PTR1R(AABB, get_support); + VCALL_PTR0R(AABB, get_longest_axis); + VCALL_PTR0R(AABB, get_longest_axis_index); + VCALL_PTR0R(AABB, get_longest_axis_size); + VCALL_PTR0R(AABB, get_shortest_axis); + VCALL_PTR0R(AABB, get_shortest_axis_index); + VCALL_PTR0R(AABB, get_shortest_axis_size); + VCALL_PTR1R(AABB, expand); + VCALL_PTR1R(AABB, grow); + VCALL_PTR1R(AABB, get_endpoint); VCALL_PTR0R(Transform2D, inverse); VCALL_PTR0R(Transform2D, affine_inverse); @@ -755,7 +755,7 @@ struct _VariantCall { case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3()); return; case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane()); return; - case Variant::RECT3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Rect3()); return; + case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB()); return; default: r_ret = Variant(); } } @@ -766,7 +766,7 @@ struct _VariantCall { case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3()); return; case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane()); return; - case Variant::RECT3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect3()); return; + case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB()); return; default: r_ret = Variant(); } } @@ -878,9 +878,9 @@ struct _VariantCall { r_ret = Color::hex(*p_args[0]); } - static void Rect3_init1(Variant &r_ret, const Variant **p_args) { + static void AABB_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Rect3(*p_args[0], *p_args[1]); + r_ret = ::AABB(*p_args[0], *p_args[1]); } static void Basis_init1(Variant &r_ret, const Variant **p_args) { @@ -1058,8 +1058,8 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i case TRANSFORM2D: return Transform2D(); case PLANE: return Plane(); case QUAT: return Quat(); - case RECT3: - return Rect3(); // 10 + case AABB: + return ::AABB(); // 10 case BASIS: return Basis(); case TRANSFORM: return Transform(); @@ -1138,8 +1138,8 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i case VECTOR3: return (Vector3(*p_args[0])); case PLANE: return (Plane(*p_args[0])); case QUAT: return (Quat(*p_args[0])); - case RECT3: - return (Rect3(*p_args[0])); // 10 + case AABB: + return (::AABB(*p_args[0])); // 10 case BASIS: return (Basis(p_args[0]->operator Basis())); case TRANSFORM: return (Transform(p_args[0]->operator Transform())); @@ -1707,26 +1707,26 @@ void register_variant_methods() { //pointerbased - ADDFUNC0R(RECT3, REAL, Rect3, get_area, varray()); - ADDFUNC0R(RECT3, BOOL, Rect3, has_no_area, varray()); - ADDFUNC0R(RECT3, BOOL, Rect3, has_no_surface, varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, intersects, RECT3, "with", varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, encloses, RECT3, "with", varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, merge, RECT3, "with", varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, intersection, RECT3, "with", varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, intersects_plane, PLANE, "plane", varray()); - ADDFUNC2R(RECT3, BOOL, Rect3, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, has_point, VECTOR3, "point", varray()); - ADDFUNC1R(RECT3, VECTOR3, Rect3, get_support, VECTOR3, "dir", varray()); - ADDFUNC0R(RECT3, VECTOR3, Rect3, get_longest_axis, varray()); - ADDFUNC0R(RECT3, INT, Rect3, get_longest_axis_index, varray()); - ADDFUNC0R(RECT3, REAL, Rect3, get_longest_axis_size, varray()); - ADDFUNC0R(RECT3, VECTOR3, Rect3, get_shortest_axis, varray()); - ADDFUNC0R(RECT3, INT, Rect3, get_shortest_axis_index, varray()); - ADDFUNC0R(RECT3, REAL, Rect3, get_shortest_axis_size, varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, expand, VECTOR3, "to_point", varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, grow, REAL, "by", varray()); - ADDFUNC1R(RECT3, VECTOR3, Rect3, get_endpoint, INT, "idx", varray()); + ADDFUNC0R(AABB, REAL, AABB, get_area, varray()); + ADDFUNC0R(AABB, BOOL, AABB, has_no_area, varray()); + ADDFUNC0R(AABB, BOOL, AABB, has_no_surface, varray()); + ADDFUNC1R(AABB, BOOL, AABB, intersects, AABB, "with", varray()); + ADDFUNC1R(AABB, BOOL, AABB, encloses, AABB, "with", varray()); + ADDFUNC1R(AABB, AABB, AABB, merge, AABB, "with", varray()); + ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray()); + ADDFUNC1R(AABB, BOOL, AABB, intersects_plane, PLANE, "plane", varray()); + ADDFUNC2R(AABB, BOOL, AABB, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray()); + ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray()); + ADDFUNC1R(AABB, VECTOR3, AABB, get_support, VECTOR3, "dir", varray()); + ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray()); + ADDFUNC0R(AABB, INT, AABB, get_longest_axis_index, varray()); + ADDFUNC0R(AABB, REAL, AABB, get_longest_axis_size, varray()); + ADDFUNC0R(AABB, VECTOR3, AABB, get_shortest_axis, varray()); + ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray()); + ADDFUNC0R(AABB, REAL, AABB, get_shortest_axis_size, varray()); + ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray()); + ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray()); + ADDFUNC1R(AABB, VECTOR3, AABB, get_endpoint, INT, "idx", varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, inverse, varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, affine_inverse, varray()); @@ -1791,7 +1791,7 @@ void register_variant_methods() { _VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::REAL, "g", Variant::REAL, "b", Variant::REAL, "a", Variant::REAL); _VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::REAL, "g", Variant::REAL, "b", Variant::REAL); - _VariantCall::add_constructor(_VariantCall::Rect3_init1, Variant::RECT3, "position", Variant::VECTOR3, "size", Variant::VECTOR3); + _VariantCall::add_constructor(_VariantCall::AABB_init1, Variant::AABB, "position", Variant::VECTOR3, "size", Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Basis_init1, Variant::BASIS, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Basis_init2, Variant::BASIS, "axis", Variant::VECTOR3, "phi", Variant::REAL); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 6362090902..c793d70ed8 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -48,7 +48,7 @@ CASE_TYPE(PREFIX, OP, TRANSFORM2D) \ CASE_TYPE(PREFIX, OP, PLANE) \ CASE_TYPE(PREFIX, OP, QUAT) \ - CASE_TYPE(PREFIX, OP, RECT3) \ + CASE_TYPE(PREFIX, OP, AABB) \ CASE_TYPE(PREFIX, OP, BASIS) \ CASE_TYPE(PREFIX, OP, TRANSFORM) \ CASE_TYPE(PREFIX, OP, COLOR) \ @@ -81,7 +81,7 @@ TYPE(PREFIX, OP, TRANSFORM2D), \ TYPE(PREFIX, OP, PLANE), \ TYPE(PREFIX, OP, QUAT), \ - TYPE(PREFIX, OP, RECT3), \ + TYPE(PREFIX, OP, AABB), \ TYPE(PREFIX, OP, BASIS), \ TYPE(PREFIX, OP, TRANSFORM), \ TYPE(PREFIX, OP, COLOR), \ @@ -465,7 +465,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3, ==, Vector3); DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, PLANE, ==, Plane); DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, QUAT, ==, Quat); - DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, RECT3, ==, _rect3); + DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, AABB, ==, _aabb); DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, BASIS, ==, _basis); DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM, ==, _transform); DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, COLOR, ==, Color); @@ -555,7 +555,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3, !=, Vector3); DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, PLANE, !=, Plane); DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, QUAT, !=, Quat); - DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, RECT3, !=, _rect3); + DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, AABB, !=, _aabb); DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, BASIS, !=, _basis); DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM, !=, _transform); DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, COLOR, !=, Color); @@ -629,7 +629,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_LESS, TRANSFORM2D) CASE_TYPE(math, OP_LESS, PLANE) CASE_TYPE(math, OP_LESS, QUAT) - CASE_TYPE(math, OP_LESS, RECT3) + CASE_TYPE(math, OP_LESS, AABB) CASE_TYPE(math, OP_LESS, BASIS) CASE_TYPE(math, OP_LESS, TRANSFORM) CASE_TYPE(math, OP_LESS, COLOR) @@ -658,7 +658,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM2D) CASE_TYPE(math, OP_LESS_EQUAL, PLANE) CASE_TYPE(math, OP_LESS_EQUAL, QUAT) - CASE_TYPE(math, OP_LESS_EQUAL, RECT3) + CASE_TYPE(math, OP_LESS_EQUAL, AABB) CASE_TYPE(math, OP_LESS_EQUAL, BASIS) CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM) CASE_TYPE(math, OP_LESS_EQUAL, COLOR) @@ -733,7 +733,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_GREATER, TRANSFORM2D) CASE_TYPE(math, OP_GREATER, PLANE) CASE_TYPE(math, OP_GREATER, QUAT) - CASE_TYPE(math, OP_GREATER, RECT3) + CASE_TYPE(math, OP_GREATER, AABB) CASE_TYPE(math, OP_GREATER, BASIS) CASE_TYPE(math, OP_GREATER, TRANSFORM) CASE_TYPE(math, OP_GREATER, COLOR) @@ -762,7 +762,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM2D) CASE_TYPE(math, OP_GREATER_EQUAL, PLANE) CASE_TYPE(math, OP_GREATER_EQUAL, QUAT) - CASE_TYPE(math, OP_GREATER_EQUAL, RECT3) + CASE_TYPE(math, OP_GREATER_EQUAL, AABB) CASE_TYPE(math, OP_GREATER_EQUAL, BASIS) CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM) CASE_TYPE(math, OP_GREATER_EQUAL, COLOR) @@ -818,7 +818,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_ADD, RECT2) CASE_TYPE(math, OP_ADD, TRANSFORM2D) CASE_TYPE(math, OP_ADD, PLANE) - CASE_TYPE(math, OP_ADD, RECT3) + CASE_TYPE(math, OP_ADD, AABB) CASE_TYPE(math, OP_ADD, BASIS) CASE_TYPE(math, OP_ADD, TRANSFORM) CASE_TYPE(math, OP_ADD, NODE_PATH) @@ -842,7 +842,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_SUBTRACT, RECT2) CASE_TYPE(math, OP_SUBTRACT, TRANSFORM2D) CASE_TYPE(math, OP_SUBTRACT, PLANE) - CASE_TYPE(math, OP_SUBTRACT, RECT3) + CASE_TYPE(math, OP_SUBTRACT, AABB) CASE_TYPE(math, OP_SUBTRACT, BASIS) CASE_TYPE(math, OP_SUBTRACT, TRANSFORM) CASE_TYPE(math, OP_SUBTRACT, NODE_PATH) @@ -923,7 +923,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_MULTIPLY, STRING) CASE_TYPE(math, OP_MULTIPLY, RECT2) CASE_TYPE(math, OP_MULTIPLY, PLANE) - CASE_TYPE(math, OP_MULTIPLY, RECT3) + CASE_TYPE(math, OP_MULTIPLY, AABB) CASE_TYPE(math, OP_MULTIPLY, NODE_PATH) CASE_TYPE(math, OP_MULTIPLY, _RID) CASE_TYPE(math, OP_MULTIPLY, OBJECT) @@ -964,7 +964,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_DIVIDE, RECT2) CASE_TYPE(math, OP_DIVIDE, TRANSFORM2D) CASE_TYPE(math, OP_DIVIDE, PLANE) - CASE_TYPE(math, OP_DIVIDE, RECT3) + CASE_TYPE(math, OP_DIVIDE, AABB) CASE_TYPE(math, OP_DIVIDE, BASIS) CASE_TYPE(math, OP_DIVIDE, TRANSFORM) CASE_TYPE(math, OP_DIVIDE, NODE_PATH) @@ -995,7 +995,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_POSITIVE, STRING) CASE_TYPE(math, OP_POSITIVE, RECT2) CASE_TYPE(math, OP_POSITIVE, TRANSFORM2D) - CASE_TYPE(math, OP_POSITIVE, RECT3) + CASE_TYPE(math, OP_POSITIVE, AABB) CASE_TYPE(math, OP_POSITIVE, BASIS) CASE_TYPE(math, OP_POSITIVE, TRANSFORM) CASE_TYPE(math, OP_POSITIVE, COLOR) @@ -1029,7 +1029,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_NEGATE, STRING) CASE_TYPE(math, OP_NEGATE, RECT2) CASE_TYPE(math, OP_NEGATE, TRANSFORM2D) - CASE_TYPE(math, OP_NEGATE, RECT3) + CASE_TYPE(math, OP_NEGATE, AABB) CASE_TYPE(math, OP_NEGATE, BASIS) CASE_TYPE(math, OP_NEGATE, TRANSFORM) CASE_TYPE(math, OP_NEGATE, NODE_PATH) @@ -1088,7 +1088,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_MODULE, TRANSFORM2D) CASE_TYPE(math, OP_MODULE, PLANE) CASE_TYPE(math, OP_MODULE, QUAT) - CASE_TYPE(math, OP_MODULE, RECT3) + CASE_TYPE(math, OP_MODULE, AABB) CASE_TYPE(math, OP_MODULE, BASIS) CASE_TYPE(math, OP_MODULE, TRANSFORM) CASE_TYPE(math, OP_MODULE, COLOR) @@ -1384,10 +1384,10 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool } } break; // 10 - case RECT3: { + case AABB: { if (p_value.type == Variant::VECTOR3) { - Rect3 *v = _data._rect3; + ::AABB *v = _data._aabb; //scalar name if (p_index == CoreStringNames::singleton->position) { v->position = *reinterpret_cast<const Vector3 *>(p_value._data._mem); @@ -1609,9 +1609,9 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const { } } break; // 10 - case RECT3: { + case AABB: { - const Rect3 *v = _data._rect3; + const ::AABB *v = _data._aabb; //scalar name if (p_index == CoreStringNames::singleton->position) { return v->position; @@ -1982,7 +1982,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) } } break; // 10 - case RECT3: { + case AABB: { if (p_value.type != Variant::VECTOR3) return; @@ -1991,7 +1991,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) //scalar name const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Rect3 *v = _data._rect3; + ::AABB *v = _data._aabb; if (*str == "position") { valid = true; v->position = p_value; @@ -2400,13 +2400,13 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { } } break; // 10 - case RECT3: { + case AABB: { if (p_index.get_type() == Variant::STRING) { //scalar name const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Rect3 *v = _data._rect3; + const ::AABB *v = _data._aabb; if (*str == "position") { valid = true; return v->position; @@ -2835,7 +2835,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::REAL, "w")); } break; // 10 - case RECT3: { + case AABB: { p_list->push_back(PropertyInfo(Variant::VECTOR3, "position")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "size")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "end")); @@ -3457,10 +3457,10 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) + *reinterpret_cast<const Vector3 *>(b._data._mem) * c; } return; - case RECT3: { - const Rect3 *ra = reinterpret_cast<const Rect3 *>(a._data._mem); - const Rect3 *rb = reinterpret_cast<const Rect3 *>(b._data._mem); - r_dst = Rect3(ra->position + rb->position * c, ra->size + rb->size * c); + case AABB: { + const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem); + const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem); + r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c); } return; case QUAT: { @@ -3591,8 +3591,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & r_dst = reinterpret_cast<const Quat *>(a._data._mem)->slerp(*reinterpret_cast<const Quat *>(b._data._mem), c); } return; - case RECT3: { - r_dst = Rect3(a._data._rect3->position.linear_interpolate(b._data._rect3->position, c), a._data._rect3->size.linear_interpolate(b._data._rect3->size, c)); + case AABB: { + r_dst = ::AABB(a._data._aabb->position.linear_interpolate(b._data._aabb->position, c), a._data._aabb->size.linear_interpolate(b._data._aabb->size, c)); } return; case BASIS: { diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index d60d10cd3a..1c02c627b5 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -595,7 +595,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Quat(args[0], args[1], args[2], args[3]); return OK; - } else if (id == "Rect3" || id == "AABB") { + } else if (id == "AABB" || id == "Rect3") { Vector<float> args; Error err = _parse_construct<float>(p_stream, args, line, r_err_str); @@ -606,7 +606,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, r_err_str = "Expected 6 arguments for constructor"; } - value = Rect3(Vector3(args[0], args[1], args[2]), Vector3(args[3], args[4], args[5])); + value = AABB(Vector3(args[0], args[1], args[2]), Vector3(args[3], args[4], args[5])); return OK; } else if (id == "Basis" || id == "Matrix3") { //compatibility @@ -1634,10 +1634,10 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "Plane( " + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + " )"); } break; - case Variant::RECT3: { + case Variant::AABB: { - Rect3 aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect3( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); + AABB aabb = p_variant; + p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); } break; case Variant::QUAT: { diff --git a/core/version.h b/core/version.h index 7d2c47df6a..b217d82c5d 100644 --- a/core/version.h +++ b/core/version.h @@ -30,8 +30,8 @@ #include "version_generated.gen.h" #ifdef VERSION_PATCH -#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." _MKSTR(VERSION_STATUS) "." _MKSTR(VERSION_REVISION) VERSION_MODULE_CONFIG +#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." VERSION_STATUS "." VERSION_BUILD VERSION_MODULE_CONFIG #else -#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_STATUS) "." _MKSTR(VERSION_REVISION) VERSION_MODULE_CONFIG +#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." VERSION_STATUS "." VERSION_BUILD VERSION_MODULE_CONFIG #endif // VERSION_PATCH -#define VERSION_FULL_NAME "" _MKSTR(VERSION_NAME) " v" VERSION_MKSTRING +#define VERSION_FULL_NAME "" VERSION_NAME " v" VERSION_MKSTRING diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 258b06f320..d9bdf0e3cf 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -44,6 +44,8 @@ <member name="JSON" type="JSON" setter="" getter=""> [JSON] singleton </member> + <member name="JavaScript" type="JavaScript" setter="" getter=""> + </member> <member name="Marshalls" type="Reference" setter="" getter=""> [Marshalls] singleton </member> @@ -1332,8 +1334,8 @@ <constant name="TYPE_QUAT" value="10"> Variable is of type [Quat]. </constant> - <constant name="TYPE_RECT3" value="11"> - Variable is of type [Rect3]. + <constant name="TYPE_AABB" value="11"> + Variable is of type [AABB]. </constant> <constant name="TYPE_BASIS" value="12"> Variable is of type [Basis]. diff --git a/doc/classes/Rect3.xml b/doc/classes/AABB.xml index 88be5fa419..494dcb8fce 100644 --- a/doc/classes/Rect3.xml +++ b/doc/classes/AABB.xml @@ -1,18 +1,18 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="Rect3" category="Built-In Types" version="3.0-alpha"> +<class name="AABB" category="Built-In Types" version="3.0-alpha"> <brief_description> Axis-Aligned Bounding Box. </brief_description> <description> - Rect3 consists of a position, a size, and several utility functions. It is typically used for fast overlap tests. + AABB consists of a position, a size, and several utility functions. It is typically used for fast overlap tests. </description> <tutorials> </tutorials> <demos> </demos> <methods> - <method name="Rect3"> - <return type="Rect3"> + <method name="AABB"> + <return type="AABB"> </return> <argument index="0" name="position" type="Vector3"> </argument> @@ -25,26 +25,26 @@ <method name="encloses"> <return type="bool"> </return> - <argument index="0" name="with" type="Rect3"> + <argument index="0" name="with" type="AABB"> </argument> <description> - Returns [code]true[/code] if this [code]Rect3[/code] completely encloses another one. + Returns [code]true[/code] if this [code]AABB[/code] completely encloses another one. </description> </method> <method name="expand"> - <return type="Rect3"> + <return type="AABB"> </return> <argument index="0" name="to_point" type="Vector3"> </argument> <description> - Returns this [code]Rect3[/code] expanded to include a given point. + Returns this [code]AABB[/code] expanded to include a given point. </description> </method> <method name="get_area"> <return type="float"> </return> <description> - Gets the area of the [code]Rect3[/code]. + Gets the area of the [code]AABB[/code]. </description> </method> <method name="get_endpoint"> @@ -53,49 +53,49 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Gets the position of the 8 endpoints of the [code]Rect3[/code] in space. + Gets the position of the 8 endpoints of the [code]AABB[/code] in space. </description> </method> <method name="get_longest_axis"> <return type="Vector3"> </return> <description> - Returns the normalized longest axis of the [code]Rect3[/code]. + Returns the normalized longest axis of the [code]AABB[/code]. </description> </method> <method name="get_longest_axis_index"> <return type="int"> </return> <description> - Returns the index of the longest axis of the [code]Rect3[/code] (according to [Vector3]::AXIS* enum). + Returns the index of the longest axis of the [code]AABB[/code] (according to [Vector3]::AXIS* enum). </description> </method> <method name="get_longest_axis_size"> <return type="float"> </return> <description> - Returns the scalar length of the longest axis of the [code]Rect3[/code]. + Returns the scalar length of the longest axis of the [code]AABB[/code]. </description> </method> <method name="get_shortest_axis"> <return type="Vector3"> </return> <description> - Returns the normalized shortest axis of the [code]Rect3[/code]. + Returns the normalized shortest axis of the [code]AABB[/code]. </description> </method> <method name="get_shortest_axis_index"> <return type="int"> </return> <description> - Returns the index of the shortest axis of the [code]Rect3[/code] (according to [Vector3]::AXIS* enum). + Returns the index of the shortest axis of the [code]AABB[/code] (according to [Vector3]::AXIS* enum). </description> </method> <method name="get_shortest_axis_size"> <return type="float"> </return> <description> - Returns the scalar length of the shortest axis of the [code]Rect3[/code]. + Returns the scalar length of the shortest axis of the [code]AABB[/code]. </description> </method> <method name="get_support"> @@ -108,26 +108,26 @@ </description> </method> <method name="grow"> - <return type="Rect3"> + <return type="AABB"> </return> <argument index="0" name="by" type="float"> </argument> <description> - Returns a copy of the [code]Rect3[/code] grown a given amount of units towards all the sides. + Returns a copy of the [code]AABB[/code] grown a given amount of units towards all the sides. </description> </method> <method name="has_no_area"> <return type="bool"> </return> <description> - Returns [code]true[/code] if the [code]Rect3[/code] is flat or empty. + Returns [code]true[/code] if the [code]AABB[/code] is flat or empty. </description> </method> <method name="has_no_surface"> <return type="bool"> </return> <description> - Returns [code]true[/code] if the [code]Rect3[/code] is empty. + Returns [code]true[/code] if the [code]AABB[/code] is empty. </description> </method> <method name="has_point"> @@ -136,25 +136,25 @@ <argument index="0" name="point" type="Vector3"> </argument> <description> - Returns [code]true[/code] if the [code]Rect3[/code] contains a point. + Returns [code]true[/code] if the [code]AABB[/code] contains a point. </description> </method> <method name="intersection"> - <return type="Rect3"> + <return type="AABB"> </return> - <argument index="0" name="with" type="Rect3"> + <argument index="0" name="with" type="AABB"> </argument> <description> - Returns the intersection between two [code]Rect3[/code]. An empty Rect3 (size 0,0,0) is returned on failure. + Returns the intersection between two [code]AABB[/code]. An empty AABB (size 0,0,0) is returned on failure. </description> </method> <method name="intersects"> <return type="bool"> </return> - <argument index="0" name="with" type="Rect3"> + <argument index="0" name="with" type="AABB"> </argument> <description> - Returns [code]true[/code] if the [code]Rect3[/code] overlaps with another. + Returns [code]true[/code] if the [code]AABB[/code] overlaps with another. </description> </method> <method name="intersects_plane"> @@ -163,7 +163,7 @@ <argument index="0" name="plane" type="Plane"> </argument> <description> - Returns [code]true[/code] if the [code]Rect3[/code] is on both sides of a plane. + Returns [code]true[/code] if the [code]AABB[/code] is on both sides of a plane. </description> </method> <method name="intersects_segment"> @@ -174,16 +174,16 @@ <argument index="1" name="to" type="Vector3"> </argument> <description> - Returns [code]true[/code] if the [code]Rect3[/code] intersects the line segment between [code]from[/code] and [code]to[/code]. + Returns [code]true[/code] if the [code]AABB[/code] intersects the line segment between [code]from[/code] and [code]to[/code]. </description> </method> <method name="merge"> - <return type="Rect3"> + <return type="AABB"> </return> - <argument index="0" name="with" type="Rect3"> + <argument index="0" name="with" type="AABB"> </argument> <description> - Returns a larger Rect3 that contains this Rect3 and [code]with[/code]. + Returns a larger AABB that contains this AABB and [code]with[/code]. </description> </method> </methods> diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml index 10456f805d..6c9b191371 100644 --- a/doc/classes/ArrayMesh.xml +++ b/doc/classes/ArrayMesh.xml @@ -66,7 +66,7 @@ </description> </method> <method name="get_custom_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> </description> @@ -95,7 +95,7 @@ <method name="set_custom_aabb"> <return type="void"> </return> - <argument index="0" name="aabb" type="Rect3"> + <argument index="0" name="aabb" type="AABB"> </argument> <description> </description> diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index ee334e26a2..83a06bcd4d 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -287,7 +287,7 @@ <argument index="1" name="send" type="String"> </argument> <description> - Connects the output of the bus at [code]bus_idx[/code] to the bus named [code]send[/send]. + Connects the output of the bus at [code]bus_idx[/code] to the bus named [code]send[/code]. </description> </method> <method name="set_bus_solo"> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index dd192e2166..bb3a9b3845 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -346,14 +346,14 @@ Get the global transform matrix of this item in relation to the canvas. </description> </method> - <method name="get_item_and_children_rect" qualifiers="const"> + <method name="edit_get_item_and_children_rect" qualifiers="const"> <return type="Rect2"> </return> <description> Get a [Rect2] with the boundaries of this item and its children. </description> </method> - <method name="get_item_rect" qualifiers="const"> + <method name="edit_get_rect" qualifiers="const"> <return type="Rect2"> </return> <description> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 79870dd411..57966fb74e 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -60,7 +60,7 @@ <argument index="1" name="constant" type="int"> </argument> <description> - Overrides an integer constant in the [theme] resource the node uses. If the [code]constant[code] is invalid, Godot clears the override. See [member Theme.INVALID_CONSTANT] for more information. + Overrides an integer constant in the [Theme] resource the node uses. If the [code]constant[/code] is invalid, Godot clears the override. See [member Theme.INVALID_CONSTANT] for more information. </description> </method> <method name="add_font_override"> @@ -228,7 +228,14 @@ <argument index="0" name="margin" type="int" enum="Margin"> </argument> <description> - Return the forced neighbour for moving the input focus to. When pressing TAB or directional/joypad directions focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function. + Return the forced neighbour for moving the input focus to. When pressing directional/joypad directions, focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function. + </description> + </method> + <method name="get_focus_next" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + Return the 'focus_next' for moving input focus to. When pressing TAB, focus is moved to the next control in the tree. However, the control to move to can be forced with this function. </description> </method> <method name="get_focus_owner" qualifiers="const"> @@ -238,6 +245,13 @@ Return which control is owning the keyboard focus, or null if no one. </description> </method> + <method name="get_focus_previous" qualifiers="const"> + <return type="NodePath"> + </return> + <description> + Return the 'focus_previous' for moving input focus to. When pressing Shift+TAB focus is moved to the previous control in the tree. However, the control to move to can be forced with this function. + </description> + </method> <method name="get_font" qualifiers="const"> <return type="Font"> </return> @@ -676,7 +690,25 @@ <argument index="1" name="neighbour" type="NodePath"> </argument> <description> - Force a neighbour for moving the input focus to. When pressing TAB or directional/joypad directions focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function. + Force a neighbour for moving the input focus to. When pressing directional/joypad directions, focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function. + </description> + </method> + <method name="set_focus_next"> + <return type="void"> + </return> + <argument index="0" name="next" type="NodePath"> + </argument> + <description> + Force the 'focus_next' for moving input focus to. When pressing TAB, focus is moved to the next control in the tree. However, the control to move to can be forced with this function. + </description> + </method> + <method name="set_focus_previous"> + <return type="void"> + </return> + <argument index="0" name="previous" type="NodePath"> + </argument> + <description> + Force the 'focus_previous' for moving input focus to. When pressing Shift+TAB, focus is moved to the previous control in the tree. However, the control to move to can be forced with this function. </description> </method> <method name="set_global_position"> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index a0e4fdb8e0..e58516d461 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -55,7 +55,7 @@ Get the list of favorite directories for this project. </description> </method> - <method name="get_project_settings_path" qualifiers="const"> + <method name="get_project_settings_dir" qualifiers="const"> <return type="String"> </return> <description> @@ -77,7 +77,7 @@ <description> </description> </method> - <method name="get_settings_path" qualifiers="const"> + <method name="get_settings_dir" qualifiers="const"> <return type="String"> </return> <description> diff --git a/doc/classes/EditorSpatialGizmo.xml b/doc/classes/EditorSpatialGizmo.xml index e111eec3b9..758024c99b 100644 --- a/doc/classes/EditorSpatialGizmo.xml +++ b/doc/classes/EditorSpatialGizmo.xml @@ -24,7 +24,7 @@ </return> <argument index="0" name="triangles" type="TriangleMesh"> </argument> - <argument index="1" name="bounds" type="Rect3"> + <argument index="1" name="bounds" type="AABB"> </argument> <description> Add collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. Call this function during [method redraw]. diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml index f43bbc2e9d..090e0d7910 100644 --- a/doc/classes/Engine.xml +++ b/doc/classes/Engine.xml @@ -71,8 +71,8 @@ "minor" - Holds the minor version number as a String "patch" - Holds the patch version number as a String "status" - Holds the status (e.g. "beta", "rc1", "rc2", ... "stable") as a String - "revision" - Holds the revision (e.g. "custom-build") as a String - "string" - major + minor + patch + status + revision in a single String + "build" - Holds the build name (e.g. "custom-build") as a String + "string" - major + minor + patch + status + build in a single String </description> </method> <method name="has_singleton" qualifiers="const"> diff --git a/doc/classes/GIProbeData.xml b/doc/classes/GIProbeData.xml index 3777eba6af..5d118be776 100644 --- a/doc/classes/GIProbeData.xml +++ b/doc/classes/GIProbeData.xml @@ -16,7 +16,7 @@ </description> </method> <method name="get_bounds" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> </description> @@ -86,7 +86,7 @@ <method name="set_bounds"> <return type="void"> </return> - <argument index="0" name="bounds" type="Rect3"> + <argument index="0" name="bounds" type="AABB"> </argument> <description> </description> @@ -167,7 +167,7 @@ <members> <member name="bias" type="float" setter="set_bias" getter="get_bias"> </member> - <member name="bounds" type="Rect3" setter="set_bounds" getter="get_bounds"> + <member name="bounds" type="AABB" setter="set_bounds" getter="get_bounds"> </member> <member name="cell_size" type="float" setter="set_cell_size" getter="get_cell_size"> </member> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 4f8da7af9e..b6eb26ce8c 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -377,13 +377,13 @@ </argument> <description> Sets the [Color] of the pixel at [code](x, y)[/code] if the image is unlocked. Example: - [code] + [codeblock] var img = Image.new() img.lock() img.set_pixel(x, y, color) # Does not have an effect img.unlock() img.set_pixel(x, y, color) # Works - [/code]. + [/codeblock] </description> </method> <method name="shrink_x2"> diff --git a/doc/classes/InputEvent.xml b/doc/classes/InputEvent.xml index 1cebed7efc..e4404fc258 100644 --- a/doc/classes/InputEvent.xml +++ b/doc/classes/InputEvent.xml @@ -18,7 +18,7 @@ <argument index="0" name="event" type="InputEvent"> </argument> <description> - Returns [code]true[/code] if this event matches [code]event[event]. + Returns [code]true[/code] if this event matches [code]event[/code]. </description> </method> <method name="as_text" qualifiers="const"> diff --git a/doc/classes/InputEventAction.xml b/doc/classes/InputEventAction.xml index 13d3a14511..383f8360fb 100644 --- a/doc/classes/InputEventAction.xml +++ b/doc/classes/InputEventAction.xml @@ -4,7 +4,7 @@ Input event type for actions. </brief_description> <description> - Contains a generic action which can be targeted from several type of inputs. Actions can be created from the project settings menu [code]Project > Project Settings > Input Map[/Code]. See [method Node._input]. + Contains a generic action which can be targeted from several type of inputs. Actions can be created from the project settings menu [code]Project > Project Settings > Input Map[/code]. See [method Node._input]. </description> <tutorials> http://docs.godotengine.org/en/stable/learning/features/inputs/inputevent.html#actions diff --git a/doc/classes/InputMap.xml b/doc/classes/InputMap.xml index a04b9e78ae..d5a1d85def 100644 --- a/doc/classes/InputMap.xml +++ b/doc/classes/InputMap.xml @@ -4,7 +4,7 @@ Singleton that manages [InputEventAction]. </brief_description> <description> - Manages all [InputEventAction] which can be created/modified from the project settings menu [code]Project > Project Settings > Input Map[/Code] or in code with [method add_action] and [method action_add_event]. See [method Node._input]. + Manages all [InputEventAction] which can be created/modified from the project settings menu [code]Project > Project Settings > Input Map[/code] or in code with [method add_action] and [method action_add_event]. See [method Node._input]. </description> <tutorials> http://docs.godotengine.org/en/stable/learning/features/inputs/inputevent.html#inputmap diff --git a/doc/classes/JavaScript.xml b/doc/classes/JavaScript.xml new file mode 100644 index 0000000000..9dd386f08e --- /dev/null +++ b/doc/classes/JavaScript.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="JavaScript" inherits="Object" category="Core" version="3.0-alpha"> + <brief_description> + Singleton that connects the engine with the browser's JavaScript context in HTML5 export. + </brief_description> + <description> + The JavaScript singleton is implemented only in HTML5 export. It's used to access the browser's JavaScript context. This allows interaction with embedding pages or calling third-party JavaScript APIs. + </description> + <tutorials> + http://docs.godotengine.org/en/stable/learning/workflow/export/exporting_for_web.html#calling-javascript-from-script + </tutorials> + <demos> + </demos> + <methods> + <method name="eval"> + <return type="Variant"> + </return> + <argument index="0" name="code" type="String"> + </argument> + <argument index="1" name="use_global_execution_context" type="bool" default="false"> + </argument> + <description> + Execute the string [code]code[/code] as JavaScript code within the browser window. This is a call to the actual global JavaScript function [code]eval()[/code]. + If [code]use_global_execution_context[/code] is [code]true[/code], the code will be evaluated in the global execution context. Otherwise, it is evaluated in the execution context of a function within the engine's runtime environment. + </description> + </method> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml index b827db474d..a423974753 100644 --- a/doc/classes/KinematicBody.xml +++ b/doc/classes/KinematicBody.xml @@ -32,7 +32,7 @@ <argument index="0" name="slide_idx" type="int"> </argument> <description> - Returns a [KinematicCollision], which contains information about a collision that occured during the last [method move_and_slide] call. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count]()-1). + Returns a [KinematicCollision], which contains information about a collision that occured during the last [method move_and_slide] call. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count] - 1). </description> </method> <method name="get_slide_count" qualifiers="const"> diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml index 264e414ad4..7285c780e5 100644 --- a/doc/classes/KinematicBody2D.xml +++ b/doc/classes/KinematicBody2D.xml @@ -32,7 +32,7 @@ <argument index="0" name="slide_idx" type="int"> </argument> <description> - Returns a [KinematicCollision2D], which contains information about a collision that occured during the last [method move_and_slide] call. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count]()-1). + Returns a [KinematicCollision2D], which contains information about a collision that occured during the last [method move_and_slide] call. Since the body can collide several times in a single call to [method move_and_slide], you must specify the index of the collision in the range 0 to ([method get_slide_count] - 1). </description> </method> <method name="get_slide_count" qualifiers="const"> diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml index f49a806f0e..7b76d94c95 100644 --- a/doc/classes/Line2D.xml +++ b/doc/classes/Line2D.xml @@ -63,7 +63,7 @@ <argument index="0" name="i" type="int"> </argument> <description> - Returns point [code]i[code]'s position. + Returns point [code]i[/code]'s position. </description> </method> <method name="get_points" qualifiers="const"> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 73384c27e4..b6a89d09f4 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -7,7 +7,7 @@ MultiMesh provides low level mesh instancing. If the amount of [Mesh] instances needed goes from hundreds to thousands (and most need to be visible at close proximity) creating such a large amount of [MeshInstance] nodes may affect performance by using too much CPU or video memory. For this case a MultiMesh becomes very useful, as it can draw thousands of instances with little API overhead. As a drawback, if the instances are too far away of each other, performance may be reduced as every single instance will always rendered (they are spatially indexed as one, for the whole object). - Since instances may have any behavior, the Rect3 used for visibility must be provided by the user. + Since instances may have any behavior, the AABB used for visibility must be provided by the user. </description> <tutorials> </tutorials> @@ -15,10 +15,10 @@ </demos> <methods> <method name="get_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> - Return the visibility Rect3. + Return the visibility AABB. </description> </method> <method name="get_color_format" qualifiers="const"> diff --git a/doc/classes/Nil.xml b/doc/classes/Nil.xml index 1fccdc0148..a4bd60d53e 100644 --- a/doc/classes/Nil.xml +++ b/doc/classes/Nil.xml @@ -100,7 +100,7 @@ </description> </method> <method name="Nil"> - <argument index="0" name="from" type="Rect3"> + <argument index="0" name="from" type="AABB"> </argument> <description> </description> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index db70b99de4..8f82040eca 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -127,11 +127,11 @@ Returns the current screen index (0 padded). </description> </method> - <method name="get_data_dir" qualifiers="const"> + <method name="get_user_data_dir" qualifiers="const"> <return type="String"> </return> <description> - Returns the absolute directory path of user data path([user://]). + Returns the absolute directory path where user data is written ([code]user://[/code]). </description> </method> <method name="get_date" qualifiers="const"> diff --git a/doc/classes/Particles.xml b/doc/classes/Particles.xml index 4e070f67fd..9a9279b0a7 100644 --- a/doc/classes/Particles.xml +++ b/doc/classes/Particles.xml @@ -13,7 +13,7 @@ </demos> <methods> <method name="capture_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> </description> @@ -105,7 +105,7 @@ </description> </method> <method name="get_visibility_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> </description> @@ -247,7 +247,7 @@ <method name="set_visibility_aabb"> <return type="void"> </return> - <argument index="0" name="aabb" type="Rect3"> + <argument index="0" name="aabb" type="AABB"> </argument> <description> </description> @@ -300,7 +300,7 @@ <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale"> Speed scaling ratio. Default value: [code]1[/code]. </member> - <member name="visibility_aabb" type="Rect3" setter="set_visibility_aabb" getter="get_visibility_aabb"> + <member name="visibility_aabb" type="AABB" setter="set_visibility_aabb" getter="get_visibility_aabb"> </member> </members> <constants> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 693bd5cf2f..18e77ff5e3 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -403,6 +403,20 @@ Triggered when the user clicks on content between [url] tags. If the meta is defined in text, e.g. [code][url={"data"="hi"}]hi[/url][/code], then the parameter for this signal will be a [String] type. If a particular type or an object is desired, the [method push_meta] method must be used to manually insert the data into the tag stack. </description> </signal> + <signal name="meta_hover_started"> + <argument index="0" name="meta" type="Nil"> + </argument> + <description> + Triggers when the mouse enters a meta tag. + </description> + </signal> + <signal name="meta_hover_ended"> + <argument index="0" name="meta" type="Nil"> + </argument> + <description> + Triggers when the mouse exits a meta tag. + </description> + </signal> </signals> <constants> <constant name="ALIGN_LEFT" value="0"> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index ecf9e54ee7..60c5e75dec 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -95,10 +95,10 @@ <method name="String"> <return type="String"> </return> - <argument index="0" name="from" type="Rect3"> + <argument index="0" name="from" type="AABB"> </argument> <description> - Constructs a new String from the given [Rect3]. + Constructs a new String from the given [AABB]. </description> </method> <method name="String"> diff --git a/doc/classes/VisibilityNotifier.xml b/doc/classes/VisibilityNotifier.xml index 1dfa60a5ac..90f1974697 100644 --- a/doc/classes/VisibilityNotifier.xml +++ b/doc/classes/VisibilityNotifier.xml @@ -12,7 +12,7 @@ </demos> <methods> <method name="get_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> Returns the bounding box of the VisibilityNotifier. @@ -28,7 +28,7 @@ <method name="set_aabb"> <return type="void"> </return> - <argument index="0" name="rect" type="Rect3"> + <argument index="0" name="rect" type="AABB"> </argument> <description> Set the visibility bounding box of the VisibilityNotifier. @@ -36,7 +36,7 @@ </method> </methods> <members> - <member name="aabb" type="Rect3" setter="set_aabb" getter="get_aabb"> + <member name="aabb" type="AABB" setter="set_aabb" getter="get_aabb"> The VisibilityNotifier's bounding box. </member> </members> diff --git a/doc/classes/VisualInstance.xml b/doc/classes/VisualInstance.xml index be2d38bf9f..7108eb13c5 100644 --- a/doc/classes/VisualInstance.xml +++ b/doc/classes/VisualInstance.xml @@ -10,7 +10,7 @@ </demos> <methods> <method name="get_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> </description> @@ -22,7 +22,7 @@ </description> </method> <method name="get_transformed_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <description> </description> diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 1030e4ecc0..d716d99e5d 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -1035,7 +1035,7 @@ </description> </method> <method name="mesh_get_custom_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <argument index="0" name="mesh" type="RID"> </argument> @@ -1085,13 +1085,13 @@ </return> <argument index="0" name="mesh" type="RID"> </argument> - <argument index="1" name="aabb" type="Rect3"> + <argument index="1" name="aabb" type="AABB"> </argument> <description> </description> </method> <method name="mesh_surface_get_aabb" qualifiers="const"> - <return type="Rect3"> + <return type="AABB"> </return> <argument index="0" name="mesh" type="RID"> </argument> diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py index dc015d781b..cd0108019b 100644 --- a/doc/tools/makerst.py +++ b/doc/tools/makerst.py @@ -7,6 +7,7 @@ import os import xml.etree.ElementTree as ET input_list = [] +cur_file = "" for arg in sys.argv[1:]: if arg.endswith(os.sep): @@ -206,6 +207,7 @@ def rstize_text(text, cclass): elif cmd == '/code': tag_text = '``' inside_code = False + escape_post = True elif inside_code: tag_text = '[' + tag_text + ']' elif cmd.find('html') == 0: @@ -217,7 +219,10 @@ def rstize_text(text, cclass): param = tag_text[space_pos + 1:] if param.find('.') != -1: - (class_param, method_param) = param.split('.') + ss = param.split('.') + if len(ss) > 2: + sys.exit("Bad reference: '" + param + "' in file: " + cur_file) + (class_param, method_param) = ss tag_text = ':ref:`' + class_param + '.' + method_param + '<class_' + class_param + '_' + method_param + '>`' else: tag_text = ':ref:`' + param + '<class_' + cclass + "_" + param + '>`' @@ -519,8 +524,8 @@ for path in input_list: elif os.path.isfile(path) and path.endswith('.xml'): file_list.append(path) -for file in file_list: - tree = ET.parse(file) +for cur_file in file_list: + tree = ET.parse(cur_file) doc = tree.getroot() if 'version' not in doc.attrib: diff --git a/drivers/SCsub b/drivers/SCsub index 34d6254578..938927f3a9 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -34,7 +34,12 @@ if env['tools']: SConscript("convex_decomp/SCsub") if env['vsproj']: + import os + path = os.getcwd() + # Change directory so the path resolves correctly in the function call. + os.chdir("..") env.AddToVSProject(env.drivers_sources) + os.chdir(path) if env.split_drivers: env.split_lib("drivers") diff --git a/drivers/gl_context/context_gl.cpp b/drivers/gl_context/context_gl.cpp index a453eef227..1581512369 100644 --- a/drivers/gl_context/context_gl.cpp +++ b/drivers/gl_context/context_gl.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "context_gl.h" -#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) ContextGL *ContextGL::singleton = NULL; diff --git a/drivers/gl_context/context_gl.h b/drivers/gl_context/context_gl.h index 399657eb52..3496f2948c 100644 --- a/drivers/gl_context/context_gl.h +++ b/drivers/gl_context/context_gl.h @@ -30,7 +30,7 @@ #ifndef CONTEXT_GL_H #define CONTEXT_GL_H -#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) #include "typedefs.h" diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 5d62d2f5a0..308a18aa9d 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -149,13 +149,6 @@ void RasterizerCanvasGLES3::canvas_begin() { storage->frame.clear_request = false; } - /*canvas_shader.unbind(); - canvas_shader.set_custom_shader(0); - canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE,false); - canvas_shader.bind(); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXTURE, 0); - canvas_use_modulate=false;*/ - reset_canvas(); state.canvas_shader.set_conditional(CanvasShaderGLES3::USE_TEXTURE_RECT, true); @@ -911,61 +904,6 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur } } -#if 0 -void RasterizerGLES2::_canvas_item_setup_shader_params(ShaderMaterial *material,Shader* shader) { - - if (canvas_shader.bind()) - rebind_texpixel_size=true; - - if (material->shader_version!=shader->version) { - //todo optimize uniforms - material->shader_version=shader->version; - } - - if (shader->has_texscreen && framebuffer.active) { - - int x = viewport.x; - int y = window_size.height-(viewport.height+viewport.y); - - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,max_texture_units-1); - glActiveTexture(GL_TEXTURE0+max_texture_units-1); - glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); - if (framebuffer.scale==1 && !canvas_texscreen_used) { -#ifdef GLEW_ENABLED - if (current_rt) { - glReadBuffer(GL_COLOR_ATTACHMENT0); - } else { - glReadBuffer(GL_BACK); - } -#endif - if (current_rt) { - glCopyTexSubImage2D(GL_TEXTURE_2D,0,viewport.x,viewport.y,viewport.x,viewport.y,viewport.width,viewport.height); - canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(viewport.y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height)); - //window_size.height-(viewport.height+viewport.y) - } else { - glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height); - } - - canvas_texscreen_used=true; - } - - glActiveTexture(GL_TEXTURE0); - - } - - if (shader->has_screen_uv) { - canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height)); - } - - - uses_texpixel_size=shader->uses_texpixel_size; - -} - -#endif - void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) { glDisable(GL_BLEND); @@ -1570,6 +1508,7 @@ void RasterizerCanvasGLES3::reset_canvas() { glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); + glDisable(GL_DITHER); glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) { diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 220a3533b7..ee61481a86 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -141,28 +141,22 @@ void RasterizerGLES3::initialize() { print_line("Using GLES3 video driver"); } -#ifdef GLEW_ENABLED - GLuint res = glewInit(); - ERR_FAIL_COND(res != GLEW_OK); - if (OS::get_singleton()->is_stdout_verbose()) { - print_line(String("GLES2: Using GLEW ") + (const char *)glewGetString(GLEW_VERSION)); +#ifdef GLAD_ENABLED + if (!gladLoadGL()) { + ERR_PRINT("Error initializing GLAD"); } - // Check for GL 2.1 compatibility, if not bail out - if (!glewIsSupported("GL_VERSION_3_0")) { - ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.0+ / GLES 3.0, sorry :(\n" +// GLVersion seems to be used for both GL and GL ES, so we need different version checks for them +#ifdef OPENGL_ENABLED // OpenGL 3.3 Core Profile required + if (GLVersion.major < 3 && GLVersion.minor < 3) { +#else // OpenGL ES 3.0 + if (GLVersion.major < 3) { +#endif + ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n" "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot will now crash with a segmentation fault."); - OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.0+ / GLES 3.0, sorry :(\n" + OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 3.3 / OpenGL ES 3.0, sorry :(\n" "Godot Engine will self-destruct as soon as you acknowledge this error message.", - "Fatal error: Insufficient OpenGL / GLES drivers"); - // TODO: If it's even possible, we should stop the execution without segfault and memory leaks :) - } -#endif - -#ifdef GLAD_ENABLED - - if (!gladLoadGL()) { - ERR_PRINT("Error initializing GLAD"); + "Fatal error: Insufficient OpenGL / GLES driver support"); } #ifdef __APPLE__ @@ -175,21 +169,20 @@ void RasterizerGLES3::initialize() { } #endif -#endif +#endif // GLAD_ENABLED - /* glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); + /* // For debugging + glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_ERROR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PORTABILITY_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_PERFORMANCE_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageControlARB(GL_DEBUG_SOURCE_API_ARB,GL_DEBUG_TYPE_OTHER_ARB,GL_DEBUG_SEVERITY_HIGH_ARB,0,NULL,GL_TRUE); glDebugMessageInsertARB( - GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_OTHER_ARB, 1, GL_DEBUG_SEVERITY_HIGH_ARB,5, "hello"); - -*/ + */ const GLubyte *renderer = glGetString(GL_RENDERER); print_line("OpenGL ES 3.0 Renderer: " + String((const char *)renderer)); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 5071fbba01..a41d84a2aa 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -2600,7 +2600,7 @@ RID RasterizerStorageGLES3::mesh_create() { return mesh_owner.make_rid(mesh); } -void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) { +void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) { PoolVector<uint8_t> array = p_array; @@ -3240,11 +3240,11 @@ VS::PrimitiveType RasterizerStorageGLES3::mesh_surface_get_primitive_type(RID p_ return mesh->surfaces[p_surface]->primitive; } -Rect3 RasterizerStorageGLES3::mesh_surface_get_aabb(RID p_mesh, int p_surface) const { +AABB RasterizerStorageGLES3::mesh_surface_get_aabb(RID p_mesh, int p_surface) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!mesh, Rect3()); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Rect3()); + ERR_FAIL_COND_V(!mesh, AABB()); + ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), AABB()); return mesh->surfaces[p_surface]->aabb; } @@ -3279,11 +3279,11 @@ Vector<PoolVector<uint8_t> > RasterizerStorageGLES3::mesh_surface_get_blend_shap return bsarr; } -Vector<Rect3> RasterizerStorageGLES3::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const { +Vector<AABB> RasterizerStorageGLES3::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!mesh, Vector<Rect3>()); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<Rect3>()); + ERR_FAIL_COND_V(!mesh, Vector<AABB>()); + ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<AABB>()); return mesh->surfaces[p_surface]->skeleton_bone_aabb; } @@ -3337,7 +3337,7 @@ int RasterizerStorageGLES3::mesh_get_surface_count(RID p_mesh) const { return mesh->surfaces.size(); } -void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb) { +void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) { Mesh *mesh = mesh_owner.getornull(p_mesh); ERR_FAIL_COND(!mesh); @@ -3345,37 +3345,37 @@ void RasterizerStorageGLES3::mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aab mesh->custom_aabb = p_aabb; } -Rect3 RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const { +AABB RasterizerStorageGLES3::mesh_get_custom_aabb(RID p_mesh) const { const Mesh *mesh = mesh_owner.getornull(p_mesh); - ERR_FAIL_COND_V(!mesh, Rect3()); + ERR_FAIL_COND_V(!mesh, AABB()); return mesh->custom_aabb; } -Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { +AABB RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, Rect3()); + ERR_FAIL_COND_V(!mesh, AABB()); - if (mesh->custom_aabb != Rect3()) + if (mesh->custom_aabb != AABB()) return mesh->custom_aabb; Skeleton *sk = NULL; if (p_skeleton.is_valid()) sk = skeleton_owner.get(p_skeleton); - Rect3 aabb; + AABB aabb; if (sk && sk->size != 0) { for (int i = 0; i < mesh->surfaces.size(); i++) { - Rect3 laabb; + AABB laabb; if ((mesh->surfaces[i]->format & VS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->skeleton_bone_aabb.size()) { int bs = mesh->surfaces[i]->skeleton_bone_aabb.size(); - const Rect3 *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr(); + const AABB *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr(); const bool *skused = mesh->surfaces[i]->skeleton_bone_used.ptr(); int sbs = sk->size; @@ -3401,7 +3401,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { mtx.basis[1].y = texture[base_ofs + 1]; mtx.origin.y = texture[base_ofs + 3]; - Rect3 baabb = mtx.xform(skbones[j]); + AABB baabb = mtx.xform(skbones[j]); if (first) { laabb = baabb; first = false; @@ -3434,7 +3434,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { mtx.basis[2].z = texture[base_ofs + 2]; mtx.origin.z = texture[base_ofs + 3]; - Rect3 baabb = mtx.xform(skbones[j]); + AABB baabb = mtx.xform(skbones[j]); if (first) { laabb = baabb; first = false; @@ -4028,10 +4028,10 @@ int RasterizerStorageGLES3::multimesh_get_visible_instances(RID p_multimesh) con return multimesh->visible_instances; } -Rect3 RasterizerStorageGLES3::multimesh_get_aabb(RID p_multimesh) const { +AABB RasterizerStorageGLES3::multimesh_get_aabb(RID p_multimesh) const { MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh); - ERR_FAIL_COND_V(!multimesh, Rect3()); + ERR_FAIL_COND_V(!multimesh, AABB()); const_cast<RasterizerStorageGLES3 *>(this)->update_dirty_multimeshes(); //update pending AABBs @@ -4053,7 +4053,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { if (multimesh->size && multimesh->dirty_aabb) { - Rect3 mesh_aabb; + AABB mesh_aabb; if (multimesh->mesh.is_valid()) { mesh_aabb = mesh_get_aabb(multimesh->mesh, RID()); @@ -4065,7 +4065,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { int count = multimesh->data.size(); float *data = multimesh->data.ptr(); - Rect3 aabb; + AABB aabb; if (multimesh->transform_format == VS::MULTIMESH_TRANSFORM_2D) { @@ -4080,7 +4080,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { xform.basis[1][1] = dataptr[5]; xform.origin[1] = dataptr[7]; - Rect3 laabb = xform.xform(mesh_aabb); + AABB laabb = xform.xform(mesh_aabb); if (i == 0) aabb = laabb; else @@ -4106,7 +4106,7 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() { xform.basis.elements[2][2] = dataptr[10]; xform.origin.z = dataptr[11]; - Rect3 laabb = xform.xform(mesh_aabb); + AABB laabb = xform.xform(mesh_aabb); if (i == 0) aabb = laabb; else @@ -4242,10 +4242,10 @@ void RasterizerStorageGLES3::immediate_clear(RID p_immediate) { im->instance_change_notify(); } -Rect3 RasterizerStorageGLES3::immediate_get_aabb(RID p_immediate) const { +AABB RasterizerStorageGLES3::immediate_get_aabb(RID p_immediate) const { Immediate *im = immediate_owner.get(p_immediate); - ERR_FAIL_COND_V(!im, Rect3()); + ERR_FAIL_COND_V(!im, AABB()); return im->aabb; } @@ -4466,6 +4466,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) { light->type = p_type; light->param[VS::LIGHT_PARAM_ENERGY] = 1.0; + light->param[VS::LIGHT_PARAM_INDIRECT_ENERGY] = 1.0; light->param[VS::LIGHT_PARAM_SPECULAR] = 0.5; light->param[VS::LIGHT_PARAM_RANGE] = 1.0; light->param[VS::LIGHT_PARAM_SPOT_ANGLE] = 45; @@ -4694,10 +4695,10 @@ uint64_t RasterizerStorageGLES3::light_get_version(RID p_light) const { return light->version; } -Rect3 RasterizerStorageGLES3::light_get_aabb(RID p_light) const { +AABB RasterizerStorageGLES3::light_get_aabb(RID p_light) const { const Light *light = light_owner.getornull(p_light); - ERR_FAIL_COND_V(!light, Rect3()); + ERR_FAIL_COND_V(!light, AABB()); switch (light->type) { @@ -4705,22 +4706,22 @@ Rect3 RasterizerStorageGLES3::light_get_aabb(RID p_light) const { float len = light->param[VS::LIGHT_PARAM_RANGE]; float size = Math::tan(Math::deg2rad(light->param[VS::LIGHT_PARAM_SPOT_ANGLE])) * len; - return Rect3(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); + return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); } break; case VS::LIGHT_OMNI: { float r = light->param[VS::LIGHT_PARAM_RANGE]; - return Rect3(-Vector3(r, r, r), Vector3(r, r, r) * 2); + return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2); } break; case VS::LIGHT_DIRECTIONAL: { - return Rect3(); + return AABB(); } break; default: {} } - ERR_FAIL_V(Rect3()); - return Rect3(); + ERR_FAIL_V(AABB()); + return AABB(); } /* PROBE API */ @@ -4842,11 +4843,11 @@ void RasterizerStorageGLES3::reflection_probe_set_cull_mask(RID p_probe, uint32_ reflection_probe->instance_change_notify(); } -Rect3 RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const { +AABB RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const { const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe); - ERR_FAIL_COND_V(!reflection_probe, Rect3()); + ERR_FAIL_COND_V(!reflection_probe, AABB()); - Rect3 aabb; + AABB aabb; aabb.position = -reflection_probe->extents; aabb.size = reflection_probe->extents * 2.0; @@ -4903,7 +4904,7 @@ RID RasterizerStorageGLES3::gi_probe_create() { GIProbe *gip = memnew(GIProbe); - gip->bounds = Rect3(Vector3(), Vector3(1, 1, 1)); + gip->bounds = AABB(Vector3(), Vector3(1, 1, 1)); gip->dynamic_range = 1.0; gip->energy = 1.0; gip->propagation = 1.0; @@ -4917,7 +4918,7 @@ RID RasterizerStorageGLES3::gi_probe_create() { return gi_probe_owner.make_rid(gip); } -void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds) { +void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) { GIProbe *gip = gi_probe_owner.getornull(p_probe); ERR_FAIL_COND(!gip); @@ -4926,10 +4927,10 @@ void RasterizerStorageGLES3::gi_probe_set_bounds(RID p_probe, const Rect3 &p_bou gip->version++; gip->instance_change_notify(); } -Rect3 RasterizerStorageGLES3::gi_probe_get_bounds(RID p_probe) const { +AABB RasterizerStorageGLES3::gi_probe_get_bounds(RID p_probe) const { const GIProbe *gip = gi_probe_owner.getornull(p_probe); - ERR_FAIL_COND_V(!gip, Rect3()); + ERR_FAIL_COND_V(!gip, AABB()); return gip->bounds; } @@ -5338,7 +5339,7 @@ void RasterizerStorageGLES3::_particles_update_histories(Particles *particles) { particles->clear = true; } -void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) { +void RasterizerStorageGLES3::particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) { Particles *particles = particles_owner.getornull(p_particles); ERR_FAIL_COND(!particles); @@ -5429,15 +5430,15 @@ void RasterizerStorageGLES3::particles_request_process(RID p_particles) { } } -Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { +AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { const Particles *particles = particles_owner.getornull(p_particles); - ERR_FAIL_COND_V(!particles, Rect3()); + ERR_FAIL_COND_V(!particles, AABB()); glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); float *data = (float *)glMapBufferRange(GL_ARRAY_BUFFER, 0, particles->amount * 16 * 6, GL_MAP_READ_BIT); - Rect3 aabb; + AABB aabb; Transform inv = particles->emission_transform.affine_inverse(); @@ -5459,7 +5460,7 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { float longest_axis = 0; for (int i = 0; i < particles->draw_passes.size(); i++) { if (particles->draw_passes[i].is_valid()) { - Rect3 maabb = mesh_get_aabb(particles->draw_passes[i], RID()); + AABB maabb = mesh_get_aabb(particles->draw_passes[i], RID()); longest_axis = MAX(maabb.get_longest_axis_size(), longest_axis); } } @@ -5469,10 +5470,10 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { return aabb; } -Rect3 RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const { +AABB RasterizerStorageGLES3::particles_get_aabb(RID p_particles) const { const Particles *particles = particles_owner.getornull(p_particles); - ERR_FAIL_COND_V(!particles, Rect3()); + ERR_FAIL_COND_V(!particles, AABB()); return particles->custom_aabb; } @@ -7027,14 +7028,22 @@ void RasterizerStorageGLES3::initialize() { glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); { const float qv[16] = { - -1, -1, - 0, 0, - -1, 1, - 0, 1, - 1, 1, - 1, 1, - 1, -1, - 1, 0, + -1, + -1, + 0, + 0, + -1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 1, + -1, + 1, + 0, }; glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index bd5aad29c9..8aa8235b42 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -592,7 +592,7 @@ public: GLuint instancing_array_wireframe_id; int index_wireframe_len; - Vector<Rect3> skeleton_bone_aabb; + Vector<AABB> skeleton_bone_aabb; Vector<bool> skeleton_bone_used; //bool packed; @@ -604,7 +604,7 @@ public: Vector<BlendShape> blend_shapes; - Rect3 aabb; + AABB aabb; int array_len; int index_array_len; @@ -659,7 +659,7 @@ public: Vector<Surface *> surfaces; int blend_shape_count; VS::BlendShapeMode blend_shape_mode; - Rect3 custom_aabb; + AABB custom_aabb; mutable uint64_t last_pass; SelfList<MultiMesh>::List multimeshes; @@ -684,7 +684,7 @@ public: virtual RID mesh_create(); - virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>()); + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()); virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount); virtual int mesh_get_blend_shape_count(RID p_mesh) const; @@ -706,17 +706,17 @@ public: virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const; virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const; - virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const; + virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const; virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const; - virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const; + virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const; virtual void mesh_remove_surface(RID p_mesh, int p_surface); virtual int mesh_get_surface_count(RID p_mesh) const; - virtual void mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb); - virtual Rect3 mesh_get_custom_aabb(RID p_mesh) const; + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb); + virtual AABB mesh_get_custom_aabb(RID p_mesh) const; - virtual Rect3 mesh_get_aabb(RID p_mesh, RID p_skeleton) const; + virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton) const; virtual void mesh_clear(RID p_mesh); void mesh_render_blend_shapes(Surface *s, float *p_weights); @@ -729,7 +729,7 @@ public: VS::MultimeshTransformFormat transform_format; VS::MultimeshColorFormat color_format; Vector<float> data; - Rect3 aabb; + AABB aabb; SelfList<MultiMesh> update_list; SelfList<MultiMesh> mesh_list; GLuint buffer; @@ -780,7 +780,7 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible); virtual int multimesh_get_visible_instances(RID p_multimesh) const; - virtual Rect3 multimesh_get_aabb(RID p_multimesh) const; + virtual AABB multimesh_get_aabb(RID p_multimesh) const; /* IMMEDIATE API */ @@ -801,7 +801,7 @@ public: List<Chunk> chunks; bool building; int mask; - Rect3 aabb; + AABB aabb; Immediate() { type = GEOMETRY_IMMEDIATE; @@ -830,7 +830,7 @@ public: virtual void immediate_clear(RID p_immediate); virtual void immediate_set_material(RID p_immediate, RID p_material); virtual RID immediate_get_material(RID p_immediate) const; - virtual Rect3 immediate_get_aabb(RID p_immediate) const; + virtual AABB immediate_get_aabb(RID p_immediate) const; /* SKELETON API */ @@ -918,7 +918,7 @@ public: virtual float light_get_param(RID p_light, VS::LightParam p_param); virtual Color light_get_color(RID p_light); - virtual Rect3 light_get_aabb(RID p_light) const; + virtual AABB light_get_aabb(RID p_light) const; virtual uint64_t light_get_version(RID p_light) const; /* PROBE API */ @@ -956,7 +956,7 @@ public: virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable); virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers); - virtual Rect3 reflection_probe_get_aabb(RID p_probe) const; + virtual AABB reflection_probe_get_aabb(RID p_probe) const; virtual VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const; virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const; @@ -969,7 +969,7 @@ public: struct GIProbe : public Instantiable { - Rect3 bounds; + AABB bounds; Transform to_cell; float cell_size; @@ -990,8 +990,8 @@ public: virtual RID gi_probe_create(); - virtual void gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds); - virtual Rect3 gi_probe_get_bounds(RID p_probe) const; + virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds); + virtual AABB gi_probe_get_bounds(RID p_probe) const; virtual void gi_probe_set_cell_size(RID p_probe, float p_size); virtual float gi_probe_get_cell_size(RID p_probe) const; @@ -1058,7 +1058,7 @@ public: float explosiveness; float randomness; bool restart_request; - Rect3 custom_aabb; + AABB custom_aabb; bool use_local_coords; RID process_material; @@ -1113,7 +1113,7 @@ public: restart_request = false; - custom_aabb = Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8)); + custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8)); draw_order = VS::PARTICLES_DRAW_ORDER_INDEX; particle_buffers[0] = 0; @@ -1155,7 +1155,7 @@ public: virtual void particles_set_pre_process_time(RID p_particles, float p_time); virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio); virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio); - virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb); + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb); virtual void particles_set_speed_scale(RID p_particles, float p_scale); virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable); virtual void particles_set_process_material(RID p_particles, RID p_material); @@ -1169,8 +1169,8 @@ public: virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh); virtual void particles_request_process(RID p_particles); - virtual Rect3 particles_get_current_aabb(RID p_particles); - virtual Rect3 particles_get_aabb(RID p_particles) const; + virtual AABB particles_get_current_aabb(RID p_particles); + virtual AABB particles_get_aabb(RID p_particles) const; virtual void _particles_update_histories(Particles *particles); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index ad08c59de8..325df8e4f1 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -741,6 +741,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n"; actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n"; actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_COLOR"] = "#define SHADOW_COLOR_USED\n"; + actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; @@ -828,6 +829,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; + actions[VS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; + actions[VS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; + actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; actions[VS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; diff --git a/drivers/unix/SCsub b/drivers/unix/SCsub index c560e1289f..ada8255580 100644 --- a/drivers/unix/SCsub +++ b/drivers/unix/SCsub @@ -2,16 +2,6 @@ Import('env') -g_set_p = '#ifdef UNIX_ENABLED\n' -g_set_p += '#include "os_unix.h"\n' -g_set_p += 'String OS_Unix::get_global_settings_path() const {\n' -g_set_p += '\treturn "' + env["unix_global_settings_path"] + '";\n' -g_set_p += '}\n' -g_set_p += '#endif' -f = open("os_unix_global_settings_path.gen.cpp", "w") -f.write(g_set_p) -f.close() - env.add_source_files(env.drivers_sources, "*.cpp") env["check_c_headers"] = [ [ "mntent.h", "HAVE_MNTENT" ] ] diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 729abd57ef..ce0967af2c 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -454,32 +454,21 @@ int OS_Unix::get_processor_count() const { return sysconf(_SC_NPROCESSORS_CONF); } -String OS_Unix::get_data_dir() const { +String OS_Unix::get_user_data_dir() const { - String an = get_safe_application_name(); - if (an != "") { - - if (has_environment("HOME")) { - - bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir"); - if (use_godot) - return get_environment("HOME") + "/.godot/app_userdata/" + an; - else - return get_environment("HOME") + "/." + an; + String appname = get_safe_application_name(); + if (appname != "") { + bool use_godot_dir = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir"); + if (use_godot_dir) { + return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname); + } else { + return get_data_path().plus_file(appname); } } return ProjectSettings::get_singleton()->get_resource_path(); } -String OS_Unix::get_installed_templates_path() const { - String p = get_global_settings_path(); - if (p != "") - return p + "/templates/"; - else - return ""; -} - String OS_Unix::get_executable_path() const { #ifdef __linux__ diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h index 82c7dee3b9..432f48408f 100644 --- a/drivers/unix/os_unix.h +++ b/drivers/unix/os_unix.h @@ -62,8 +62,6 @@ protected: String stdin_buf; - String get_global_settings_path() const; - public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); virtual String get_stdin_string(bool p_block); @@ -108,11 +106,8 @@ public: virtual void debug_break(); - virtual String get_installed_templates_path() const; virtual String get_executable_path() const; - virtual String get_data_dir() const; - - //virtual void run( MainLoop * p_main_loop ); + virtual String get_user_data_dir() const; }; class UnixTerminalLogger : public StdLogger { diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp index 54eb695178..7d877bdb8c 100644 --- a/editor/animation_editor.cpp +++ b/editor/animation_editor.cpp @@ -1368,7 +1368,7 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x-=hsep; */ - track_ofs[0] = size.width - icon_ofs.x; + track_ofs[0] = size.width - icon_ofs.x + ofs.x; icon_ofs.x -= down_icon->get_width(); te->draw_texture(down_icon, icon_ofs - Size2(0, 4 * EDSCALE)); @@ -1380,7 +1380,7 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x -= hsep; te->draw_line(Point2(icon_ofs.x, ofs.y + y), Point2(icon_ofs.x, ofs.y + y + h), sepcolor); - track_ofs[1] = size.width - icon_ofs.x; + track_ofs[1] = size.width - icon_ofs.x + ofs.x; icon_ofs.x -= down_icon->get_width(); te->draw_texture(down_icon, icon_ofs - Size2(0, 4 * EDSCALE)); @@ -1394,7 +1394,7 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x -= hsep; te->draw_line(Point2(icon_ofs.x, ofs.y + y), Point2(icon_ofs.x, ofs.y + y + h), sepcolor); - track_ofs[2] = size.width - icon_ofs.x; + track_ofs[2] = size.width - icon_ofs.x + ofs.x; if (animation->track_get_type(idx) == Animation::TYPE_VALUE) { @@ -1415,13 +1415,12 @@ void AnimationKeyEditor::_track_editor_draw() { icon_ofs.x -= hsep; te->draw_line(Point2(icon_ofs.x, ofs.y + y), Point2(icon_ofs.x, ofs.y + y + h), sepcolor); - track_ofs[3] = size.width - icon_ofs.x; + track_ofs[3] = size.width - icon_ofs.x + ofs.x; icon_ofs.x -= hsep; icon_ofs.x -= add_key_icon->get_width(); te->draw_texture((mouse_over.over == MouseOver::OVER_ADD_KEY && mouse_over.track == idx) ? add_key_icon_hl : add_key_icon, icon_ofs); - - track_ofs[4] = size.width - icon_ofs.x; + track_ofs[4] = size.width - icon_ofs.x + ofs.x; //draw the keys; int tt = animation->track_get_type(idx); @@ -2080,7 +2079,7 @@ void AnimationKeyEditor::_track_editor_gui_input(const Ref<InputEvent> &p_input) return; } - if (mpos.x < name_limit) { + if (mpos.x < name_limit - (type_icon[0]->get_width() / 2.0)) { //name column // area @@ -3330,7 +3329,7 @@ int AnimationKeyEditor::_confirm_insert(InsertData p_id, int p_last_track) { h.type == Variant::VECTOR2 || h.type == Variant::RECT2 || h.type == Variant::VECTOR3 || - h.type == Variant::RECT3 || + h.type == Variant::AABB || h.type == Variant::QUAT || h.type == Variant::COLOR || h.type == Variant::TRANSFORM) { diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 0100c221c4..c7012a0c14 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -56,6 +56,7 @@ void GotoLineDialog::ok_pressed() { if (get_line() < 1 || get_line() > text_editor->get_line_count()) return; + text_editor->unfold_line(get_line() - 1); text_editor->cursor_set_line(get_line() - 1); hide(); } @@ -139,6 +140,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) if (found) { if (!preserve_cursor) { + text_edit->unfold_line(line); text_edit->cursor_set_line(line, false); text_edit->cursor_set_column(col + text.length(), false); text_edit->center_viewport_to_cursor(); @@ -167,6 +169,7 @@ void FindReplaceBar::_replace() { if (result_line != -1 && result_col != -1) { text_edit->begin_complex_operation(); + text_edit->unfold_line(result_line); text_edit->select(result_line, result_col, result_line, result_col + get_search_text().length()); text_edit->insert_text_at_cursor(get_replace_text()); @@ -214,6 +217,7 @@ void FindReplaceBar::_replace_all() { prev_match = Point2i(result_line, result_col + replace_text.length()); + text_edit->unfold_line(result_line); text_edit->select(result_line, result_col, result_line, match_to.y); if (selection_enabled && is_selection_only()) { @@ -751,6 +755,7 @@ bool FindReplaceDialog::_search() { if (found) { // print_line("found"); + text_edit->unfold_line(line); text_edit->cursor_set_line(line); if (is_backwards()) text_edit->cursor_set_column(col); @@ -1093,6 +1098,8 @@ void CodeTextEditor::update_editor_settings() { text_editor->cursor_set_blink_enabled(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink")); text_editor->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); text_editor->set_draw_breakpoint_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/show_breakpoint_gutter")); + text_editor->set_hiding_enabled(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding")); + text_editor->set_draw_fold_gutter(EditorSettings::get_singleton()->get("text_editor/line_numbers/code_folding")); text_editor->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); text_editor->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling")); text_editor->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed")); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index b4c2ac95cc..cd60455f4f 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -209,7 +209,7 @@ void ConnectDialog::_add_bind() { case Variant::VECTOR3: value = Vector3(); break; case Variant::PLANE: value = Plane(); break; case Variant::QUAT: value = Quat(); break; - case Variant::RECT3: value = Rect3(); break; + case Variant::AABB: value = AABB(); break; case Variant::BASIS: value = Basis(); break; case Variant::TRANSFORM: value = Transform(); break; case Variant::COLOR: value = Color(); break; @@ -295,7 +295,7 @@ ConnectDialog::ConnectDialog() { type_list->add_item("Vector3", Variant::VECTOR3); type_list->add_item("Plane", Variant::PLANE); type_list->add_item("Quat", Variant::QUAT); - type_list->add_item("Rect3", Variant::RECT3); + type_list->add_item("AABB", Variant::AABB); type_list->add_item("Basis", Variant::BASIS); type_list->add_item("Transform", Variant::TRANSFORM); //type_list->add_separator(); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 95b4f7e982..c058d290bf 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -41,7 +41,7 @@ void CreateDialog::popup_create(bool p_dontclear) { recent->clear(); - FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_path().plus_file("create_recent." + base_type), FileAccess::READ); + FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ); if (f) { @@ -63,7 +63,7 @@ void CreateDialog::popup_create(bool p_dontclear) { favorites->clear(); - f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_path().plus_file("favorites." + base_type), FileAccess::READ); + f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::READ); favorite_list.clear(); @@ -97,6 +97,15 @@ void CreateDialog::popup_create(bool p_dontclear) { search_box->grab_focus(); _update_search(); + + bool enable_rl = EditorSettings::get_singleton()->get("docks/scene_tree/draw_relationship_lines"); + Color rl_color = EditorSettings::get_singleton()->get("docks/scene_tree/relationship_line_color"); + + if (enable_rl) { + search_options->add_constant_override("draw_relationship_lines", 1); + search_options->add_color_override("relationship_line_color", rl_color); + } else + search_options->add_constant_override("draw_relationship_lines", 0); } void CreateDialog::_text_changed(const String &p_newtext) { @@ -307,7 +316,7 @@ void CreateDialog::_confirmed() { if (!ti) return; - FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_path().plus_file("create_recent." + base_type), FileAccess::WRITE); + FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::WRITE); if (f) { f->store_line(get_selected_type()); @@ -467,7 +476,7 @@ void CreateDialog::_favorite_toggled() { void CreateDialog::_save_favorite_list() { - FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_path().plus_file("favorites." + base_type), FileAccess::WRITE); + FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::WRITE); if (f) { diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 29e2423e9b..ec0ca3add5 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -281,6 +281,47 @@ DependencyEditor::DependencyEditor() { } ///////////////////////////////////// +void DependencyEditorOwners::_list_rmb_select(int p_item, const Vector2 &p_pos) { + + file_options->clear(); + file_options->set_size(Size2(1, 1)); + if (p_item >= 0) { + file_options->add_item(TTR("Open"), FILE_OPEN); + } + + file_options->set_position(owners->get_global_position() + p_pos); + file_options->popup(); +} + +void DependencyEditorOwners::_select_file(int p_idx) { + + String fpath = owners->get_item_text(p_idx); + + if (ResourceLoader::get_resource_type(fpath) == "PackedScene") { + editor->open_request(fpath); + hide(); + emit_signal("confirmed"); + } +} + +void DependencyEditorOwners::_file_option(int p_option) { + + switch (p_option) { + case FILE_OPEN: { + int idx = owners->get_current(); + if (idx < 0 || idx >= owners->get_item_count()) + break; + _select_file(idx); + } break; + } +} + +void DependencyEditorOwners::_bind_methods() { + + ClassDB::bind_method(D_METHOD("_list_rmb_select"), &DependencyEditorOwners::_list_rmb_select); + ClassDB::bind_method(D_METHOD("_file_option"), &DependencyEditorOwners::_file_option); + ClassDB::bind_method(D_METHOD("_select_file"), &DependencyEditorOwners::_select_file); +} void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) { @@ -329,9 +370,19 @@ void DependencyEditorOwners::show(const String &p_path) { set_title(TTR("Owners Of:") + " " + p_path.get_file()); } -DependencyEditorOwners::DependencyEditorOwners() { +DependencyEditorOwners::DependencyEditorOwners(EditorNode *p_editor) { + + editor = p_editor; + + file_options = memnew(PopupMenu); + add_child(file_options); + file_options->connect("id_pressed", this, "_file_option"); owners = memnew(ItemList); + owners->set_select_mode(ItemList::SELECT_SINGLE); + owners->connect("item_rmb_selected", this, "_list_rmb_select"); + owners->connect("item_activated", this, "_select_file"); + owners->set_allow_rmb_select(true); add_child(owners); } diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h index c7e9baa5c2..9b0aca67d5 100644 --- a/editor/dependency_editor.h +++ b/editor/dependency_editor.h @@ -36,6 +36,7 @@ #include "scene/gui/tree.h" class EditorFileSystemDirectory; +class EditorNode; class DependencyEditor : public AcceptDialog { GDCLASS(DependencyEditor, AcceptDialog); @@ -71,12 +72,25 @@ class DependencyEditorOwners : public AcceptDialog { GDCLASS(DependencyEditorOwners, AcceptDialog); ItemList *owners; + PopupMenu *file_options; + EditorNode *editor; String editing; + void _fill_owners(EditorFileSystemDirectory *efsd); + static void _bind_methods(); + void _list_rmb_select(int p_item, const Vector2 &p_pos); + void _select_file(int p_idx); + void _file_option(int p_option); + +private: + enum FileMenu { + FILE_OPEN + }; + public: void show(const String &p_path); - DependencyEditorOwners(); + DependencyEditorOwners(EditorNode *p_editor); }; class DependencyRemoveDialog : public ConfirmationDialog { diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index f7f823c945..1f9884aa70 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -951,7 +951,7 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri if (c.category == "") category = "Core"; header += " category=\"" + category + "\""; - header += String(" version=\"") + _MKSTR(VERSION_MAJOR) + "." + _MKSTR(VERSION_MINOR) + "-" + _MKSTR(VERSION_STATUS) + "\""; + header += String(" version=\"") + itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + "\""; header += ">"; _write_string(f, 0, header); _write_string(f, 1, "<brief_description>"); diff --git a/editor/doc/doc_dump.cpp b/editor/doc/doc_dump.cpp index 13dbb149d5..9dd05d9d0f 100644 --- a/editor/doc/doc_dump.cpp +++ b/editor/doc/doc_dump.cpp @@ -82,7 +82,7 @@ void DocDump::dump(const String &p_file) { FileAccess *f = FileAccess::open(p_file, FileAccess::WRITE); _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); - _write_string(f, 0, String("<doc version=\"") + _MKSTR(VERSION_MAJOR) + "." + _MKSTR(VERSION_MINOR) + "-" + _MKSTR(VERSION_STATUS) + "\" name=\"Engine Types\">"); + _write_string(f, 0, String("<doc version=\"") + itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + "\" name=\"Engine Types\">"); while (class_list.size()) { @@ -182,7 +182,7 @@ void DocDump::dump(const String &p_file) { case Variant::VECTOR3: case Variant::PLANE: case Variant::QUAT: - case Variant::RECT3: + case Variant::AABB: case Variant::BASIS: case Variant::COLOR: case Variant::POOL_BYTE_ARRAY: diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index 2cb5340b8b..443004f820 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -913,8 +913,8 @@ void EditorSelection::update() { if (!changed) return; - emit_signal("selection_changed"); changed = false; + emit_signal("selection_changed"); } List<Node *> &EditorSelection::get_selected_node_list() { diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index a458a10cd2..519bc33d42 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -336,33 +336,18 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat String EditorExportPlatform::find_export_template(String template_file_name, String *err) const { - String base_name = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + _MKSTR(VERSION_STATUS) + "/" + template_file_name; - String user_file = EditorSettings::get_singleton()->get_settings_path() + "/templates/" + base_name; - String system_file = OS::get_singleton()->get_installed_templates_path(); - bool has_system_path = (system_file != ""); - system_file = system_file.plus_file(base_name); - - // Prefer user file - if (FileAccess::exists(user_file)) { - return user_file; - } + String current_version = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + VERSION_MODULE_CONFIG; + String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version).plus_file(template_file_name); - // Now check system file - if (has_system_path) { - if (FileAccess::exists(system_file)) { - return system_file; - } + if (FileAccess::exists(template_path)) { + return template_path; } // Not found if (err) { - *err += "No export template found at \"" + user_file + "\""; - if (has_system_path) - *err += "\n or \"" + system_file + "\"."; - else - *err += "."; + *err += "No export template found at \"" + template_path + "\"."; } - return String(); // not found + return String(); } bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const { @@ -692,7 +677,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> & } String config_file = "project.binary"; - String engine_cfb = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp" + config_file; + String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file); ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list); Vector<uint8_t> data = FileAccess::get_file_as_array(engine_cfb); @@ -705,7 +690,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c EditorProgress ep("savepack", TTR("Packing"), 102); - String tmppath = EditorSettings::get_singleton()->get_settings_path() + "/tmp/packtmp"; + String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp"); FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE); ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 9db3bcba00..8d5bad3346 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -188,7 +188,7 @@ void EditorFileSystem::_scan_filesystem() { String project = ProjectSettings::get_singleton()->get_resource_path(); - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3"); FileAccess *f = FileAccess::open(fscache, FileAccess::READ); if (f) { @@ -238,7 +238,7 @@ void EditorFileSystem::_scan_filesystem() { memdelete(f); } - String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3"); + String update_cache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update3"); if (FileAccess::exists(update_cache)) { { @@ -282,7 +282,7 @@ void EditorFileSystem::_scan_filesystem() { } void EditorFileSystem::_save_filesystem_cache() { - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_cache3"); FileAccess *f = FileAccess::open(fscache, FileAccess::WRITE); _save_filesystem_cache(filesystem, f); @@ -1180,7 +1180,7 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p void EditorFileSystem::_save_late_updated_files() { //files that already existed, and were modified, need re-scanning for dependencies upon project restart. This is done via saving this special file - String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3"); + String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file("filesystem_update3"); FileAccessRef f = FileAccess::open(fscache, FileAccess::WRITE); for (Set<String>::Element *E = late_update_files.front(); E; E = E->next()) { f->store_line(E->get()); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e8b341c97f..109f132d76 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -141,13 +141,33 @@ void EditorNode::_update_scene_tabs() { } scene_tabs->set_current_tab(editor_data.get_edited_scene()); - scene_tabs->ensure_tab_visible(editor_data.get_edited_scene()); + + int current = editor_data.get_edited_scene(); + if (scene_tabs->get_offset_buttons_visible()) { + // move add button to fixed position on the tabbar + if (scene_tab_add->get_parent() == scene_tabs) { + scene_tab_add->set_position(Point2(0, 0)); + scene_tabs->remove_child(scene_tab_add); + tabbar_container->add_child(scene_tab_add); + tabbar_container->move_child(scene_tab_add, 1); + } + } else { + // move add button to after last tab + if (scene_tab_add->get_parent() == tabbar_container) { + tabbar_container->remove_child(scene_tab_add); + scene_tabs->add_child(scene_tab_add); + } + Rect2 last_tab = Rect2(); + if (scene_tabs->get_tab_count() != 0) + last_tab = scene_tabs->get_tab_rect(scene_tabs->get_tab_count() - 1); + scene_tab_add->set_position(Point2(last_tab.get_position().x + last_tab.get_size().x + 3, last_tab.get_position().y)); + } } void EditorNode::_update_title() { String appname = ProjectSettings::get_singleton()->get("application/config/name"); - String title = appname.empty() ? String(VERSION_FULL_NAME) : String(_MKSTR(VERSION_NAME) + String(" - ") + appname); + String title = appname.empty() ? String(VERSION_FULL_NAME) : String(VERSION_NAME + String(" - ") + appname); String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String(); if (!edited.empty()) title += " - " + String(edited.get_file()); @@ -326,6 +346,7 @@ void EditorNode::_notification(int p_what) { prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons")); distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons")); + scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons")); resource_new_button->set_icon(gui_base->get_icon("New", "EditorIcons")); resource_load_button->set_icon(gui_base->get_icon("Load", "EditorIcons")); @@ -343,6 +364,9 @@ void EditorNode::_notification(int p_what) { dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons")); } + if (p_what = Control::NOTIFICATION_RESIZED) { + _update_scene_tabs(); + } } void EditorNode::_fs_changed() { @@ -378,7 +402,15 @@ void EditorNode::_fs_changed() { // ensures export_project does not loop infinitely, because notifications may // come during the export export_defer.preset = ""; - platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0); + if (!preset->is_runnable() && (export_defer.path.ends_with(".pck") || export_defer.path.ends_with(".zip"))) { + if (export_defer.path.ends_with(".zip")) { + platform->save_zip(preset, export_defer.path); + } else if (export_defer.path.ends_with(".pck")) { + platform->save_pack(preset, export_defer.path); + } + } else { + platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0); + } } } @@ -704,7 +736,7 @@ void EditorNode::_get_scene_metadata(const String &p_file) { if (!scene) return; - String path = EditorSettings::get_singleton()->get_project_settings_path().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); + String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); Ref<ConfigFile> cf; cf.instance(); @@ -738,7 +770,7 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) { scene->set_meta("__editor_run_settings__", Variant()); //clear it (no point in keeping it) scene->set_meta("__editor_plugin_states__", Variant()); - String path = EditorSettings::get_singleton()->get_project_settings_path().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); + String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg"); Ref<ConfigFile> cf; cf.instance(); @@ -905,27 +937,33 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) { int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size"); preview_size *= EDSCALE; - int width, height; - if (img->get_width() > preview_size && img->get_width() >= img->get_height()) { - width = preview_size; - height = img->get_height() * preview_size / img->get_width(); - } else if (img->get_height() > preview_size && img->get_height() >= img->get_width()) { + // consider a square region + int vp_size = MIN(img->get_width(), img->get_height()); + int x = (img->get_width() - vp_size) / 2; + int y = (img->get_height() - vp_size) / 2; - height = preview_size; - width = img->get_width() * preview_size / img->get_height(); + img->convert(Image::FORMAT_RGB8); + + if (vp_size < preview_size) { + // just square it. + img->crop_from_point(x, y, vp_size, vp_size); } else { + int ratio = vp_size / preview_size; + int size = preview_size * (ratio / 2); + + x = (img->get_width() - size) / 2; + y = (img->get_height() - size) / 2; - width = img->get_width(); - height = img->get_height(); + img->crop_from_point(x, y, size, size); + // We could get better pictures with better filters + img->resize(preview_size, preview_size, Image::INTERPOLATE_CUBIC); } - img->convert(Image::FORMAT_RGB8); - img->resize(width, height); img->flip_y(); //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5 - String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp"); + String temp_path = EditorSettings::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); @@ -1108,7 +1146,7 @@ void EditorNode::_dialog_action(String p_file) { _save_default_environment(); _save_scene_with_preview(p_file); - _run(false); + _run(false, p_file); } } break; @@ -1197,7 +1235,7 @@ void EditorNode::_dialog_action(String p_file) { Ref<ConfigFile> config; config.instance(); - Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts-3.cfg")); + Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); if (err == ERR_CANT_OPEN) { config.instance(); // new config @@ -1208,7 +1246,7 @@ void EditorNode::_dialog_action(String p_file) { _save_docks_to_config(config, p_file); - config->save(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts-3.cfg")); + config->save(EditorSettings::get_singleton()->get_editor_layouts_config()); layout_dialog->hide(); _update_layouts_menu(); @@ -1225,7 +1263,7 @@ void EditorNode::_dialog_action(String p_file) { Ref<ConfigFile> config; config.instance(); - Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts-3.cfg")); + Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); if (err != OK || !config->has_section(p_file)) { show_warning(TTR("Layout name not found!")); @@ -1239,7 +1277,7 @@ void EditorNode::_dialog_action(String p_file) { config->set_value(p_file, E->get(), Variant()); } - config->save(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts-3.cfg")); + config->save(EditorSettings::get_singleton()->get_editor_layouts_config()); layout_dialog->hide(); _update_layouts_menu(); @@ -1770,6 +1808,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { int idx = editor_data.add_edited_scene(-1); _scene_tab_changed(idx); editor_data.clear_editor_states(); + _update_scene_tabs(); } break; case FILE_NEW_INHERITED_SCENE: @@ -3284,7 +3323,7 @@ void EditorNode::register_editor_types() { ClassDB::register_class<EditorResourceConversionPlugin>(); // FIXME: Is this stuff obsolete, or should it be ported to new APIs? - //ClassDB::register_class<EditorScenePostImport>(); + ClassDB::register_class<EditorScenePostImport>(); //ClassDB::register_type<EditorImportExport>(); } @@ -3592,7 +3631,7 @@ void EditorNode::_save_docks() { _save_docks_to_config(config, "docks"); editor_data.get_plugin_window_layout(config); - config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg")); + config->save(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); } void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) { @@ -3654,7 +3693,7 @@ void EditorNode::_load_docks() { Ref<ConfigFile> config; config.instance(); - Error err = config->load(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg")); + Error err = config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg")); if (err != OK) { //no config if (overridden_default_layout >= 0) { @@ -3823,7 +3862,7 @@ void EditorNode::_update_layouts_menu() { Ref<ConfigFile> config; config.instance(); - Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts-3.cfg")); + Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); if (err != OK) { return; //no config } @@ -3871,7 +3910,7 @@ void EditorNode::_layout_menu_option(int p_id) { Ref<ConfigFile> config; config.instance(); - Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts-3.cfg")); + Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config()); if (err != OK) { return; //no config } @@ -3908,6 +3947,7 @@ void EditorNode::_scene_tab_closed(int p_tab) { } else { _discard_changes(); } + _update_scene_tabs(); } void EditorNode::_scene_tab_hover(int p_tab) { @@ -4287,12 +4327,19 @@ Variant EditorNode::drag_files_and_dirs(const Vector<String> &p_paths, Control * void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) { - /* - String cur_path = filesystem_dock->get_current_path(); - for(int i=0;i<EditorImportExport::get_singleton()->get_import_plugin_count();i++) { - EditorImportExport::get_singleton()->get_import_plugin(i)->import_from_drop(p_files,cur_path); + String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_current_path()); + DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + for (int i = 0; i < p_files.size(); i++) { + + String from = p_files[i]; + if (!ResourceFormatImporter::get_singleton()->can_be_imported(from)) { + continue; + } + String to = to_path.plus_file(from.get_file()); + dir->copy(from, to); } - */ + EditorFileSystem::get_singleton()->scan_changes(); } void EditorNode::_file_access_close_error_notify(const String &p_str) { @@ -4563,6 +4610,11 @@ static Node *_resource_get_edited_scene() { return EditorNode::get_singleton()->get_edited_scene(); } +void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_error) { + EditorNode *en = (EditorNode *)p_this; + en->log->add_message(p_string, p_error); +} + EditorNode::EditorNode() { Resource::_get_local_scene_func = _resource_get_edited_scene; @@ -4799,7 +4851,12 @@ EditorNode::EditorNode() { dock_tab_move_left->set_focus_mode(Control::FOCUS_NONE); dock_tab_move_left->connect("pressed", this, "_dock_move_left"); dock_hb->add_child(dock_tab_move_left); - dock_hb->add_spacer(); + + Label *dock_label = memnew(Label); + dock_label->set_text(TTR("Dock Position")); + dock_label->set_h_size_flags(Control::SIZE_EXPAND_FILL); + dock_hb->add_child(dock_label); + dock_tab_move_right = memnew(ToolButton); dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); dock_tab_move_right->set_focus_mode(Control::FOCUS_NONE); @@ -4869,20 +4926,28 @@ EditorNode::EditorNode() { scene_tabs->connect("mouse_exited", this, "_scene_tab_exit"); scene_tabs->connect("gui_input", this, "_scene_tab_input"); scene_tabs->connect("reposition_active_tab_request", this, "_reposition_active_tab"); + scene_tabs->connect("resized", this, "_update_scene_tabs"); - HBoxContainer *tabbar_container = memnew(HBoxContainer); + tabbar_container = memnew(HBoxContainer); scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL); srt->add_child(tabbar_container); tabbar_container->add_child(scene_tabs); distraction_free = memnew(ToolButton); - tabbar_container->add_child(distraction_free); distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11)); distraction_free->set_tooltip(TTR("Toggle distraction-free mode.")); distraction_free->connect("pressed", this, "_toggle_distraction_free_mode"); distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons")); distraction_free->set_toggle_mode(true); + scene_tab_add = memnew(ToolButton); + tabbar_container->add_child(scene_tab_add); + tabbar_container->add_child(distraction_free); + scene_tab_add->set_tooltip(TTR("Add a new scene.")); + scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons")); + scene_tab_add->add_color_override("icon_color_normal", Color(0.6f, 0.6f, 0.6f, 0.8f)); + scene_tab_add->connect("pressed", this, "_menu_option", make_binds(FILE_NEW_SCENE)); + scene_root_parent = memnew(PanelContainer); scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE); scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); @@ -5663,6 +5728,10 @@ EditorNode::EditorNode() { _dim_timer->connect("timeout", this, "_dim_timeout"); add_child(_dim_timer); + print_handler.printfunc = _print_handler; + print_handler.userdata = this; + add_print_handler(&print_handler); + ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F1); ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F2); ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F3); //hack neded for script editor F3 search to work :) Assign like this or don't use F3 @@ -5674,6 +5743,7 @@ EditorNode::EditorNode() { EditorNode::~EditorNode() { + remove_print_handler(&print_handler); memdelete(EditorHelp::get_doc_data()); memdelete(editor_selection); memdelete(editor_plugins_over); diff --git a/editor/editor_node.h b/editor/editor_node.h index 81ff886228..a2b4a0a049 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -30,6 +30,7 @@ #ifndef EDITOR_NODE_H #define EDITOR_NODE_H +#include "core/print_string.h" #include "editor/connections_dialog.h" #include "editor/create_dialog.h" #include "editor/editor_about.h" @@ -343,7 +344,10 @@ private: int dock_popup_selected; Timer *dock_drag_timer; bool docks_visible; + + HBoxContainer *tabbar_container; ToolButton *distraction_free; + ToolButton *scene_tab_add; bool scene_distraction; bool script_distraction; @@ -610,6 +614,9 @@ private: Vector<Ref<EditorResourceConversionPlugin> > resource_conversion_plugins; + PrintHandlerList print_handler; + static void _print_handler(void *p_this, const String &p_string, bool p_error); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 0bd677ca1b..38e8b301b7 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -102,14 +102,14 @@ Vector<Ref<Texture> > EditorInterface::make_mesh_previews(const Vector<Ref<Mesh> textures.push_back(Ref<Texture>()); continue; } - Rect3 aabb = mesh->get_aabb(); + AABB aabb = mesh->get_aabb(); print_line("aabb: " + aabb); Vector3 ofs = aabb.position + aabb.size * 0.5; aabb.position -= ofs; Transform xform; xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.25); xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.25) * xform.basis; - Rect3 rot_aabb = xform.xform(aabb); + AABB rot_aabb = xform.xform(aabb); print_line("rot_aabb: " + rot_aabb); float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5; if (m == 0) { @@ -455,7 +455,11 @@ void EditorPlugin::make_visible(bool p_visible) { void EditorPlugin::edit(Object *p_object) { if (get_script_instance() && get_script_instance()->has_method("edit")) { - get_script_instance()->call("edit", p_object); + if (p_object->is_class("Resource")) { + get_script_instance()->call("edit", Ref<Resource>(Object::cast_to<Resource>(p_object))); + } else { + get_script_instance()->call("edit", p_object); + } } } diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index 5b4bdb59d3..467451cd2b 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -198,7 +198,7 @@ void EditorResourcePreview::_thread() { } else { - String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp"); + String temp_path = EditorSettings::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(item.path).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index bf4ef3ae39..9817ce0047 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -135,7 +135,7 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const { void EditorSettings::_initial_set(const StringName &p_name, const Variant &p_value) { set(p_name, p_value); props[p_name].initial = p_value; - props[p_name].initial_set = true; + props[p_name].has_default_value = true; } struct _EVCSort { @@ -221,7 +221,7 @@ bool EditorSettings::has_default_value(const String &p_setting) const { if (!props.has(p_setting)) return false; - return props[p_setting].initial_set; + return props[p_setting].has_default_value; } void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { @@ -334,6 +334,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("text_editor/line_numbers/show_line_numbers", true); _initial_set("text_editor/line_numbers/line_numbers_zero_padded", false); _initial_set("text_editor/line_numbers/show_breakpoint_gutter", true); + _initial_set("text_editor/line_numbers/code_folding", true); _initial_set("text_editor/line_numbers/show_line_length_guideline", false); _initial_set("text_editor/line_numbers/line_length_guideline_column", 80); hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 10"); @@ -423,6 +424,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.9)); _initial_set("editors/2d/keep_margins_when_changing_anchors", false); _initial_set("editors/2d/warped_mouse_panning", true); + _initial_set("editors/2d/simple_spacebar_panning", false); _initial_set("editors/2d/scroll_to_pan", false); _initial_set("editors/2d/pan_speed", 20); @@ -639,10 +641,14 @@ void EditorSettings::create() { return; //pointless DirAccess *dir = NULL; - Variant meta; + String data_path; + String data_dir; String config_path; String config_dir; + String cache_path; + String cache_dir; + Ref<ConfigFile> extra_config = memnew(ConfigFile); String exe_path = OS::get_singleton()->get_executable_path().get_base_dir(); @@ -659,38 +665,50 @@ void EditorSettings::create() { memdelete(d); if (self_contained) { - // editor is self contained + + // editor is self contained, all in same folder + data_path = exe_path; + data_dir = data_path.plus_file("editor_data"); config_path = exe_path; - config_dir = "editor_data"; + config_dir = data_dir; + cache_path = exe_path; + cache_dir = data_dir.plus_file("cache"); } else { - if (OS::get_singleton()->has_environment("APPDATA")) { - // Most likely under windows, save here - config_path = OS::get_singleton()->get_environment("APPDATA"); - config_dir = String(_MKSTR(VERSION_SHORT_NAME)).capitalize(); - } else if (OS::get_singleton()->has_environment("HOME")) { - - config_path = OS::get_singleton()->get_environment("HOME"); - config_dir = "." + String(_MKSTR(VERSION_SHORT_NAME)).to_lower(); + // Typically XDG_DATA_HOME or %APPDATA% + data_path = OS::get_singleton()->get_data_path(); + data_dir = data_path.plus_file(OS::get_singleton()->get_godot_dir_name()); + // Can be different from data_path e.g. on Linux or macOS + config_path = OS::get_singleton()->get_config_path(); + config_dir = config_path.plus_file(OS::get_singleton()->get_godot_dir_name()); + // Can be different from above paths, otherwise a subfolder of data_dir + cache_path = OS::get_singleton()->get_cache_path(); + if (cache_path == data_path) { + cache_dir = data_dir.plus_file("cache"); + } else { + cache_dir = cache_path.plus_file(OS::get_singleton()->get_godot_dir_name()); } - }; + } ClassDB::register_class<EditorSettings>(); //otherwise it can't be unserialized + String config_file_path; - if (config_path != "") { + if (data_path != "" && config_path != "" && cache_path != "") { + + // Validate/create data dir and subdirectories dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - if (dir->change_dir(config_path) != OK) { - ERR_PRINT("Cannot find path for config directory!"); + if (dir->change_dir(data_path) != OK) { + ERR_PRINT("Cannot find path for data directory!"); memdelete(dir); goto fail; } - if (dir->change_dir(config_dir) != OK) { - dir->make_dir(config_dir); - if (dir->change_dir(config_dir) != OK) { - ERR_PRINT("Cannot create config directory!"); + if (dir->change_dir(data_dir) != OK) { + dir->make_dir(data_dir); + if (dir->change_dir(data_dir) != OK) { + ERR_PRINT("Cannot create data directory!"); memdelete(dir); goto fail; } @@ -699,10 +717,43 @@ void EditorSettings::create() { if (dir->change_dir("templates") != OK) { dir->make_dir("templates"); } else { - dir->change_dir(".."); } + // Validate/create cache dir + + if (dir->change_dir(cache_path) != OK) { + ERR_PRINT("Cannot find path for cache directory!"); + memdelete(dir); + goto fail; + } + + if (dir->change_dir(cache_dir) != OK) { + dir->make_dir(cache_dir); + if (dir->change_dir(cache_dir) != OK) { + ERR_PRINT("Cannot create cache directory!"); + memdelete(dir); + goto fail; + } + } + + // Validate/create config dir and subdirectories + + if (dir->change_dir(config_path) != OK) { + ERR_PRINT("Cannot find path for config directory!"); + memdelete(dir); + goto fail; + } + + if (dir->change_dir(config_dir) != OK) { + dir->make_dir(config_dir); + if (dir->change_dir(config_dir) != OK) { + ERR_PRINT("Cannot create config directory!"); + memdelete(dir); + goto fail; + } + } + if (dir->change_dir("text_editor_themes") != OK) { dir->make_dir("text_editor_themes"); } else { @@ -714,52 +765,40 @@ void EditorSettings::create() { } else { dir->change_dir(".."); } - _create_script_templates(dir->get_current_dir() + "/script_templates"); - - if (dir->change_dir("tmp") != OK) { - dir->make_dir("tmp"); - } else { - - dir->change_dir(".."); - } + _create_script_templates(dir->get_current_dir().plus_file("script_templates")); - if (dir->change_dir("config") != OK) { - dir->make_dir("config"); + if (dir->change_dir("projects") != OK) { + dir->make_dir("projects"); } else { - dir->change_dir(".."); } - dir->change_dir("config"); + // Validate/create project-specific config dir - String pcp = ProjectSettings::get_singleton()->get_resource_path(); - if (pcp.ends_with("/")) - pcp = config_path.substr(0, pcp.size() - 1); - pcp = pcp.get_file() + "-" + pcp.md5_text(); + dir->change_dir("projects"); + String project_config_dir = ProjectSettings::get_singleton()->get_resource_path(); + if (project_config_dir.ends_with("/")) + project_config_dir = config_path.substr(0, project_config_dir.size() - 1); + project_config_dir = project_config_dir.get_file() + "-" + project_config_dir.md5_text(); - if (dir->change_dir(pcp)) { - dir->make_dir(pcp); + if (dir->change_dir(project_config_dir) != OK) { + dir->make_dir(project_config_dir); } else { dir->change_dir(".."); } - dir->change_dir(".."); - // path at least is validated, so validate config file - - String config_file_name = "editor_settings-" + String(_MKSTR(VERSION_MAJOR)) + ".tres"; - config_file_path = config_path + "/" + config_dir + "/" + config_file_name; - - String open_path = config_file_path; + // Validate editor config file + String config_file_name = "editor_settings-" + itos(VERSION_MAJOR) + ".tres"; + config_file_path = config_dir.plus_file(config_file_name); if (!dir->file_exists(config_file_name)) { - goto fail; } memdelete(dir); - singleton = ResourceLoader::load(open_path, "EditorSettings"); + singleton = ResourceLoader::load(config_file_path, "EditorSettings"); if (singleton.is_null()) { WARN_PRINT("Could not open config file."); @@ -768,8 +807,10 @@ void EditorSettings::create() { singleton->save_changed_setting = true; singleton->config_file_path = config_file_path; - singleton->project_config_path = pcp; - singleton->settings_path = config_path + "/" + config_dir; + singleton->project_config_dir = project_config_dir; + singleton->settings_dir = config_dir; + singleton->data_dir = data_dir; + singleton->cache_dir = cache_dir; if (OS::get_singleton()->is_stdout_verbose()) { @@ -799,7 +840,9 @@ fail: singleton = Ref<EditorSettings>(memnew(EditorSettings)); singleton->save_changed_setting = true; singleton->config_file_path = config_file_path; - singleton->settings_path = config_path + "/" + config_dir; + singleton->settings_dir = config_dir; + singleton->data_dir = data_dir; + singleton->cache_dir = cache_dir; singleton->_load_defaults(extra_config); singleton->setup_language(); singleton->setup_network(); @@ -922,9 +965,10 @@ void EditorSettings::raise_order(const String &p_setting) { void EditorSettings::set_initial_value(const StringName &p_setting, const Variant &p_value) { - ERR_FAIL_COND(!props.has(p_setting)); + if (!props.has(p_setting)) + return; props[p_setting].initial = p_value; - props[p_setting].initial_set = true; + props[p_setting].has_default_value = true; } Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default) { @@ -932,10 +976,10 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default) { Variant ret = p_default; if (EditorSettings::get_singleton()->has_setting(p_setting)) ret = EditorSettings::get_singleton()->get(p_setting); - if (!EditorSettings::get_singleton()->has_default_value(p_setting)) { - EditorSettings::get_singleton()->set_initial_value(p_setting, p_default); + else EditorSettings::get_singleton()->set(p_setting, p_default); - } + if (!EditorSettings::get_singleton()->has_default_value(p_setting)) + EditorSettings::get_singleton()->set_initial_value(p_setting, p_default); return ret; } @@ -969,21 +1013,52 @@ void EditorSettings::add_property_hint(const PropertyInfo &p_hint) { hints[p_hint.name] = p_hint; } -// Settings paths and saved metadata +// Data directories -String EditorSettings::get_settings_path() const { +String EditorSettings::get_data_dir() const { - return settings_path; + return data_dir; } -String EditorSettings::get_project_settings_path() const { +String EditorSettings::get_templates_dir() const { - return get_settings_path().plus_file("config").plus_file(project_config_path); + return get_data_dir().plus_file("templates"); } +// Config directories + +String EditorSettings::get_settings_dir() const { + + return settings_dir; +} + +String EditorSettings::get_project_settings_dir() const { + + return get_settings_dir().plus_file("projects").plus_file(project_config_dir); +} + +String EditorSettings::get_text_editor_themes_dir() const { + + return get_settings_dir().plus_file("text_editor_themes"); +} + +String EditorSettings::get_script_templates_dir() const { + + return get_settings_dir().plus_file("script_templates"); +} + +// Cache directory + +String EditorSettings::get_cache_dir() const { + + return cache_dir; +} + +// Metadata + void EditorSettings::set_project_metadata(const String &p_section, const String &p_key, Variant p_data) { Ref<ConfigFile> cf = memnew(ConfigFile); - String path = get_project_settings_path().plus_file("project_metadata.cfg"); + String path = get_project_settings_dir().plus_file("project_metadata.cfg"); cf->load(path); cf->set_value(p_section, p_key, p_data); cf->save(path); @@ -991,7 +1066,7 @@ void EditorSettings::set_project_metadata(const String &p_section, const String Variant EditorSettings::get_project_metadata(const String &p_section, const String &p_key, Variant p_default) { Ref<ConfigFile> cf = memnew(ConfigFile); - String path = get_project_settings_path().plus_file("project_metadata.cfg"); + String path = get_project_settings_dir().plus_file("project_metadata.cfg"); Error err = cf->load(path); if (err != OK) { return p_default; @@ -1002,7 +1077,7 @@ Variant EditorSettings::get_project_metadata(const String &p_section, const Stri void EditorSettings::set_favorite_dirs(const Vector<String> &p_favorites_dirs) { favorite_dirs = p_favorites_dirs; - FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("favorite_dirs"), FileAccess::WRITE); + FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorite_dirs"), FileAccess::WRITE); if (f) { for (int i = 0; i < favorite_dirs.size(); i++) f->store_line(favorite_dirs[i]); @@ -1018,7 +1093,7 @@ Vector<String> EditorSettings::get_favorite_dirs() const { void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) { recent_dirs = p_recent_dirs; - FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("recent_dirs"), FileAccess::WRITE); + FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::WRITE); if (f) { for (int i = 0; i < recent_dirs.size(); i++) f->store_line(recent_dirs[i]); @@ -1033,7 +1108,7 @@ Vector<String> EditorSettings::get_recent_dirs() const { void EditorSettings::load_favorites() { - FileAccess *f = FileAccess::open(get_project_settings_path().plus_file("favorite_dirs"), FileAccess::READ); + FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorite_dirs"), FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (line != "") { @@ -1043,7 +1118,7 @@ void EditorSettings::load_favorites() { memdelete(f); } - f = FileAccess::open(get_project_settings_path().plus_file("recent_dirs"), FileAccess::READ); + f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::READ); if (f) { String line = f->get_line().strip_edges(); while (line != "") { @@ -1056,7 +1131,7 @@ void EditorSettings::load_favorites() { void EditorSettings::list_text_editor_themes() { String themes = "Adaptive,Default"; - DirAccess *d = DirAccess::open(get_settings_path().plus_file("text_editor_themes")); + DirAccess *d = DirAccess::open(get_text_editor_themes_dir()); if (d) { d->list_dir_begin(); String file = d->get_next(); @@ -1078,7 +1153,7 @@ void EditorSettings::load_text_editor_theme() { return; } - String theme_path = get_settings_path().plus_file("text_editor_themes").plus_file((String)get("text_editor/theme/color_theme") + ".tet"); + String theme_path = get_text_editor_themes_dir().plus_file((String)get("text_editor/theme/color_theme") + ".tet"); Ref<ConfigFile> cf = memnew(ConfigFile); Error err = cf->load(theme_path); @@ -1116,9 +1191,9 @@ bool EditorSettings::import_text_editor_theme(String p_file) { return false; } - DirAccess *d = DirAccess::open(get_settings_path().plus_file("text_editor_themes")); + DirAccess *d = DirAccess::open(get_text_editor_themes_dir()); if (d) { - d->copy(p_file, get_settings_path().plus_file("text_editor_themes").plus_file(p_file.get_file())); + d->copy(p_file, get_text_editor_themes_dir().plus_file(p_file.get_file())); memdelete(d); return true; } @@ -1133,7 +1208,7 @@ bool EditorSettings::save_text_editor_theme() { if (p_file.get_file().to_lower() == "default" || p_file.get_file().to_lower() == "adaptive") { return false; } - String theme_path = get_settings_path().plus_file("text_editor_themes").plus_file(p_file + ".tet"); + String theme_path = get_text_editor_themes_dir().plus_file(p_file + ".tet"); return _save_text_editor_theme(theme_path); } @@ -1151,7 +1226,7 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) { list_text_editor_themes(); String theme_name = p_file.substr(0, p_file.length() - 4).get_file(); - if (p_file.get_base_dir() == get_settings_path().plus_file("text_editor_themes")) { + if (p_file.get_base_dir() == get_text_editor_themes_dir()) { _initial_set("text_editor/theme/color_theme", theme_name); load_text_editor_theme(); } @@ -1163,7 +1238,7 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) { Vector<String> EditorSettings::get_script_templates(const String &p_extension) { Vector<String> templates; - DirAccess *d = DirAccess::open(get_settings_path().plus_file("script_templates")); + DirAccess *d = DirAccess::open(get_script_templates_dir()); if (d) { d->list_dir_begin(); String file = d->get_next(); @@ -1179,6 +1254,11 @@ Vector<String> EditorSettings::get_script_templates(const String &p_extension) { return templates; } +String EditorSettings::get_editor_layouts_config() const { + + return get_settings_dir().plus_file("editor_layouts.cfg"); +} + // Shortcuts void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut) { @@ -1285,8 +1365,8 @@ void EditorSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &EditorSettings::property_get_revert); ClassDB::bind_method(D_METHOD("add_property_info", "info"), &EditorSettings::_add_property_info_bind); - ClassDB::bind_method(D_METHOD("get_settings_path"), &EditorSettings::get_settings_path); - ClassDB::bind_method(D_METHOD("get_project_settings_path"), &EditorSettings::get_project_settings_path); + ClassDB::bind_method(D_METHOD("get_settings_dir"), &EditorSettings::get_settings_dir); + ClassDB::bind_method(D_METHOD("get_project_settings_dir"), &EditorSettings::get_project_settings_dir); ClassDB::bind_method(D_METHOD("set_favorite_dirs", "dirs"), &EditorSettings::set_favorite_dirs); ClassDB::bind_method(D_METHOD("get_favorite_dirs"), &EditorSettings::get_favorite_dirs); diff --git a/editor/editor_settings.h b/editor/editor_settings.h index 29665369c4..a8c991a6d9 100644 --- a/editor/editor_settings.h +++ b/editor/editor_settings.h @@ -66,13 +66,13 @@ private: int order; Variant variant; Variant initial; - bool initial_set; + bool has_default_value; bool hide_from_editor; bool save; VariantContainer() { order = 0; hide_from_editor = false; - initial_set = false; + has_default_value = false; save = false; } VariantContainer(const Variant &p_variant, int p_order) { @@ -93,9 +93,11 @@ private: Map<String, Ref<ShortCut> > shortcuts; String resource_path; + String settings_dir; + String data_dir; + String cache_dir; String config_file_path; - String settings_path; - String project_config_path; + String project_config_dir; Vector<String> favorite_dirs; Vector<String> recent_dirs; @@ -147,8 +149,13 @@ public: void set_resource_clipboard(const Ref<Resource> &p_resource) { clipboard = p_resource; } Ref<Resource> get_resource_clipboard() const { return clipboard; } - String get_settings_path() const; - String get_project_settings_path() const; + String get_data_dir() const; + String get_templates_dir() const; + String get_settings_dir() const; + String get_project_settings_dir() const; + String get_text_editor_themes_dir() const; + String get_script_templates_dir() const; + String get_cache_dir() const; void set_project_metadata(const String &p_section, const String &p_key, Variant p_data); Variant get_project_metadata(const String &p_section, const String &p_key, Variant p_default); @@ -166,6 +173,7 @@ public: bool save_text_editor_theme_as(String p_file); Vector<String> get_script_templates(const String &p_extension); + String get_editor_layouts_config() const; void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut); bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 0f9f50095d..ae29b7420e 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -738,6 +738,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("button", "Tabs", style_menu); theme->set_icon("increment", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); theme->set_icon("decrement", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); + theme->set_icon("increment", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); + theme->set_icon("decrement", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); + theme->set_icon("increment_highlight", "Tabs", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); + theme->set_icon("decrement_highlight", "Tabs", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); + theme->set_icon("increment_highlight", "TabContainer", theme->get_icon("GuiScrollArrowRight", "EditorIcons")); + theme->set_icon("decrement_highlight", "TabContainer", theme->get_icon("GuiScrollArrowLeft", "EditorIcons")); + theme->set_constant("hseparation", "Tabs", 4 * EDSCALE); // Content of each tab Ref<StyleBoxFlat> style_content_panel = style_default->duplicate(); diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 8641fc7667..d208bbe662 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -35,6 +35,7 @@ #include "io/zip_io.h" #include "os/dir_access.h" #include "version.h" + void ExportTemplateManager::_update_template_list() { while (current_hb->get_child_count()) { @@ -46,7 +47,7 @@ void ExportTemplateManager::_update_template_list() { } DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - Error err = d->change_dir(EditorSettings::get_singleton()->get_settings_path().plus_file("templates")); + Error err = d->change_dir(EditorSettings::get_singleton()->get_templates_dir()); d->list_dir_begin(); Set<String> templates; @@ -66,7 +67,7 @@ void ExportTemplateManager::_update_template_list() { memdelete(d); - String current_version = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + _MKSTR(VERSION_STATUS) + VERSION_MODULE_CONFIG; + String current_version = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + VERSION_STATUS + VERSION_MODULE_CONFIG; Label *current = memnew(Label); current->set_h_size_flags(SIZE_EXPAND_FILL); @@ -142,7 +143,7 @@ void ExportTemplateManager::_uninstall_template(const String &p_version) { void ExportTemplateManager::_uninstall_template_confirm() { DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - Error err = d->change_dir(EditorSettings::get_singleton()->get_settings_path().plus_file("templates")); + Error err = d->change_dir(EditorSettings::get_singleton()->get_templates_dir()); ERR_FAIL_COND(err != OK); @@ -244,7 +245,7 @@ void ExportTemplateManager::_install_from_file(const String &p_file) { return; } - String template_path = EditorSettings::get_singleton()->get_settings_path().plus_file("templates").plus_file(version); + String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version); DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = d->make_dir_recursive(template_path); @@ -393,7 +394,7 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int if (p_code != 200) { template_list_state->set_text(TTR("Failed:") + " " + itos(p_code)); } else { - String path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_templates.tpz"); + String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_templates.tpz"); FileAccess *f = FileAccess::open(path, FileAccess::WRITE); if (!f) { template_list_state->set_text(TTR("Can't write file.")); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 533401b317..9c432323f4 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1447,6 +1447,15 @@ void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) { file_options->popup(); } +void FileSystemDock::_rmb_pressed(const Vector2 &p_pos) { + folder_options->clear(); + folder_options->set_size(Size2(1, 1)); + + folder_options->add_item(TTR("New Folder.."), FOLDER_NEW_FOLDER); + folder_options->set_position(files->get_global_position() + p_pos); + folder_options->popup(); +} + void FileSystemDock::select_file(const String &p_file) { navigate_to_path(p_file); @@ -1547,6 +1556,7 @@ void FileSystemDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_file_selected"), &FileSystemDock::_file_selected); ClassDB::bind_method(D_METHOD("_file_multi_selected"), &FileSystemDock::_file_multi_selected); ClassDB::bind_method(D_METHOD("_update_import_dock"), &FileSystemDock::_update_import_dock); + ClassDB::bind_method(D_METHOD("_rmb_pressed"), &FileSystemDock::_rmb_pressed); ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::POOL_STRING_ARRAY, "files"))); ADD_SIGNAL(MethodInfo("open")); @@ -1665,6 +1675,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { files->connect("item_rmb_selected", this, "_files_list_rmb_select"); files->connect("item_selected", this, "_file_selected"); files->connect("multi_selected", this, "_file_multi_selected"); + files->connect("rmb_clicked", this, "_rmb_pressed"); files->set_allow_rmb_select(true); file_list_vb->add_child(files); @@ -1683,7 +1694,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { deps_editor = memnew(DependencyEditor); add_child(deps_editor); - owners_editor = memnew(DependencyEditorOwners); + owners_editor = memnew(DependencyEditorOwners(editor)); add_child(owners_editor); remove_dialog = memnew(DependencyRemoveDialog); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index d100de8b72..f1fd342052 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -192,6 +192,7 @@ private: void _dir_rmb_pressed(const Vector2 &p_pos); void _files_list_rmb_select(int p_item, const Vector2 &p_pos); + void _rmb_pressed(const Vector2 &p_pos); struct FileInfo { String name; diff --git a/editor/icons/icon_GUI_ellipsis.svg b/editor/icons/icon_GUI_ellipsis.svg new file mode 100644 index 0000000000..5565fd2947 --- /dev/null +++ b/editor/icons/icon_GUI_ellipsis.svg @@ -0,0 +1,5 @@ +<svg width="14" height="8" version="1.1" viewBox="0 0 14 8" xmlns="http://www.w3.org/2000/svg"> +<g transform="translate(0 -1044.4)"> +<path transform="translate(0 1040.4)" d="m3.8594 4c-2.1381 0-3.8594 1.7213-3.8594 3.8594v0.28125c0 2.1381 1.7213 3.8594 3.8594 3.8594h6.2812c2.1381 0 3.8594-1.7213 3.8594-3.8594v-0.28125c0-2.1381-1.7213-3.8594-3.8594-3.8594zm-0.85938 3a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#fff" fill-opacity=".39216"/> +</g> +</svg> diff --git a/editor/icons/icon_animation.svg b/editor/icons/icon_animation.svg index 146403ece5..600faeeddb 100644 --- a/editor/icons/icon_animation.svg +++ b/editor/icons/icon_animation.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 4 -1.5352v1.5352h0.001953a2 2 0 0 0 0.26562 1 2 2 0 0 0 1.7324 1h1v-1-1h-0.5a0.5 0.49999 0 0 1 -0.5 -0.5v-0.5-5a6 6 0 0 0 -6 -6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm3.4414 2a1 1 0 0 1 0.88867 0.5 1 1 0 0 1 -0.36523 1.3652 1 1 0 0 1 -1.3672 -0.36523 1 1 0 0 1 0.36719 -1.3652 1 1 0 0 1 0.47656 -0.13477zm-6.9531 0.0019531a1 1 0 0 1 0.54688 0.13281 1 1 0 0 1 0.36719 1.3652 1 1 0 0 1 -1.3672 0.36523 1 1 0 0 1 -0.36523 -1.3652 1 1 0 0 1 0.81836 -0.49805zm0.023438 3.998a1 1 0 0 1 0.89062 0.5 1 1 0 0 1 -0.36719 1.3652 1 1 0 0 1 -1.3652 -0.36523 1 1 0 0 1 0.36523 -1.3652 1 1 0 0 1 0.47656 -0.13477zm6.9043 0.0019531a1 1 0 0 1 0.54883 0.13281 1 1 0 0 1 0.36523 1.3652 1 1 0 0 1 -1.3652 0.36523 1 1 0 0 1 -0.36719 -1.3652 1 1 0 0 1 0.81836 -0.49805zm-3.416 1.998a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#e0e0e0"/> -</g> +<path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 4 -1.5352v1.5352h0.001953a2 2 0 0 0 0.26562 1 2 2 0 0 0 1.7324 1h1v-1-1h-0.5a0.5 0.49999 0 0 1 -0.5 -0.5v-0.5-5a6 6 0 0 0 -6 -6zm0 1a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm3.4414 2a1 1 0 0 1 0.88867 0.5 1 1 0 0 1 -0.36523 1.3652 1 1 0 0 1 -1.3672 -0.36523 1 1 0 0 1 0.36719 -1.3652 1 1 0 0 1 0.47656 -0.13477zm-6.9531 0.0019531a1 1 0 0 1 0.54688 0.13281 1 1 0 0 1 0.36719 1.3652 1 1 0 0 1 -1.3672 0.36523 1 1 0 0 1 -0.36523 -1.3652 1 1 0 0 1 0.81836 -0.49805zm0.023438 3.998a1 1 0 0 1 0.89062 0.5 1 1 0 0 1 -0.36719 1.3652 1 1 0 0 1 -1.3652 -0.36523 1 1 0 0 1 0.36523 -1.3652 1 1 0 0 1 0.47656 -0.13477zm6.9043 0.0019531a1 1 0 0 1 0.54883 0.13281 1 1 0 0 1 0.36523 1.3652 1 1 0 0 1 -1.3652 0.36523 1 1 0 0 1 -0.36719 -1.3652 1 1 0 0 1 0.81836 -0.49805zm-3.416 1.998a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1z" fill="#e0e0e0"/> </svg> diff --git a/editor/icons/icon_area.svg b/editor/icons/icon_area.svg index ac673d10fc..5e1a385f58 100644 --- a/editor/icons/icon_area.svg +++ b/editor/icons/icon_area.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#fc9c9c"/> -</g> +<path d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#fc9c9c"/> </svg> diff --git a/editor/icons/icon_area_2d.svg b/editor/icons/icon_area_2d.svg index d6ecb6abe5..28fc4d7804 100644 --- a/editor/icons/icon_area_2d.svg +++ b/editor/icons/icon_area_2d.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#a5b7f3"/> -</g> +<path d="m1 1v2 2h2v-2h2v-2h-4zm10 0v2h2v2h2v-4h-4zm-7 3v2 4 2h8v-2-6h-8zm2 2h4v4h-4v-4zm-5 5v2 2h2 2v-2h-2v-2h-2zm12 0v2h-2v2h4v-2-2h-2z" fill="#a5b7f3"/> </svg> diff --git a/editor/icons/icon_array_mesh.svg b/editor/icons/icon_array_mesh.svg index 68890c4366..867fc95b0c 100644 --- a/editor/icons/icon_array_mesh.svg +++ b/editor/icons/icon_array_mesh.svg @@ -1,5 +1,3 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> -</g> +<path d="m3 1a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm10 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2zm-2 7v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2zm-8 3a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2 -2 2 2 0 0 0 -2 -2z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#ffd684" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </svg> diff --git a/editor/icons/icon_editor_handle_add.svg b/editor/icons/icon_editor_handle_add.svg deleted file mode 100644 index 0e7fe7129a..0000000000 --- a/editor/icons/icon_editor_handle_add.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg"> - <g transform="translate(0 -1044.4)"> - <ellipse cx="4" cy="1048.4" rx="4" ry="4" fill="#fff"/> - <ellipse cx="4" cy="1048.4" rx="2.8572" ry="2.8571" fill="#84ff84"/> - </g> -</svg> diff --git a/editor/icons/icon_editor_handle_selected.svg b/editor/icons/icon_editor_handle_selected.svg deleted file mode 100644 index 8d338c1fbd..0000000000 --- a/editor/icons/icon_editor_handle_selected.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg width="8" height="8" version="1.1" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg"> - <g transform="translate(0 -1044.4)"> - <ellipse cx="4" cy="1048.4" rx="4" ry="4" fill="#fff"/> - <ellipse cx="4" cy="1048.4" rx="2.8572" ry="2.8571" fill="#8484ff"/> - </g> -</svg> diff --git a/editor/icons/icon_h_button_array.svg b/editor/icons/icon_h_button_array.svg deleted file mode 100644 index 3f95dbbde1..0000000000 --- a/editor/icons/icon_h_button_array.svg +++ /dev/null @@ -1,5 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m4 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm8 4v2h-2v2h2v2h2v-2h2v-2h-2v-2h-2zm-8.5 4c-0.831 0-1.5 0.669-1.5 1.5v0.5 1h-1v2h8v-2h-1v-1-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z" fill="#a5efac"/> -</g> -</svg> diff --git a/editor/icons/icon_onion.svg b/editor/icons/icon_onion.svg new file mode 100644 index 0000000000..5bb2a99423 --- /dev/null +++ b/editor/icons/icon_onion.svg @@ -0,0 +1,3 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m8 1c-2 2-7 4-7 8s3 6 7 6c-7-3-6.5995-7.703 0-13-2.2981 3.9516-5.4951 8.9197 0 13 4.8692-4.2391 2.7733-8.1815 1-12 5.5855 4.704 5.3995 8.6488-1 12 4 0 7-2 7-6s-5-6-7-8z" fill="#e0e0e0"/> +</svg> diff --git a/editor/icons/icon_texture_button.svg b/editor/icons/icon_texture_button.svg index 17f87ab861..19f5e8d5c9 100644 --- a/editor/icons/icon_texture_button.svg +++ b/editor/icons/icon_texture_button.svg @@ -1,7 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<path transform="translate(0 1036.4)" d="m1 3v8h14v-8h-1-12-1zm8 2h1v1h1v2h1v2h-2-2-2-2v-1h1v-1h1v-1h2v-1h1v-1z" fill="#a5efac"/> -<rect transform="scale(1,-1)" x="1" y="-1049.4" width="14" height="2.0001" fill="#a5efac"/> -<rect transform="scale(1,-1)" x="1" y="-1049.4" width="14" height="2.0001" fill-opacity=".078431"/> +<path transform="translate(0 1036.4)" d="m8 1v2h6v10h-4v2h6v-14h-8zm-5 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm7 4v1h-1v1h-1v1h1v2h2 2v-2h-1v-2h-1v-1h-1zm-7.5 4c-0.831 0-1.5 0.669-1.5 1.5v0.5 1h-1v2h8v-2h-1v-1-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z" fill="#a5efac"/> </g> </svg> diff --git a/editor/icons/icon_texture_rect.svg b/editor/icons/icon_texture_rect.svg index 86d24ac223..2dbbe7f247 100644 --- a/editor/icons/icon_texture_rect.svg +++ b/editor/icons/icon_texture_rect.svg @@ -1,6 +1,5 @@ <svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> <g transform="translate(0 -1036.4)"> -<rect x="2" y="1038.4" width="12" height="12" fill="none" stroke="#a5efac" stroke-linecap="round" stroke-width="2"/> -<path d="m9 1042.4v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1h-1z" fill="#a5efac"/> +<path transform="translate(0 1036.4)" d="m1 1v14h14v-14h-14zm2 2h10v10h-10v-10zm6 3v1h-1v1h-2v1h-1v1h-1v1h2 2 2 2v-2h-1v-2h-1v-1h-1z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#a5efac" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/> </g> </svg> diff --git a/editor/icons/icon_v_button_array.svg b/editor/icons/icon_v_button_array.svg deleted file mode 100644 index ac7ce6064c..0000000000 --- a/editor/icons/icon_v_button_array.svg +++ /dev/null @@ -1,6 +0,0 @@ -<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> -<g transform="translate(0 -1036.4)" fill="#a5efac"> -<path transform="translate(0 1036.4)" d="m7 1v2.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-2.1328h-2zm-0.5 6c-0.831 0-1.5 0.669-1.5 1.5v0.5h-1v2h2v-2h4v2h2v-2h-1v-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z"/> -<path d="m7 1046.4v2h-2v2h2v2h2v-2h2v-2h-2v-2z"/> -</g> -</svg> diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 4541c77085..bd24aac99b 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -413,6 +413,7 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in for (List<Ref<Mesh> >::Element *E = meshes.front(); E; E = E->next()) { MeshInstance *mi = memnew(MeshInstance); + mi->set_mesh(E->get()); mi->set_name(E->get()->get_name()); scene->add_child(mi); mi->set_owner(scene); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index d8c3b8d3ed..63d4039295 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -302,7 +302,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Array // get mesh instance and bounding box MeshInstance *mi = Object::cast_to<MeshInstance>(p_node); - Rect3 aabb = mi->get_aabb(); + AABB aabb = mi->get_aabb(); // create a new rigid body collision node RigidBody *rigid_body = memnew(RigidBody); @@ -907,12 +907,11 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String String ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material"); if (p_keep_materials && FileAccess::exists(ext_name)) { //if exists, use it - Ref<Material> existing = ResourceLoader::load(ext_name); - p_materials[mat] = existing; + p_materials[mat] = ResourceLoader::load(ext_name); } else { ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat] = mat; + p_materials[mat] = ResourceLoader::load(ext_name); } } @@ -936,7 +935,8 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh"); ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH); - p_meshes[mesh] = mesh; + p_meshes[mesh] = ResourceLoader::load(ext_name); + p_node->set(E->get().name, p_meshes[mesh]); mesh_just_added = true; } } @@ -956,18 +956,24 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String ; if (FileAccess::exists(ext_name)) { //if exists, use it - Ref<Material> existing = ResourceLoader::load(ext_name); - p_materials[mat] = existing; + p_materials[mat] = ResourceLoader::load(ext_name); } else { ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH); - p_materials[mat] = mat; + p_materials[mat] = ResourceLoader::load(ext_name); } } if (p_materials[mat] != mat) { mesh->surface_set_material(i, p_materials[mat]); + + //re-save the mesh since a material is now assigned + if (p_make_meshes) { + String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh"); + ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH); + p_meshes[mesh] = ResourceLoader::load(ext_name); + } } } diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index d2e7feb6e1..b63352389e 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -47,9 +47,9 @@ void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, co for (int i = 0; i < 5; i++) { if (i < p_rating) - stars[i]->set_texture(get_icon("RatingStar", "EditorIcons")); + stars[i]->set_texture(get_icon("Favorites", "EditorIcons")); else - stars[i]->set_texture(get_icon("RatingNoStar", "EditorIcons")); + stars[i]->set_texture(get_icon("NonFavorite", "EditorIcons")); } } @@ -273,15 +273,15 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() { HBoxContainer *hbox = memnew(HBoxContainer); vbox->add_child(hbox); - vbox->add_constant_override("separation", 15); + vbox->add_constant_override("separation", 15 * EDSCALE); VBoxContainer *desc_vbox = memnew(VBoxContainer); hbox->add_child(desc_vbox); - hbox->add_constant_override("separation", 15); + hbox->add_constant_override("separation", 15 * EDSCALE); item = memnew(EditorAssetLibraryItem); desc_vbox->add_child(item); - desc_vbox->set_custom_minimum_size(Size2(300, 0)); + desc_vbox->set_custom_minimum_size(Size2(300 * EDSCALE, 0)); desc_bg = memnew(PanelContainer); desc_vbox->add_child(desc_bg); @@ -292,12 +292,12 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() { desc_bg->add_child(description); preview = memnew(TextureRect); - preview->set_custom_minimum_size(Size2(640, 345)); + preview->set_custom_minimum_size(Size2(640 * EDSCALE, 345 * EDSCALE)); hbox->add_child(preview); previews_bg = memnew(PanelContainer); vbox->add_child(previews_bg); - previews_bg->set_custom_minimum_size(Size2(0, 85)); + previews_bg->set_custom_minimum_size(Size2(0, 101 * EDSCALE)); previews = memnew(ScrollContainer); previews_bg->add_child(previews); @@ -445,7 +445,7 @@ void EditorAssetLibraryItemDownload::_install() { void EditorAssetLibraryItemDownload::_make_request() { download->cancel_request(); - download->set_download_file(EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); + download->set_download_file(EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_asset_" + itos(asset_id)) + ".zip"); Error err = download->request(host); if (err != OK) { @@ -680,7 +680,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt PoolByteArray image_data = p_data; if (use_cache) { - String cache_filename_base = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); + String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); FileAccess *file = FileAccess::open(cache_filename_base + ".data", FileAccess::READ); @@ -702,15 +702,28 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt Ref<Image> image = Ref<Image>(memnew(Image(r.ptr(), len))); if (!image->empty()) { - float max_height = 10000; switch (image_queue[p_queue_id].image_type) { - case IMAGE_QUEUE_ICON: max_height = 80; break; - case IMAGE_QUEUE_THUMBNAIL: max_height = 80; break; - case IMAGE_QUEUE_SCREENSHOT: max_height = 345; break; - } - float scale_ratio = max_height / image->get_height(); - if (scale_ratio < 1) { - image->resize(image->get_width() * scale_ratio, image->get_height() * scale_ratio, Image::INTERPOLATE_CUBIC); + case IMAGE_QUEUE_ICON: + + image->resize(80 * EDSCALE, 80 * EDSCALE, Image::INTERPOLATE_CUBIC); + + break; + case IMAGE_QUEUE_THUMBNAIL: { + float max_height = 85 * EDSCALE; + + float scale_ratio = max_height / (image->get_height() * EDSCALE); + if (scale_ratio < 1) { + image->resize(image->get_width() * EDSCALE * scale_ratio, image->get_height() * EDSCALE * scale_ratio, Image::INTERPOLATE_CUBIC); + } + } break; + case IMAGE_QUEUE_SCREENSHOT: { + float max_height = 397 * EDSCALE; + + float scale_ratio = max_height / (image->get_height() * EDSCALE); + if (scale_ratio < 1) { + image->resize(image->get_width() * EDSCALE * scale_ratio, image->get_height() * EDSCALE * scale_ratio, Image::INTERPOLATE_CUBIC); + } + } break; } Ref<ImageTexture> tex; @@ -738,7 +751,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons if (p_code != HTTPClient::RESPONSE_NOT_MODIFIED) { for (int i = 0; i < headers.size(); i++) { if (headers[i].findn("ETag:") == 0) { // Save etag - String cache_filename_base = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); + String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + image_queue[p_queue_id].image_url.md5_text()); String new_etag = headers[i].substr(headers[i].find(":") + 1, headers[i].length()).strip_edges(); FileAccess *file; @@ -786,7 +799,7 @@ void EditorAssetLibrary::_update_image_queue() { for (Map<int, ImageQueue>::Element *E = image_queue.front(); E; E = E->next()) { if (!E->get().active && current_images < max_images) { - String cache_filename_base = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp").plus_file("assetimage_" + E->get().image_url.md5_text()); + String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + E->get().image_url.md5_text()); Vector<String> headers; if (FileAccess::exists(cache_filename_base + ".etag") && FileAccess::exists(cache_filename_base + ".data")) { diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 38467369db..6cb4171f5a 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -176,9 +176,9 @@ void CanvasItemEditor::_edit_set_pivot(const Vector2 &mouse_pos) { for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { Node2D *n2d = Object::cast_to<Node2D>(E->get()); - if (n2d && n2d->edit_has_pivot()) { + if (n2d && n2d->_edit_use_pivot()) { - Vector2 offset = n2d->edit_get_pivot(); + Vector2 offset = n2d->_edit_get_pivot(); Vector2 gpos = n2d->get_global_position(); Vector2 local_mouse_pos = n2d->get_canvas_transform().affine_inverse().xform(mouse_pos); @@ -186,9 +186,9 @@ void CanvasItemEditor::_edit_set_pivot(const Vector2 &mouse_pos) { Vector2 motion_ofs = gpos - local_mouse_pos; undo_redo->add_do_method(n2d, "set_global_position", local_mouse_pos); - undo_redo->add_do_method(n2d, "edit_set_pivot", offset + n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs)); + undo_redo->add_do_method(n2d, "_edit_set_pivot", offset + n2d->get_global_transform().affine_inverse().basis_xform(motion_ofs)); undo_redo->add_undo_method(n2d, "set_global_position", gpos); - undo_redo->add_undo_method(n2d, "edit_set_pivot", offset); + undo_redo->add_undo_method(n2d, "_edit_set_pivot", offset); for (int i = 0; i < n2d->get_child_count(); i++) { Node2D *n2dc = Object::cast_to<Node2D>(n2d->get_child(i)); if (!n2dc) @@ -249,8 +249,8 @@ void CanvasItemEditor::_snap_other_nodes(Point2 p_value, Point2 &r_current_snap, Transform2D ci_transform = canvas_item->get_global_transform_with_canvas(); Transform2D to_snap_transform = p_to_snap ? p_to_snap->get_global_transform_with_canvas() : Transform2D(); if (fmod(ci_transform.get_rotation() - to_snap_transform.get_rotation(), (real_t)360.0) == 0.0) { - Point2 begin = ci_transform.xform(canvas_item->get_item_rect().get_position()); - Point2 end = ci_transform.xform(canvas_item->get_item_rect().get_position() + canvas_item->get_item_rect().get_size()); + Point2 begin = ci_transform.xform(canvas_item->_edit_get_rect().get_position()); + Point2 end = ci_transform.xform(canvas_item->_edit_get_rect().get_position() + canvas_item->_edit_get_rect().get_size()); _snap_if_closer_point(p_value, begin, r_current_snap, r_snapped, ci_transform.get_rotation()); _snap_if_closer_point(p_value, end, r_current_snap, r_snapped, ci_transform.get_rotation()); @@ -282,8 +282,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const end = p_canvas_item->get_global_transform_with_canvas().xform(_anchor_to_position(c, Point2(1, 1))); can_snap = true; } else if (const CanvasItem *parent_ci = Object::cast_to<CanvasItem>(p_canvas_item->get_parent())) { - begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->get_item_rect().get_position()); - end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->get_item_rect().get_position() + parent_ci->get_item_rect().get_size()); + begin = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position()); + end = p_canvas_item->get_transform().affine_inverse().xform(parent_ci->_edit_get_rect().get_position() + parent_ci->_edit_get_rect().get_size()); can_snap = true; } @@ -306,8 +306,8 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, const // Self sides (for anchors) if ((snap_active && snap_node_sides && (p_modes & SNAP_NODE_SIDES)) || (p_forced_modes & SNAP_NODE_SIDES)) { - begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position()); - end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->get_item_rect().get_position() + p_canvas_item->get_item_rect().get_size()); + begin = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position()); + end = p_canvas_item->get_global_transform_with_canvas().xform(p_canvas_item->_edit_get_rect().get_position() + p_canvas_item->_edit_get_rect().get_size()); _snap_if_closer_point(p_target, begin, output, snapped, rotation); _snap_if_closer_point(p_target, end, output, snapped, rotation); } @@ -629,7 +629,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !Object::cast_to<CanvasLayer>(c)) { - Rect2 rect = c->get_item_rect(); + Rect2 rect = c->_edit_get_rect(); Point2 local_pos = (p_parent_xform * p_canvas_xform * c->get_transform()).affine_inverse().xform(p_pos); if (rect.has_point(local_pos)) { @@ -675,7 +675,7 @@ void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_n if (c && c->is_visible_in_tree() && !c->has_meta("_edit_lock_") && !Object::cast_to<CanvasLayer>(c)) { - Rect2 rect = c->get_item_rect(); + Rect2 rect = c->_edit_get_rect(); Transform2D xform = p_parent_xform * p_canvas_xform * c->get_transform(); if (p_rect.has_point(xform.xform(rect.position)) && @@ -767,15 +767,15 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE if (p_snap) drag *= grid_step * Math::pow(2.0, grid_step_multiplier); - undo_redo->add_undo_method(canvas_item, "edit_set_state", canvas_item->edit_get_state()); + undo_redo->add_undo_method(canvas_item, "_edit_set_state", canvas_item->_edit_get_state()); if (p_move_mode == MOVE_VIEW_BASE) { // drag = transform.affine_inverse().basis_xform(p_dir); // zoom sensitive drag = canvas_item->get_global_transform_with_canvas().affine_inverse().basis_xform(drag); - Rect2 local_rect = canvas_item->get_item_rect(); + Rect2 local_rect = canvas_item->_edit_get_rect(); local_rect.position += drag; - undo_redo->add_do_method(canvas_item, "edit_set_rect", local_rect); + undo_redo->add_do_method(canvas_item, "_edit_set_rect", local_rect); } else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT @@ -816,7 +816,7 @@ Point2 CanvasItemEditor::_find_topleftmost_point() { if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) continue; - Rect2 rect = canvas_item->get_item_rect(); + Rect2 rect = canvas_item->_edit_get_rect(); Transform2D xform = canvas_item->get_global_transform_with_canvas(); r2.expand_to(xform.xform(rect.position)); @@ -877,7 +877,7 @@ CanvasItemEditor::DragType CanvasItemEditor::_get_resize_handle_drag_type(const ERR_FAIL_COND_V(!canvas_item, DRAG_NONE); - Rect2 rect = canvas_item->get_item_rect(); + Rect2 rect = canvas_item->_edit_get_rect(); Transform2D xforml = canvas_item->get_global_transform_with_canvas(); Transform2D xform = transform * xforml; @@ -1011,14 +1011,14 @@ void CanvasItemEditor::_prepare_drag(const Point2 &p_click_pos) { if (!se) continue; - se->undo_state = canvas_item->edit_get_state(); + se->undo_state = canvas_item->_edit_get_state(); if (Object::cast_to<Node2D>(canvas_item)) - se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot(); + se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->_edit_get_pivot(); if (Object::cast_to<Control>(canvas_item)) se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset(); se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); - se->pre_drag_rect = canvas_item->get_item_rect(); + se->pre_drag_rect = canvas_item->_edit_get_rect(); } if (selection.size() == 1 && Object::cast_to<Node2D>(selection[0]) && bone_ik_list.size() == 0) { @@ -1500,7 +1500,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { // Cancel a drag if (bone_ik_list.size()) { for (List<BoneIK>::Element *E = bone_ik_list.back(); E; E = E->prev()) { - E->get().node->edit_set_state(E->get().orig_state); + E->get().node->_edit_set_state(E->get().orig_state); } bone_ik_list.clear(); @@ -1519,9 +1519,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { if (!se) continue; - canvas_item->edit_set_state(se->undo_state); + canvas_item->_edit_set_state(se->undo_state); if (Object::cast_to<Node2D>(canvas_item)) - Object::cast_to<Node2D>(canvas_item)->edit_set_pivot(se->undo_pivot); + Object::cast_to<Node2D>(canvas_item)->_edit_set_pivot(se->undo_pivot); if (Object::cast_to<Control>(canvas_item)) Object::cast_to<Control>(canvas_item)->set_pivot_offset(se->undo_pivot); } @@ -1574,8 +1574,8 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { for (List<BoneIK>::Element *E = bone_ik_list.back(); E; E = E->prev()) { - undo_redo->add_do_method(E->get().node, "edit_set_state", E->get().node->edit_get_state()); - undo_redo->add_undo_method(E->get().node, "edit_set_state", E->get().orig_state); + undo_redo->add_do_method(E->get().node, "_edit_set_state", E->get().node->_edit_get_state()); + undo_redo->add_undo_method(E->get().node, "_edit_set_state", E->get().orig_state); } undo_redo->add_do_method(viewport, "update"); @@ -1601,14 +1601,14 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { if (!se) continue; - Variant state = canvas_item->edit_get_state(); - undo_redo->add_do_method(canvas_item, "edit_set_state", state); - undo_redo->add_undo_method(canvas_item, "edit_set_state", se->undo_state); + Variant state = canvas_item->_edit_get_state(); + undo_redo->add_do_method(canvas_item, "_edit_set_state", state); + undo_redo->add_undo_method(canvas_item, "_edit_set_state", se->undo_state); { Node2D *pvt = Object::cast_to<Node2D>(canvas_item); - if (pvt && pvt->edit_has_pivot()) { - undo_redo->add_do_method(canvas_item, "edit_set_pivot", pvt->edit_get_pivot()); - undo_redo->add_undo_method(canvas_item, "edit_set_pivot", se->undo_pivot); + if (pvt && pvt->_edit_use_pivot()) { + undo_redo->add_do_method(canvas_item, "_edit_set_pivot", pvt->_edit_get_pivot()); + undo_redo->add_undo_method(canvas_item, "_edit_set_pivot", se->undo_pivot); } Control *cnt = Object::cast_to<Control>(canvas_item); @@ -1709,7 +1709,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { BoneIK bik; bik.node = b; bik.len = len; - bik.orig_state = b->edit_get_state(); + bik.orig_state = b->_edit_get_state(); bone_ik_list.push_back(bik); @@ -1741,13 +1741,13 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { if ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) { drag = DRAG_ROTATE; drag_from = transform.affine_inverse().xform(click); - se->undo_state = canvas_item->edit_get_state(); + se->undo_state = canvas_item->_edit_get_state(); if (Object::cast_to<Node2D>(canvas_item)) - se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot(); + se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->_edit_get_pivot(); if (Object::cast_to<Control>(canvas_item)) se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset(); se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); - se->pre_drag_rect = canvas_item->get_item_rect(); + se->pre_drag_rect = canvas_item->_edit_get_rect(); return; } @@ -1764,13 +1764,13 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { drag = _get_resize_handle_drag_type(click, drag_point_from); if (drag != DRAG_NONE) { drag_from = transform.affine_inverse().xform(click); - se->undo_state = canvas_item->edit_get_state(); + se->undo_state = canvas_item->_edit_get_state(); if (Object::cast_to<Node2D>(canvas_item)) - se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->edit_get_pivot(); + se->undo_pivot = Object::cast_to<Node2D>(canvas_item)->_edit_get_pivot(); if (Object::cast_to<Control>(canvas_item)) se->undo_pivot = Object::cast_to<Control>(canvas_item)->get_pivot_offset(); se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); - se->pre_drag_rect = canvas_item->get_item_rect(); + se->pre_drag_rect = canvas_item->_edit_get_rect(); return; } @@ -1780,9 +1780,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { drag = _get_anchor_handle_drag_type(click, drag_point_from); if (drag != DRAG_NONE) { drag_from = transform.affine_inverse().xform(click); - se->undo_state = canvas_item->edit_get_state(); + se->undo_state = canvas_item->_edit_get_state(); se->pre_drag_xform = canvas_item->get_global_transform_with_canvas(); - se->pre_drag_rect = canvas_item->get_item_rect(); + se->pre_drag_rect = canvas_item->_edit_get_rect(); return; } } @@ -1858,7 +1858,17 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { } if (drag == DRAG_NONE) { - if (((m->get_button_mask() & BUTTON_MASK_LEFT) && tool == TOOL_PAN) || (m->get_button_mask() & BUTTON_MASK_MIDDLE) || ((m->get_button_mask() & BUTTON_MASK_LEFT) && Input::get_singleton()->is_key_pressed(KEY_SPACE))) { + bool space_pressed = Input::get_singleton()->is_key_pressed(KEY_SPACE); + bool simple_panning = EditorSettings::get_singleton()->get("editors/2d/simple_spacebar_panning"); + int button = m->get_button_mask(); + + // Check if any of the panning triggers are activated + bool panning_tool = (button & BUTTON_MASK_LEFT) && tool == TOOL_PAN; + bool panning_middle_button = button & BUTTON_MASK_MIDDLE; + bool panning_spacebar = (button & BUTTON_MASK_LEFT) && space_pressed; + bool panning_spacebar_simple = space_pressed && simple_panning; + + if (panning_tool || panning_middle_button || panning_spacebar || panning_spacebar_simple) { // Pan the viewport Point2i relative; if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { @@ -1890,9 +1900,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { bool dragging_bone = drag == DRAG_ALL && selection.size() == 1 && bone_ik_list.size(); if (!dragging_bone) { - canvas_item->edit_set_state(se->undo_state); //reset state and reapply + canvas_item->_edit_set_state(se->undo_state); //reset state and reapply if (Object::cast_to<Node2D>(canvas_item)) - Object::cast_to<Node2D>(canvas_item)->edit_set_pivot(se->undo_pivot); + Object::cast_to<Node2D>(canvas_item)->_edit_set_pivot(se->undo_pivot); if (Object::cast_to<Control>(canvas_item)) Object::cast_to<Control>(canvas_item)->set_pivot_offset(se->undo_pivot); } @@ -2003,10 +2013,10 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dto) - canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom); - Rect2 local_rect = canvas_item->get_item_rect(); + Rect2 local_rect = canvas_item->_edit_get_rect(); Vector2 begin = local_rect.position; Vector2 end = local_rect.position + local_rect.size; - Vector2 minsize = canvas_item->edit_get_minimum_size(); + Vector2 minsize = canvas_item->_edit_get_minimum_size(); if (uniform) { // Keep the height/width ratio of the item @@ -2084,7 +2094,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { if (Object::cast_to<Node2D>(canvas_item)) { Node2D *n2d = Object::cast_to<Node2D>(canvas_item); - n2d->edit_set_pivot(se->undo_pivot + drag_vector); + n2d->_edit_set_pivot(se->undo_pivot + drag_vector); } if (Object::cast_to<Control>(canvas_item)) { Object::cast_to<Control>(canvas_item)->set_pivot_offset(se->undo_pivot + drag_vector); @@ -2103,7 +2113,7 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { local_rect.position = begin; local_rect.size = end - begin; - canvas_item->edit_set_rect(local_rect); + canvas_item->_edit_set_rect(local_rect); } else { //ok, all that had to be done was done, now solve IK @@ -2454,7 +2464,7 @@ void CanvasItemEditor::_draw_selection() { if (!se) continue; - Rect2 rect = canvas_item->get_item_rect(); + Rect2 rect = canvas_item->_edit_get_rect(); if (show_helpers && drag != DRAG_NONE && drag != DRAG_PIVOT) { const Transform2D pre_drag_xform = transform * se->pre_drag_xform; @@ -2496,7 +2506,7 @@ void CanvasItemEditor::_draw_selection() { Node2D *node2d = Object::cast_to<Node2D>(canvas_item); if (node2d) { - if (node2d->edit_has_pivot()) { + if (node2d->_edit_use_pivot()) { viewport->draw_texture(pivot_icon, xform.get_origin() + (-pivot_icon->get_size() / 2).floor()); can_move_pivot = true; pivot_found = true; @@ -2868,7 +2878,7 @@ void CanvasItemEditor::_get_encompassing_rect(Node *p_node, Rect2 &r_rect, const CanvasItem *c = Object::cast_to<CanvasItem>(p_node); if (c && c->is_visible_in_tree()) { - Rect2 rect = c->get_item_rect(); + Rect2 rect = c->_edit_get_rect(); Transform2D xform = p_xform * c->get_transform(); r_rect.expand_to(xform.xform(rect.position)); r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0))); @@ -2963,7 +2973,7 @@ void CanvasItemEditor::_notification(int p_what) { if (!se) continue; - Rect2 r = canvas_item->get_item_rect(); + Rect2 r = canvas_item->_edit_get_rect(); Transform2D xform = canvas_item->get_transform(); if (r != se->prev_rect || xform != se->prev_xform) { @@ -3899,7 +3909,7 @@ void CanvasItemEditor::_focus_selection(int p_op) { //if (!canvas_item->is_visible_in_tree()) continue; ++count; - Rect2 item_rect = canvas_item->get_item_rect(); + Rect2 item_rect = canvas_item->_edit_get_rect(); Vector2 pos = canvas_item->get_global_transform().get_origin(); Vector2 scale = canvas_item->get_global_transform().get_scale(); diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp index 24c4813771..0818c8975e 100644 --- a/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_editor_plugin.cpp @@ -389,7 +389,7 @@ void CollisionPolygonEditor::_polygon_draw() { rect = rect.grow(1); - Rect3 r; + AABB r; r.position.x = rect.position.x; r.position.y = rect.position.y; r.position.z = depth; diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 5f73d0b465..ed04c90cc5 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -184,7 +184,7 @@ Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) { Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) { - String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp"); + String temp_path = EditorSettings::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text(); cache_base = temp_path.plus_file("resthumb-" + cache_base); @@ -790,13 +790,13 @@ Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) { VS::get_singleton()->instance_set_base(mesh_instance, mesh->get_rid()); - Rect3 aabb = mesh->get_aabb(); + AABB aabb = mesh->get_aabb(); Vector3 ofs = aabb.position + aabb.size * 0.5; aabb.position -= ofs; Transform xform; xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.125); xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.125) * xform.basis; - Rect3 rot_aabb = xform.xform(aabb); + AABB rot_aabb = xform.xform(aabb); float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5; if (m == 0) return Ref<Texture>(); diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp index 74618aecc2..60e8858b2d 100644 --- a/editor/plugins/mesh_editor_plugin.cpp +++ b/editor/plugins/mesh_editor_plugin.cpp @@ -95,7 +95,7 @@ void MeshEditor::edit(Ref<Mesh> p_mesh) { rot_y = 0; _update_rotation(); - Rect3 aabb = mesh->get_aabb(); + AABB aabb = mesh->get_aabb(); print_line("aabb: " + aabb); Vector3 ofs = aabb.position + aabb.size * 0.5; float m = aabb.get_longest_axis_size(); diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index 10834b74ff..f4a9960087 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -153,15 +153,15 @@ void ParticlesEditor::_generate_aabb() { EditorProgress ep("gen_aabb", TTR("Generating AABB"), int(time)); - Rect3 rect; + AABB rect; while (running < time) { uint64_t ticks = OS::get_singleton()->get_ticks_usec(); ep.step("Generating..", int(running), true); OS::get_singleton()->delay_usec(1000); - Rect3 capture = node->capture_aabb(); - if (rect == Rect3()) + AABB capture = node->capture_aabb(); + if (rect == AABB()) rect = capture; else rect.merge_with(capture); @@ -247,7 +247,7 @@ void ParticlesEditor::_generate_emission_points() { PoolVector<Face3>::Read r = geometry.read(); - Rect3 aabb; + AABB aabb; for (int i = 0; i < gcount; i++) { diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 607ccaa4e7..3c2d52c128 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -586,6 +586,32 @@ void ScriptEditor::_close_docs_tab() { } } +void ScriptEditor::_close_other_tabs() { + + int child_count = tab_container->get_child_count(); + int current_idx = tab_container->get_current_tab(); + for (int i = child_count - 1; i >= 0; i--) { + + if (i == current_idx) { + continue; + } + + tab_container->set_current_tab(i); + ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i)); + + if (se) { + + // Maybe there are unsaved changes + if (se->is_unsaved()) { + _ask_close_current_unsaved_tab(se); + continue; + } + } + + _close_current_tab(); + } +} + void ScriptEditor::_close_all_tabs() { int child_count = tab_container->get_child_count(); @@ -855,7 +881,7 @@ void ScriptEditor::_menu_option(int p_option) { file_dialog_option = FILE_SAVE_THEME_AS; file_dialog->clear_filters(); file_dialog->add_filter("*.tet"); - file_dialog->set_current_path(EditorSettings::get_singleton()->get_settings_path() + "/text_editor_themes/" + EditorSettings::get_singleton()->get("text_editor/theme/color_theme")); + file_dialog->set_current_path(EditorSettings::get_singleton()->get_text_editor_themes_dir().plus_file(EditorSettings::get_singleton()->get("text_editor/theme/color_theme"))); file_dialog->popup_centered_ratio(); file_dialog->set_title(TTR("Save Theme As..")); } break; @@ -1003,6 +1029,9 @@ void ScriptEditor::_menu_option(int p_option) { case CLOSE_DOCS: { _close_docs_tab(); } break; + case CLOSE_OTHER_TABS: { + _close_other_tabs(); + } break; case CLOSE_ALL: { _close_all_tabs(); } break; @@ -1078,6 +1107,9 @@ void ScriptEditor::_menu_option(int p_option) { case CLOSE_DOCS: { _close_docs_tab(); } break; + case CLOSE_OTHER_TABS: { + _close_other_tabs(); + } break; case CLOSE_ALL: { _close_all_tabs(); } break; @@ -1119,6 +1151,7 @@ void ScriptEditor::_notification(int p_what) { editor->connect("script_add_function_request", this, "_add_callback"); editor->connect("resource_saved", this, "_res_saved_callback"); script_list->connect("item_selected", this, "_script_selected"); + members_overview->connect("item_selected", this, "_members_overview_selected"); help_overview->connect("item_selected", this, "_help_overview_selected"); script_split->connect("dragged", this, "_script_split_dragged"); @@ -1583,7 +1616,7 @@ void ScriptEditor::_update_script_names() { } } - if (_sort_list_on_update) { + if (_sort_list_on_update && !sedata.empty()) { sedata.sort(); // change actual order of tab_container so that the order can be rearranged by user @@ -2139,6 +2172,8 @@ void ScriptEditor::_make_script_list_context_menu() { context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save"), FILE_SAVE); context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/save_as"), FILE_SAVE_AS); context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_file"), FILE_CLOSE); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_all"), CLOSE_ALL); + context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/close_other_tabs"), CLOSE_OTHER_TABS); context_menu->add_separator(); context_menu->add_shortcut(ED_GET_SHORTCUT("script_editor/reload_script_soft"), FILE_TOOL_RELOAD_SOFT); @@ -2458,6 +2493,7 @@ void ScriptEditor::_bind_methods() { ClassDB::bind_method("_close_discard_current_tab", &ScriptEditor::_close_discard_current_tab); ClassDB::bind_method("_close_docs_tab", &ScriptEditor::_close_docs_tab); ClassDB::bind_method("_close_all_tabs", &ScriptEditor::_close_all_tabs); + ClassDB::bind_method("_close_other_tabs", &ScriptEditor::_close_other_tabs); ClassDB::bind_method("_open_recent_script", &ScriptEditor::_open_recent_script); ClassDB::bind_method("_editor_play", &ScriptEditor::_editor_play); ClassDB::bind_method("_editor_pause", &ScriptEditor::_editor_pause); @@ -2539,7 +2575,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { script_list->set_v_size_flags(SIZE_EXPAND_FILL); script_split->set_split_offset(140); //list_split->set_split_offset(500); - _sort_list_on_update = true; script_list->connect("gui_input", this, "_script_list_gui_input"); script_list->set_allow_rmb_select(true); @@ -2604,6 +2639,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_docs", TTR("Close Docs")), CLOSE_DOCS); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_file", TTR("Close"), KEY_MASK_CMD | KEY_W), FILE_CLOSE); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_all", TTR("Close All")), CLOSE_ALL); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/close_other_tabs", TTR("Close Other Tabs")), CLOSE_OTHER_TABS); file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/run_file", TTR("Run"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_X), FILE_RUN); file_menu->get_popup()->add_separator(); @@ -2861,7 +2897,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) { EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true); EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true); EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15); - EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5)); + EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.3)); EDITOR_DEF("text_editor/open_scripts/group_help_pages", true); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path")); EDITOR_DEF("text_editor/open_scripts/sort_scripts_by", 0); diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h index b8317f9e86..77ca4bc9d9 100644 --- a/editor/plugins/script_editor_plugin.h +++ b/editor/plugins/script_editor_plugin.h @@ -135,6 +135,7 @@ class ScriptEditor : public PanelContainer { FILE_CLOSE, CLOSE_DOCS, CLOSE_ALL, + CLOSE_OTHER_TABS, TOGGLE_SCRIPTS_PANEL, FILE_TOOL_RELOAD, FILE_TOOL_RELOAD_SOFT, @@ -251,6 +252,7 @@ class ScriptEditor : public PanelContainer { void _close_current_tab(); void _close_discard_current_tab(const String &p_str); void _close_docs_tab(); + void _close_other_tabs(); void _close_all_tabs(); void _ask_close_current_unsaved_tab(ScriptEditorBase *current); diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 6b945157e8..214f24b386 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -201,7 +201,7 @@ void ScriptTextEditor::_set_theme_for_script() { text_edit->add_keyword_color("Rect2", basetype_color); text_edit->add_keyword_color("Transform2D", basetype_color); text_edit->add_keyword_color("Vector3", basetype_color); - text_edit->add_keyword_color("Rect3", basetype_color); + text_edit->add_keyword_color("AABB", basetype_color); text_edit->add_keyword_color("Basis", basetype_color); text_edit->add_keyword_color("Plane", basetype_color); text_edit->add_keyword_color("Transform", basetype_color); @@ -518,7 +518,9 @@ void ScriptTextEditor::tag_saved_version() { } void ScriptTextEditor::goto_line(int p_line, bool p_with_error) { - code_editor->get_text_edit()->call_deferred("cursor_set_line", p_line); + TextEdit *tx = code_editor->get_text_edit(); + tx->unfold_line(p_line); + tx->call_deferred("cursor_set_line", p_line); } void ScriptTextEditor::ensure_focus() { @@ -712,15 +714,6 @@ void ScriptTextEditor::_breakpoint_toggled(int p_row) { ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row)); } -static void swap_lines(TextEdit *tx, int line1, int line2) { - String tmp = tx->get_line(line1); - String tmp2 = tx->get_line(line2); - tx->set_line(line2, tmp); - tx->set_line(line1, tmp2); - - tx->cursor_set_line(line2); -} - void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) { Node *base = get_tree()->get_edited_scene_root(); @@ -799,39 +792,41 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c void ScriptTextEditor::_edit_option(int p_op) { + TextEdit *tx = code_editor->get_text_edit(); + switch (p_op) { case EDIT_UNDO: { - code_editor->get_text_edit()->undo(); - code_editor->get_text_edit()->call_deferred("grab_focus"); + + tx->undo(); + tx->call_deferred("grab_focus"); } break; case EDIT_REDO: { - code_editor->get_text_edit()->redo(); - code_editor->get_text_edit()->call_deferred("grab_focus"); + + tx->redo(); + tx->call_deferred("grab_focus"); } break; case EDIT_CUT: { - code_editor->get_text_edit()->cut(); - code_editor->get_text_edit()->call_deferred("grab_focus"); + tx->cut(); + tx->call_deferred("grab_focus"); } break; case EDIT_COPY: { - code_editor->get_text_edit()->copy(); - code_editor->get_text_edit()->call_deferred("grab_focus"); + tx->copy(); + tx->call_deferred("grab_focus"); } break; case EDIT_PASTE: { - code_editor->get_text_edit()->paste(); - code_editor->get_text_edit()->call_deferred("grab_focus"); + tx->paste(); + tx->call_deferred("grab_focus"); } break; case EDIT_SELECT_ALL: { - code_editor->get_text_edit()->select_all(); - code_editor->get_text_edit()->call_deferred("grab_focus"); - + tx->select_all(); + tx->call_deferred("grab_focus"); } break; case EDIT_MOVE_LINE_UP: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = script; if (scr.is_null()) return; @@ -850,6 +845,9 @@ void ScriptTextEditor::_edit_option(int p_op) { if (line_id == 0 || next_id < 0) return; + tx->unfold_line(line_id); + tx->unfold_line(next_id); + tx->swap_lines(line_id, next_id); tx->cursor_set_line(next_id); } @@ -863,16 +861,17 @@ void ScriptTextEditor::_edit_option(int p_op) { if (line_id == 0 || next_id < 0) return; + tx->unfold_line(line_id); + tx->unfold_line(next_id); + tx->swap_lines(line_id, next_id); tx->cursor_set_line(next_id); } tx->end_complex_operation(); tx->update(); - } break; case EDIT_MOVE_LINE_DOWN: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; @@ -891,6 +890,9 @@ void ScriptTextEditor::_edit_option(int p_op) { if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count()) return; + tx->unfold_line(line_id); + tx->unfold_line(next_id); + tx->swap_lines(line_id, next_id); tx->cursor_set_line(next_id); } @@ -904,6 +906,9 @@ void ScriptTextEditor::_edit_option(int p_op) { if (line_id == tx->get_line_count() - 1 || next_id > tx->get_line_count()) return; + tx->unfold_line(line_id); + tx->unfold_line(next_id); + tx->swap_lines(line_id, next_id); tx->cursor_set_line(next_id); } @@ -913,7 +918,6 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case EDIT_INDENT_LEFT: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; @@ -938,11 +942,9 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->end_complex_operation(); tx->update(); //tx->deselect(); - } break; case EDIT_INDENT_RIGHT: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; @@ -959,11 +961,9 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->end_complex_operation(); tx->update(); //tx->deselect(); - } break; case EDIT_DELETE_LINE: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; @@ -972,13 +972,12 @@ void ScriptTextEditor::_edit_option(int p_op) { int line = tx->cursor_get_line(); tx->set_line(tx->cursor_get_line(), ""); tx->backspace_at_cursor(); + tx->unfold_line(line); tx->cursor_set_line(line); tx->end_complex_operation(); - } break; case EDIT_CLONE_DOWN: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; @@ -997,6 +996,7 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->begin_complex_operation(); for (int i = from_line; i <= to_line; i++) { + tx->unfold_line(i); if (i >= tx->get_line_count() - 1) { tx->set_line(i, tx->get_line(i) + "\n"); } @@ -1012,11 +1012,29 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->end_complex_operation(); tx->update(); + } break; + case EDIT_FOLD_LINE: { + + tx->fold_line(tx->cursor_get_line()); + tx->update(); + } break; + case EDIT_UNFOLD_LINE: { + + tx->unfold_line(tx->cursor_get_line()); + tx->update(); + } break; + case EDIT_FOLD_ALL_LINES: { + + tx->fold_all_lines(); + tx->update(); + } break; + case EDIT_UNFOLD_ALL_LINES: { + tx->unhide_all_lines(); + tx->update(); } break; case EDIT_TOGGLE_COMMENT: { - TextEdit *tx = code_editor->get_text_edit(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; @@ -1065,62 +1083,65 @@ void ScriptTextEditor::_edit_option(int p_op) { tx->end_complex_operation(); tx->update(); //tx->deselect(); - } break; case EDIT_COMPLETE: { - code_editor->get_text_edit()->query_code_comple(); - + tx->query_code_comple(); } break; case EDIT_AUTO_INDENT: { - TextEdit *te = code_editor->get_text_edit(); - String text = te->get_text(); + String text = tx->get_text(); Ref<Script> scr = get_edited_script(); if (scr.is_null()) return; - te->begin_complex_operation(); + tx->begin_complex_operation(); int begin, end; - if (te->is_selection_active()) { - begin = te->get_selection_from_line(); - end = te->get_selection_to_line(); + if (tx->is_selection_active()) { + begin = tx->get_selection_from_line(); + end = tx->get_selection_to_line(); // ignore if the cursor is not past the first column - if (te->get_selection_to_column() == 0) { + if (tx->get_selection_to_column() == 0) { end--; } } else { begin = 0; - end = te->get_line_count() - 1; + end = tx->get_line_count() - 1; } scr->get_language()->auto_indent_code(text, begin, end); Vector<String> lines = text.split("\n"); for (int i = begin; i <= end; ++i) { - te->set_line(i, lines[i]); + tx->set_line(i, lines[i]); } - te->end_complex_operation(); - + tx->end_complex_operation(); } break; case EDIT_TRIM_TRAILING_WHITESAPCE: { + trim_trailing_whitespace(); } break; case EDIT_CONVERT_INDENT_TO_SPACES: { + convert_indent_to_spaces(); } break; case EDIT_CONVERT_INDENT_TO_TABS: { + convert_indent_to_tabs(); } break; case EDIT_PICK_COLOR: { + color_panel->popup(); } break; case EDIT_TO_UPPERCASE: { + _convert_case(UPPER); } break; case EDIT_TO_LOWERCASE: { + _convert_case(LOWER); } break; case EDIT_CAPITALIZE: { + _convert_case(CAPITALIZE); } break; case SEARCH_FIND: { @@ -1145,41 +1166,47 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case SEARCH_GOTO_LINE: { - goto_line_dialog->popup_find_line(code_editor->get_text_edit()); + goto_line_dialog->popup_find_line(tx); } break; case DEBUG_TOGGLE_BREAKPOINT: { - int line = code_editor->get_text_edit()->cursor_get_line(); - bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line); - code_editor->get_text_edit()->set_line_as_breakpoint(line, dobreak); + + int line = tx->cursor_get_line(); + bool dobreak = !tx->is_line_set_as_breakpoint(line); + tx->set_line_as_breakpoint(line, dobreak); ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak); } break; case DEBUG_REMOVE_ALL_BREAKPOINTS: { + List<int> bpoints; - code_editor->get_text_edit()->get_breakpoints(&bpoints); + tx->get_breakpoints(&bpoints); for (List<int>::Element *E = bpoints.front(); E; E = E->next()) { int line = E->get(); - bool dobreak = !code_editor->get_text_edit()->is_line_set_as_breakpoint(line); - code_editor->get_text_edit()->set_line_as_breakpoint(line, dobreak); + bool dobreak = !tx->is_line_set_as_breakpoint(line); + tx->set_line_as_breakpoint(line, dobreak); ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(get_edited_script()->get_path(), line + 1, dobreak); } } case DEBUG_GOTO_NEXT_BREAKPOINT: { + List<int> bpoints; - code_editor->get_text_edit()->get_breakpoints(&bpoints); + tx->get_breakpoints(&bpoints); if (bpoints.size() <= 0) { return; } - int line = code_editor->get_text_edit()->cursor_get_line(); + int line = tx->cursor_get_line(); + // wrap around if (line >= bpoints[bpoints.size() - 1]) { - code_editor->get_text_edit()->cursor_set_line(bpoints[0]); + tx->unfold_line(bpoints[0]); + tx->cursor_set_line(bpoints[0]); } else { for (List<int>::Element *E = bpoints.front(); E; E = E->next()) { int bline = E->get(); if (bline > line) { - code_editor->get_text_edit()->cursor_set_line(bline); + tx->unfold_line(bline); + tx->cursor_set_line(bline); return; } } @@ -1187,21 +1214,24 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case DEBUG_GOTO_PREV_BREAKPOINT: { + List<int> bpoints; - code_editor->get_text_edit()->get_breakpoints(&bpoints); + tx->get_breakpoints(&bpoints); if (bpoints.size() <= 0) { return; } - int line = code_editor->get_text_edit()->cursor_get_line(); + int line = tx->cursor_get_line(); // wrap around if (line <= bpoints[0]) { - code_editor->get_text_edit()->cursor_set_line(bpoints[bpoints.size() - 1]); + tx->unfold_line(bpoints[bpoints.size() - 1]); + tx->cursor_set_line(bpoints[bpoints.size() - 1]); } else { for (List<int>::Element *E = bpoints.back(); E; E = E->prev()) { int bline = E->get(); if (bline < line) { - code_editor->get_text_edit()->cursor_set_line(bline); + tx->unfold_line(bline); + tx->cursor_set_line(bline); return; } } @@ -1210,9 +1240,10 @@ void ScriptTextEditor::_edit_option(int p_op) { } break; case HELP_CONTEXTUAL: { - String text = code_editor->get_text_edit()->get_selection_text(); + + String text = tx->get_selection_text(); if (text == "") - text = code_editor->get_text_edit()->get_word_under_cursor(); + text = tx->get_word_under_cursor(); if (text != "") { emit_signal("request_help_search", text); } @@ -1398,6 +1429,9 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { Vector2 mpos = mb->get_global_position() - tx->get_global_position(); bool have_selection = (tx->get_selection_text().length() > 0); bool have_color = (tx->get_word_at_pos(mpos) == "Color"); + int fold_state = 0; + bool can_fold = tx->can_fold(row); + bool is_folded = tx->is_folded(row); if (have_color) { String line = tx->get_line(row); @@ -1428,7 +1462,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) { have_color = false; } } - _make_context_menu(have_selection, have_color); + _make_context_menu(have_selection, have_color, can_fold, is_folded); } } } @@ -1447,7 +1481,7 @@ void ScriptTextEditor::_color_changed(const Color &p_color) { code_editor->get_text_edit()->set_line(color_line, new_line); } -void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color) { +void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded) { context_menu->clear(); if (p_selection) { @@ -1467,6 +1501,13 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color) { context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/indent_right"), EDIT_INDENT_RIGHT); context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); } + if (p_can_fold) { + // can fold + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_line"), EDIT_FOLD_LINE); + } else if (p_is_folded) { + // can unfold + context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_line"), EDIT_UNFOLD_LINE); + } if (p_color) { context_menu->add_separator(); context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR); @@ -1530,6 +1571,10 @@ ScriptTextEditor::ScriptTextEditor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/delete_line"), EDIT_DELETE_LINE); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_comment"), EDIT_TOGGLE_COMMENT); edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/clone_down"), EDIT_CLONE_DOWN); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_line"), EDIT_FOLD_LINE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/fold_all_lines"), EDIT_FOLD_ALL_LINES); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_line"), EDIT_UNFOLD_LINE); + edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/unfold_all_lines"), EDIT_UNFOLD_ALL_LINES); edit_menu->get_popup()->add_separator(); #ifdef OSX_ENABLED edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/complete_symbol"), EDIT_COMPLETE); @@ -1607,6 +1652,10 @@ void ScriptTextEditor::register_editor() { ED_SHORTCUT("script_text_editor/indent_right", TTR("Indent Right"), 0); ED_SHORTCUT("script_text_editor/toggle_comment", TTR("Toggle Comment"), KEY_MASK_CMD | KEY_K); ED_SHORTCUT("script_text_editor/clone_down", TTR("Clone Down"), KEY_MASK_CMD | KEY_B); + ED_SHORTCUT("script_text_editor/fold_line", TTR("Fold Line"), KEY_MASK_ALT | KEY_LEFT); + ED_SHORTCUT("script_text_editor/unfold_line", TTR("Unfold Line"), KEY_MASK_ALT | KEY_RIGHT); + ED_SHORTCUT("script_text_editor/fold_all_lines", TTR("Fold All Lines"), 0); + ED_SHORTCUT("script_text_editor/unfold_all_lines", TTR("Unfold All Lines"), 0); #ifdef OSX_ENABLED ED_SHORTCUT("script_text_editor/complete_symbol", TTR("Complete Symbol"), KEY_MASK_CTRL | KEY_SPACE); #else diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index 83f3ea57c0..722015ef3e 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -91,6 +91,10 @@ class ScriptTextEditor : public ScriptEditorBase { EDIT_TO_UPPERCASE, EDIT_TO_LOWERCASE, EDIT_CAPITALIZE, + EDIT_FOLD_LINE, + EDIT_UNFOLD_LINE, + EDIT_FOLD_ALL_LINES, + EDIT_UNFOLD_ALL_LINES, SEARCH_FIND, SEARCH_FIND_NEXT, SEARCH_FIND_PREV, @@ -118,7 +122,7 @@ protected: static void _bind_methods(); void _edit_option(int p_op); - void _make_context_menu(bool p_selection, bool p_color); + void _make_context_menu(bool p_selection, bool p_color, bool p_can_fold, bool p_is_folded); void _text_edit_gui_input(const Ref<InputEvent> &ev); void _color_changed(const Color &p_color); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index ca80908ab5..448daab226 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -758,17 +758,49 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig } } + bool is_plane_scale = false; + // plane select + if (col_axis == -1) { + col_d = 1e20; + + for (int i = 0; i < 3; i++) { + + Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized(); + Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized(); + + Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST); + + Vector3 r; + Plane plane(gt.origin, gt.basis.get_axis(i).normalized()); + + if (plane.intersects_ray(ray_pos, ray, &r)) { + + float dist = r.distance_to(grabber_pos); + if (dist < (gs * GIZMO_PLANE_SIZE)) { + + float d = ray_pos.distance_to(r); + if (d < col_d) { + col_d = d; + col_axis = i; + + is_plane_scale = true; + } + } + } + } + } + if (col_axis != -1) { if (p_highlight_only) { - spatial_editor->select_gizmo_highlight_axis(col_axis + 9); + spatial_editor->select_gizmo_highlight_axis(col_axis + (is_plane_scale ? 12 : 9)); } else { //handle scale _edit.mode = TRANSFORM_SCALE; _compute_edit(Point2(p_screenpos.x, p_screenpos.y)); - _edit.plane = TransformPlane(TRANSFORM_X_AXIS + col_axis); + _edit.plane = TransformPlane(TRANSFORM_X_AXIS + col_axis + (is_plane_scale ? 3 : 0)); } return true; } @@ -1065,7 +1097,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (get_selected_count() == 0) break; //bye - //handle rotate + //handle scale _edit.mode = TRANSFORM_SCALE; _compute_edit(b->get_position()); break; @@ -1255,6 +1287,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector3 motion_mask; Plane plane; + bool plane_mv = false; switch (_edit.plane) { case TRANSFORM_VIEW: @@ -1273,6 +1306,21 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2); plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized()); break; + case TRANSFORM_YZ: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2) + spatial_editor->get_gizmo_transform().basis.get_axis(1); + plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(0)); + plane_mv = true; + break; + case TRANSFORM_XZ: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2) + spatial_editor->get_gizmo_transform().basis.get_axis(0); + plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(1)); + plane_mv = true; + break; + case TRANSFORM_XY: + motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0) + spatial_editor->get_gizmo_transform().basis.get_axis(1); + plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2)); + plane_mv = true; + break; } Vector3 intersection; @@ -1284,8 +1332,19 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { break; Vector3 motion = intersection - click; - if (motion_mask != Vector3()) { - motion = motion_mask.dot(motion) * motion_mask; + if (_edit.plane != TRANSFORM_VIEW) { + + if (!plane_mv) { + + motion = motion_mask.dot(motion) * motion_mask; + + } else { + + // Alternative planar scaling mode + if (_get_key_modifier(m) != KEY_SHIFT) { + motion = motion_mask.dot(motion) * motion_mask; + } + } } else { float center_click_dist = click.distance_to(_edit.center); @@ -1326,6 +1385,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } + if (sp->has_meta("_edit_lock_")) { + continue; + } + Transform original = se->original; Transform original_local = se->original_local; Transform base = Transform(Basis(), _edit.center); @@ -1379,7 +1442,6 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { switch (_edit.plane) { case TRANSFORM_VIEW: - motion_mask = Vector3(0, 0, 0); plane = Plane(_edit.center, _get_camera_normal()); break; case TRANSFORM_X_AXIS: @@ -1417,7 +1479,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { break; Vector3 motion = intersection - click; - if (motion_mask != Vector3()) { + if (_edit.plane != TRANSFORM_VIEW) { if (!plane_mv) { motion = motion_mask.dot(motion) * motion_mask; } @@ -1451,6 +1513,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { continue; } + if (sp->has_meta("_edit_lock_")) { + continue; + } + Transform original = se->original; Transform t; @@ -1547,6 +1613,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (!se) continue; + if (sp->has_meta("_edit_lock_")) { + continue; + } + Transform t; if (local_coords) { @@ -2011,7 +2081,7 @@ void SpatialEditorViewport::_notification(int p_what) { if (se->aabb.has_no_surface()) { - se->aabb = vi ? vi->get_aabb() : Rect3(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4)); + se->aabb = vi ? vi->get_aabb() : AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4)); } Transform t = sp->get_global_transform(); @@ -2099,6 +2169,29 @@ void SpatialEditorViewport::_notification(int p_what) { } } + // FPS Counter. + bool show_fps = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FPS)); + if (show_fps != fps->is_visible()) { + if (show_fps) + fps->show(); + else + fps->hide(); + } + + if (show_fps) { + String text; + const float temp_fps = Engine::get_singleton()->get_frames_per_second(); + text += TTR("FPS") + ": " + itos(temp_fps) + " (" + String::num(1000.0f / temp_fps, 2) + " ms)"; + + if (fps_label->get_text() != text || surface->get_size() != prev_size) { + fps_label->set_text(text); + Size2 ms = fps->get_size(); + Size2 size = surface->get_size(); + size.y = ms.y + 20; + fps->set_position(size - ms - Vector2(20, 0) * EDSCALE); + } + } + prev_size = surface->get_size(); } @@ -2109,6 +2202,7 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("mouse_entered", this, "_smouseenter"); surface->connect("mouse_exited", this, "_smouseexit"); info->add_style_override("panel", get_stylebox("panel", "Panel")); + fps->add_style_override("panel", get_stylebox("panel", "Panel")); preview_camera->set_icon(get_icon("Camera", "EditorIcons")); _init_gizmo_instance(index); } @@ -2431,6 +2525,13 @@ void SpatialEditorViewport::_menu_option(int p_option) { view_menu->get_popup()->set_item_checked(idx, !current); } break; + case VIEW_FPS: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_FPS); + bool current = view_menu->get_popup()->is_item_checked(idx); + view_menu->get_popup()->set_item_checked(idx, !current); + + } break; case VIEW_DISPLAY_NORMAL: { viewport->set_debug_draw(Viewport::DEBUG_DRAW_DISABLED); @@ -2516,6 +2617,14 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) { //VS::get_singleton()->instance_geometry_set_flag(scale_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true); VS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF); VS::get_singleton()->instance_set_layer_mask(scale_gizmo_instance[i], layer); + + scale_plane_gizmo_instance[i] = VS::get_singleton()->instance_create(); + VS::get_singleton()->instance_set_base(scale_plane_gizmo_instance[i], spatial_editor->get_scale_plane_gizmo(i)->get_rid()); + VS::get_singleton()->instance_set_scenario(scale_plane_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario()); + VS::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false); + //VS::get_singleton()->instance_geometry_set_flag(scale_plane_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true); + VS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_plane_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF); + VS::get_singleton()->instance_set_layer_mask(scale_plane_gizmo_instance[i], layer); } } @@ -2526,6 +2635,7 @@ void SpatialEditorViewport::_finish_gizmo_instances() { VS::get_singleton()->free(move_plane_gizmo_instance[i]); VS::get_singleton()->free(rotate_gizmo_instance[i]); VS::get_singleton()->free(scale_gizmo_instance[i]); + VS::get_singleton()->free(scale_plane_gizmo_instance[i]); } } void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) { @@ -2622,6 +2732,8 @@ void SpatialEditorViewport::update_transform_gizmo_view() { VisualServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE)); VisualServer::get_singleton()->instance_set_transform(scale_gizmo_instance[i], xform); VisualServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE)); + VisualServer::get_singleton()->instance_set_transform(scale_plane_gizmo_instance[i], xform); + VisualServer::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE)); } } @@ -2756,7 +2868,7 @@ void SpatialEditorViewport::focus_selection() { cursor.pos = center; } -void SpatialEditorViewport::assign_pending_data_pointers(Spatial *p_preview_node, Rect3 *p_preview_bounds, AcceptDialog *p_accept) { +void SpatialEditorViewport::assign_pending_data_pointers(Spatial *p_preview_node, AABB *p_preview_bounds, AcceptDialog *p_accept) { preview_node = p_preview_node; preview_bounds = p_preview_bounds; accept = p_accept; @@ -2819,14 +2931,14 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const return point + offset; } -Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) { - Rect3 bounds = p_bounds; +AABB SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const AABB p_bounds) { + AABB bounds = p_bounds; for (int i = 0; i < p_parent->get_child_count(); i++) { Spatial *child = Object::cast_to<Spatial>(p_parent->get_child(i)); if (child) { MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(child); if (mesh_instance) { - Rect3 mesh_instance_bounds = mesh_instance->get_aabb(); + AABB mesh_instance_bounds = mesh_instance->get_aabb(); mesh_instance_bounds.position += mesh_instance->get_global_transform().origin - p_parent->get_global_transform().origin; bounds.merge_with(mesh_instance_bounds); } @@ -2858,7 +2970,7 @@ void SpatialEditorViewport::_create_preview(const Vector<String> &files) const { editor->get_scene_root()->add_child(preview_node); } } - *preview_bounds = _calculate_spatial_bounds(preview_node, Rect3()); + *preview_bounds = _calculate_spatial_bounds(preview_node, AABB()); } void SpatialEditorViewport::_remove_preview() { @@ -3149,6 +3261,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("View Environment")), VIEW_ENVIRONMENT); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION); + view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_fps", TTR("View FPS")), VIEW_FPS); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT), true); view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_half_resolution", TTR("Half Resolution")), VIEW_HALF_RESOLUTION); @@ -3191,6 +3304,14 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed info->add_child(info_label); info->hide(); + // FPS Counter. + fps = memnew(PanelContainer); + fps->set_self_modulate(Color(1, 1, 1, 0.4)); + surface->add_child(fps); + fps_label = memnew(Label); + fps->add_child(fps_label); + fps->hide(); + accept = NULL; freelook_active = false; @@ -3528,13 +3649,14 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) { move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? gizmo_hl : plane_gizmo_color[i]); rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_hl : gizmo_color[i]); scale_gizmo[i]->surface_set_material(0, (i + 9) == p_axis ? gizmo_hl : gizmo_color[i]); + scale_plane_gizmo[i]->surface_set_material(0, (i + 12) == p_axis ? gizmo_hl : plane_gizmo_color[i]); } } void SpatialEditor::update_transform_gizmo() { List<Node *> &selection = editor_selection->get_selected_node_list(); - Rect3 center; + AABB center; bool first = true; Basis gizmo_basis; @@ -3595,7 +3717,7 @@ Object *SpatialEditor::_get_editor_data(Object *p_what) { void SpatialEditor::_generate_selection_box() { - Rect3 aabb(Vector3(), Vector3(1, 1, 1)); + AABB aabb(Vector3(), Vector3(1, 1, 1)); aabb.grow_by(aabb.get_longest_axis_size() / 20.0); Ref<SurfaceTool> st = memnew(SurfaceTool); @@ -3984,6 +4106,44 @@ void SpatialEditor::_menu_item_pressed(int p_option) { settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50)); } break; + case MENU_LOCK_SELECTED: { + + List<Node *> &selection = editor_selection->get_selected_node_list(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + + Spatial *spatial = Object::cast_to<Spatial>(E->get()); + if (!spatial || !spatial->is_visible_in_tree()) + continue; + + if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root()) + continue; + + spatial->set_meta("_edit_lock_", true); + emit_signal("item_lock_status_changed"); + } + + _refresh_menu_icons(); + } break; + case MENU_UNLOCK_SELECTED: { + + List<Node *> &selection = editor_selection->get_selected_node_list(); + + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + + Spatial *spatial = Object::cast_to<Spatial>(E->get()); + if (!spatial || !spatial->is_visible_in_tree()) + continue; + + if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root()) + continue; + + spatial->set_meta("_edit_lock_", Variant()); + emit_signal("item_lock_status_changed"); + } + + _refresh_menu_icons(); + } break; } } @@ -4101,6 +4261,7 @@ void SpatialEditor::_init_indicators() { move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); scale_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); + scale_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh)); Ref<SpatialMaterial> mat = memnew(SpatialMaterial); mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); @@ -4296,6 +4457,49 @@ void SpatialEditor::_init_indicators() { surftool->set_material(mat); surftool->commit(scale_gizmo[i]); } + + // Plane Scale + { + Ref<SurfaceTool> surftool = memnew(SurfaceTool); + surftool->begin(Mesh::PRIMITIVE_TRIANGLES); + + Vector3 vec = ivec2 - ivec3; + Vector3 plane[4] = { + vec * GIZMO_PLANE_DST, + vec * GIZMO_PLANE_DST + ivec2 * GIZMO_PLANE_SIZE, + vec * (GIZMO_PLANE_DST + GIZMO_PLANE_SIZE), + vec * GIZMO_PLANE_DST - ivec3 * GIZMO_PLANE_SIZE + }; + + Basis ma(ivec, Math_PI / 2); + + Vector3 points[4] = { + ma.xform(plane[0]), + ma.xform(plane[1]), + ma.xform(plane[2]), + ma.xform(plane[3]), + }; + surftool->add_vertex(points[0]); + surftool->add_vertex(points[1]); + surftool->add_vertex(points[2]); + + surftool->add_vertex(points[0]); + surftool->add_vertex(points[2]); + surftool->add_vertex(points[3]); + + Ref<SpatialMaterial> plane_mat = memnew(SpatialMaterial); + plane_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true); + plane_mat->set_on_top_of_alpha(); + plane_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true); + plane_mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); + Color col; + col[i] = 1.0; + col.a = gizmo_alph; + plane_mat->set_albedo(col); + plane_gizmo_color[i] = plane_mat; // needed, so we can draw planes from both sides + surftool->set_material(plane_mat); + surftool->commit(scale_plane_gizmo[i]); + } } } @@ -4323,6 +4527,28 @@ bool SpatialEditor::is_any_freelook_active() const { return false; } +void SpatialEditor::_refresh_menu_icons() { + + bool all_locked = true; + + List<Node *> &selection = editor_selection->get_selected_node_list(); + + if (selection.empty()) { + all_locked = false; + } else { + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + if (Object::cast_to<Spatial>(E->get()) && !Object::cast_to<Spatial>(E->get())->has_meta("_edit_lock_")) { + all_locked = false; + break; + } + } + } + + tool_button[TOOL_LOCK_SELECTED]->set_visible(!all_locked); + tool_button[TOOL_LOCK_SELECTED]->set_disabled(selection.empty()); + tool_button[TOOL_UNLOCK_SELECTED]->set_visible(all_locked); +} + void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) { if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack()) @@ -4361,6 +4587,8 @@ void SpatialEditor::_notification(int p_what) { tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons")); tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons")); tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons")); + tool_button[SpatialEditor::TOOL_LOCK_SELECTED]->set_icon(get_icon("Lock", "EditorIcons")); + tool_button[SpatialEditor::TOOL_UNLOCK_SELECTED]->set_icon(get_icon("Unlock", "EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons")); view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons")); @@ -4371,7 +4599,11 @@ void SpatialEditor::_notification(int p_what) { _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT); + _refresh_menu_icons(); + get_tree()->connect("node_removed", this, "_node_removed"); + EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->connect("node_changed", this, "_refresh_menu_icons"); + editor_selection->connect("selection_changed", this, "_refresh_menu_icons"); } if (p_what == NOTIFICATION_ENTER_TREE) { @@ -4514,8 +4746,10 @@ void SpatialEditor::_bind_methods() { ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data); ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo); ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view); + ClassDB::bind_method("_refresh_menu_icons", &SpatialEditor::_refresh_menu_icons); ADD_SIGNAL(MethodInfo("transform_key_request")); + ADD_SIGNAL(MethodInfo("item_lock_status_changed")); } void SpatialEditor::clear() { @@ -4617,12 +4851,24 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { tool_button[TOOL_MODE_LIST_SELECT]->connect("pressed", this, "_menu_item_pressed", button_binds); tool_button[TOOL_MODE_LIST_SELECT]->set_tooltip(TTR("Show a list of all objects at the position clicked\n(same as Alt+RMB in select mode).")); + tool_button[TOOL_LOCK_SELECTED] = memnew(ToolButton); + hbc_menu->add_child(tool_button[TOOL_LOCK_SELECTED]); + button_binds[0] = MENU_LOCK_SELECTED; + tool_button[TOOL_LOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds); + tool_button[TOOL_LOCK_SELECTED]->set_tooltip(TTR("Lock the selected object in place (can't be moved).")); + + tool_button[TOOL_UNLOCK_SELECTED] = memnew(ToolButton); + hbc_menu->add_child(tool_button[TOOL_UNLOCK_SELECTED]); + button_binds[0] = MENU_UNLOCK_SELECTED; + tool_button[TOOL_UNLOCK_SELECTED]->connect("pressed", this, "_menu_item_pressed", button_binds); + tool_button[TOOL_UNLOCK_SELECTED]->set_tooltip(TTR("Unlock the selected object (can be moved).")); + vs = memnew(VSeparator); hbc_menu->add_child(vs); // Drag and drop support; preview_node = memnew(Spatial); - preview_bounds = Rect3(); + preview_bounds = AABB(); ED_SHORTCUT("spatial_editor/bottom_view", TTR("Bottom View"), KEY_MASK_ALT + KEY_KP_7); ED_SHORTCUT("spatial_editor/top_view", TTR("Top View"), KEY_KP_7); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index c2b698068f..ad11ec33df 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -88,6 +88,7 @@ class SpatialEditorViewport : public Control { VIEW_AUDIO_DOPPLER, VIEW_GIZMOS, VIEW_INFORMATION, + VIEW_FPS, VIEW_DISPLAY_NORMAL, VIEW_DISPLAY_WIREFRAME, VIEW_DISPLAY_OVERDRAW, @@ -108,7 +109,7 @@ private: Size2 prev_size; Spatial *preview_node; - Rect3 *preview_bounds; + AABB *preview_bounds; Vector<String> selected_files; AcceptDialog *accept; @@ -138,6 +139,9 @@ private: PanelContainer *info; Label *info_label; + PanelContainer *fps; + Label *fps_label; + struct _RayResult { Spatial *item; @@ -255,7 +259,7 @@ private: real_t zoom_indicator_delay; - RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3], scale_gizmo_instance[3]; + RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3], scale_gizmo_instance[3], scale_plane_gizmo_instance[3]; String last_message; String message; @@ -287,7 +291,7 @@ private: Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const; Vector3 _get_instance_position(const Point2 &p_pos) const; - static Rect3 _calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds); + static AABB _calculate_spatial_bounds(const Spatial *p_parent, const AABB p_bounds); void _create_preview(const Vector<String> &files) const; void _remove_preview(); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); @@ -314,7 +318,7 @@ public: void assign_pending_data_pointers( Spatial *p_preview_node, - Rect3 *p_preview_bounds, + AABB *p_preview_bounds, AcceptDialog *p_accept); Viewport *get_viewport_node() { return viewport; } @@ -327,7 +331,7 @@ class SpatialEditorSelectedItem : public Object { GDCLASS(SpatialEditorSelectedItem, Object); public: - Rect3 aabb; + AABB aabb; Transform original; // original location when moving Transform original_local; Transform last_xform; // last transform @@ -387,6 +391,8 @@ public: TOOL_MODE_ROTATE, TOOL_MODE_SCALE, TOOL_MODE_LIST_SELECT, + TOOL_LOCK_SELECTED, + TOOL_UNLOCK_SELECTED, TOOL_MAX }; @@ -418,7 +424,7 @@ private: bool grid_enable[3]; //should be always visible if true bool grid_enabled; - Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3], scale_gizmo[3]; + Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[3], scale_gizmo[3], scale_plane_gizmo[3]; Ref<SpatialMaterial> gizmo_color[3]; Ref<SpatialMaterial> plane_gizmo_color[3]; Ref<SpatialMaterial> gizmo_hl; @@ -435,7 +441,7 @@ private: // Scene drag and drop support Spatial *preview_node; - Rect3 preview_bounds; + AABB preview_bounds; /* struct Selected { @@ -475,7 +481,8 @@ private: MENU_VIEW_ORIGIN, MENU_VIEW_GRID, MENU_VIEW_CAMERA_SETTINGS, - + MENU_LOCK_SELECTED, + MENU_UNLOCK_SELECTED }; Button *tool_button[TOOL_MAX]; @@ -483,6 +490,9 @@ private: MenuButton *transform_menu; MenuButton *view_menu; + ToolButton *lock_button; + ToolButton *unlock_button; + AcceptDialog *accept; ConfirmationDialog *snap_dialog; @@ -539,6 +549,8 @@ private: bool is_any_freelook_active() const; + void _refresh_menu_icons(); + protected: void _notification(int p_what); //void _gui_input(InputEvent p_event); @@ -571,6 +583,7 @@ public: Ref<ArrayMesh> get_move_plane_gizmo(int idx) const { return move_plane_gizmo[idx]; } Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; } Ref<ArrayMesh> get_scale_gizmo(int idx) const { return scale_gizmo[idx]; } + Ref<ArrayMesh> get_scale_plane_gizmo(int idx) const { return scale_plane_gizmo[idx]; } void update_transform_gizmo(); diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 0ee0eed3a2..ffddd8a3a9 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -363,7 +363,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era return PoolVector<Vector2>(); } - Rect2i r = node->get_item_rect(); + Rect2i r = node->_edit_get_rect(); r.position = r.position / node->get_cell_size(); r.size = r.size / node->get_cell_size(); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index cc9de3e44d..16b85121ef 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -233,7 +233,7 @@ private: fdialog->set_mode(FileDialog::MODE_OPEN_FILE); fdialog->clear_filters(); - fdialog->add_filter("project.godot ; " _MKSTR(VERSION_NAME) " Project"); + fdialog->add_filter("project.godot ; " VERSION_NAME " Project"); } else { fdialog->set_mode(FileDialog::MODE_OPEN_DIR); } @@ -1483,13 +1483,13 @@ ProjectManager::ProjectManager() { String cp; cp.push_back(0xA9); cp.push_back(0); - OS::get_singleton()->set_window_title(_MKSTR(VERSION_NAME) + String(" - ") + TTR("Project Manager") + " - " + cp + " 2008-2017 Juan Linietsky, Ariel Manzur & Godot Contributors"); + OS::get_singleton()->set_window_title(VERSION_NAME + String(" - ") + TTR("Project Manager") + " - " + cp + " 2008-2017 Juan Linietsky, Ariel Manzur & Godot Contributors"); HBoxContainer *top_hb = memnew(HBoxContainer); vb->add_child(top_hb); CenterContainer *ccl = memnew(CenterContainer); Label *l = memnew(Label); - l->set_text(_MKSTR(VERSION_NAME) + String(" - ") + TTR("Project Manager")); + l->set_text(VERSION_NAME + String(" - ") + TTR("Project Manager")); ccl->add_child(l); top_hb->add_child(ccl); top_hb->add_spacer(); @@ -1498,11 +1498,8 @@ ProjectManager::ProjectManager() { if (hash.length() != 0) hash = "." + hash.left(7); l->set_text("v" VERSION_MKSTRING "" + hash); - //l->add_font_override("font",get_font("bold","Fonts")); l->set_align(Label::ALIGN_CENTER); top_hb->add_child(l); - //vb->add_child(memnew(HSeparator)); - //vb->add_margin_child("\n",memnew(Control)); Control *center_box = memnew(Control); center_box->set_v_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index 2c6418136f..bc7d8f4b14 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -416,7 +416,11 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: menu->clear(); Vector<String> options = hint_text.split(","); for (int i = 0; i < options.size(); i++) { - menu->add_item(options[i], i); + if (options[i].find(":") != -1) { + menu->add_item(options[i].get_slicec(':', 0), options[i].get_slicec(':', 1).to_int()); + } else { + menu->add_item(options[i], i); + } } menu->set_position(get_position()); menu->popup(); @@ -756,7 +760,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: value_editor[3]->set_text(String::num(q.w)); } break; - case Variant::RECT3: { + case Variant::AABB: { field_names.push_back("px"); field_names.push_back("py"); @@ -766,7 +770,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant:: field_names.push_back("sz"); config_value_editors(6, 3, 16, field_names); - Rect3 aabb = v; + AABB aabb = v; value_editor[0]->set_text(String::num(aabb.position.x)); value_editor[1]->set_text(String::num(aabb.position.y)); value_editor[2]->set_text(String::num(aabb.position.z)); @@ -1587,7 +1591,7 @@ void CustomPropertyEditor::_modified(String p_string) { _emit_changed_whole_or_field(); } break; - case Variant::RECT3: { + case Variant::AABB: { Vector3 pos; Vector3 size; @@ -1607,7 +1611,7 @@ void CustomPropertyEditor::_modified(String p_string) { size.y = value_editor[4]->get_text().to_double(); size.z = value_editor[5]->get_text().to_double(); } - v = Rect3(pos, size); + v = AABB(pos, size); _emit_changed_whole_or_field(); } break; @@ -1729,7 +1733,7 @@ void CustomPropertyEditor::_focus_enter() { case Variant::VECTOR3: case Variant::PLANE: case Variant::QUAT: - case Variant::RECT3: + case Variant::AABB: case Variant::TRANSFORM2D: case Variant::BASIS: case Variant::TRANSFORM: { @@ -1754,7 +1758,7 @@ void CustomPropertyEditor::_focus_exit() { case Variant::VECTOR3: case Variant::PLANE: case Variant::QUAT: - case Variant::RECT3: + case Variant::AABB: case Variant::TRANSFORM2D: case Variant::BASIS: case Variant::TRANSFORM: { @@ -2240,7 +2244,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p case Variant::VECTOR3: case Variant::QUAT: case Variant::VECTOR2: - case Variant::RECT3: + case Variant::AABB: case Variant::RECT2: case Variant::TRANSFORM2D: case Variant::BASIS: @@ -3374,13 +3378,13 @@ void PropertyEditor::update_tree() { item->set_icon(0, get_icon("Plane", "EditorIcons")); } break; - case Variant::RECT3: { + case Variant::AABB: { item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM); item->set_editable(1, true); - item->set_text(1, "Rect3"); + item->set_text(1, "AABB"); if (show_type_icons) - item->set_icon(0, get_icon("Rect3", "EditorIcons")); + item->set_icon(0, get_icon("AABB", "EditorIcons")); } break; case Variant::QUAT: { @@ -3735,7 +3739,7 @@ void PropertyEditor::_item_edited() { case Variant::QUAT: { } break; - case Variant::RECT3: { + case Variant::AABB: { } break; case Variant::BASIS: { diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp index 13d74a6593..575ff40287 100644 --- a/editor/pvrtc_compress.cpp +++ b/editor/pvrtc_compress.cpp @@ -62,12 +62,12 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) { } return; } - String spath = EditorSettings::get_singleton()->get_settings_path(); + String tmppath = EditorSettings::get_singleton()->get_cache_dir(); List<String> args; - String src_img = spath + "/" + "_tmp_src_img.png"; - String dst_img = spath + "/" + "_tmp_dst_img.pvr"; + String src_img = tmppath.plus_file("_tmp_src_img.png"); + String dst_img = tmppath.plus_file("_tmp_dst_img.pvr"); args.push_back("-i"); args.push_back(src_img); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 94f218757d..1d2647badc 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -443,8 +443,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { List<Node *> owned; node->get_owned_by(node->get_owner(), &owned); - Map<Node *, Node *> duplimap; - Node *dup = _duplicate(node, duplimap); + Map<const Node *, Node *> duplimap; + Node *dup = node->duplicate_from_editor(duplimap); ERR_CONTINUE(!dup); @@ -745,6 +745,10 @@ void SceneTreeDock::_notification(int p_what) { canvas_item_plugin->get_canvas_item_editor()->connect("item_group_status_changed", scene_tree, "_update_tree"); scene_tree->connect("node_changed", canvas_item_plugin->get_canvas_item_editor()->get_viewport_control(), "update"); } + + SpatialEditorPlugin *spatial_editor_plugin = Object::cast_to<SpatialEditorPlugin>(editor_data->get_editor("3D")); + spatial_editor_plugin->get_spatial_editor()->connect("item_lock_status_changed", scene_tree, "_update_tree"); + button_add->set_icon(get_icon("Add", "EditorIcons")); button_instance->set_icon(get_icon("Instance", "EditorIcons")); button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons")); @@ -821,82 +825,6 @@ void SceneTreeDock::_node_renamed() { _node_selected(); } -Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node *, Node *> &duplimap) { - - Node *node = NULL; - - if (p_node->get_filename() != "") { //an instance - - Ref<PackedScene> sd = ResourceLoader::load(p_node->get_filename()); - ERR_FAIL_COND_V(!sd.is_valid(), NULL); - node = sd->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); - ERR_FAIL_COND_V(!node, NULL); - node->set_scene_instance_load_placeholder(p_node->get_scene_instance_load_placeholder()); - } else { - Object *obj = ClassDB::instance(p_node->get_class()); - ERR_FAIL_COND_V(!obj, NULL); - node = Object::cast_to<Node>(obj); - if (!node) - memdelete(obj); - ERR_FAIL_COND_V(!node, NULL); - } - - List<PropertyInfo> plist; - - p_node->get_property_list(&plist); - - for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { - - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) - continue; - String name = E->get().name; - Variant value = p_node->get(name); - // Duplicate dictionaries and arrays, mainly needed for __meta__ - if (value.get_type() == Variant::DICTIONARY) { - value = Dictionary(value).copy(); - } else if (value.get_type() == Variant::ARRAY) { - value = Array(value).duplicate(); - } - node->set(name, value); - } - - List<Connection> conns; - p_node->get_all_signal_connections(&conns); - for (List<Connection>::Element *E = conns.front(); E; E = E->next()) { - if (E->get().flags & CONNECT_PERSIST) { - node->connect(E->get().signal, E->get().target, E->get().method, E->get().binds, E->get().flags); - } - } - - List<Node::GroupInfo> group_info; - p_node->get_groups(&group_info); - for (List<Node::GroupInfo>::Element *E = group_info.front(); E; E = E->next()) { - - if (E->get().persistent) - node->add_to_group(E->get().name, true); - } - - node->set_name(p_node->get_name()); - duplimap[p_node] = node; - - for (int i = 0; i < p_node->get_child_count(); i++) { - - Node *child = p_node->get_child(i); - if (p_node->get_owner() != child->get_owner()) - continue; //don't bother with not in-scene nodes. - - Node *dup = _duplicate(child, duplimap); - if (!dup) { - memdelete(node); - return NULL; - } - - node->add_child(dup); - } - - return node; -} - void SceneTreeDock::_set_owners(Node *p_owner, const Array &p_nodes) { for (int i = 0; i < p_nodes.size(); i++) { @@ -1459,6 +1387,8 @@ void SceneTreeDock::_create() { for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) continue; + if (E->get().name == "__meta__") + continue; newnode->set(E->get().name, n->get(E->get().name)); } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 97d3c4748a..7848052241 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -130,7 +130,6 @@ class SceneTreeDock : public VBoxContainer { void _add_children_to_popup(Object *p_obj, int p_depth); - Node *_duplicate(Node *p_node, Map<Node *, Node *> &duplimap); void _node_reparent(NodePath p_path, bool p_keep_global_xform); void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index c4b86c6b2b..dfda8a780d 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -88,7 +88,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i } else if (p_id == BUTTON_LOCK) { - if (n->is_class("CanvasItem")) { + if (n->is_class("CanvasItem") || n->is_class("Spatial")) { n->set_meta("_edit_lock_", Variant()); _update_tree(); emit_signal("node_changed"); @@ -266,6 +266,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { _update_visibility_color(p_node, item); } else if (p_node->is_class("Spatial")) { + bool is_locked = p_node->has_meta("_edit_lock_"); + if (is_locked) + item->add_button(0, get_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock")); + bool v = p_node->call("is_visible"); if (v) item->add_button(0, get_icon("Visible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility")); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 0f1712c224..3cab14b0c4 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -128,7 +128,7 @@ void ScriptCreateDialog::_template_changed(int p_template) { } String ext = ScriptServer::get_language(language_menu->get_selected())->get_extension(); String name = template_list[p_template - 1] + "." + ext; - script_template = EditorSettings::get_singleton()->get_settings_path() + "/script_templates/" + name; + script_template = EditorSettings::get_singleton()->get_script_templates_dir().plus_file(name); } void ScriptCreateDialog::ok_pressed() { diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 3f8d93d976..3ffc61cb45 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -149,7 +149,7 @@ void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mat md = MAX(0, p_lines[i].length()); } if (md) { - mesh->set_custom_aabb(Rect3(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0)); + mesh->set_custom_aabb(AABB(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0)); } } @@ -196,7 +196,7 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material, md = MAX(0, vs[i].length()); } if (md) { - mesh->set_custom_aabb(Rect3(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0)); + mesh->set_custom_aabb(AABB(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0)); } } @@ -211,7 +211,7 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material, instances.push_back(ins); } -void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds) { +void EditorSpatialGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const AABB &p_bounds) { collision_mesh = p_tmesh; collision_mesh_bounds = p_bounds; @@ -270,7 +270,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi md = MAX(0, p_handles[i].length()); } if (md) { - mesh->set_custom_aabb(Rect3(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0)); + mesh->set_custom_aabb(AABB(Vector3(-md, -md, -md), Vector3(md, md, md) * 2.0)); } } @@ -1274,7 +1274,7 @@ void MeshInstanceSpatialGizmo::redraw() { Ref<TriangleMesh> tm = m->generate_triangle_mesh(); if (tm.is_valid()) { - Rect3 aabb; + AABB aabb; add_collision_triangles(tm, aabb); } } @@ -1336,7 +1336,7 @@ void SkeletonSpatialGizmo::redraw() { weights[0] = 1; - Rect3 aabb; + AABB aabb; Color bonecolor = Color(1.0, 0.4, 0.4, 0.3); Color rootcolor = Color(0.4, 1.0, 0.4, 0.1); @@ -1961,7 +1961,7 @@ void CollisionShapeSpatialGizmo::redraw() { Ref<BoxShape> bs = s; Vector<Vector3> lines; - Rect3 aabb; + AABB aabb; aabb.position = -bs->get_extents(); aabb.size = aabb.position * -2; @@ -2191,7 +2191,7 @@ void VisibilityNotifierGizmo::set_handle(int p_idx, Camera *p_camera, const Poin //gt.orthonormalize(); Transform gi = gt.affine_inverse(); - Rect3 aabb = notifier->get_aabb(); + AABB aabb = notifier->get_aabb(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -2234,7 +2234,7 @@ void VisibilityNotifierGizmo::redraw() { clear(); Vector<Vector3> lines; - Rect3 aabb = notifier->get_aabb(); + AABB aabb = notifier->get_aabb(); for (int i = 0; i < 12; i++) { Vector3 a, b; @@ -2293,7 +2293,7 @@ void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_poi bool move = p_idx >= 3; p_idx = p_idx % 3; - Rect3 aabb = particles->get_visibility_aabb(); + AABB aabb = particles->get_visibility_aabb(); Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); @@ -2347,7 +2347,7 @@ void ParticlesGizmo::redraw() { clear(); Vector<Vector3> lines; - Rect3 aabb = particles->get_visibility_aabb(); + AABB aabb = particles->get_visibility_aabb(); for (int i = 0; i < 12; i++) { Vector3 a, b; @@ -2420,7 +2420,7 @@ String ReflectionProbeGizmo::get_handle_name(int p_idx) const { } Variant ReflectionProbeGizmo::get_handle_value(int p_idx) const { - return Rect3(probe->get_extents(), probe->get_origin_offset()); + return AABB(probe->get_extents(), probe->get_origin_offset()); } void ReflectionProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) { @@ -2474,7 +2474,7 @@ void ReflectionProbeGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 void ReflectionProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) { - Rect3 restore = p_restore; + AABB restore = p_restore; if (p_cancel) { probe->set_extents(restore.position); @@ -2499,7 +2499,7 @@ void ReflectionProbeGizmo::redraw() { Vector<Vector3> internal_lines; Vector3 extents = probe->get_extents(); - Rect3 aabb; + AABB aabb; aabb.position = -extents; aabb.size = extents * 2; @@ -2641,7 +2641,7 @@ void GIProbeGizmo::redraw() { static const int subdivs[GIProbe::SUBDIV_MAX] = { 64, 128, 256, 512 }; - Rect3 aabb = Rect3(-extents, extents * 2); + AABB aabb = AABB(-extents, extents * 2); int subdiv = subdivs[probe->get_subdiv()]; float cell_size = aabb.get_longest_axis_size() / subdiv; diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h index afe64c723c..751bad2b13 100644 --- a/editor/spatial_editor_gizmos.h +++ b/editor/spatial_editor_gizmos.h @@ -78,7 +78,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo { Vector<Vector3> collision_segments; Ref<TriangleMesh> collision_mesh; - Rect3 collision_mesh_bounds; + AABB collision_mesh_bounds; struct Handle { Vector3 pos; @@ -100,7 +100,7 @@ protected: void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false); void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID()); void add_collision_segments(const Vector<Vector3> &p_lines); - void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const Rect3 &p_bounds = Rect3()); + void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh, const AABB &p_bounds = AABB()); void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1); void add_handles(const Vector<Vector3> &p_handles, bool p_billboard = false, bool p_secondary = false); void add_solid_box(Ref<Material> &p_material, Vector3 size); diff --git a/main/main.cpp b/main/main.cpp index cc6e66d352..5410aae1d2 100644..100755 --- a/main/main.cpp +++ b/main/main.cpp @@ -35,6 +35,7 @@ #include "message_queue.h" #include "modules/register_module_types.h" #include "os/os.h" +#include "platform/register_platform_apis.h" #include "project_settings.h" #include "scene/register_scene_types.h" #include "script_debugger_local.h" @@ -176,7 +177,7 @@ static String get_full_version_string() { void Main::print_help(const char *p_binary) { - print_line(String(_MKSTR(VERSION_NAME)) + " v" + get_full_version_string() + " - https://godotengine.org"); + print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - https://godotengine.org"); OS::get_singleton()->print("(c) 2007-2017 Juan Linietsky, Ariel Manzur.\n"); OS::get_singleton()->print("(c) 2014-2017 Godot Engine contributors.\n"); OS::get_singleton()->print("\n"); @@ -426,6 +427,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "-m" || I->get() == "--maximized") { // force maximized window init_maximized = true; + video_mode.maximized = true; } else if (I->get() == "-w" || I->get() == "--windowed") { // force windowed window init_windowed = true; @@ -747,6 +749,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::get_singleton()->set_editor_hint(true); main_args.push_back("--editor"); init_maximized = true; + video_mode.maximized = true; use_custom_res = false; } @@ -1108,6 +1111,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: Load Modules, Physics, Drivers, Scripts"); + register_platform_apis(); register_module_types(); initialize_physics(); @@ -1825,6 +1829,7 @@ void Main::cleanup() { unregister_driver_types(); unregister_module_types(); + unregister_platform_apis(); unregister_scene_types(); unregister_server_types(); diff --git a/methods.py b/methods.py index 6e4fecd67e..2be73f02d2 100644 --- a/methods.py +++ b/methods.py @@ -1150,26 +1150,26 @@ def build_gles3_headers(target, source, env): def add_module_version_string(self,s): - self.module_version_string+="."+s + self.module_version_string += "." + s def update_version(module_version_string=""): - rev = "custom_build" + build_name = "custom_build" + if (os.getenv("BUILD_NAME") != None): + build_name = os.getenv("BUILD_NAME") + print("Using custom build name: " + build_name) - if (os.getenv("BUILD_REVISION") != None): - rev = os.getenv("BUILD_REVISION") - print("Using custom revision: " + rev) import version f = open("core/version_generated.gen.h", "w") - f.write("#define VERSION_SHORT_NAME " + str(version.short_name) + "\n") - f.write("#define VERSION_NAME " + str(version.name) + "\n") + f.write("#define VERSION_SHORT_NAME \"" + str(version.short_name) + "\"\n") + f.write("#define VERSION_NAME \"" + str(version.name) + "\"\n") f.write("#define VERSION_MAJOR " + str(version.major) + "\n") f.write("#define VERSION_MINOR " + str(version.minor) + "\n") if (hasattr(version, 'patch')): f.write("#define VERSION_PATCH " + str(version.patch) + "\n") - f.write("#define VERSION_REVISION " + str(rev) + "\n") - f.write("#define VERSION_STATUS " + str(version.status) + "\n") + f.write("#define VERSION_STATUS \"" + str(version.status) + "\"\n") + f.write("#define VERSION_BUILD \"" + str(build_name) + "\"\n") f.write("#define VERSION_MODULE_CONFIG \"" + str(version.module_config) + module_version_string + "\"\n") import datetime f.write("#define VERSION_YEAR " + str(datetime.datetime.now().year) + "\n") @@ -1686,6 +1686,17 @@ def find_visual_c_batch_file(env): (host_platform, target_platform,req_target_platform) = get_host_target(env) return find_batch_file(env, version, host_platform, target_platform)[0] +def generate_cpp_hint_file(filename): + import os.path + if os.path.isfile(filename): + # Don't overwrite an existing hint file since the user may have customized it. + pass + else: + try: + fd = open(filename, "w") + fd.write("#define GDCLASS(m_class, m_inherits)\n") + except IOError: + print("Could not write cpp.hint file.") def generate_vs_project(env, num_jobs): batch_file = find_visual_c_batch_file(env) @@ -1712,9 +1723,9 @@ def generate_vs_project(env, num_jobs): # to double quote off the directory. However, the path ends # in a backslash, so we need to remove this, lest it escape the # last double quote off, confusing MSBuild - env['MSVSBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs)) - env['MSVSREBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" platform=windows target=$(Configuration) tools=!tools! vsproj=yes -j' + str(num_jobs)) - env['MSVSCLEANCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" --clean platform=windows target=$(Configuration) tools=!tools! -j' + str(num_jobs)) + env['MSVSBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" platform=windows progress=no target=$(Configuration) tools=!tools! -j' + str(num_jobs)) + env['MSVSREBUILDCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" platform=windows progress=no target=$(Configuration) tools=!tools! vsproj=yes -j' + str(num_jobs)) + env['MSVSCLEANCOM'] = build_commandline('scons --directory="$(ProjectDir.TrimEnd(\'\\\'))" --clean platform=windows progress=no target=$(Configuration) tools=!tools! -j' + str(num_jobs)) # This version information (Win32, x64, Debug, Release, Release_Debug seems to be # required for Visual Studio to understand that it needs to generate an NMAKE diff --git a/misc/dist/html/default.html b/misc/dist/html/default.html index 9fae34f97e..0f78fc640e 100644 --- a/misc/dist/html/default.html +++ b/misc/dist/html/default.html @@ -225,12 +225,11 @@ $GODOT_HEAD_INCLUDE <script type="text/javascript" src="$GODOT_BASENAME.js"></script> <script type="text/javascript">//<![CDATA[ - var game = new Engine; + var engine = new Engine; (function() { const BASENAME = '$GODOT_BASENAME'; - const MEMORY_SIZE = $GODOT_TOTAL_MEMORY; const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED; const INDETERMINATE_STATUS_STEP_MS = 100; @@ -246,8 +245,7 @@ $GODOT_HEAD_INCLUDE var indeterminiateStatusAnimationId = 0; setStatusMode('indeterminate'); - game.setCanvas(canvas); - game.setAsmjsMemorySize(MEMORY_SIZE); + engine.setCanvas(canvas); function setStatusMode(mode) { @@ -302,7 +300,7 @@ $GODOT_HEAD_INCLUDE }); }; - game.setProgressFunc((current, total) => { + engine.setProgressFunc((current, total) => { if (total > 0) { statusProgressInner.style.width = current/total * 100 + '%'; @@ -332,10 +330,6 @@ $GODOT_HEAD_INCLUDE outputRoot.style.display = 'block'; function print(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - if (text.length <= 0) return; while (outputScroll.childElementCount >= OUTPUT_MSG_COUNT_MAX) { outputScroll.firstChild.remove(); } @@ -356,26 +350,31 @@ $GODOT_HEAD_INCLUDE }; function printError(text) { - print('**ERROR**' + ":", text); + if (!text.startsWith('**ERROR**: ')) { + text = '**ERROR**: ' + text; + } + print(text); } - game.setStdoutFunc(text => { + engine.setStdoutFunc(text => { print(text); console.log(text); }); - game.setStderrFunc(text => { + engine.setStderrFunc(text => { printError(text); console.warn(text); }); } - game.start(BASENAME + '.pck').then(() => { + engine.startGame(BASENAME + '.pck').then(() => { setStatusMode('hidden'); initializing = false; }, err => { - if (DEBUG_ENABLED) + if (DEBUG_ENABLED) { printError(err.message); + console.warn(err); + } setStatusNotice(err.message); setStatusMode('notice'); initializing = false; diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp index bc60c9cb6b..cbf30c8a2e 100644 --- a/modules/bullet/godot_result_callbacks.cpp +++ b/modules/bullet/godot_result_callbacks.cpp @@ -77,7 +77,7 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo PhysicsDirectSpaceState::ShapeResult &result = m_results[count]; - result.shape = convexResult.m_localShapeInfo->m_shapePart; + result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID result.rid = gObj->get_self(); result.collider_id = gObj->get_instance_id(); result.collider = 0 == result.collider_id ? NULL : ObjectDB::get_instance(result.collider_id); @@ -122,7 +122,7 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) { btScalar res = btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace); - m_shapePart = convexResult.m_localShapeInfo->m_shapePart; + m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID return res; } @@ -242,3 +242,21 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp return cp.getDistance(); } + +void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) { + + if (depth < 0) { + // Has penetration + if (m_most_penetrated_distance > depth) { + + bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); + + m_most_penetrated_distance = depth; + m_pointCollisionObject = (isSwapped ? m_body0Wrap : m_body1Wrap)->getCollisionObject(); + m_other_compound_shape_index = isSwapped ? m_index1 : m_index0; + m_pointNormalWorld = isSwapped ? normalOnBInWorld * -1 : normalOnBInWorld; + m_pointWorld = isSwapped ? (pointInWorldOnB + normalOnBInWorld * depth) : pointInWorldOnB; + m_penetration_distance = depth; + } + } +} diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h index 68dff5b12a..ba5142676b 100644 --- a/modules/bullet/godot_result_callbacks.h +++ b/modules/bullet/godot_result_callbacks.h @@ -88,7 +88,7 @@ public: struct GodotClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: const Set<RID> *m_exclude; - int m_shapePart; + int m_shapeId; GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude) : btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld), m_exclude(p_exclude) {} @@ -149,4 +149,31 @@ public: virtual btScalar addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1); }; +struct GodotDeepPenetrationContactResultCallback : public btManifoldResult { + btVector3 m_pointNormalWorld; + btVector3 m_pointWorld; + btScalar m_penetration_distance; + int m_other_compound_shape_index; + const btCollisionObject *m_pointCollisionObject; + + btScalar m_most_penetrated_distance; + + GodotDeepPenetrationContactResultCallback(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) + : btManifoldResult(body0Wrap, body1Wrap), + m_pointCollisionObject(NULL), + m_penetration_distance(0), + m_other_compound_shape_index(0), + m_most_penetrated_distance(1e20) {} + + void reset() { + m_pointCollisionObject = NULL; + m_most_penetrated_distance = 1e20; + } + + bool hasHit() { + return m_pointCollisionObject; + } + + virtual void addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorld, btScalar depth); +}; #endif // GODOT_RESULT_CALLBACKS_H diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp index 9df01aee3e..853906063b 100644 --- a/modules/bullet/space_bullet.cpp +++ b/modules/bullet/space_bullet.cpp @@ -115,12 +115,13 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); - btConvexShape *btConvex = dynamic_cast<btConvexShape *>(shape->create_bt_shape()); - if (!btConvex) { - bulletdelete(btConvex); + btCollisionShape *btShape = shape->create_bt_shape(); + if (!btShape->isConvex()) { + bulletdelete(btShape); ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } + btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); btVector3 scale_with_margin; G_TO_B(p_xform.basis.get_scale(), scale_with_margin); @@ -147,12 +148,13 @@ int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Tra bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, ShapeRestInfo *r_info) { ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); - btConvexShape *bt_convex_shape = dynamic_cast<btConvexShape *>(shape->create_bt_shape()); - if (!bt_convex_shape) { - bulletdelete(bt_convex_shape); + btCollisionShape *btShape = shape->create_bt_shape(); + if (!btShape->isConvex()) { + bulletdelete(btShape); ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } + btConvexShape *bt_convex_shape = static_cast<btConvexShape *>(btShape); btVector3 bt_motion; G_TO_B(p_motion, bt_motion); @@ -174,16 +176,18 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf space->dynamicsWorld->convexSweepTest(bt_convex_shape, bt_xform_from, bt_xform_to, btResult, 0.002); if (btResult.hasHit()) { - if (btCollisionObject::CO_RIGID_BODY == btResult.m_hitCollisionObject->getInternalType()) { - B_TO_G(static_cast<const btRigidBody *>(btResult.m_hitCollisionObject)->getVelocityInLocalPoint(btResult.m_hitPointWorld), r_info->linear_velocity); - } - CollisionObjectBullet *collision_object = static_cast<CollisionObjectBullet *>(btResult.m_hitCollisionObject->getUserPointer()); p_closest_safe = p_closest_unsafe = btResult.m_closestHitFraction; - B_TO_G(btResult.m_hitPointWorld, r_info->point); - B_TO_G(btResult.m_hitNormalWorld, r_info->normal); - r_info->rid = collision_object->get_self(); - r_info->collider_id = collision_object->get_instance_id(); - r_info->shape = btResult.m_shapePart; + if (r_info) { + if (btCollisionObject::CO_RIGID_BODY == btResult.m_hitCollisionObject->getInternalType()) { + B_TO_G(static_cast<const btRigidBody *>(btResult.m_hitCollisionObject)->getVelocityInLocalPoint(btResult.m_hitPointWorld), r_info->linear_velocity); + } + CollisionObjectBullet *collision_object = static_cast<CollisionObjectBullet *>(btResult.m_hitCollisionObject->getUserPointer()); + B_TO_G(btResult.m_hitPointWorld, r_info->point); + B_TO_G(btResult.m_hitNormalWorld, r_info->normal); + r_info->rid = collision_object->get_self(); + r_info->collider_id = collision_object->get_instance_id(); + r_info->shape = btResult.m_shapeId; + } } bulletdelete(bt_convex_shape); @@ -197,12 +201,13 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform & ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); - btConvexShape *btConvex = dynamic_cast<btConvexShape *>(shape->create_bt_shape()); - if (!btConvex) { - bulletdelete(btConvex); + btCollisionShape *btShape = shape->create_bt_shape(); + if (!btShape->isConvex()) { + bulletdelete(btShape); ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } + btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); btVector3 scale_with_margin; G_TO_B(p_shape_xform.basis.get_scale(), scale_with_margin); @@ -231,12 +236,13 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->get(p_shape); - btConvexShape *btConvex = dynamic_cast<btConvexShape *>(shape->create_bt_shape()); - if (!btConvex) { - bulletdelete(btConvex); + btCollisionShape *btShape = shape->create_bt_shape(); + if (!btShape->isConvex()) { + bulletdelete(btShape); ERR_PRINTS("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type())); return 0; } + btConvexShape *btConvex = static_cast<btConvexShape *>(btShape); btVector3 scale_with_margin; G_TO_B(p_shape_xform.basis.get_scale() + Vector3(p_margin, p_margin, p_margin), scale_with_margin); @@ -777,7 +783,8 @@ void SpaceBullet::check_body_collision() { void SpaceBullet::update_gravity() { btVector3 btGravity; G_TO_B(gravityDirection * gravityMagnitude, btGravity); - dynamicsWorld->setGravity(btGravity); + //dynamicsWorld->setGravity(btGravity); + dynamicsWorld->setGravity(btVector3(0, 0, 0)); if (soft_body_world_info) { soft_body_world_info->m_gravity = btGravity; } @@ -877,11 +884,11 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f continue; } - btConvexShape *convex_shape_test(dynamic_cast<btConvexShape *>(p_body->get_bt_shape(shIndex))); - if (!convex_shape_test) { + if (!p_body->get_bt_shape(shIndex)->isConvex()) { // Skip no convex shape continue; } + btConvexShape *convex_shape_test(static_cast<btConvexShape *>(p_body->get_bt_shape(shIndex))); btTransform shape_world_from; G_TO_B(p_body->get_shape_transform(shIndex), shape_world_from); @@ -910,26 +917,26 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f { /// Phase three - Recover + contact test with margin - RecoverResult recover_result; + RecoverResult r_recover_result; - hasPenetration = recover_from_penetration(p_body, body_safe_position, recovered_motion, &recover_result); + hasPenetration = recover_from_penetration(p_body, body_safe_position, recovered_motion, &r_recover_result); if (r_result) { B_TO_G(recovered_motion + recover_initial_position, r_result->motion); if (hasPenetration) { - const btRigidBody *btRigid = static_cast<const btRigidBody *>(recover_result.other_collision_object); + const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object); CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer()); r_result->remainder = p_motion - r_result->motion; // is the remaining movements - B_TO_G(recover_result.pointWorld, r_result->collision_point); - B_TO_G(recover_result.pointNormalWorld, r_result->collision_normal); - B_TO_G(btRigid->getVelocityInLocalPoint(recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot + B_TO_G(r_recover_result.pointWorld, r_result->collision_point); + B_TO_G(r_recover_result.pointNormalWorld, r_result->collision_normal); + B_TO_G(btRigid->getVelocityInLocalPoint(r_recover_result.pointWorld - btRigid->getWorldTransform().getOrigin()), r_result->collider_velocity); // It calculates velocity at point and assign it using special function Bullet_to_Godot r_result->collider = collisionObject->get_self(); r_result->collider_id = collisionObject->get_instance_id(); - r_result->collider_shape = recover_result.other_compound_shape_index; - r_result->collision_local_shape = recover_result.local_shape_most_recovered; + r_result->collider_shape = r_recover_result.other_compound_shape_index; + r_result->collision_local_shape = r_recover_result.local_shape_most_recovered; //{ /// Add manifold point to manage collisions // btPersistentManifold* manifold = dynamicsWorld->getDispatcher()->getNewManifold(p_body->getBtBody(), btRigid); @@ -995,7 +1002,7 @@ public: } }; -bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btVector3 &out_recover_position, RecoverResult *recover_result) { +bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btVector3 &r_recover_position, RecoverResult *r_recover_result) { RecoverPenetrationBroadPhaseCallback recover_broad_result(p_body->get_bt_collision_object(), p_body->get_collision_layer(), p_body->get_collision_mask()); @@ -1005,9 +1012,6 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran // Broad phase support btVector3 minAabb, maxAabb; - // GJK support - btGjkPairDetector::ClosestPointInput gjk_input; - bool penetration = false; // For each shape @@ -1022,7 +1026,7 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran body_shape_position = p_body_position * kin_shape.transform; body_shape_position_recovered = body_shape_position; - body_shape_position_recovered.getOrigin() += out_recover_position; + body_shape_position_recovered.getOrigin() += r_recover_position; kin_shape.shape->getAabb(body_shape_position_recovered, minAabb, maxAabb); dynamicsWorld->getBroadphase()->aabbTest(minAabb, maxAabb, recover_broad_result); @@ -1032,66 +1036,33 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) continue; - if (otherObject->getCollisionShape()->isCompound()) { /// Execute GJK test against all shapes + if (otherObject->getCollisionShape()->isCompound()) { // Each convex shape btCompoundShape *cs = static_cast<btCompoundShape *>(otherObject->getCollisionShape()); for (int x = cs->getNumChildShapes() - 1; 0 <= x; --x) { - if (!cs->getChildShape(x)->isConvex()) - continue; + if (cs->getChildShape(x)->isConvex()) { + if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), otherObject, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), r_recover_position, r_recover_result)) { - // Initialize GJK input - gjk_input.m_transformA = body_shape_position; - gjk_input.m_transformA.getOrigin() += out_recover_position; - gjk_input.m_transformB = otherObject->getWorldTransform() * cs->getChildTransform(x); + penetration = true; + } + } else { + if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(x), p_body->get_bt_collision_object(), otherObject, kinIndex, x, body_shape_position, otherObject->getWorldTransform() * cs->getChildTransform(x), r_recover_position, r_recover_result)) { - // Perform GJK test - btPointCollector result; - btGjkPairDetector gjk_pair_detector(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(x)), gjk_simplex_solver, gjk_epa_pen_solver); - gjk_pair_detector.getClosestPoints(gjk_input, result, 0); - if (0 > result.m_distance) { - // Has penetration - out_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1); - penetration = true; - - if (recover_result) { - - recover_result->hasPenetration = true; - recover_result->other_collision_object = otherObject; - recover_result->other_compound_shape_index = x; - recover_result->penetration_distance = result.m_distance; - recover_result->pointNormalWorld = result.m_normalOnBInWorld; - recover_result->pointWorld = result.m_pointInWorld; + penetration = true; } } } - } else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape + if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, 0, body_shape_position, otherObject->getWorldTransform(), r_recover_position, r_recover_result)) { - // Initialize GJK input - gjk_input.m_transformA = body_shape_position; - gjk_input.m_transformA.getOrigin() += out_recover_position; - gjk_input.m_transformB = otherObject->getWorldTransform(); - - // Perform GJK test - btPointCollector result; - btGjkPairDetector gjk_pair_detector(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), gjk_simplex_solver, gjk_epa_pen_solver); - gjk_pair_detector.getClosestPoints(gjk_input, result, 0); - if (0 > result.m_distance) { - // Has penetration - out_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1); penetration = true; + } + } else { + if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, body_shape_position, otherObject->getWorldTransform(), r_recover_position, r_recover_result)) { - if (recover_result) { - - recover_result->hasPenetration = true; - recover_result->other_collision_object = otherObject; - recover_result->other_compound_shape_index = 0; - recover_result->penetration_distance = result.m_distance; - recover_result->pointNormalWorld = result.m_normalOnBInWorld; - recover_result->pointWorld = result.m_pointInWorld; - } + penetration = true; } } } @@ -1099,3 +1070,70 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran return penetration; } + +bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result) { + + // Initialize GJK input + btGjkPairDetector::ClosestPointInput gjk_input; + gjk_input.m_transformA = p_transformA; + gjk_input.m_transformA.getOrigin() += r_recover_position; + gjk_input.m_transformB = p_transformB; + + // Perform GJK test + btPointCollector result; + btGjkPairDetector gjk_pair_detector(p_shapeA, p_shapeB, gjk_simplex_solver, gjk_epa_pen_solver); + gjk_pair_detector.getClosestPoints(gjk_input, result, 0); + if (0 > result.m_distance) { + // Has penetration + r_recover_position += result.m_normalOnBInWorld * (result.m_distance * -1); + + if (r_recover_result) { + + r_recover_result->hasPenetration = true; + r_recover_result->other_collision_object = p_objectB; + r_recover_result->other_compound_shape_index = p_shapeId_B; + r_recover_result->penetration_distance = result.m_distance; + r_recover_result->pointNormalWorld = result.m_normalOnBInWorld; + r_recover_result->pointWorld = result.m_pointInWorld; + } + return true; + } + return false; +} + +bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result) { + + /// Contact test + + btTransform p_recovered_transformA(p_transformA); + p_recovered_transformA.getOrigin() += r_recover_position; + + btCollisionObjectWrapper obA(NULL, p_shapeA, p_objectA, p_recovered_transformA, -1, p_shapeId_A); + btCollisionObjectWrapper obB(NULL, p_shapeB, p_objectB, p_transformB, -1, p_shapeId_B); + + btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, NULL, BT_CLOSEST_POINT_ALGORITHMS); + if (algorithm) { + GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB); + //discrete collision detection query + algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult); + + algorithm->~btCollisionAlgorithm(); + dispatcher->freeCollisionAlgorithm(algorithm); + + if (contactPointResult.hasHit()) { + r_recover_position += contactPointResult.m_pointNormalWorld * (contactPointResult.m_penetration_distance * -1); + + if (r_recover_result) { + + r_recover_result->hasPenetration = true; + r_recover_result->other_collision_object = p_objectB; + r_recover_result->other_compound_shape_index = p_shapeId_B; + r_recover_result->penetration_distance = contactPointResult.m_penetration_distance; + r_recover_result->pointNormalWorld = contactPointResult.m_pointNormalWorld; + r_recover_result->pointWorld = contactPointResult.m_pointWorld; + } + return true; + } + } + return false; +} diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h index d9206f8046..9acac9a7d6 100644 --- a/modules/bullet/space_bullet.h +++ b/modules/bullet/space_bullet.h @@ -189,6 +189,12 @@ private: : hasPenetration(false) {} }; - bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btVector3 &out_recover_position, RecoverResult *recover_result = NULL); + bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_from, btVector3 &r_recover_position, RecoverResult *r_recover_result = NULL); + /// This is an API that recover a kinematic object from penetration + /// This allow only Convex Convex test and it always use GJK algorithm, With this API we don't benefit of Bullet special accelerated functions + bool RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result); + /// This is an API that recover a kinematic object from penetration + /// Using this we leave Bullet to select the best algorithm, For example GJK in case we have Convex Convex, or a Bullet accelerated algorithm + bool RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btVector3 &r_recover_position, RecoverResult *r_recover_result); }; #endif diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp index c50886ad3c..1e18ec0d18 100644 --- a/modules/enet/networked_multiplayer_enet.cpp +++ b/modules/enet/networked_multiplayer_enet.cpp @@ -505,7 +505,7 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const { hash = hash_djb2_one_32( (uint32_t)OS::get_singleton()->get_unix_time(), hash); hash = hash_djb2_one_32( - (uint32_t)OS::get_singleton()->get_data_dir().hash64(), hash); + (uint32_t)OS::get_singleton()->get_user_data_dir().hash64(), hash); /* hash = hash_djb2_one_32( (uint32_t)OS::get_singleton()->get_unique_id().hash64(), hash ); diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 66b8d5cbdd..485bf4b9df 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -49,19 +49,6 @@ def _build_gdnative_api_struct_header(api): 'extern "C" {', '#endif', '', - 'typedef struct godot_gdnative_api_version {', - '\tunsigned int major;', - '\tunsigned int minor;', - '} godot_gdnative_api_version;', - '', - 'typedef struct godot_gdnative_api_struct godot_gdnative_api_struct;', - '', - 'struct godot_gdnative_api_struct {', - '\tunsigned int type;', - '\tgodot_gdnative_api_version version;', - '\tconst godot_gdnative_api_struct *next;', - '};', - '', 'enum GDNATIVE_API_TYPES {', '\tGDNATIVE_' + api['core']['type'] + ',' ] diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 44d6dffc85..f98a16a5d7 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -64,7 +64,6 @@ void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_current_library_path"), &GDNativeLibrary::get_current_library_path); ClassDB::bind_method(D_METHOD("get_current_dependencies"), &GDNativeLibrary::get_current_dependencies); - ClassDB::bind_method(D_METHOD("is_current_library_statically_linked"), &GDNativeLibrary::is_current_library_statically_linked); ClassDB::bind_method(D_METHOD("should_load_once"), &GDNativeLibrary::should_load_once); ClassDB::bind_method(D_METHOD("is_singleton"), &GDNativeLibrary::is_singleton); @@ -109,6 +108,9 @@ Ref<GDNativeLibrary> GDNative::get_library() { return library; } +extern "C" void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have); +extern "C" void _gdnative_report_loading_error(const godot_object *p_library, const char *p_what); + bool GDNative::initialize() { if (library.is_null()) { ERR_PRINT("No library set, can't initialize GDNative object"); @@ -116,7 +118,7 @@ bool GDNative::initialize() { } String lib_path = library->get_current_library_path(); - if (lib_path.empty() && !library->is_current_library_statically_linked()) { + if (lib_path.empty()) { ERR_PRINT("No library set for this platform"); return false; } @@ -137,7 +139,7 @@ bool GDNative::initialize() { } Error err = OS::get_singleton()->open_dynamic_library(path, native_handle); - if (err != OK && !library->is_current_library_statically_linked()) { + if (err != OK) { return false; } @@ -151,8 +153,7 @@ bool GDNative::initialize() { initialized = false; if (err || !library_init) { - if (!library->is_current_library_statically_linked()) - OS::get_singleton()->close_dynamic_library(native_handle); + OS::get_singleton()->close_dynamic_library(native_handle); native_handle = NULL; ERR_PRINT("Failed to obtain godot_gdnative_init symbol"); return false; @@ -168,6 +169,8 @@ bool GDNative::initialize() { options.core_api_hash = ClassDB::get_api_hash(ClassDB::API_CORE); options.editor_api_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); options.no_api_hash = ClassDB::get_api_hash(ClassDB::API_NONE); + options.report_version_mismatch = &_gdnative_report_version_mismatch; + options.report_loading_error = &_gdnative_report_loading_error; options.gd_native_library = (godot_object *)(get_library().ptr()); options.active_library_path = (godot_string *)&path; @@ -369,40 +372,8 @@ RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_or } } - bool is_statically_linked = false; - { - - List<String> static_linking_keys; - config->get_section_keys("static_linking", &static_linking_keys); - - for (List<String>::Element *E = static_linking_keys.front(); E; E = E->next()) { - String key = E->get(); - - Vector<String> tags = key.split("."); - - bool skip = false; - - for (int i = 0; i < tags.size(); i++) { - bool has_feature = OS::get_singleton()->has_feature(tags[i]); - - if (!has_feature) { - skip = true; - break; - } - } - - if (skip) { - continue; - } - - is_statically_linked = config->get_value("static_linking", key); - break; - } - } - lib->current_library_path = entry_lib_path; lib->current_dependencies = dependency_paths; - lib->current_library_statically_linked = is_statically_linked; return lib; } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 061dff9267..052ce1fef1 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -55,7 +55,6 @@ class GDNativeLibrary : public Resource { String current_library_path; Vector<String> current_dependencies; - bool current_library_statically_linked; bool singleton; bool load_once; @@ -75,9 +74,6 @@ public: _FORCE_INLINE_ Vector<String> get_current_dependencies() const { return current_dependencies; } - _FORCE_INLINE_ bool is_current_library_statically_linked() const { - return current_library_statically_linked; - } // things that are a property of the library itself, not platform specific _FORCE_INLINE_ bool should_load_once() const { @@ -103,12 +99,10 @@ public: static void _bind_methods(); }; -typedef godot_variant (*native_call_cb)(void *, godot_array *); - struct GDNativeCallRegistry { static GDNativeCallRegistry *singleton; - inline GDNativeCallRegistry *get_singleton() { + inline static GDNativeCallRegistry *get_singleton() { return singleton; } diff --git a/modules/gdnative/gdnative/aabb.cpp b/modules/gdnative/gdnative/aabb.cpp new file mode 100644 index 0000000000..6c89bcdceb --- /dev/null +++ b/modules/gdnative/gdnative/aabb.cpp @@ -0,0 +1,217 @@ +/*************************************************************************/ +/* aabb.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "gdnative/aabb.h" + +#include "core/math/aabb.h" +#include "core/variant.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) { + const Vector3 *pos = (const Vector3 *)p_pos; + const Vector3 *size = (const Vector3 *)p_size; + AABB *dest = (AABB *)r_dest; + *dest = AABB(*pos, *size); +} + +godot_vector3 GDAPI godot_aabb_get_position(const godot_aabb *p_self) { + godot_vector3 raw_ret; + const AABB *self = (const AABB *)p_self; + Vector3 *ret = (Vector3 *)&raw_ret; + *ret = self->position; + return raw_ret; +} + +void GDAPI godot_aabb_set_position(const godot_aabb *p_self, const godot_vector3 *p_v) { + AABB *self = (AABB *)p_self; + const Vector3 *v = (const Vector3 *)p_v; + self->position = *v; +} + +godot_vector3 GDAPI godot_aabb_get_size(const godot_aabb *p_self) { + godot_vector3 raw_ret; + const AABB *self = (const AABB *)p_self; + Vector3 *ret = (Vector3 *)&raw_ret; + *ret = self->size; + return raw_ret; +} + +void GDAPI godot_aabb_set_size(const godot_aabb *p_self, const godot_vector3 *p_v) { + AABB *self = (AABB *)p_self; + const Vector3 *v = (const Vector3 *)p_v; + self->size = *v; +} + +godot_string GDAPI godot_aabb_as_string(const godot_aabb *p_self) { + godot_string ret; + const AABB *self = (const AABB *)p_self; + memnew_placement(&ret, String(*self)); + return ret; +} + +godot_real GDAPI godot_aabb_get_area(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->get_area(); +} + +godot_bool GDAPI godot_aabb_has_no_area(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->has_no_area(); +} + +godot_bool GDAPI godot_aabb_has_no_surface(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->has_no_surface(); +} + +godot_bool GDAPI godot_aabb_intersects(const godot_aabb *p_self, const godot_aabb *p_with) { + const AABB *self = (const AABB *)p_self; + const AABB *with = (const AABB *)p_with; + return self->intersects(*with); +} + +godot_bool GDAPI godot_aabb_encloses(const godot_aabb *p_self, const godot_aabb *p_with) { + const AABB *self = (const AABB *)p_self; + const AABB *with = (const AABB *)p_with; + return self->encloses(*with); +} + +godot_aabb GDAPI godot_aabb_merge(const godot_aabb *p_self, const godot_aabb *p_with) { + godot_aabb dest; + const AABB *self = (const AABB *)p_self; + const AABB *with = (const AABB *)p_with; + *((AABB *)&dest) = self->merge(*with); + return dest; +} + +godot_aabb GDAPI godot_aabb_intersection(const godot_aabb *p_self, const godot_aabb *p_with) { + godot_aabb dest; + const AABB *self = (const AABB *)p_self; + const AABB *with = (const AABB *)p_with; + *((AABB *)&dest) = self->intersection(*with); + return dest; +} + +godot_bool GDAPI godot_aabb_intersects_plane(const godot_aabb *p_self, const godot_plane *p_plane) { + const AABB *self = (const AABB *)p_self; + const Plane *plane = (const Plane *)p_plane; + return self->intersects_plane(*plane); +} + +godot_bool GDAPI godot_aabb_intersects_segment(const godot_aabb *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to) { + const AABB *self = (const AABB *)p_self; + const Vector3 *from = (const Vector3 *)p_from; + const Vector3 *to = (const Vector3 *)p_to; + return self->intersects_segment(*from, *to); +} + +godot_bool GDAPI godot_aabb_has_point(const godot_aabb *p_self, const godot_vector3 *p_point) { + const AABB *self = (const AABB *)p_self; + const Vector3 *point = (const Vector3 *)p_point; + return self->has_point(*point); +} + +godot_vector3 GDAPI godot_aabb_get_support(const godot_aabb *p_self, const godot_vector3 *p_dir) { + godot_vector3 dest; + const AABB *self = (const AABB *)p_self; + const Vector3 *dir = (const Vector3 *)p_dir; + *((Vector3 *)&dest) = self->get_support(*dir); + return dest; +} + +godot_vector3 GDAPI godot_aabb_get_longest_axis(const godot_aabb *p_self) { + godot_vector3 dest; + const AABB *self = (const AABB *)p_self; + *((Vector3 *)&dest) = self->get_longest_axis(); + return dest; +} + +godot_int GDAPI godot_aabb_get_longest_axis_index(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->get_longest_axis_index(); +} + +godot_real GDAPI godot_aabb_get_longest_axis_size(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->get_longest_axis_size(); +} + +godot_vector3 GDAPI godot_aabb_get_shortest_axis(const godot_aabb *p_self) { + godot_vector3 dest; + const AABB *self = (const AABB *)p_self; + *((Vector3 *)&dest) = self->get_shortest_axis(); + return dest; +} + +godot_int GDAPI godot_aabb_get_shortest_axis_index(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->get_shortest_axis_index(); +} + +godot_real GDAPI godot_aabb_get_shortest_axis_size(const godot_aabb *p_self) { + const AABB *self = (const AABB *)p_self; + return self->get_shortest_axis_size(); +} + +godot_aabb GDAPI godot_aabb_expand(const godot_aabb *p_self, const godot_vector3 *p_to_point) { + godot_aabb dest; + const AABB *self = (const AABB *)p_self; + const Vector3 *to_point = (const Vector3 *)p_to_point; + *((AABB *)&dest) = self->expand(*to_point); + return dest; +} + +godot_aabb GDAPI godot_aabb_grow(const godot_aabb *p_self, const godot_real p_by) { + godot_aabb dest; + const AABB *self = (const AABB *)p_self; + + *((AABB *)&dest) = self->grow(p_by); + return dest; +} + +godot_vector3 GDAPI godot_aabb_get_endpoint(const godot_aabb *p_self, const godot_int p_idx) { + godot_vector3 dest; + const AABB *self = (const AABB *)p_self; + + *((Vector3 *)&dest) = self->get_endpoint(p_idx); + return dest; +} + +godot_bool GDAPI godot_aabb_operator_equal(const godot_aabb *p_self, const godot_aabb *p_b) { + const AABB *self = (const AABB *)p_self; + const AABB *b = (const AABB *)p_b; + return *self == *b; +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 6dfa7ec20b..92a88e354b 100644 --- a/modules/gdnative/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -36,6 +36,8 @@ #include "os/os.h" #include "variant.h" +#include "modules/gdnative/gdnative.h" + #ifdef __cplusplus extern "C" { #endif @@ -113,6 +115,10 @@ godot_dictionary GDAPI godot_get_global_constants() { } // System functions +void GDAPI godot_register_native_call_type(const char *p_call_type, native_call_cb p_callback) { + GDNativeCallRegistry::get_singleton()->register_native_call_type(StringName(p_call_type), p_callback); +} + void GDAPI *godot_alloc(int p_bytes) { return memalloc(p_bytes); } @@ -137,6 +143,32 @@ void GDAPI godot_print(const godot_string *p_message) { print_line(*(String *)p_message); } +void _gdnative_report_version_mismatch(const godot_object *p_library, const char *p_ext, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have) { + String message = "Error loading GDNative file "; + GDNativeLibrary *library = (GDNativeLibrary *)p_library; + + message += library->get_current_library_path() + ": Extension \"" + p_ext + "\" can't be loaded.\n"; + + Dictionary versions; + versions["have_major"] = p_have.major; + versions["have_minor"] = p_have.minor; + versions["want_major"] = p_want.major; + versions["want_minor"] = p_want.minor; + + message += String("Got version {have_major}.{have_minor} but needs {want_major}.{want_minor}!").format(versions); + + _err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr()); +} + +void _gdnative_report_loading_error(const godot_object *p_library, const char *p_what) { + String message = "Error loading GDNative file "; + GDNativeLibrary *library = (GDNativeLibrary *)p_library; + + message += library->get_current_library_path() + ": " + p_what; + + _err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr()); +} + #ifdef __cplusplus } #endif diff --git a/modules/gdnative/gdnative/rect3.cpp b/modules/gdnative/gdnative/rect3.cpp deleted file mode 100644 index 8e088743b4..0000000000 --- a/modules/gdnative/gdnative/rect3.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/*************************************************************************/ -/* rect3.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "gdnative/rect3.h" - -#include "core/math/rect3.h" -#include "core/variant.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) { - const Vector3 *pos = (const Vector3 *)p_pos; - const Vector3 *size = (const Vector3 *)p_size; - Rect3 *dest = (Rect3 *)r_dest; - *dest = Rect3(*pos, *size); -} - -godot_vector3 GDAPI godot_rect3_get_position(const godot_rect3 *p_self) { - godot_vector3 raw_ret; - const Rect3 *self = (const Rect3 *)p_self; - Vector3 *ret = (Vector3 *)&raw_ret; - *ret = self->position; - return raw_ret; -} - -void GDAPI godot_rect3_set_position(const godot_rect3 *p_self, const godot_vector3 *p_v) { - Rect3 *self = (Rect3 *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - self->position = *v; -} - -godot_vector3 GDAPI godot_rect3_get_size(const godot_rect3 *p_self) { - godot_vector3 raw_ret; - const Rect3 *self = (const Rect3 *)p_self; - Vector3 *ret = (Vector3 *)&raw_ret; - *ret = self->size; - return raw_ret; -} - -void GDAPI godot_rect3_set_size(const godot_rect3 *p_self, const godot_vector3 *p_v) { - Rect3 *self = (Rect3 *)p_self; - const Vector3 *v = (const Vector3 *)p_v; - self->size = *v; -} - -godot_string GDAPI godot_rect3_as_string(const godot_rect3 *p_self) { - godot_string ret; - const Rect3 *self = (const Rect3 *)p_self; - memnew_placement(&ret, String(*self)); - return ret; -} - -godot_real GDAPI godot_rect3_get_area(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->get_area(); -} - -godot_bool GDAPI godot_rect3_has_no_area(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->has_no_area(); -} - -godot_bool GDAPI godot_rect3_has_no_surface(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->has_no_surface(); -} - -godot_bool GDAPI godot_rect3_intersects(const godot_rect3 *p_self, const godot_rect3 *p_with) { - const Rect3 *self = (const Rect3 *)p_self; - const Rect3 *with = (const Rect3 *)p_with; - return self->intersects(*with); -} - -godot_bool GDAPI godot_rect3_encloses(const godot_rect3 *p_self, const godot_rect3 *p_with) { - const Rect3 *self = (const Rect3 *)p_self; - const Rect3 *with = (const Rect3 *)p_with; - return self->encloses(*with); -} - -godot_rect3 GDAPI godot_rect3_merge(const godot_rect3 *p_self, const godot_rect3 *p_with) { - godot_rect3 dest; - const Rect3 *self = (const Rect3 *)p_self; - const Rect3 *with = (const Rect3 *)p_with; - *((Rect3 *)&dest) = self->merge(*with); - return dest; -} - -godot_rect3 GDAPI godot_rect3_intersection(const godot_rect3 *p_self, const godot_rect3 *p_with) { - godot_rect3 dest; - const Rect3 *self = (const Rect3 *)p_self; - const Rect3 *with = (const Rect3 *)p_with; - *((Rect3 *)&dest) = self->intersection(*with); - return dest; -} - -godot_bool GDAPI godot_rect3_intersects_plane(const godot_rect3 *p_self, const godot_plane *p_plane) { - const Rect3 *self = (const Rect3 *)p_self; - const Plane *plane = (const Plane *)p_plane; - return self->intersects_plane(*plane); -} - -godot_bool GDAPI godot_rect3_intersects_segment(const godot_rect3 *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to) { - const Rect3 *self = (const Rect3 *)p_self; - const Vector3 *from = (const Vector3 *)p_from; - const Vector3 *to = (const Vector3 *)p_to; - return self->intersects_segment(*from, *to); -} - -godot_bool GDAPI godot_rect3_has_point(const godot_rect3 *p_self, const godot_vector3 *p_point) { - const Rect3 *self = (const Rect3 *)p_self; - const Vector3 *point = (const Vector3 *)p_point; - return self->has_point(*point); -} - -godot_vector3 GDAPI godot_rect3_get_support(const godot_rect3 *p_self, const godot_vector3 *p_dir) { - godot_vector3 dest; - const Rect3 *self = (const Rect3 *)p_self; - const Vector3 *dir = (const Vector3 *)p_dir; - *((Vector3 *)&dest) = self->get_support(*dir); - return dest; -} - -godot_vector3 GDAPI godot_rect3_get_longest_axis(const godot_rect3 *p_self) { - godot_vector3 dest; - const Rect3 *self = (const Rect3 *)p_self; - *((Vector3 *)&dest) = self->get_longest_axis(); - return dest; -} - -godot_int GDAPI godot_rect3_get_longest_axis_index(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->get_longest_axis_index(); -} - -godot_real GDAPI godot_rect3_get_longest_axis_size(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->get_longest_axis_size(); -} - -godot_vector3 GDAPI godot_rect3_get_shortest_axis(const godot_rect3 *p_self) { - godot_vector3 dest; - const Rect3 *self = (const Rect3 *)p_self; - *((Vector3 *)&dest) = self->get_shortest_axis(); - return dest; -} - -godot_int GDAPI godot_rect3_get_shortest_axis_index(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->get_shortest_axis_index(); -} - -godot_real GDAPI godot_rect3_get_shortest_axis_size(const godot_rect3 *p_self) { - const Rect3 *self = (const Rect3 *)p_self; - return self->get_shortest_axis_size(); -} - -godot_rect3 GDAPI godot_rect3_expand(const godot_rect3 *p_self, const godot_vector3 *p_to_point) { - godot_rect3 dest; - const Rect3 *self = (const Rect3 *)p_self; - const Vector3 *to_point = (const Vector3 *)p_to_point; - *((Rect3 *)&dest) = self->expand(*to_point); - return dest; -} - -godot_rect3 GDAPI godot_rect3_grow(const godot_rect3 *p_self, const godot_real p_by) { - godot_rect3 dest; - const Rect3 *self = (const Rect3 *)p_self; - - *((Rect3 *)&dest) = self->grow(p_by); - return dest; -} - -godot_vector3 GDAPI godot_rect3_get_endpoint(const godot_rect3 *p_self, const godot_int p_idx) { - godot_vector3 dest; - const Rect3 *self = (const Rect3 *)p_self; - - *((Vector3 *)&dest) = self->get_endpoint(p_idx); - return dest; -} - -godot_bool GDAPI godot_rect3_operator_equal(const godot_rect3 *p_self, const godot_rect3 *p_b) { - const Rect3 *self = (const Rect3 *)p_self; - const Rect3 *b = (const Rect3 *)p_b; - return *self == *b; -} - -#ifdef __cplusplus -} -#endif diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 781b8754bd..67a037736c 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -89,11 +89,6 @@ wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, cons return self->operator[](p_idx); } -const char GDAPI *godot_string_c_str(const godot_string *p_self) { - const String *self = (const String *)p_self; - return self->utf8().get_data(); -} - const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self) { const String *self = (const String *)p_self; return self->c_str(); diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp index 96b2ec8a7a..b07fcffcb6 100644 --- a/modules/gdnative/gdnative/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -198,20 +198,20 @@ godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_s return raw_dest; } -godot_rect3 GDAPI godot_transform_xform_rect3(const godot_transform *p_self, const godot_rect3 *p_v) { - godot_rect3 raw_dest; - Rect3 *dest = (Rect3 *)&raw_dest; +godot_aabb GDAPI godot_transform_xform_aabb(const godot_transform *p_self, const godot_aabb *p_v) { + godot_aabb raw_dest; + AABB *dest = (AABB *)&raw_dest; const Transform *self = (const Transform *)p_self; - const Rect3 *v = (const Rect3 *)p_v; + const AABB *v = (const AABB *)p_v; *dest = self->xform(*v); return raw_dest; } -godot_rect3 GDAPI godot_transform_xform_inv_rect3(const godot_transform *p_self, const godot_rect3 *p_v) { - godot_rect3 raw_dest; - Rect3 *dest = (Rect3 *)&raw_dest; +godot_aabb GDAPI godot_transform_xform_inv_aabb(const godot_transform *p_self, const godot_aabb *p_v) { + godot_aabb raw_dest; + AABB *dest = (AABB *)&raw_dest; const Transform *self = (const Transform *)p_self; - const Rect3 *v = (const Rect3 *)p_v; + const AABB *v = (const AABB *)p_v; *dest = self->xform_inv(*v); return raw_dest; } diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 0c31bc643c..6483d19d74 100644 --- a/modules/gdnative/gdnative/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -118,10 +118,10 @@ void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_qua memnew_placement_custom(dest, Variant, Variant(*quat)); } -void GDAPI godot_variant_new_rect3(godot_variant *r_dest, const godot_rect3 *p_rect3) { +void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb) { Variant *dest = (Variant *)r_dest; - Rect3 *rect3 = (Rect3 *)p_rect3; - memnew_placement_custom(dest, Variant, Variant(*rect3)); + AABB *aabb = (AABB *)p_aabb; + memnew_placement_custom(dest, Variant, Variant(*aabb)); } void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis) { @@ -304,10 +304,10 @@ godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self) { return raw_dest; } -godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_self) { - godot_rect3 raw_dest; +godot_aabb GDAPI godot_variant_as_aabb(const godot_variant *p_self) { + godot_aabb raw_dest; const Variant *self = (const Variant *)p_self; - Rect3 *dest = (Rect3 *)&raw_dest; + AABB *dest = (AABB *)&raw_dest; *dest = *self; return raw_dest; } diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json index 770fb429c7..007c7955d4 100644 --- a/modules/gdnative/gdnative_api.json +++ b/modules/gdnative/gdnative_api.json @@ -3221,209 +3221,209 @@ ] }, { - "name": "godot_rect3_new", + "name": "godot_aabb_new", "return_type": "void", "arguments": [ - ["godot_rect3 *", "r_dest"], + ["godot_aabb *", "r_dest"], ["const godot_vector3 *", "p_pos"], ["const godot_vector3 *", "p_size"] ] }, { - "name": "godot_rect3_get_position", + "name": "godot_aabb_get_position", "return_type": "godot_vector3", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_set_position", + "name": "godot_aabb_set_position", "return_type": "void", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_vector3 *", "p_v"] ] }, { - "name": "godot_rect3_get_size", + "name": "godot_aabb_get_size", "return_type": "godot_vector3", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_set_size", + "name": "godot_aabb_set_size", "return_type": "void", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_vector3 *", "p_v"] ] }, { - "name": "godot_rect3_as_string", + "name": "godot_aabb_as_string", "return_type": "godot_string", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_get_area", + "name": "godot_aabb_get_area", "return_type": "godot_real", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_has_no_area", + "name": "godot_aabb_has_no_area", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_has_no_surface", + "name": "godot_aabb_has_no_surface", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_intersects", + "name": "godot_aabb_intersects", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"], - ["const godot_rect3 *", "p_with"] + ["const godot_aabb *", "p_self"], + ["const godot_aabb *", "p_with"] ] }, { - "name": "godot_rect3_encloses", + "name": "godot_aabb_encloses", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"], - ["const godot_rect3 *", "p_with"] + ["const godot_aabb *", "p_self"], + ["const godot_aabb *", "p_with"] ] }, { - "name": "godot_rect3_merge", - "return_type": "godot_rect3", + "name": "godot_aabb_merge", + "return_type": "godot_aabb", "arguments": [ - ["const godot_rect3 *", "p_self"], - ["const godot_rect3 *", "p_with"] + ["const godot_aabb *", "p_self"], + ["const godot_aabb *", "p_with"] ] }, { - "name": "godot_rect3_intersection", - "return_type": "godot_rect3", + "name": "godot_aabb_intersection", + "return_type": "godot_aabb", "arguments": [ - ["const godot_rect3 *", "p_self"], - ["const godot_rect3 *", "p_with"] + ["const godot_aabb *", "p_self"], + ["const godot_aabb *", "p_with"] ] }, { - "name": "godot_rect3_intersects_plane", + "name": "godot_aabb_intersects_plane", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_plane *", "p_plane"] ] }, { - "name": "godot_rect3_intersects_segment", + "name": "godot_aabb_intersects_segment", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_vector3 *", "p_from"], ["const godot_vector3 *", "p_to"] ] }, { - "name": "godot_rect3_has_point", + "name": "godot_aabb_has_point", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_vector3 *", "p_point"] ] }, { - "name": "godot_rect3_get_support", + "name": "godot_aabb_get_support", "return_type": "godot_vector3", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_vector3 *", "p_dir"] ] }, { - "name": "godot_rect3_get_longest_axis", + "name": "godot_aabb_get_longest_axis", "return_type": "godot_vector3", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_get_longest_axis_index", + "name": "godot_aabb_get_longest_axis_index", "return_type": "godot_int", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_get_longest_axis_size", + "name": "godot_aabb_get_longest_axis_size", "return_type": "godot_real", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_get_shortest_axis", + "name": "godot_aabb_get_shortest_axis", "return_type": "godot_vector3", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_get_shortest_axis_index", + "name": "godot_aabb_get_shortest_axis_index", "return_type": "godot_int", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_get_shortest_axis_size", + "name": "godot_aabb_get_shortest_axis_size", "return_type": "godot_real", "arguments": [ - ["const godot_rect3 *", "p_self"] + ["const godot_aabb *", "p_self"] ] }, { - "name": "godot_rect3_expand", - "return_type": "godot_rect3", + "name": "godot_aabb_expand", + "return_type": "godot_aabb", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_vector3 *", "p_to_point"] ] }, { - "name": "godot_rect3_grow", - "return_type": "godot_rect3", + "name": "godot_aabb_grow", + "return_type": "godot_aabb", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_real", "p_by"] ] }, { - "name": "godot_rect3_get_endpoint", + "name": "godot_aabb_get_endpoint", "return_type": "godot_vector3", "arguments": [ - ["const godot_rect3 *", "p_self"], + ["const godot_aabb *", "p_self"], ["const godot_int", "p_idx"] ] }, { - "name": "godot_rect3_operator_equal", + "name": "godot_aabb_operator_equal", "return_type": "godot_bool", "arguments": [ - ["const godot_rect3 *", "p_self"], - ["const godot_rect3 *", "p_b"] + ["const godot_aabb *", "p_self"], + ["const godot_aabb *", "p_b"] ] }, { @@ -3632,19 +3632,19 @@ ] }, { - "name": "godot_transform_xform_rect3", - "return_type": "godot_rect3", + "name": "godot_transform_xform_aabb", + "return_type": "godot_aabb", "arguments": [ ["const godot_transform *", "p_self"], - ["const godot_rect3 *", "p_v"] + ["const godot_aabb *", "p_v"] ] }, { - "name": "godot_transform_xform_inv_rect3", - "return_type": "godot_rect3", + "name": "godot_transform_xform_inv_aabb", + "return_type": "godot_aabb", "arguments": [ ["const godot_transform *", "p_self"], - ["const godot_rect3 *", "p_v"] + ["const godot_aabb *", "p_v"] ] }, { @@ -3930,11 +3930,11 @@ ] }, { - "name": "godot_variant_new_rect3", + "name": "godot_variant_new_aabb", "return_type": "void", "arguments": [ ["godot_variant *", "r_dest"], - ["const godot_rect3 *", "p_rect3"] + ["const godot_aabb *", "p_aabb"] ] }, { @@ -4135,8 +4135,8 @@ ] }, { - "name": "godot_variant_as_rect3", - "return_type": "godot_rect3", + "name": "godot_variant_as_aabb", + "return_type": "godot_aabb", "arguments": [ ["const godot_variant *", "p_self"] ] @@ -4362,13 +4362,6 @@ ] }, { - "name": "godot_string_c_str", - "return_type": "const char *", - "arguments": [ - ["const godot_string *", "p_self"] - ] - }, - { "name": "godot_string_unicode_str", "return_type": "const wchar_t *", "arguments": [ @@ -5556,6 +5549,14 @@ ] }, { + "name": "godot_register_native_call_type", + "return_type": "void", + "arguments": [ + ["const char *", "call_type"], + ["native_call_cb", "p_callback"] + ] + }, + { "name": "godot_alloc", "return_type": "void *", "arguments": [ diff --git a/modules/gdnative/include/gdnative/aabb.h b/modules/gdnative/include/gdnative/aabb.h new file mode 100644 index 0000000000..34339fa242 --- /dev/null +++ b/modules/gdnative/include/gdnative/aabb.h @@ -0,0 +1,117 @@ +/*************************************************************************/ +/* aabb.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef GODOT_AABB_H +#define GODOT_AABB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> + +#define GODOT_AABB_SIZE 24 + +#ifndef GODOT_CORE_API_GODOT_AABB_TYPE_DEFINED +#define GODOT_CORE_API_GODOT_AABB_TYPE_DEFINED +typedef struct { + uint8_t _dont_touch_that[GODOT_AABB_SIZE]; +} godot_aabb; +#endif + +// reduce extern "C" nesting for VS2013 +#ifdef __cplusplus +} +#endif + +#include <gdnative/gdnative.h> +#include <gdnative/plane.h> +#include <gdnative/vector3.h> + +#ifdef __cplusplus +extern "C" { +#endif + +void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size); + +godot_vector3 GDAPI godot_aabb_get_position(const godot_aabb *p_self); +void GDAPI godot_aabb_set_position(const godot_aabb *p_self, const godot_vector3 *p_v); + +godot_vector3 GDAPI godot_aabb_get_size(const godot_aabb *p_self); +void GDAPI godot_aabb_set_size(const godot_aabb *p_self, const godot_vector3 *p_v); + +godot_string GDAPI godot_aabb_as_string(const godot_aabb *p_self); + +godot_real GDAPI godot_aabb_get_area(const godot_aabb *p_self); + +godot_bool GDAPI godot_aabb_has_no_area(const godot_aabb *p_self); + +godot_bool GDAPI godot_aabb_has_no_surface(const godot_aabb *p_self); + +godot_bool GDAPI godot_aabb_intersects(const godot_aabb *p_self, const godot_aabb *p_with); + +godot_bool GDAPI godot_aabb_encloses(const godot_aabb *p_self, const godot_aabb *p_with); + +godot_aabb GDAPI godot_aabb_merge(const godot_aabb *p_self, const godot_aabb *p_with); + +godot_aabb GDAPI godot_aabb_intersection(const godot_aabb *p_self, const godot_aabb *p_with); + +godot_bool GDAPI godot_aabb_intersects_plane(const godot_aabb *p_self, const godot_plane *p_plane); + +godot_bool GDAPI godot_aabb_intersects_segment(const godot_aabb *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to); + +godot_bool GDAPI godot_aabb_has_point(const godot_aabb *p_self, const godot_vector3 *p_point); + +godot_vector3 GDAPI godot_aabb_get_support(const godot_aabb *p_self, const godot_vector3 *p_dir); + +godot_vector3 GDAPI godot_aabb_get_longest_axis(const godot_aabb *p_self); + +godot_int GDAPI godot_aabb_get_longest_axis_index(const godot_aabb *p_self); + +godot_real GDAPI godot_aabb_get_longest_axis_size(const godot_aabb *p_self); + +godot_vector3 GDAPI godot_aabb_get_shortest_axis(const godot_aabb *p_self); + +godot_int GDAPI godot_aabb_get_shortest_axis_index(const godot_aabb *p_self); + +godot_real GDAPI godot_aabb_get_shortest_axis_size(const godot_aabb *p_self); + +godot_aabb GDAPI godot_aabb_expand(const godot_aabb *p_self, const godot_vector3 *p_to_point); + +godot_aabb GDAPI godot_aabb_grow(const godot_aabb *p_self, const godot_real p_by); + +godot_vector3 GDAPI godot_aabb_get_endpoint(const godot_aabb *p_self, const godot_int p_idx); + +godot_bool GDAPI godot_aabb_operator_equal(const godot_aabb *p_self, const godot_aabb *p_b); + +#ifdef __cplusplus +} +#endif + +#endif // GODOT_AABB_H diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index a479eced16..0a884e6106 100644 --- a/modules/gdnative/include/gdnative/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -169,9 +169,9 @@ typedef void godot_object; #include <gdnative/quat.h> -/////// Rect3 +/////// AABB -#include <gdnative/rect3.h> +#include <gdnative/aabb.h> /////// Basis @@ -229,13 +229,28 @@ void GDAPI godot_method_bind_ptrcall(godot_method_bind *p_method_bind, godot_obj godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, godot_object *p_instance, const godot_variant **p_args, const int p_arg_count, godot_variant_call_error *p_call_error); ////// Script API -struct godot_gdnative_api_struct; // Forward declaration +typedef struct godot_gdnative_api_version { + unsigned int major; + unsigned int minor; +} godot_gdnative_api_version; + +typedef struct godot_gdnative_api_struct godot_gdnative_api_struct; + +struct godot_gdnative_api_struct { + unsigned int type; + godot_gdnative_api_version version; + const godot_gdnative_api_struct *next; +}; + +#define GDNATIVE_VERSION_COMPATIBLE(want, have) (want.major == have.major && want.minor <= have.minor) typedef struct { godot_bool in_editor; uint64_t core_api_hash; uint64_t editor_api_hash; uint64_t no_api_hash; + void (*report_version_mismatch)(const godot_object *p_library, const char *p_what, godot_gdnative_api_version p_want, godot_gdnative_api_version p_have); + void (*report_loading_error)(const godot_object *p_library, const char *p_what); godot_object *gd_native_library; // pointer to GDNativeLibrary that is being initialized const struct godot_gdnative_core_api_struct *api_struct; const godot_string *active_library_path; @@ -259,6 +274,9 @@ typedef godot_variant (*godot_gdnative_procedure_fn)(godot_array *); ////// System Functions +typedef godot_variant (*native_call_cb)(void *, godot_array *); +void GDAPI godot_register_native_call_type(const char *p_call_type, native_call_cb p_callback); + //using these will help Godot track how much memory is in use in debug mode void GDAPI *godot_alloc(int p_bytes); void GDAPI *godot_realloc(void *p_ptr, int p_bytes); diff --git a/modules/gdnative/include/gdnative/rect3.h b/modules/gdnative/include/gdnative/rect3.h deleted file mode 100644 index f603a9268a..0000000000 --- a/modules/gdnative/include/gdnative/rect3.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************/ -/* rect3.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef GODOT_RECT3_H -#define GODOT_RECT3_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdint.h> - -#define GODOT_RECT3_SIZE 24 - -#ifndef GODOT_CORE_API_GODOT_RECT3_TYPE_DEFINED -#define GODOT_CORE_API_GODOT_RECT3_TYPE_DEFINED -typedef struct { - uint8_t _dont_touch_that[GODOT_RECT3_SIZE]; -} godot_rect3; -#endif - -// reduce extern "C" nesting for VS2013 -#ifdef __cplusplus -} -#endif - -#include <gdnative/gdnative.h> -#include <gdnative/plane.h> -#include <gdnative/vector3.h> - -#ifdef __cplusplus -extern "C" { -#endif - -void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size); - -godot_vector3 GDAPI godot_rect3_get_position(const godot_rect3 *p_self); -void GDAPI godot_rect3_set_position(const godot_rect3 *p_self, const godot_vector3 *p_v); - -godot_vector3 GDAPI godot_rect3_get_size(const godot_rect3 *p_self); -void GDAPI godot_rect3_set_size(const godot_rect3 *p_self, const godot_vector3 *p_v); - -godot_string GDAPI godot_rect3_as_string(const godot_rect3 *p_self); - -godot_real GDAPI godot_rect3_get_area(const godot_rect3 *p_self); - -godot_bool GDAPI godot_rect3_has_no_area(const godot_rect3 *p_self); - -godot_bool GDAPI godot_rect3_has_no_surface(const godot_rect3 *p_self); - -godot_bool GDAPI godot_rect3_intersects(const godot_rect3 *p_self, const godot_rect3 *p_with); - -godot_bool GDAPI godot_rect3_encloses(const godot_rect3 *p_self, const godot_rect3 *p_with); - -godot_rect3 GDAPI godot_rect3_merge(const godot_rect3 *p_self, const godot_rect3 *p_with); - -godot_rect3 GDAPI godot_rect3_intersection(const godot_rect3 *p_self, const godot_rect3 *p_with); - -godot_bool GDAPI godot_rect3_intersects_plane(const godot_rect3 *p_self, const godot_plane *p_plane); - -godot_bool GDAPI godot_rect3_intersects_segment(const godot_rect3 *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to); - -godot_bool GDAPI godot_rect3_has_point(const godot_rect3 *p_self, const godot_vector3 *p_point); - -godot_vector3 GDAPI godot_rect3_get_support(const godot_rect3 *p_self, const godot_vector3 *p_dir); - -godot_vector3 GDAPI godot_rect3_get_longest_axis(const godot_rect3 *p_self); - -godot_int GDAPI godot_rect3_get_longest_axis_index(const godot_rect3 *p_self); - -godot_real GDAPI godot_rect3_get_longest_axis_size(const godot_rect3 *p_self); - -godot_vector3 GDAPI godot_rect3_get_shortest_axis(const godot_rect3 *p_self); - -godot_int GDAPI godot_rect3_get_shortest_axis_index(const godot_rect3 *p_self); - -godot_real GDAPI godot_rect3_get_shortest_axis_size(const godot_rect3 *p_self); - -godot_rect3 GDAPI godot_rect3_expand(const godot_rect3 *p_self, const godot_vector3 *p_to_point); - -godot_rect3 GDAPI godot_rect3_grow(const godot_rect3 *p_self, const godot_real p_by); - -godot_vector3 GDAPI godot_rect3_get_endpoint(const godot_rect3 *p_self, const godot_int p_idx); - -godot_bool GDAPI godot_rect3_operator_equal(const godot_rect3 *p_self, const godot_rect3 *p_b); - -#ifdef __cplusplus -} -#endif - -#endif // GODOT_RECT3_H diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h index 29510313c9..10358ceade 100644 --- a/modules/gdnative/include/gdnative/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -51,6 +51,7 @@ typedef struct { } #endif +#include <gdnative/array.h> #include <gdnative/gdnative.h> #include <gdnative/variant.h> @@ -67,7 +68,6 @@ void GDAPI godot_string_get_data(const godot_string *p_self, char *p_dest, int * wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx); wchar_t GDAPI godot_string_operator_index_const(const godot_string *p_self, const godot_int p_idx); -const char GDAPI *godot_string_c_str(const godot_string *p_self); const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self); godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b); diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h index 8f50b01fb5..3b5c189bdf 100644 --- a/modules/gdnative/include/gdnative/transform.h +++ b/modules/gdnative/include/gdnative/transform.h @@ -98,9 +98,9 @@ godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v); -godot_rect3 GDAPI godot_transform_xform_rect3(const godot_transform *p_self, const godot_rect3 *p_v); +godot_aabb GDAPI godot_transform_xform_aabb(const godot_transform *p_self, const godot_aabb *p_v); -godot_rect3 GDAPI godot_transform_xform_inv_rect3(const godot_transform *p_self, const godot_rect3 *p_v); +godot_aabb GDAPI godot_transform_xform_inv_aabb(const godot_transform *p_self, const godot_aabb *p_v); #ifdef __cplusplus } diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h index 3d744ef1f2..06cafcfa63 100644 --- a/modules/gdnative/include/gdnative/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -62,7 +62,7 @@ typedef enum godot_variant_type { GODOT_VARIANT_TYPE_TRANSFORM2D, GODOT_VARIANT_TYPE_PLANE, GODOT_VARIANT_TYPE_QUAT, // 10 - GODOT_VARIANT_TYPE_RECT3, + GODOT_VARIANT_TYPE_AABB, GODOT_VARIANT_TYPE_BASIS, GODOT_VARIANT_TYPE_TRANSFORM, @@ -104,6 +104,7 @@ typedef struct godot_variant_call_error { } #endif +#include <gdnative/aabb.h> #include <gdnative/array.h> #include <gdnative/basis.h> #include <gdnative/color.h> @@ -113,7 +114,6 @@ typedef struct godot_variant_call_error { #include <gdnative/pool_arrays.h> #include <gdnative/quat.h> #include <gdnative/rect2.h> -#include <gdnative/rect3.h> #include <gdnative/rid.h> #include <gdnative/string.h> #include <gdnative/transform.h> @@ -145,7 +145,7 @@ void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d); void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane); void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat); -void GDAPI godot_variant_new_rect3(godot_variant *r_dest, const godot_rect3 *p_rect3); +void GDAPI godot_variant_new_aabb(godot_variant *r_dest, const godot_aabb *p_aabb); void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis); void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans); void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color); @@ -173,7 +173,7 @@ godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self); godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_self); godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_self); godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self); -godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_self); +godot_aabb GDAPI godot_variant_as_aabb(const godot_variant *p_self); godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self); godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self); godot_color GDAPI godot_variant_as_color(const godot_variant *p_self); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 29b0a6719c..8af643df50 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -371,7 +371,7 @@ void unregister_gdnative_types() { print_line(String("poolarray:\t") + itos(sizeof(PoolByteArray))); print_line(String("quat:\t") + itos(sizeof(Quat))); print_line(String("rect2:\t") + itos(sizeof(Rect2))); - print_line(String("rect3:\t") + itos(sizeof(Rect3))); + print_line(String("aabb:\t") + itos(sizeof(AABB))); print_line(String("rid:\t") + itos(sizeof(RID))); print_line(String("string:\t") + itos(sizeof(String))); print_line(String("transform:\t") + itos(sizeof(Transform))); diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index 467dbf3e56..c6066ceefb 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -642,7 +642,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } //str+="\n"; - OS::get_singleton()->printerr("%s\n", str.utf8().get_data()); + print_error(str); r_ret = Variant(); } break; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 29b9865b1d..1e677f11c4 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -3758,22 +3758,82 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { current_export.hint = PROPERTY_HINT_NONE; } - } else if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER) { + } else { - String identifier = tokenizer->get_token_identifier(); - if (!ClassDB::is_parent_class(identifier, "Resource")) { + parenthesis++; + Node *subexpr = _parse_and_reduce_expression(p_class, true, true); + if (!subexpr) { + if (_recover_from_completion()) { + break; + } + return; + } + parenthesis--; + if (subexpr->type != Node::TYPE_CONSTANT) { current_export = PropertyInfo(); - _set_error("Export hint not a type or resource."); + _set_error("Expected a constant expression."); } - current_export.type = Variant::OBJECT; - current_export.hint = PROPERTY_HINT_RESOURCE_TYPE; - current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; + Variant constant = static_cast<ConstantNode *>(subexpr)->value; - current_export.hint_string = identifier; + if (constant.get_type() == Variant::OBJECT) { + GDScriptNativeClass *native_class = Object::cast_to<GDScriptNativeClass>(constant); - tokenizer->advance(); + if (native_class && ClassDB::is_parent_class(native_class->get_name(), "Resource")) { + current_export.type = Variant::OBJECT; + current_export.hint = PROPERTY_HINT_RESOURCE_TYPE; + current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE; + + current_export.hint_string = native_class->get_name(); + + } else { + current_export = PropertyInfo(); + _set_error("Export hint not a resource type."); + } + } else if (constant.get_type() == Variant::DICTIONARY) { + // Enumeration + bool is_flags = false; + + if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { + tokenizer->advance(); + + if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") { + is_flags = true; + tokenizer->advance(); + } else { + current_export = PropertyInfo(); + _set_error("Expected 'FLAGS' after comma."); + } + } + + current_export.type = Variant::INT; + current_export.hint = is_flags ? PROPERTY_HINT_FLAGS : PROPERTY_HINT_ENUM; + Dictionary enum_values = constant; + + List<Variant> keys; + enum_values.get_key_list(&keys); + + bool first = true; + for (List<Variant>::Element *E = keys.front(); E; E = E->next()) { + if (enum_values[E->get()].get_type() == Variant::INT) { + if (!first) + current_export.hint_string += ","; + else + first = false; + + current_export.hint_string += E->get().operator String().camelcase_to_underscore(true).capitalize().xml_escape(); + if (!is_flags) { + current_export.hint_string += ":"; + current_export.hint_string += enum_values[E->get()].operator String().xml_escape(); + } + } + } + } else { + current_export = PropertyInfo(); + _set_error("Expected type for export."); + return; + } } if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index 174bb02967..e3a0af8ee6 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -148,7 +148,7 @@ static const _bit _type_list[] = { { Variant::RECT2, "Rect2" }, { Variant::TRANSFORM2D, "Transform2D" }, { Variant::VECTOR3, "Vector3" }, - { Variant::RECT3, "Rect3" }, + { Variant::AABB, "AABB" }, { Variant::PLANE, "Plane" }, { Variant::QUAT, "Quat" }, { Variant::BASIS, "Basis" }, @@ -253,9 +253,9 @@ bool GDScriptTokenizer::is_token_literal(int p_offset, bool variable_safe) const case TK_BUILT_IN_FUNC: case TK_OP_IN: - //case TK_OP_NOT: - //case TK_OP_OR: - //case TK_OP_AND: + //case TK_OP_NOT: + //case TK_OP_OR: + //case TK_OP_AND: case TK_PR_CLASS: case TK_PR_CONST: @@ -1125,7 +1125,7 @@ void GDScriptTokenizerText::advance(int p_amount) { _advance(); } -////////////////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////////////////// #define BYTECODE_VERSION 12 diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index bceb2b7db7..491adb31ee 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -1137,7 +1137,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { for (int i = 0; i < 12; i++) { - Rect3 base(Vector3(0, 0, 0), Vector3(1, 1, 1)); + AABB base(Vector3(0, 0, 0), Vector3(1, 1, 1)); Vector3 a, b; base.get_edge(i, a, b); lines.push_back(a); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 161e130a07..dfa5e720ae 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -346,7 +346,7 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::TRANSFORM2D, Variant::PLANE, Variant::QUAT, - Variant::RECT3, + Variant::AABB, Variant::BASIS, Variant::TRANSFORM, Variant::COLOR, diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index a293cc2c50..59a2b73dbc 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -1721,7 +1721,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; case Variant::PLANE: - case Variant::RECT3: + case Variant::AABB: case Variant::COLOR: r_iarg.default_argument = "new Color(1, 1, 1, 1)"; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; @@ -1793,7 +1793,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() { INSERT_STRUCT_TYPE(Basis, "real_t*") INSERT_STRUCT_TYPE(Quat, "real_t*") INSERT_STRUCT_TYPE(Transform, "real_t*") - INSERT_STRUCT_TYPE(Rect3, "real_t*") + INSERT_STRUCT_TYPE(AABB, "real_t*") INSERT_STRUCT_TYPE(Color, "real_t*") INSERT_STRUCT_TYPE(Plane, "real_t*") diff --git a/modules/mono/glue/cs_files/Rect3.cs b/modules/mono/glue/cs_files/AABB.cs index 617d33e7fd..6ee3bbe53a 100644 --- a/modules/mono/glue/cs_files/Rect3.cs +++ b/modules/mono/glue/cs_files/AABB.cs @@ -1,15 +1,15 @@ using System; -// file: core/math/rect3.h +// file: core/math/aabb.h // commit: 7ad14e7a3e6f87ddc450f7e34621eb5200808451 -// file: core/math/rect3.cpp +// file: core/math/aabb.cpp // commit: bd282ff43f23fe845f29a3e25c8efc01bd65ffb0 // file: core/variant_call.cpp // commit: 5ad9be4c24e9d7dc5672fdc42cea896622fe5685 namespace Godot { - public struct Rect3 : IEquatable<Rect3> + public struct AABB : IEquatable<AABB> { private Vector3 position; private Vector3 size; @@ -38,7 +38,7 @@ namespace Godot } } - public bool encloses(Rect3 with) + public bool encloses(AABB with) { Vector3 src_min = position; Vector3 src_max = position + size; @@ -53,7 +53,7 @@ namespace Godot (src_max.z > dst_max.z)); } - public Rect3 expand(Vector3 to_point) + public AABB expand(Vector3 to_point) { Vector3 begin = position; Vector3 end = position + size; @@ -72,7 +72,7 @@ namespace Godot if (to_point.z > end.z) end.z = to_point.z; - return new Rect3(begin, end - begin); + return new AABB(begin, end - begin); } public float get_area() @@ -222,9 +222,9 @@ namespace Godot (dir.z > 0f) ? -half_extents.z : half_extents.z); } - public Rect3 grow(float by) + public AABB grow(float by) { - Rect3 res = this; + AABB res = this; res.position.x -= by; res.position.y -= by; @@ -264,7 +264,7 @@ namespace Godot return true; } - public Rect3 intersection(Rect3 with) + public AABB intersection(AABB with) { Vector3 src_min = position; Vector3 src_max = position + size; @@ -275,7 +275,7 @@ namespace Godot if (src_min.x > dst_max.x || src_max.x < dst_min.x) { - return new Rect3(); + return new AABB(); } else { @@ -285,7 +285,7 @@ namespace Godot if (src_min.y > dst_max.y || src_max.y < dst_min.y) { - return new Rect3(); + return new AABB(); } else { @@ -295,7 +295,7 @@ namespace Godot if (src_min.z > dst_max.z || src_max.z < dst_min.z) { - return new Rect3(); + return new AABB(); } else { @@ -303,10 +303,10 @@ namespace Godot max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z; } - return new Rect3(min, max - min); + return new AABB(min, max - min); } - public bool intersects(Rect3 with) + public bool intersects(AABB with) { if (position.x >= (with.position.x + with.size.x)) return false; @@ -398,7 +398,7 @@ namespace Godot return true; } - public Rect3 merge(Rect3 with) + public AABB merge(AABB with) { Vector3 beg_1 = position; Vector3 beg_2 = with.position; @@ -417,36 +417,36 @@ namespace Godot (end_1.z > end_2.z) ? end_1.z : end_2.z ); - return new Rect3(min, max - min); + return new AABB(min, max - min); } - public Rect3(Vector3 position, Vector3 size) + public AABB(Vector3 position, Vector3 size) { this.position = position; this.size = size; } - public static bool operator ==(Rect3 left, Rect3 right) + public static bool operator ==(AABB left, AABB right) { return left.Equals(right); } - public static bool operator !=(Rect3 left, Rect3 right) + public static bool operator !=(AABB left, AABB right) { return !left.Equals(right); } public override bool Equals(object obj) { - if (obj is Rect3) + if (obj is AABB) { - return Equals((Rect3)obj); + return Equals((AABB)obj); } return false; } - public bool Equals(Rect3 other) + public bool Equals(AABB other) { return position == other.position && size == other.size; } diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 7cc2168b70..a0c2508b0d 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -57,7 +57,7 @@ String _get_expected_build_config() { String _get_mono_user_dir() { #ifdef TOOLS_ENABLED if (EditorSettings::get_singleton()) { - return EditorSettings::get_singleton()->get_settings_path().plus_file("mono"); + return EditorSettings::get_singleton()->get_data_dir().plus_file("mono"); } else { String settings_path; @@ -68,19 +68,13 @@ String _get_mono_user_dir() { // contain yourself settings_path = exe_dir.plus_file("editor_data"); } else { - if (OS::get_singleton()->has_environment("APPDATA")) { - String app_data = OS::get_singleton()->get_environment("APPDATA").replace("\\", "/"); - settings_path = app_data.plus_file(String(_MKSTR(VERSION_SHORT_NAME)).capitalize()); - } else if (OS::get_singleton()->has_environment("HOME")) { - String home = OS::get_singleton()->get_environment("HOME"); - settings_path = home.plus_file("." + String(_MKSTR(VERSION_SHORT_NAME)).to_lower()); - } + settings_path = OS::get_singleton()->get_data_path().plus_file(OS::get_singleton()->get_godot_dir_name()); } return settings_path.plus_file("mono"); } #else - return OS::get_singleton()->get_data_dir().plus_file("mono"); + return OS::get_singleton()->get_user_data_dir().plus_file("mono"); #endif } diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 1643f8cfc5..eb34f9dd3f 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -41,7 +41,7 @@ void GDMonoField::set_value_raw(MonoObject *p_object, void *p_ptr) { void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) { #define SET_FROM_STRUCT_AND_BREAK(m_type) \ { \ - const m_type &val = p_value.operator m_type(); \ + const m_type &val = p_value.operator ::m_type(); \ MARSHALLED_OUT(m_type, val, raw); \ mono_field_set_value(p_object, mono_field, raw); \ break; \ @@ -129,8 +129,8 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) { if (tclass == CACHED_CLASS(Transform)) SET_FROM_STRUCT_AND_BREAK(Transform); - if (tclass == CACHED_CLASS(Rect3)) - SET_FROM_STRUCT_AND_BREAK(Rect3); + if (tclass == CACHED_CLASS(AABB)) + SET_FROM_STRUCT_AND_BREAK(AABB); if (tclass == CACHED_CLASS(Color)) SET_FROM_STRUCT_AND_BREAK(Color); @@ -229,7 +229,7 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) { case Variant::TRANSFORM2D: SET_FROM_STRUCT_AND_BREAK(Transform2D); case Variant::PLANE: SET_FROM_STRUCT_AND_BREAK(Plane); case Variant::QUAT: SET_FROM_STRUCT_AND_BREAK(Quat); - case Variant::RECT3: SET_FROM_STRUCT_AND_BREAK(Rect3); + case Variant::AABB: SET_FROM_STRUCT_AND_BREAK(AABB); case Variant::BASIS: SET_FROM_STRUCT_AND_BREAK(Basis); case Variant::TRANSFORM: SET_FROM_STRUCT_AND_BREAK(Transform); case Variant::COLOR: SET_FROM_STRUCT_AND_BREAK(Color); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 01392447f3..8bc2bb5096 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -36,7 +36,7 @@ namespace GDMonoMarshal { #define RETURN_BOXED_STRUCT(m_t, m_var_in) \ { \ - const m_t &m_in = m_var_in->operator m_t(); \ + const m_t &m_in = m_var_in->operator ::m_t(); \ MARSHALLED_OUT(m_t, m_in, raw); \ return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(m_t), raw); \ } @@ -104,8 +104,8 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { if (tclass == CACHED_CLASS(Transform)) return Variant::TRANSFORM; - if (tclass == CACHED_CLASS(Rect3)) - return Variant::RECT3; + if (tclass == CACHED_CLASS(AABB)) + return Variant::AABB; if (tclass == CACHED_CLASS(Color)) return Variant::COLOR; @@ -297,8 +297,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty if (tclass == CACHED_CLASS(Transform)) RETURN_BOXED_STRUCT(Transform, p_var); - if (tclass == CACHED_CLASS(Rect3)) - RETURN_BOXED_STRUCT(Rect3, p_var); + if (tclass == CACHED_CLASS(AABB)) + RETURN_BOXED_STRUCT(AABB, p_var); if (tclass == CACHED_CLASS(Color)) RETURN_BOXED_STRUCT(Color, p_var); @@ -394,8 +394,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty RETURN_BOXED_STRUCT(Plane, p_var); case Variant::QUAT: RETURN_BOXED_STRUCT(Quat, p_var); - case Variant::RECT3: - RETURN_BOXED_STRUCT(Rect3, p_var); + case Variant::AABB: + RETURN_BOXED_STRUCT(AABB, p_var); case Variant::BASIS: RETURN_BOXED_STRUCT(Basis, p_var); case Variant::TRANSFORM: @@ -518,8 +518,8 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { if (tclass == CACHED_CLASS(Transform)) RETURN_UNBOXED_STRUCT(Transform, p_obj); - if (tclass == CACHED_CLASS(Rect3)) - RETURN_UNBOXED_STRUCT(Rect3, p_obj); + if (tclass == CACHED_CLASS(AABB)) + RETURN_UNBOXED_STRUCT(AABB, p_obj); if (tclass == CACHED_CLASS(Color)) RETURN_UNBOXED_STRUCT(Color, p_obj); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 9f403b787f..443e947fb5 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -197,10 +197,10 @@ Dictionary mono_object_to_Dictionary(MonoObject *p_dict); Basis(m_in[0], m_in[1], m_in[2], m_in[3], m_in[4], m_in[5], m_in[6], m_in[7], m_in[8]), \ Vector3(m_in[9], m_in[10], m_in[11])); -// Rect3 +// AABB -#define MARSHALLED_OUT_Rect3(m_in, m_out) real_t m_out[6] = { m_in.position.x, m_in.position.y, m_in.position.z, m_in.size.x, m_in.size.y, m_in.size.z }; -#define MARSHALLED_IN_Rect3(m_in, m_out) Rect3 m_out(Vector3(m_in[0], m_in[1], m_in[2]), Vector3(m_in[3], m_in[4], m_in[5])); +#define MARSHALLED_OUT_AABB(m_in, m_out) real_t m_out[6] = { m_in.position.x, m_in.position.y, m_in.position.z, m_in.size.x, m_in.size.y, m_in.size.z }; +#define MARSHALLED_IN_AABB(m_in, m_out) AABB m_out(Vector3(m_in[0], m_in[1], m_in[2]), Vector3(m_in[3], m_in[4], m_in[5])); // Color @@ -214,6 +214,6 @@ Dictionary mono_object_to_Dictionary(MonoObject *p_dict); #endif -} // GDMonoMarshal +} // namespace GDMonoMarshal #endif // GDMONOMARSHAL_H diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 53e45002c4..1cccd0ad9d 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -80,7 +80,7 @@ void MonoCache::clear_members() { class_Basis = NULL; class_Quat = NULL; class_Transform = NULL; - class_Rect3 = NULL; + class_AABB = NULL; class_Color = NULL; class_Plane = NULL; class_NodePath = NULL; @@ -147,7 +147,7 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis)); CACHE_CLASS_AND_CHECK(Quat, GODOT_API_CLASS(Quat)); CACHE_CLASS_AND_CHECK(Transform, GODOT_API_CLASS(Transform)); - CACHE_CLASS_AND_CHECK(Rect3, GODOT_API_CLASS(Rect3)); + CACHE_CLASS_AND_CHECK(AABB, GODOT_API_CLASS(AABB)); CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color)); CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane)); CACHE_CLASS_AND_CHECK(NodePath, GODOT_API_CLASS(NodePath)); @@ -364,4 +364,4 @@ String get_exception_name_and_message(MonoObject *p_ex) { return res; } -} +} // namespace GDMonoUtils diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index ebb5d28e4d..c38f8c5af5 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -82,7 +82,7 @@ struct MonoCache { GDMonoClass *class_Basis; GDMonoClass *class_Quat; GDMonoClass *class_Transform; - GDMonoClass *class_Rect3; + GDMonoClass *class_AABB; GDMonoClass *class_Color; GDMonoClass *class_Plane; GDMonoClass *class_NodePath; @@ -166,7 +166,7 @@ MonoDomain *create_domain(const String &p_friendly_name); String get_exception_name_and_message(MonoObject *p_ex); -} // GDMonoUtils +} // namespace GDMonoUtils #define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(NULL))) diff --git a/modules/regex/doc_classes/RegExMatch.xml b/modules/regex/doc_classes/RegExMatch.xml index 354febf89a..8c6951fea2 100644 --- a/modules/regex/doc_classes/RegExMatch.xml +++ b/modules/regex/doc_classes/RegExMatch.xml @@ -4,7 +4,7 @@ Contains the results of a regex search. </brief_description> <description> - Contains the results of a single regex match returned by [method RegEx.search] and [method.RegEx.search_all]. It can be used to find the position and range of the match and its capturing groups, and it can extract its sub-string for you. + Contains the results of a single regex match returned by [method RegEx.search] and [method RegEx.search_all]. It can be used to find the position and range of the match and its capturing groups, and it can extract its sub-string for you. </description> <tutorials> </tutorials> diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp index 7c9d306831..8f7fe58bee 100644 --- a/modules/visual_script/visual_script_builtin_funcs.cpp +++ b/modules/visual_script/visual_script_builtin_funcs.cpp @@ -1109,7 +1109,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in String str = *p_inputs[0]; //str+="\n"; - OS::get_singleton()->printerr("%s\n", str.utf8().get_data()); + print_error(str); } break; case VisualScriptBuiltinFunc::TEXT_PRINTRAW: { diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 86cf5b27e6..83b8d8da2d 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -349,7 +349,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::TRANSFORM2D: color = Color::html("#c4ec69"); break; case Variant::PLANE: color = Color::html("#f77070"); break; case Variant::QUAT: color = Color::html("#ec69a3"); break; - case Variant::RECT3: color = Color::html("#ee7991"); break; + case Variant::AABB: color = Color::html("#ee7991"); break; case Variant::BASIS: color = Color::html("#e3ec69"); break; case Variant::TRANSFORM: color = Color::html("#f6a86e"); break; @@ -386,7 +386,7 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::TRANSFORM2D: color = Color::html("#96ce1a"); break; case Variant::PLANE: color = Color::html("#f77070"); break; case Variant::QUAT: color = Color::html("#ec69a3"); break; - case Variant::RECT3: color = Color::html("#ee7991"); break; + case Variant::AABB: color = Color::html("#ee7991"); break; case Variant::BASIS: color = Color::html("#b2bb19"); break; case Variant::TRANSFORM: color = Color::html("#f49047"); break; diff --git a/platform/SCsub b/platform/SCsub new file mode 100644 index 0000000000..4ef23ab053 --- /dev/null +++ b/platform/SCsub @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +from compat import open_utf8 + +Import('env') +platform_sources = [] + +# Register platform-exclusive APIs +reg_apis_inc = '#include "register_platform_apis.h"\n' +reg_apis = 'void register_platform_apis() {\n' +unreg_apis = 'void unregister_platform_apis() {\n' +for platform in env.platform_apis: + platform_dir = env.Dir(platform) + platform_sources.append(platform_dir.File('api/api.cpp')) + reg_apis += '\tregister_' + platform + '_api();\n' + unreg_apis += '\tunregister_' + platform + '_api();\n' + reg_apis_inc += '#include "' + platform + '/api/api.h"\n' +reg_apis_inc += '\n' +reg_apis += '}\n\n' +unreg_apis += '}\n' +f = open_utf8('register_platform_apis.gen.cpp', 'w') +f.write(reg_apis_inc) +f.write(reg_apis) +f.write(unreg_apis) +f.close() +platform_sources.append('register_platform_apis.gen.cpp') + +env.Prepend(LIBS=env.Library('platform', platform_sources)) + +Export('env') diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template index 7cb6cf860a..11c49fbb50 100644 --- a/platform/android/build.gradle.template +++ b/platform/android/build.gradle.template @@ -31,7 +31,7 @@ android { disable 'MissingTranslation' } - compileSdkVersion 23 + compileSdkVersion 24 buildToolsVersion "26.0.1" useLibrary 'org.apache.http.legacy' diff --git a/platform/android/detect.py b/platform/android/detect.py index a3ada5cf51..bc67f6e6dc 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -205,7 +205,7 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"]) env.Append(CPPFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split()) - env.Append(CPPFLAGS='-DNO_STATVFS -DGLES2_ENABLED'.split()) + env.Append(CPPFLAGS='-DNO_STATVFS -DGLES_ENABLED'.split()) env['neon_enabled'] = False if env['android_arch'] == 'x86': diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 79be1501a7..e1ff12c5ac 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -370,7 +370,7 @@ class EditorExportAndroid : public EditorExportPlatform { } if (aname == "") { - aname = _MKSTR(VERSION_NAME); + aname = VERSION_NAME; } return aname; @@ -945,16 +945,17 @@ public: public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - int api = p_preset->get("graphics/api"); + // Reenable when a GLES 2.0 backend is readded + /*int api = p_preset->get("graphics/api"); if (api == 0) r_features->push_back("etc"); - else - r_features->push_back("etc2"); + else*/ + r_features->push_back("etc2"); } virtual void get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1)); + /*r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1));*/ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), "")); @@ -1066,7 +1067,7 @@ public: if (use_reverse) p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST; - String export_to = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport.apk"; + String export_to = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk"); Error err = export_project(p_preset, true, export_to, p_debug_flags); if (err) { device_lock->unlock(); @@ -1291,7 +1292,7 @@ public: zlib_filefunc_def io2 = io; FileAccess *dst_f = NULL; io2.opaque = &dst_f; - String unaligned_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport-unaligned.apk"; + String unaligned_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned.apk"); zipFile unaligned_apk = zipOpen2(unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); bool export_x86 = p_preset->get("architecture/x86"); diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp index c73b578154..0e1c17e9c8 100644 --- a/platform/android/globals/global_defaults.cpp +++ b/platform/android/globals/global_defaults.cpp @@ -31,12 +31,4 @@ #include "project_settings.h" void register_android_global_defaults() { - - /* GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false); - GLOBAL_DEF("rasterizer.Android/fp16_framebuffer",false); - GLOBAL_DEF("display.Android/driver","GLES2"); - //GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false); - - ProjectSettings::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES2")); - */ } diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp index 9d056bca7c..f9bcbadc24 100644 --- a/platform/android/godot_android.cpp +++ b/platform/android/godot_android.cpp @@ -29,24 +29,23 @@ /*************************************************************************/ #ifdef ANDROID_NATIVE_ACTIVITY -#include <errno.h> -#include <jni.h> - -#include <EGL/egl.h> -#include <GLES2/gl2.h> - #include "engine.h" #include "file_access_android.h" #include "main/main.h" #include "os_android.h" #include "project_settings.h" + +#include <EGL/egl.h> #include <android/log.h> #include <android/sensor.h> #include <android/window.h> #include <android_native_app_glue.h> +#include <errno.h> +#include <jni.h> #include <stdlib.h> #include <string.h> #include <unistd.h> + #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "godot", __VA_ARGS__)) #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "godot", __VA_ARGS__)) diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 90144d9b4d..40dfe6d909 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -647,7 +647,7 @@ static int _open_uri(const String &p_uri) { return env->CallIntMethod(godot_io, _openURI, jStr); } -static String _get_data_dir() { +static String _get_user_data_dir() { JNIEnv *env = ThreadAndroid::get_env(); jstring s = (jstring)env->CallObjectMethod(godot_io, _getDataDir); @@ -825,7 +825,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en AudioDriverAndroid::setup(gob); } - os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); + os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); os_android->set_need_reload_hooks(p_need_reload_hook); char wd[500]; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 2578bd6d96..d5ccf76631 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -612,13 +612,13 @@ void OS_Android::set_need_reload_hooks(bool p_needs_them) { use_reload_hooks = p_needs_them; } -String OS_Android::get_data_dir() const { +String OS_Android::get_user_data_dir() const { if (data_dir_cache != String()) return data_dir_cache; - if (get_data_dir_func) { - String data_dir = get_data_dir_func(); + if (get_user_data_dir_func) { + String data_dir = get_user_data_dir_func(); //store current dir char real_current_dir_name[2048]; @@ -641,7 +641,6 @@ String OS_Android::get_data_dir() const { } return "."; - //return Engine::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir"); } void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) { @@ -709,7 +708,7 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) { return p_feature == "mobile" || p_feature == "etc" || p_feature == "etc2"; //TODO support etc2 only if GLES3 driver is selected } -OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) { +OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) { use_apk_expansion = p_use_apk_expansion; default_videomode.width = 800; @@ -725,7 +724,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI use_gl2 = false; open_uri_func = p_open_uri_func; - get_data_dir_func = p_get_data_dir_func; + get_user_data_dir_func = p_get_user_data_dir_func; get_locale_func = p_get_locale_func; get_model_func = p_get_model_func; get_screen_dpi_func = p_get_screen_dpi_func; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 750afa7a14..d25f60d540 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -48,7 +48,7 @@ typedef void (*GFXInitFunc)(void *ud, bool gl2); typedef int (*OpenURIFunc)(const String &); -typedef String (*GetDataDirFunc)(); +typedef String (*GetUserDataDirFunc)(); typedef String (*GetLocaleFunc)(); typedef String (*GetModelFunc)(); typedef int (*GetScreenDPIFunc)(); @@ -116,7 +116,7 @@ private: MainLoop *main_loop; OpenURIFunc open_uri_func; - GetDataDirFunc get_data_dir_func; + GetUserDataDirFunc get_user_data_dir_func; GetLocaleFunc get_locale_func; GetModelFunc get_model_func; GetScreenDPIFunc get_screen_dpi_func; @@ -208,7 +208,7 @@ public: virtual void set_screen_orientation(ScreenOrientation p_orientation); virtual Error shell_open(String p_uri); - virtual String get_data_dir() const; + virtual String get_user_data_dir() const; virtual String get_resource_dir() const; virtual String get_locale() const; virtual String get_model_name() const; @@ -237,7 +237,7 @@ public: void joy_connection_changed(int p_device, bool p_connected, String p_name); virtual bool _check_internal_feature_support(const String &p_feature); - OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion); + OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion); ~OS_Android(); }; diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 50f9783dd2..7c62654ef6 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -67,7 +67,7 @@ def configure(env): ## Flags env.Append(CPPPATH=['#platform/haiku']) - env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL']) + env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED', '-DGLES_OVER_GL']) env.Append(CPPFLAGS=['-DMEDIA_KIT_ENABLED']) # env.Append(CCFLAGS=['-DFREETYPE_ENABLED']) env.Append(CPPFLAGS=['-DPTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 0c34e39655..ef5a065107 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -76,7 +76,7 @@ int OS_Haiku::get_video_driver_count() const { } const char *OS_Haiku::get_video_driver_name(int p_driver) const { - return "GLES2"; + return "GLES3"; } void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { @@ -106,7 +106,9 @@ void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_ context_gl->initialize(); context_gl->make_current(); - rasterizer = memnew(RasterizerGLES2); + /* Port to GLES 3 rasterizer */ + //rasterizer = memnew(RasterizerGLES2); + #endif visual_server = memnew(VisualServerRaster(rasterizer)); @@ -314,3 +316,36 @@ bool OS_Haiku::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc" || p_feature == "s3tc"; } + +String OS_Haiku::get_config_path() const { + + if (has_environment("XDG_CONFIG_HOME")) { + return get_environment("XDG_CONFIG_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".config"); + } else { + return "."; + } +} + +String OS_Haiku::get_data_path() const { + + if (has_environment("XDG_DATA_HOME")) { + return get_environment("XDG_DATA_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".local/share"); + } else { + return get_config_path(); + } +} + +String OS_Haiku::get_cache_path() const { + + if (has_environment("XDG_CACHE_HOME")) { + return get_environment("XDG_CACHE_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".cache"); + } else { + return get_config_path(); + } +} diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 86148f1fb4..4ee54fb48d 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -117,6 +117,10 @@ public: virtual int get_power_percent_left(); virtual bool _check_internal_feature_support(const String &p_feature); + + virtual String get_config_path() const; + virtual String get_data_path() const; + virtual String get_cache_path() const; }; #endif diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index d426b478bf..4ea358f871 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -163,7 +163,7 @@ def configure(env): env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' env.Append(CPPPATH=['#platform/iphone']) - env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DMPC_FIXED_POINT', '-DCOREAUDIO_ENABLED']) + env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DMPC_FIXED_POINT', '-DCOREAUDIO_ENABLED']) # TODO: Move that to opus module's config if 'module_opus_enabled' in env and env['module_opus_enabled']: diff --git a/platform/iphone/globals/global_defaults.cpp b/platform/iphone/globals/global_defaults.cpp index 4bdc716d6e..b81e6def3b 100644 --- a/platform/iphone/globals/global_defaults.cpp +++ b/platform/iphone/globals/global_defaults.cpp @@ -31,11 +31,4 @@ #include "project_settings.h" void register_iphone_global_defaults() { - - /*GLOBAL_DEF("rasterizer.iOS/use_fragment_lighting",false); - GLOBAL_DEF("rasterizer.iOS/fp16_framebuffer",false); - GLOBAL_DEF("display.iOS/driver","GLES2"); - ProjectSettings::get_singleton()->set_custom_property_info("display.iOS/driver",PropertyInfo(Variant::STRING,"display.iOS/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2")); - GLOBAL_DEF("display.iOS/use_cadisplaylink",true); - */ } diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm index 9efd4b9891..25f4e1e166 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -92,6 +92,7 @@ void InAppStore::_bind_methods() { PoolRealArray prices; PoolStringArray ids; PoolStringArray localized_prices; + PoolStringArray currency_codes; for (int i = 0; i < [products count]; i++) { @@ -105,12 +106,14 @@ void InAppStore::_bind_methods() { prices.push_back([product.price doubleValue]); ids.push_back(String::utf8([product.productIdentifier UTF8String])); localized_prices.push_back(String::utf8([product.localizedPrice UTF8String])); + currency_codes.push_back(String::utf8([[[product priceLocale] objectForKey:NSLocaleCurrencyCode] UTF8String])); }; ret["titles"] = titles; ret["descriptions"] = descriptions; ret["prices"] = prices; ret["ids"] = ids; ret["localized_prices"] = localized_prices; + ret["currency_codes"] = currency_codes; PoolStringArray invalid_ids; diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index d0865a35b9..95d7710c76 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -54,7 +54,7 @@ int OSIPhone::get_video_driver_count() const { const char *OSIPhone::get_video_driver_name(int p_driver) const { - return "GLES2"; + return "GLES3"; }; OSIPhone *OSIPhone::get_singleton() { @@ -470,7 +470,7 @@ void OSIPhone::set_cursor_shape(CursorShape p_shape){ }; -String OSIPhone::get_data_dir() const { +String OSIPhone::get_user_data_dir() const { return data_dir; }; @@ -509,7 +509,7 @@ Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_ FileAccess *f = FileAccess::open(p_path, FileAccess::READ); bool exists = f && f->is_open(); - String tempFile = get_data_dir(); + String tempFile = get_user_data_dir(); if (!exists) return FAILED; @@ -521,7 +521,7 @@ Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_ p_path = p_path.replace("res:/", ProjectSettings::get_singleton()->get_resource_path()); } } else if (p_path.begins_with("user://")) - p_path = p_path.replace("user:/", get_data_dir()); + p_path = p_path.replace("user:/", get_user_data_dir()); memdelete(f); diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 6627fddf08..433228b599 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -178,7 +178,7 @@ public: Error shell_open(String p_uri); - String get_data_dir() const; + String get_user_data_dir() const; void set_locale(String p_locale); String get_locale() const; diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h index 54de66082e..7ff6e7a9a9 100644 --- a/platform/iphone/platform_config.h +++ b/platform/iphone/platform_config.h @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include <alloca.h> -// #define GLES2_INCLUDE_H <ES2/gl.h> + #define GLES3_INCLUDE_H <ES3/gl.h> #define PLATFORM_REFCOUNT diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index e3015d87b9..8d505a5829 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -21,37 +21,21 @@ for x in javascript_files: env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_main_after_fs_sync','_send_notification']\""]) -# output file name without file extension -basename = "godot" + env["PROGSUFFIX"] target_dir = env.Dir("#bin") - -zip_dir = target_dir.Dir('.javascript_zip') -zip_files = env.InstallAs(zip_dir.File('godot.html'), '#misc/dist/html/default.html') - -implicit_targets = [] -if env['wasm']: - wasm = target_dir.File(basename + '.wasm') - implicit_targets.append(wasm) - zip_files.append(InstallAs(zip_dir.File('godot.wasm'), wasm)) - prejs = env.File('pre_wasm.js') -else: - asmjs_files = [target_dir.File(basename + '.asm.js'), target_dir.File(basename + '.js.mem')] - implicit_targets.extend(asmjs_files) - zip_files.append(InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files)) - prejs = env.File('pre_asmjs.js') - -js = env.Program(['#bin/godot'] + implicit_targets, javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js')[0]; -zip_files.append(InstallAs(zip_dir.File('godot.js'), js)) +build = env.Program(['#bin/godot', target_dir.File('godot' + env['PROGSUFFIX'] + '.wasm')], javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js'); js_libraries = [] js_libraries.append(env.File('http_request.js')) for lib in js_libraries: env.Append(LINKFLAGS=['--js-library', lib.path]) -env.Depends(js, js_libraries) +env.Depends(build, js_libraries) +prejs = env.File('pre.js') postjs = env.File('engine.js') -env.Depends(js, [prejs, postjs]) env.Append(LINKFLAGS=['--pre-js', prejs.path]) env.Append(LINKFLAGS=['--post-js', postjs.path]) +env.Depends(build, [prejs, postjs]) +zip_dir = target_dir.Dir('.javascript_zip') +zip_files = env.InstallAs([zip_dir.File('godot.js'), zip_dir.File('godot.wasm'), zip_dir.File('godot.html')], build + ['#misc/dist/html/default.html']) Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX'] + env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET") diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp new file mode 100644 index 0000000000..f2b2ca40bf --- /dev/null +++ b/platform/javascript/api/api.cpp @@ -0,0 +1,73 @@ +/*************************************************************************/ +/* api.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "api.h" +#include "engine.h" +#include "javascript_eval.h" + +static JavaScript *javascript_eval; + +void register_javascript_api() { + + ClassDB::register_virtual_class<JavaScript>(); + javascript_eval = memnew(JavaScript); + Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval)); +} + +void unregister_javascript_api() { + + memdelete(javascript_eval); +} + +JavaScript *JavaScript::singleton = NULL; + +JavaScript *JavaScript::get_singleton() { + + return singleton; +} + +JavaScript::JavaScript() { + + ERR_FAIL_COND(singleton != NULL); + singleton = this; +} + +JavaScript::~JavaScript() {} + +void JavaScript::_bind_methods() { + + ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, DEFVAL(false)); +} + +#if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED) +Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { + + return Variant(); +} +#endif diff --git a/platform/javascript/api/api.h b/platform/javascript/api/api.h new file mode 100644 index 0000000000..53cd9239fc --- /dev/null +++ b/platform/javascript/api/api.h @@ -0,0 +1,31 @@ +/*************************************************************************/ +/* api.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +void register_javascript_api(); +void unregister_javascript_api(); diff --git a/platform/javascript/javascript_eval.h b/platform/javascript/api/javascript_eval.h index ed7cf383da..4d0b0b21ff 100644 --- a/platform/javascript/javascript_eval.h +++ b/platform/javascript/api/javascript_eval.h @@ -27,8 +27,6 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifdef JAVASCRIPT_EVAL_ENABLED - #ifndef JAVASCRIPT_EVAL_H #define JAVASCRIPT_EVAL_H @@ -52,4 +50,3 @@ public: }; #endif // JAVASCRIPT_EVAL_H -#endif // JAVASCRIPT_EVAL_ENABLED diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index a2988d9c60..8472c3ccab 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -19,7 +19,6 @@ def can_build(): def get_opts(): from SCons.Variables import BoolVariable return [ - BoolVariable('wasm', 'Compile to WebAssembly', False), BoolVariable('javascript_eval', 'Enable JavaScript eval interface', True), ] @@ -103,20 +102,13 @@ def configure(env): ## Link flags - env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"']) + env.Append(LINKFLAGS=['-s', 'BINARYEN=1']) + env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1']) env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) + env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"']) - if env['wasm']: - env.Append(LINKFLAGS=['-s', 'BINARYEN=1']) - # In contrast to asm.js, enabling memory growth on WebAssembly has no - # major performance impact, and causes only a negligible increase in - # memory size. - env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1']) - env.extra_suffix = '.webassembly' + env.extra_suffix - else: - env.Append(LINKFLAGS=['-s', 'ASM_JS=1']) - env.Append(LINKFLAGS=['--separate-asm']) - env.Append(LINKFLAGS=['--memory-init-file', '1']) + env.Append(LINKFLAGS=['-s', 'INVOKE_RUN=0']) + env.Append(LINKFLAGS=['-s', 'NO_EXIT_RUNTIME=1']) # TODO: Move that to opus module's config if 'module_opus_enabled' in env and env['module_opus_enabled']: diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js index 99d1c20bbd..dc4bdc7efb 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -5,7 +5,6 @@ (function() { var engine = Engine; - var USING_WASM = engine.USING_WASM; var DOWNLOAD_ATTEMPTS_MAX = 4; var basePath = null; @@ -32,87 +31,101 @@ this.rtenv = null; - var gameInitPromise = null; + var initPromise = null; var unloadAfterInit = true; - var memorySize = 268435456; + var preloadedFiles = []; + + var resizeCanvasOnStart = true; var progressFunc = null; - var pckProgressTracker = {}; + var preloadProgressTracker = {}; var lastProgress = { loaded: 0, total: 0 }; var canvas = null; + var executableName = null; + var locale = null; var stdout = null; var stderr = null; - this.initGame = function(mainPack) { - - if (!gameInitPromise) { + this.init = function(newBasePath) { - if (mainPack === undefined) { - if (basePath !== null) { - mainPack = basePath + '.pck'; - } else { - return Promise.reject(new Error("No main pack to load specified")); - } - } - if (basePath === null) - basePath = getBasePath(mainPack); - - gameInitPromise = Engine.initEngine().then( + if (!initPromise) { + initPromise = Engine.load(newBasePath).then( instantiate.bind(this) ); - var gameLoadPromise = loadPromise(mainPack, pckProgressTracker).then(function(xhr) { return xhr.response; }); - gameInitPromise = Promise.all([gameLoadPromise, gameInitPromise]).then(function(values) { - // resolve with pck - return new Uint8Array(values[0]); - }); - if (unloadAfterInit) - gameInitPromise.then(Engine.unloadEngine); requestAnimationFrame(animateProgress); + if (unloadAfterInit) + initPromise.then(Engine.unloadEngine); } - return gameInitPromise; + return initPromise; }; - function instantiate(initializer) { + function instantiate(wasmBuf) { - var rtenvOpts = { - noInitialRun: true, - thisProgram: getBaseName(basePath), + var rtenvProps = { engine: this, + ENV: {}, }; if (typeof stdout === 'function') - rtenvOpts.print = stdout; + rtenvProps.print = stdout; if (typeof stderr === 'function') - rtenvOpts.printErr = stderr; - if (typeof WebAssembly === 'object' && initializer instanceof ArrayBuffer) { - rtenvOpts.instantiateWasm = function(imports, onSuccess) { - WebAssembly.instantiate(initializer, imports).then(function(result) { - onSuccess(result.instance); - }); - return {}; - }; - } else if (initializer.asm && initializer.mem) { - rtenvOpts.asm = initializer.asm; - rtenvOpts.memoryInitializerRequest = initializer.mem; - rtenvOpts.TOTAL_MEMORY = memorySize; - } else { - throw new Error("Invalid initializer"); - } + rtenvProps.printErr = stderr; + rtenvProps.instantiateWasm = function(imports, onSuccess) { + WebAssembly.instantiate(wasmBuf, imports).then(function(result) { + onSuccess(result.instance); + }); + return {}; + }; return new Promise(function(resolve, reject) { - rtenvOpts.onRuntimeInitialized = resolve; - rtenvOpts.onAbort = reject; - rtenvOpts.engine.rtenv = Engine.RuntimeEnvironment(rtenvOpts); + rtenvProps.onRuntimeInitialized = resolve; + rtenvProps.onAbort = reject; + rtenvProps.engine.rtenv = Engine.RuntimeEnvironment(rtenvProps); }); } - this.start = function(mainPack) { + this.preloadFile = function(pathOrBuffer, bufferFilename) { + + if (pathOrBuffer instanceof ArrayBuffer) { + pathOrBuffer = new Uint8Array(pathOrBuffer); + } else if (ArrayBuffer.isView(pathOrBuffer)) { + pathOrBuffer = new Uint8Array(pathOrBuffer.buffer); + } + if (pathOrBuffer instanceof Uint8Array) { + preloadedFiles.push({ + name: bufferFilename, + buffer: pathOrBuffer + }); + return Promise.resolve(); + } else if (typeof pathOrBuffer === 'string') { + return loadPromise(pathOrBuffer, preloadProgressTracker).then(function(xhr) { + preloadedFiles.push({ + name: pathOrBuffer, + buffer: xhr.response + }); + }); + } else { + throw Promise.reject("Invalid object for preloading"); + } + }; + + this.start = function() { + + return this.init().then( + Function.prototype.apply.bind(synchronousStart, this, arguments) + ); + }; + + this.startGame = function(mainPack) { - return this.initGame(mainPack).then(synchronousStart.bind(this)); + executableName = getBaseName(mainPack); + return Promise.all([this.init(getBasePath(mainPack)), this.preloadFile(mainPack)]).then( + Function.prototype.apply.bind(synchronousStart, this, []) + ); }; - function synchronousStart(pckView) { - // TODO don't expect canvas when runninng as cli tool + function synchronousStart() { + if (canvas instanceof HTMLCanvasElement) { this.rtenv.canvas = canvas; } else { @@ -147,15 +160,33 @@ ev.preventDefault(); }, false); - this.rtenv.FS.createDataFile('/', this.rtenv.thisProgram + '.pck', pckView, true, true, true); - gameInitPromise = null; - this.rtenv.callMain(); + if (locale) { + this.rtenv.locale = locale; + } else { + this.rtenv.locale = navigator.languages ? navigator.languages[0] : navigator.language; + } + this.rtenv.locale = this.rtenv.locale.split('.')[0]; + this.rtenv.resizeCanvasOnStart = resizeCanvasOnStart; + + this.rtenv.thisProgram = executableName || getBaseName(basePath); + + preloadedFiles.forEach(function(file) { + this.rtenv.FS.createDataFile('/', file.name, new Uint8Array(file.buffer), true, true, true); + }, this); + + preloadedFiles = null; + initPromise = null; + this.rtenv.callMain(arguments); } this.setProgressFunc = function(func) { progressFunc = func; }; + this.setResizeCanvasOnStart = function(enabled) { + resizeCanvasOnStart = enabled; + }; + function animateProgress() { var loaded = 0; @@ -163,7 +194,7 @@ var totalIsValid = true; var progressIsFinal = true; - [loadingFiles, pckProgressTracker].forEach(function(tracker) { + [loadingFiles, preloadProgressTracker].forEach(function(tracker) { Object.keys(tracker).forEach(function(file) { if (!tracker[file].final) progressIsFinal = false; @@ -190,14 +221,20 @@ canvas = elem; }; - this.setAsmjsMemorySize = function(size) { - memorySize = size; + this.setExecutableName = function(newName) { + + executableName = newName; + }; + + this.setLocale = function(newLocale) { + + locale = newLocale; }; this.setUnloadAfterInit = function(enabled) { - if (enabled && !unloadAfterInit && gameInitPromise) { - gameInitPromise.then(Engine.unloadEngine); + if (enabled && !unloadAfterInit && initPromise) { + initPromise.then(Engine.unloadEngine); } unloadAfterInit = enabled; }; @@ -232,26 +269,16 @@ Engine.RuntimeEnvironment = engine.RuntimeEnvironment; - Engine.initEngine = function(newBasePath) { + Engine.load = function(newBasePath) { if (newBasePath !== undefined) basePath = getBasePath(newBasePath); if (engineLoadPromise === null) { - if (USING_WASM) { - if (typeof WebAssembly !== 'object') - return Promise.reject(new Error("Browser doesn't support WebAssembly")); - // TODO cache/retrieve module to/from idb - engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) { - return xhr.response; - }); - } else { - var asmjsPromise = loadPromise(basePath + '.asm.js').then(function(xhr) { - return asmjsModulePromise(xhr.response); - }); - var memPromise = loadPromise(basePath + '.mem'); - engineLoadPromise = Promise.all([asmjsPromise, memPromise]).then(function(values) { - return { asm: values[0], mem: values[1] }; - }); - } + if (typeof WebAssembly !== 'object') + return Promise.reject(new Error("Browser doesn't support WebAssembly")); + // TODO cache/retrieve module to/from idb + engineLoadPromise = loadPromise(basePath + '.wasm').then(function(xhr) { + return xhr.response; + }); engineLoadPromise = engineLoadPromise.catch(function(err) { engineLoadPromise = null; throw err; @@ -260,34 +287,7 @@ return engineLoadPromise; }; - function asmjsModulePromise(module) { - var elem = document.createElement('script'); - var script = new Blob([ - 'Engine.asm = (function() { var Module = {};', - module, - 'return Module.asm; })();' - ]); - var url = URL.createObjectURL(script); - elem.src = url; - return new Promise(function(resolve, reject) { - elem.addEventListener('load', function() { - URL.revokeObjectURL(url); - var asm = Engine.asm; - Engine.asm = undefined; - setTimeout(function() { - // delay to reclaim compilation memory - resolve(asm); - }, 1); - }); - elem.addEventListener('error', function() { - URL.revokeObjectURL(url); - reject("asm.js faiilure"); - }); - document.body.appendChild(elem); - }); - } - - Engine.unloadEngine = function() { + Engine.unload = function() { engineLoadPromise = null; }; @@ -306,7 +306,7 @@ if (!file.endsWith('.js')) { xhr.responseType = 'arraybuffer'; } - ['loadstart', 'progress', 'load', 'error', 'timeout', 'abort'].forEach(function(ev) { + ['loadstart', 'progress', 'load', 'error', 'abort'].forEach(function(ev) { xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker)); }); xhr.send(); @@ -321,7 +321,7 @@ this.abort(); return; } else { - loadXHR(resolve, reject, file); + setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); } } @@ -348,12 +348,11 @@ break; case 'error': - case 'timeout': if (++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { tracker[file].final = true; reject(new Error("Failed loading file '" + file + "'")); } else { - loadXHR(resolve, reject, file); + setTimeout(loadXHR.bind(null, resolve, reject, file, tracker), 1000); } break; diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 4a97bf4c32..943f6d8f35 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -30,13 +30,12 @@ #include "editor/editor_node.h" #include "editor_export.h" #include "io/zip_io.h" +#include "main/splash.gen.h" #include "platform/javascript/logo.gen.h" #include "platform/javascript/run_icon.gen.h" #define EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE "webassembly_release.zip" #define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip" -#define EXPORT_TEMPLATE_ASMJS_RELEASE "javascript_release.zip" -#define EXPORT_TEMPLATE_ASMJS_DEBUG "javascript_debug.zip" class EditorExportPlatformJavaScript : public EditorExportPlatform { @@ -47,18 +46,11 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform { bool runnable_when_last_polled; void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug); - void _fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size); public: - enum Target { - TARGET_WEBASSEMBLY, - TARGET_ASMJS - }; - virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features); virtual void get_export_options(List<ExportOption> *r_options); - virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; virtual String get_name() const; virtual String get_os_name() const; @@ -90,17 +82,9 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re String str_export; Vector<String> lines = str_template.split("\n"); - int memory_mb; - if (p_preset->get("options/target").operator int() != TARGET_ASMJS) - // WebAssembly allows memory growth, so start with a reasonable default - memory_mb = 1 << 4; - else - memory_mb = 1 << (p_preset->get("options/memory_size").operator int() + 5); - for (int i = 0; i < lines.size(); i++) { String current_line = lines[i]; - current_line = current_line.replace("$GODOT_TOTAL_MEMORY", itos(memory_mb * 1024 * 1024)); current_line = current_line.replace("$GODOT_BASENAME", p_name); current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include")); current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false"); @@ -129,24 +113,15 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "options/target", PROPERTY_HINT_ENUM, "WebAssembly,asm.js"), TARGET_WEBASSEMBLY)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "options/memory_size", PROPERTY_HINT_ENUM, "32 MB,64 MB,128 MB,256 MB,512 MB,1 GB"), 3)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_GLOBAL_FILE, "html"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); } -bool EditorExportPlatformJavaScript::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { - - if (p_option == "options/memory_size") { - return p_options["options/target"].operator int() == TARGET_ASMJS; - } - return true; -} - String EditorExportPlatformJavaScript::get_name() const { return "HTML5"; @@ -166,17 +141,10 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p r_missing_templates = false; - if (p_preset->get("options/target").operator int() == TARGET_WEBASSEMBLY) { - if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) == String()) - r_missing_templates = true; - else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) == String()) - r_missing_templates = true; - } else { - if (find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE) == String()) - r_missing_templates = true; - else if (find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG) == String()) - r_missing_templates = true; - } + if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) == String()) + r_missing_templates = true; + else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) == String()) + r_missing_templates = true; return !r_missing_templates; } @@ -190,6 +158,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese String custom_debug = p_preset->get("custom_template/debug"); String custom_release = p_preset->get("custom_template/release"); + String custom_html = p_preset->get("html/custom_html_shell"); String template_path = p_debug ? custom_debug : custom_release; @@ -197,17 +166,10 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese if (template_path == String()) { - if (p_preset->get("options/target").operator int() == TARGET_WEBASSEMBLY) { - if (p_debug) - template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG); - else - template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE); - } else { - if (p_debug) - template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG); - else - template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE); - } + if (p_debug) + template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG); + else + template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE); } if (template_path != String() && !FileAccess::exists(template_path)) { @@ -222,14 +184,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese return error; } - FileAccess *f = FileAccess::open(pck_path, FileAccess::READ); - if (!f) { - EditorNode::get_singleton()->show_warning(TTR("Could not read file:\n") + pck_path); - return ERR_FILE_CANT_READ; - } - size_t pack_size = f->get_len(); - memdelete(f); - FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); unzFile pkg = unzOpen2(template_path.utf8().get_data(), &io); @@ -240,13 +194,17 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese return ERR_FILE_NOT_FOUND; } - int ret = unzGoToFirstFile(pkg); - while (ret == UNZ_OK) { + if (unzGoToFirstFile(pkg) != UNZ_OK) { + EditorNode::get_singleton()->show_warning(TTR("Invalid export template:\n") + template_path); + unzClose(pkg); + return ERR_FILE_CORRUPT; + } + do { //get filename unz_file_info info; char fname[16384]; - ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); + unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); String file = fname; @@ -262,20 +220,18 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese if (file == "godot.html") { + if (!custom_html.empty()) { + continue; + } _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug); file = p_path.get_file(); + } else if (file == "godot.js") { file = p_path.get_file().get_basename() + ".js"; } else if (file == "godot.wasm") { file = p_path.get_file().get_basename() + ".wasm"; - } else if (file == "godot.asm.js") { - - file = p_path.get_file().get_basename() + ".asm.js"; - } else if (file == "godot.mem") { - - file = p_path.get_file().get_basename() + ".mem"; } String dst = p_path.get_base_dir().plus_file(file); @@ -288,9 +244,50 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese f->store_buffer(data.ptr(), data.size()); memdelete(f); - ret = unzGoToNextFile(pkg); + } while (unzGoToNextFile(pkg) == UNZ_OK); + unzClose(pkg); + + if (!custom_html.empty()) { + + FileAccess *f = FileAccess::open(custom_html, FileAccess::READ); + if (!f) { + EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:\n") + custom_html); + return ERR_FILE_CANT_READ; + } + Vector<uint8_t> buf; + buf.resize(f->get_len()); + f->get_buffer(buf.ptr(), buf.size()); + memdelete(f); + _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug); + + f = FileAccess::open(p_path, FileAccess::WRITE); + if (!f) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + p_path); + return ERR_FILE_CANT_WRITE; + } + f->store_buffer(buf.ptr(), buf.size()); + memdelete(f); } + Ref<Image> splash; + String splash_path = GLOBAL_GET("application/boot_splash/image"); + splash_path = splash_path.strip_edges(); + if (!splash_path.empty()) { + splash.instance(); + Error err = splash->load(splash_path); + if (err) { + EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:\n") + splash_path + "\nUsing default boot splash image"); + splash.unref(); + } + } + if (splash.is_null()) { + splash = Ref<Image>(memnew(Image(boot_splash_png))); + } + String png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png"); + if (splash->save_png(png_path) != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + png_path); + return ERR_FILE_CANT_WRITE; + } return OK; } @@ -319,7 +316,7 @@ int EditorExportPlatformJavaScript::get_device_count() const { Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { - String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp_export.html"; + String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_export.html"); Error err = export_project(p_preset, true, path, p_debug_flags); if (err) { return err; diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp index 1d737879f6..a755dcb5c4 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/platform/javascript/javascript_eval.cpp @@ -29,16 +29,9 @@ /*************************************************************************/ #ifdef JAVASCRIPT_EVAL_ENABLED -#include "javascript_eval.h" +#include "api/javascript_eval.h" #include "emscripten.h" -JavaScript *JavaScript::singleton = NULL; - -JavaScript *JavaScript::get_singleton() { - - return singleton; -} - extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_poolbytearray_and_open_write(PoolByteArray *p_arr, PoolByteArray::Write *r_write, int p_len) { p_arr->resize(p_len); @@ -182,18 +175,4 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { return Variant(); } -void JavaScript::_bind_methods() { - - ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, false); -} - -JavaScript::JavaScript() { - - ERR_FAIL_COND(singleton != NULL); - singleton = this; -} - -JavaScript::~JavaScript() { -} - #endif // JAVASCRIPT_EVAL_ENABLED diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index ed4f416cfd..5c5d608524 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -61,7 +61,6 @@ int main(int argc, char *argv[]) { // run the 'main_after_fs_sync' function /* clang-format off */ EM_ASM( - Module.noExitRuntime = true; FS.mkdir('/userfs'); FS.mount(IDBFS, {}, '/userfs'); FS.syncfs(true, function(err) { diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 77d81aec5d..74cfec14a6 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -438,25 +438,23 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i video_mode = p_desired; // can't fulfil fullscreen request due to browser security video_mode.fullscreen = false; - set_window_size(Size2(p_desired.width, p_desired.height)); + /* clang-format off */ + bool resize_canvas_on_start = EM_ASM_INT_V( + return Module.resizeCanvasOnStart; + ); + /* clang-format on */ + if (resize_canvas_on_start) { + set_window_size(Size2(video_mode.width, video_mode.height)); + } else { + Size2 canvas_size = get_window_size(); + video_mode.width = canvas_size.width; + video_mode.height = canvas_size.height; + } - // find locale, emscripten only sets "C" char locale_ptr[16]; /* clang-format off */ - EM_ASM_({ - var locale = ""; - if (Module.locale) { - // best case: server-side script reads Accept-Language early and - // defines the locale to be read here - locale = Module.locale; - } else { - // no luck, use what the JS engine can tell us - // if this turns out not compatible enough, add tests for - // browserLanguage, systemLanguage and userLanguage - locale = navigator.languages ? navigator.languages[0] : navigator.language; - } - locale = locale.split('.')[0]; - stringToUTF8(locale, $0, 16); + EM_ASM_ARGS({ + stringToUTF8(Module.locale, $0, 16); }, locale_ptr); /* clang-format on */ setenv("LANG", locale_ptr, true); @@ -512,11 +510,6 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i #undef SET_EM_CALLBACK #undef EM_CHECK -#ifdef JAVASCRIPT_EVAL_ENABLED - javascript_eval = memnew(JavaScript); - Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval)); -#endif - visual_server->init(); } @@ -889,11 +882,11 @@ String OS_JavaScript::get_resource_dir() const { return "/"; //javascript has it's own filesystem for resources inside the APK } -String OS_JavaScript::get_data_dir() const { +String OS_JavaScript::get_user_data_dir() const { /* - if (get_data_dir_func) - return get_data_dir_func(); + if (get_user_data_dir_func) + return get_user_data_dir_func(); */ return "/userfs"; }; @@ -993,7 +986,7 @@ bool OS_JavaScript::is_userfs_persistent() const { return idbfs_available; } -OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func) { +OS_JavaScript::OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func) { set_cmdline(p_execpath, get_cmdline_args()); main_loop = NULL; gl_extensions = NULL; @@ -1001,7 +994,7 @@ OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_d soft_fs_enabled = false; canvas_size_adjustment_requested = false; - get_data_dir_func = p_get_data_dir_func; + get_user_data_dir_func = p_get_user_data_dir_func; FileAccessUnix::close_notification_func = _close_notification_funcs; idbfs_available = false; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index f478f95dd2..77eeb02a9f 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -32,7 +32,6 @@ #include "audio_driver_javascript.h" #include "drivers/unix/os_unix.h" -#include "javascript_eval.h" #include "main/input_default.h" #include "os/input.h" #include "os/main_loop.h" @@ -42,7 +41,7 @@ #include <emscripten/html5.h> -typedef String (*GetDataDirFunc)(); +typedef String (*GetUserDataDirFunc)(); class OS_JavaScript : public OS_Unix { @@ -63,14 +62,10 @@ class OS_JavaScript : public OS_Unix { CursorShape cursor_shape; MainLoop *main_loop; - GetDataDirFunc get_data_dir_func; + GetUserDataDirFunc get_user_data_dir_func; PowerJavascript *power_manager; -#ifdef JAVASCRIPT_EVAL_ENABLED - JavaScript *javascript_eval; -#endif - static void _close_notification_funcs(const String &p_file, int p_flags); void process_joypads(); @@ -146,7 +141,7 @@ public: void set_opengl_extensions(const char *p_gl_extensions); virtual Error shell_open(String p_uri); - virtual String get_data_dir() const; + virtual String get_user_data_dir() const; String get_executable_path() const; virtual String get_resource_dir() const; @@ -165,7 +160,7 @@ public: void set_idbfs_available(bool p_idbfs_available); - OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func); + OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func); ~OS_JavaScript(); }; diff --git a/platform/javascript/pre_wasm.js b/platform/javascript/pre.js index be4383c8c9..311aa44fda 100644 --- a/platform/javascript/pre_wasm.js +++ b/platform/javascript/pre.js @@ -1,3 +1,2 @@ var Engine = { - USING_WASM: true, RuntimeEnvironment: function(Module) { diff --git a/platform/javascript/pre_asmjs.js b/platform/javascript/pre_asmjs.js deleted file mode 100644 index 3c497721b6..0000000000 --- a/platform/javascript/pre_asmjs.js +++ /dev/null @@ -1,3 +0,0 @@ -var Engine = { - USING_WASM: false, - RuntimeEnvironment: function(Module) { diff --git a/platform/osx/detect.py b/platform/osx/detect.py index c24bd98bf6..ff7cf2ad2f 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -110,7 +110,7 @@ def configure(env): ## Flags env.Append(CPPPATH=['#platform/osx']) - env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED']) + env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED']) env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback']) env.Append(LIBS=['pthread']) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 8a6f1dc04c..f6922377e3 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -160,7 +160,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ copy->convert(Image::FORMAT_RGBA8); copy->resize(size, size); it->create_from_image(copy); - String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/icon.png"; + String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png"); ResourceSaver::save(path, it); FileAccess *f = FileAccess::open(path, FileAccess::READ); @@ -344,7 +344,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (use_dmg()) { // We're on OSX so we can export to DMG, but first we create our application bundle - tmp_app_path_name = EditorSettings::get_singleton()->get_settings_path() + "/tmp/" + pkg_name + ".app"; + tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app"); print_line("Exporting to " + tmp_app_path_name); DirAccess *tmp_app_path = DirAccess::create_for_path(tmp_app_path_name); if (!tmp_app_path) { @@ -539,7 +539,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p OS::get_singleton()->move_to_trash(tmp_app_path_name); } else { - String pack_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/" + pkg_name + ".pck"; + String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck"); Error err = save_pack(p_preset, pack_path); if (err == OK) { diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 1df847eb79..aa8ee1fe83 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -154,6 +154,11 @@ public: virtual MainLoop *get_main_loop() const; + virtual String get_config_path() const; + virtual String get_data_path() const; + virtual String get_cache_path() const; + virtual String get_godot_dir_name() const; + virtual String get_system_dir(SystemDir p_dir) const; virtual bool can_draw() const; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 2e0e2620be..110cb776ee 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -36,6 +36,7 @@ #include "print_string.h" #include "sem_osx.h" #include "servers/visual/visual_server_raster.h" +#include "version_generated.gen.h" #include <Carbon/Carbon.h> #import <Cocoa/Cocoa.h> @@ -896,7 +897,7 @@ int OS_OSX::get_video_driver_count() const { const char *OS_OSX::get_video_driver_name(int p_driver) const { - return "GLES2"; + return "GLES3"; } void OS_OSX::initialize_core() { @@ -1066,8 +1067,6 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au zoomed = true; /*** END OSX INITIALIZATION ***/ - /*** END OSX INITIALIZATION ***/ - /*** END OSX INITIALIZATION ***/ bool use_gl2 = p_video_driver != 1; @@ -1077,16 +1076,12 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au RasterizerGLES3::register_config(); RasterizerGLES3::make_current(); - //rasterizer = instance_RasterizerGLES2(); - //visual_server = memnew( VisualServerRaster(rasterizer) ); - visual_server = memnew(VisualServerRaster); if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } visual_server->init(); - // visual_server->cursor_set_visible(false, 0); AudioDriverManager::initialize(p_audio_driver); @@ -1095,7 +1090,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au power_manager = memnew(power_osx); - _ensure_data_dir(); + _ensure_user_data_dir(); restore_rect = Rect2(get_window_position(), get_window_size()); } @@ -1340,6 +1335,43 @@ MainLoop *OS_OSX::get_main_loop() const { return main_loop; } +String OS_OSX::get_config_path() const { + + if (has_environment("XDG_CONFIG_HOME")) { + return get_environment("XDG_CONFIG_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file("Library/Application Support"); + } else { + return "."; + } +} + +String OS_OSX::get_data_path() const { + + if (has_environment("XDG_DATA_HOME")) { + return get_environment("XDG_DATA_HOME"); + } else { + return get_config_path(); + } +} + +String OS_OSX::get_cache_path() const { + + if (has_environment("XDG_CACHE_HOME")) { + return get_environment("XDG_CACHE_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file("Library/Caches"); + } else { + return get_config_path(); + } +} + +// Get properly capitalized engine name for system paths +String OS_OSX::get_godot_dir_name() const { + + return String(VERSION_SHORT_NAME).capitalize(); +} + String OS_OSX::get_system_dir(SystemDir p_dir) const { NSSearchPathDirectory id = 0; diff --git a/platform/register_platform_apis.h b/platform/register_platform_apis.h new file mode 100644 index 0000000000..37f98f6cd3 --- /dev/null +++ b/platform/register_platform_apis.h @@ -0,0 +1,36 @@ +/*************************************************************************/ +/* register_platform_apis.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#ifndef REGISTER_APIS_H +#define REGISTER_APIS_H + +void register_platform_apis(); +void unregister_platform_apis(); + +#endif diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index ca73f610e4..5b852af738 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -73,7 +73,7 @@ void OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p input = memnew(InputDefault); - _ensure_data_dir(); + _ensure_user_data_dir(); } void OS_Server::finalize() { diff --git a/platform/uwp/app.h b/platform/uwp/app.h index e079fa9c9d..b812512a98 100644 --- a/platform/uwp/app.h +++ b/platform/uwp/app.h @@ -33,6 +33,7 @@ #include <wrl.h> +// ANGLE doesn't provide a specific lib for GLES3, so we keep using GLES2 #include "GLES2/gl2.h" #include "os_uwp.h" diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 434c597449..7cc8afff06 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -136,7 +136,7 @@ def configure(env): env.Append(CPPPATH=['#platform/uwp', '#drivers/windows']) env.Append(CCFLAGS=['/DUWP_ENABLED', '/DWINDOWS_ENABLED', '/DTYPED_METHOD_BIND']) - env.Append(CCFLAGS=['/DGLES2_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED']) + env.Append(CCFLAGS=['/DGLES_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED']) winver = "0x0602" # Windows 8 is the minimum target for UWP build env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver]) diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index d66bcaa91c..120df9bc3f 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -456,8 +456,8 @@ void AppxPackager::init(FileAccess *p_fa) { package = p_fa; central_dir_offset = 0; end_of_central_dir_offset = 0; - tmp_blockmap_file_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpblockmap.xml"; - tmp_content_types_file_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpcontenttypes.xml"; + tmp_blockmap_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpblockmap.xml"); + tmp_content_types_file_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpcontenttypes.xml"); } void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) { @@ -886,7 +886,7 @@ class EditorExportUWP : public EditorExportPlatform { if (!image) return data; - String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/uwp_tmp_logo.png"); + String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("uwp_tmp_logo.png"); Error err = image->get_data()->save_png(tmp_path); diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index acb0ba4bca..64e319327f 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "os_uwp.h" + #include "drivers/gles3/rasterizer_gles3.h" #include "drivers/unix/ip_unix.h" #include "drivers/windows/dir_access_windows.h" @@ -69,7 +70,7 @@ int OSUWP::get_video_driver_count() const { } const char *OSUWP::get_video_driver_name(int p_driver) const { - return "GLES2"; + return "GLES3"; } Size2 OSUWP::get_window_size() const { @@ -298,7 +299,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud ref new TypedEventHandler<Gyrometer ^, GyrometerReadingChangedEventArgs ^>(managed_object, &ManagedType::on_gyroscope_reading_changed); } - _ensure_data_dir(); + _ensure_user_data_dir(); if (is_keep_screen_on()) display_request->RequestActive(); @@ -781,7 +782,7 @@ MainLoop *OSUWP::get_main_loop() const { return main_loop; } -String OSUWP::get_data_dir() const { +String OSUWP::get_user_data_dir() const { Windows::Storage::StorageFolder ^ data_folder = Windows::Storage::ApplicationData::Current->LocalFolder; diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 2931e9b07d..3c52fc29a8 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -226,7 +226,7 @@ public: virtual String get_locale() const; virtual void move_window_to_foreground(); - virtual String get_data_dir() const; + virtual String get_user_data_dir() const; virtual bool _check_internal_feature_support(const String &p_feature); diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index 8571f0dc65..81aa18dd23 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -27,25 +27,12 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) - -// -// C++ Implementation: context_gl_x11 -// -// Description: -// -// +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + // Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008 -// -// Copyright: See COPYING file that comes with this distribution -// -// #include "context_gl_win.h" -//#include "drivers/opengl/glwrapper.h" -//#include "ctxgl_procaddr.h" - #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_FLAGS_ARB 0x2094 diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h index 0059cbc311..5a280b0d08 100644 --- a/platform/windows/context_gl_win.h +++ b/platform/windows/context_gl_win.h @@ -27,18 +27,9 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED) -// -// C++ Interface: context_gl_x11 -// -// Description: -// -// +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + // Author: Juan Linietsky <reduzio@gmail.com>, (C) 2008 -// -// Copyright: See COPYING file that comes with this distribution -// -// #ifndef CONTEXT_GL_WIN_H #define CONTEXT_GL_WIN_H diff --git a/platform/windows/godot_res.rc b/platform/windows/godot_res.rc index b86869d316..c535a749c0 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -23,13 +23,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Godot Engine" - VALUE "FileDescription", _MKSTR(VERSION_NAME) " Editor" + VALUE "FileDescription", VERSION_NAME " Editor" VALUE "FileVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) - VALUE "ProductName", _MKSTR(VERSION_NAME) + VALUE "ProductName", VERSION_NAME VALUE "Licence", "MIT" VALUE "LegalCopyright", "Copyright (c) 2007-" _MKSTR(VERSION_YEAR) " Juan Linietsky, Ariel Manzur" - VALUE "Info", "http://www.godotengine.org" - VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) PATCH_STRING "." _MKSTR(VERSION_REVISION) + VALUE "Info", "https://godotengine.org" + VALUE "ProductVersion", _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) PATCH_STRING "." VERSION_BUILD END END BLOCK "VarFileInfo" diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 0f62dbb9e8..72d51ad62a 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -47,6 +47,7 @@ #include "servers/visual/visual_server_wrap_mt.h" #include "stream_peer_winsock.h" #include "tcp_server_winsock.h" +#include "version_generated.gen.h" #include "windows_terminal_logger.h" #include <process.h> @@ -143,7 +144,7 @@ int OS_Windows::get_video_driver_count() const { } const char *OS_Windows::get_video_driver_name(int p_driver) const { - return "GLES2"; + return "GLES3"; } int OS_Windows::get_audio_driver_count() const { @@ -1090,7 +1091,7 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int //RegisterTouchWindow(hWnd, 0); // Windows 7 - _ensure_data_dir(); + _ensure_user_data_dir(); DragAcceptFiles(hWnd, true); @@ -2131,6 +2132,43 @@ MainLoop *OS_Windows::get_main_loop() const { return main_loop; } +String OS_Windows::get_config_path() const { + + if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not? + return get_environment("XDG_CONFIG_HOME"); + } else if (has_environment("APPDATA")) { + return get_environment("APPDATA"); + } else { + return "."; + } +} + +String OS_Windows::get_data_path() const { + + if (has_environment("XDG_DATA_HOME")) { + return get_environment("XDG_DATA_HOME"); + } else { + return get_config_path(); + } +} + +String OS_Windows::get_cache_path() const { + + if (has_environment("XDG_CACHE_HOME")) { + return get_environment("XDG_CACHE_HOME"); + } else if (has_environment("TEMP")) { + return get_environment("TEMP"); + } else { + return get_config_path(); + } +} + +// Get properly capitalized engine name for system paths +String OS_Windows::get_godot_dir_name() const { + + return String(VERSION_SHORT_NAME).capitalize(); +} + String OS_Windows::get_system_dir(SystemDir p_dir) const { int id; @@ -2167,18 +2205,17 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const { ERR_FAIL_COND_V(res != S_OK, String()); return String(szPath); } -String OS_Windows::get_data_dir() const { - String an = get_safe_application_name(); - if (an != "") { +String OS_Windows::get_user_data_dir() const { - if (has_environment("APPDATA")) { + String appname = get_safe_application_name(); + if (appname != "") { - bool use_godot = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir"); - if (!use_godot) - return (OS::get_singleton()->get_environment("APPDATA") + "/" + an).replace("\\", "/"); - else - return (OS::get_singleton()->get_environment("APPDATA") + "/Godot/app_userdata/" + an).replace("\\", "/"); + bool use_godot_dir = ProjectSettings::get_singleton()->get("application/config/use_shared_user_dir"); + if (use_godot_dir) { + return get_data_path().plus_file(get_godot_dir_name()).plus_file("app_userdata").plus_file(appname).replace("\\", "/"); + } else { + return get_data_path().plus_file(appname).replace("\\", "/"); } } diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index fbd60e5f0d..5e0c240dba 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -253,8 +253,14 @@ public: virtual void enable_for_stealing_focus(ProcessID pid); virtual void move_window_to_foreground(); - virtual String get_data_dir() const; + + virtual String get_config_path() const; + virtual String get_data_path() const; + virtual String get_cache_path() const; + virtual String get_godot_dir_name() const; + virtual String get_system_dir(SystemDir p_dir) const; + virtual String get_user_data_dir() const; virtual void release_rendering_thread(); virtual void make_rendering_thread(); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 6bd0ac8317..3d07851c4f 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -236,7 +236,7 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Append(CPPPATH=['#platform/x11']) - env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL']) + env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED', '-DGLES_OVER_GL']) env.Append(LIBS=['GL', 'pthread']) if (platform.system() == "Linux"): diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index f018145d82..d1aa129e77 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -250,41 +250,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } - - // borderless fullscreen window mode - if (current_videomode.fullscreen) { - // set bypass compositor hint - Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False); - unsigned long compositing_disable_on = 1; - XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1); - - // needed for lxde/openbox, possibly others - Hints hints; - Atom property; - hints.flags = 2; - hints.decorations = 0; - property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True); - XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5); - XMapRaised(x11_display, x11_window); - XWindowAttributes xwa; - XGetWindowAttributes(x11_display, DefaultRootWindow(x11_display), &xwa); - XMoveResizeWindow(x11_display, x11_window, 0, 0, xwa.width, xwa.height); - - // code for netwm-compliants - XEvent xev; - Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); - Atom fullscreen = XInternAtom(x11_display, "_NET_WM_STATE_FULLSCREEN", False); - - memset(&xev, 0, sizeof(xev)); - xev.type = ClientMessage; - xev.xclient.window = x11_window; - xev.xclient.message_type = wm_state; - xev.xclient.format = 32; - xev.xclient.data.l[0] = 1; - xev.xclient.data.l[1] = fullscreen; - xev.xclient.data.l[2] = 0; - - XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev); + if (current_videomode.maximized) { + current_videomode.maximized = false; + set_window_maximized(true); + // borderless fullscreen window mode + } else if (current_videomode.fullscreen) { + current_videomode.fullscreen = false; + set_window_fullscreen(true); } else if (current_videomode.borderless_window) { Hints hints; Atom property; @@ -464,11 +436,20 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au #ifdef JOYDEV_ENABLED joypad = memnew(JoypadLinux(input)); #endif - _ensure_data_dir(); + _ensure_user_data_dir(); power_manager = memnew(PowerX11); + + XEvent xevent; + while (XCheckIfEvent(x11_display, &xevent, _check_window_events, NULL)) { + _window_changed(&xevent); + } } +int OS_X11::_check_window_events(Display *display, XEvent *event, char *arg) { + if (event->type == ConfigureNotify) return 1; + return 0; +} void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data, ::XPointer call_data) { @@ -648,6 +629,9 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con } void OS_X11::set_wm_fullscreen(bool p_enabled) { + if (current_videomode.fullscreen == p_enabled) + return; + if (p_enabled && !is_window_resizable()) { // Set the window as resizable to prevent window managers to ignore the fullscreen state flag. XSizeHints *xsh; @@ -971,6 +955,9 @@ bool OS_X11::is_window_minimized() const { } void OS_X11::set_window_maximized(bool p_enabled) { + if (is_window_maximized() == p_enabled) + return; + // Using EWMH -- Extended Window Manager Hints XEvent xev; Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); @@ -1417,6 +1404,20 @@ static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p return None; } +void OS_X11::_window_changed(XEvent *event) { + + if (xic) { + // Not portable. + set_ime_position(Point2(0, 1)); + } + if ((event->xconfigure.width == current_videomode.width) && + (event->xconfigure.height == current_videomode.height)) + return; + + current_videomode.width = event->xconfigure.width; + current_videomode.height = event->xconfigure.height; +} + void OS_X11::process_xevents() { //printf("checking events %i\n", XPending(x11_display)); @@ -1498,18 +1499,7 @@ void OS_X11::process_xevents() { break; case ConfigureNotify: - if (xic) { - // Not portable. - set_ime_position(Point2(0, 1)); - } - /* call resizeGLScene only if our window-size changed */ - - if ((event.xconfigure.width == current_videomode.width) && - (event.xconfigure.height == current_videomode.height)) - break; - - current_videomode.width = event.xconfigure.width; - current_videomode.height = event.xconfigure.height; + _window_changed(&event); break; case ButtonPress: case ButtonRelease: { @@ -1941,6 +1931,39 @@ bool OS_X11::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc" || p_feature == "s3tc"; } +String OS_X11::get_config_path() const { + + if (has_environment("XDG_CONFIG_HOME")) { + return get_environment("XDG_CONFIG_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".config"); + } else { + return "."; + } +} + +String OS_X11::get_data_path() const { + + if (has_environment("XDG_DATA_HOME")) { + return get_environment("XDG_DATA_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".local/share"); + } else { + return get_config_path(); + } +} + +String OS_X11::get_cache_path() const { + + if (has_environment("XDG_CACHE_HOME")) { + return get_environment("XDG_CACHE_HOME"); + } else if (has_environment("HOME")) { + return get_environment("HOME").plus_file(".cache"); + } else { + return get_config_path(); + } +} + String OS_X11::get_system_dir(SystemDir p_dir) const { String xdgparam; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 0ea5bbfdb6..a74e6ee5f3 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -187,6 +187,9 @@ protected: virtual void set_main_loop(MainLoop *p_main_loop); + void _window_changed(XEvent *xevent); + static int _check_window_events(Display *display, XEvent *xevent, char *arg); + public: virtual String get_name(); @@ -213,6 +216,10 @@ public: virtual void make_rendering_thread(); virtual void swap_buffers(); + virtual String get_config_path() const; + virtual String get_data_path() const; + virtual String get_cache_path() const; + virtual String get_system_dir(SystemDir p_dir) const; virtual Error shell_open(String p_uri); diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index 5982556c18..4865858b7d 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -247,16 +247,16 @@ SpriteFrames::SpriteFrames() { add_animation(SceneStringNames::get_singleton()->_default); } -void AnimatedSprite::edit_set_pivot(const Point2 &p_pivot) { +void AnimatedSprite::_edit_set_pivot(const Point2 &p_pivot) { set_offset(p_pivot); } -Point2 AnimatedSprite::edit_get_pivot() const { +Point2 AnimatedSprite::_edit_get_pivot() const { return get_offset(); } -bool AnimatedSprite::edit_has_pivot() const { +bool AnimatedSprite::_edit_use_pivot() const { return true; } @@ -509,17 +509,17 @@ bool AnimatedSprite::is_flipped_v() const { return vflip; } -Rect2 AnimatedSprite::get_item_rect() const { +Rect2 AnimatedSprite::_edit_get_rect() const { if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { - return Node2D::get_item_rect(); + return Node2D::_edit_get_rect(); } Ref<Texture> t; if (animation) t = frames->get_frame(animation, frame); if (t.is_null()) - return Node2D::get_item_rect(); + return Node2D::_edit_get_rect(); Size2i s = t->get_size(); Point2 ofs = offset; diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h index 6c660d0381..a8d0db021a 100644 --- a/scene/2d/animated_sprite.h +++ b/scene/2d/animated_sprite.h @@ -149,9 +149,9 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; void set_sprite_frames(const Ref<SpriteFrames> &p_frames); Ref<SpriteFrames> get_sprite_frames() const; @@ -181,7 +181,7 @@ public: void set_modulate(const Color &p_color); Color get_modulate() const; - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; virtual String get_configuration_warning() const; AnimatedSprite(); diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp index 2858ddaad5..e4f52a227a 100644 --- a/scene/2d/back_buffer_copy.cpp +++ b/scene/2d/back_buffer_copy.cpp @@ -49,7 +49,7 @@ void BackBufferCopy::_update_copy_mode() { } } -Rect2 BackBufferCopy::get_item_rect() const { +Rect2 BackBufferCopy::_edit_get_rect() const { return rect; } diff --git a/scene/2d/back_buffer_copy.h b/scene/2d/back_buffer_copy.h index 2424dd7b19..cfd632d755 100644 --- a/scene/2d/back_buffer_copy.h +++ b/scene/2d/back_buffer_copy.h @@ -52,14 +52,14 @@ protected: static void _bind_methods(); public: + Rect2 _edit_get_rect() const; + void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; void set_copy_mode(CopyMode p_mode); CopyMode get_copy_mode() const; - Rect2 get_item_rect() const; - BackBufferCopy(); ~BackBufferCopy(); }; diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index d65a3bfe80..3164344d15 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -52,7 +52,11 @@ void Camera2D::_update_scroll() { if (viewport) { viewport->set_canvas_transform(xform); } - get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_camera_moved", xform); + + Size2 screen_size = viewport->get_visible_rect().size; + Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5) : Point2()); + + get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_camera_moved", xform, screen_offset); }; } diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index fa45c61f68..66abe1baa8 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -306,22 +306,7 @@ void CanvasItem::hide() { _change_notify("visible"); } -Variant CanvasItem::edit_get_state() const { - - return Variant(); -} -void CanvasItem::edit_set_state(const Variant &p_state) { -} - -void CanvasItem::edit_set_rect(const Rect2 &p_edit_rect) { - - //used by editors, implement at will -} - -void CanvasItem::edit_rotate(float p_rot) { -} - -Size2 CanvasItem::edit_get_minimum_size() const { +Size2 CanvasItem::_edit_get_minimum_size() const { return Size2(-1, -1); //no limit } @@ -941,15 +926,22 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self); ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback); - - ClassDB::bind_method(D_METHOD("edit_set_state", "state"), &CanvasItem::edit_set_state); - ClassDB::bind_method(D_METHOD("edit_get_state"), &CanvasItem::edit_get_state); - ClassDB::bind_method(D_METHOD("edit_set_rect", "rect"), &CanvasItem::edit_set_rect); - ClassDB::bind_method(D_METHOD("edit_rotate", "degrees"), &CanvasItem::edit_rotate); - - ClassDB::bind_method(D_METHOD("get_item_rect"), &CanvasItem::get_item_rect); - ClassDB::bind_method(D_METHOD("get_item_and_children_rect"), &CanvasItem::get_item_and_children_rect); - //ClassDB::bind_method(D_METHOD("get_transform"),&CanvasItem::get_transform); + ClassDB::bind_method(D_METHOD("_edit_set_state", "state"), &CanvasItem::_edit_set_state); + ClassDB::bind_method(D_METHOD("_edit_get_state"), &CanvasItem::_edit_get_state); + + ClassDB::bind_method(D_METHOD("_edit_set_position", "position"), &CanvasItem::_edit_set_position); + ClassDB::bind_method(D_METHOD("_edit_get_position"), &CanvasItem::_edit_get_position); + ClassDB::bind_method(D_METHOD("_edit_use_position"), &CanvasItem::_edit_use_position); + ClassDB::bind_method(D_METHOD("_edit_set_rect", "rect"), &CanvasItem::_edit_set_rect); + ClassDB::bind_method(D_METHOD("_edit_get_rect"), &CanvasItem::_edit_get_rect); + ClassDB::bind_method(D_METHOD("_edit_use_rect"), &CanvasItem::_edit_use_rect); + ClassDB::bind_method(D_METHOD("_edit_get_item_and_children_rect"), &CanvasItem::_edit_get_item_and_children_rect); + ClassDB::bind_method(D_METHOD("_edit_set_rotation", "degrees"), &CanvasItem::_edit_set_rotation); + ClassDB::bind_method(D_METHOD("_edit_get_rotation"), &CanvasItem::_edit_get_rotation); + ClassDB::bind_method(D_METHOD("_edit_use_rotation"), &CanvasItem::_edit_use_rotation); + ClassDB::bind_method(D_METHOD("_edit_set_pivot", "pivot"), &CanvasItem::_edit_set_pivot); + ClassDB::bind_method(D_METHOD("_edit_get_pivot"), &CanvasItem::_edit_get_pivot); + ClassDB::bind_method(D_METHOD("_edit_use_pivot"), &CanvasItem::_edit_use_pivot); ClassDB::bind_method(D_METHOD("get_canvas_item"), &CanvasItem::get_canvas_item); @@ -1119,14 +1111,14 @@ int CanvasItem::get_canvas_layer() const { return 0; } -Rect2 CanvasItem::get_item_and_children_rect() const { +Rect2 CanvasItem::_edit_get_item_and_children_rect() const { - Rect2 rect = get_item_rect(); + Rect2 rect = _edit_get_rect(); for (int i = 0; i < get_child_count(); i++) { CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i)); if (c) { - Rect2 sir = c->get_transform().xform(c->get_item_and_children_rect()); + Rect2 sir = c->get_transform().xform(c->_edit_get_item_and_children_rect()); rect = rect.merge(sir); } } diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 1a043c204f..c877a94755 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -216,11 +216,31 @@ public: /* EDITOR */ - virtual Variant edit_get_state() const; - virtual void edit_set_state(const Variant &p_state); - virtual void edit_set_rect(const Rect2 &p_edit_rect); - virtual void edit_rotate(float p_rot); - virtual Size2 edit_get_minimum_size() const; + virtual void _edit_set_state(const Dictionary &p_state){}; + virtual Dictionary _edit_get_state() const { return Dictionary(); }; + + // Used to move/select the node + virtual void _edit_set_position(const Point2 &p_position){}; + virtual Point2 _edit_get_position() const { return Point2(); }; + virtual bool _edit_use_position() const { return false; }; + + // Used to resize/move/select the node + virtual void _edit_set_rect(const Rect2 &p_rect){}; + virtual Rect2 _edit_get_rect() const { return Rect2(-32, -32, 64, 64); }; + Rect2 _edit_get_item_and_children_rect() const; + virtual bool _edit_use_rect() const { return false; }; + + // Used to rotate the node + virtual void _edit_set_rotation(float p_rotation){}; + virtual float _edit_get_rotation() const { return 0.0; }; + virtual bool _edit_use_rotation() const { return false; }; + + // Used to set a pivot + virtual void _edit_set_pivot(const Point2 &p_pivot){}; + virtual Point2 _edit_get_pivot() const { return Point2(); }; + virtual bool _edit_use_pivot() const { return false; }; + + virtual Size2 _edit_get_minimum_size() const; /* VISIBILITY */ @@ -272,14 +292,11 @@ public: CanvasItem *get_parent_item() const; - virtual Rect2 get_item_rect() const = 0; virtual Transform2D get_transform() const = 0; virtual Transform2D get_global_transform() const; virtual Transform2D get_global_transform_with_canvas() const; - Rect2 get_item_and_children_rect() const; - CanvasItem *get_toplevel() const; _FORCE_INLINE_ RID get_canvas_item() const { return canvas_item; } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index a840744c78..92855299ae 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -243,7 +243,7 @@ CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const { return build_mode; } -Rect2 CollisionPolygon2D::get_item_rect() const { +Rect2 CollisionPolygon2D::_edit_get_rect() const { return aabb; } diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h index c9ec860e36..2fb08a4599 100644 --- a/scene/2d/collision_polygon_2d.h +++ b/scene/2d/collision_polygon_2d.h @@ -69,7 +69,7 @@ public: void set_polygon(const Vector<Point2> &p_polygon); Vector<Point2> get_polygon() const; - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; virtual String get_configuration_warning() const; diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 0758f4a9bf..f7cb5473e3 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -158,7 +158,7 @@ Ref<Shape2D> CollisionShape2D::get_shape() const { return shape; } -Rect2 CollisionShape2D::get_item_rect() const { +Rect2 CollisionShape2D::_edit_get_rect() const { return rect; } diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h index 04203a75b4..4745c659c8 100644 --- a/scene/2d/collision_shape_2d.h +++ b/scene/2d/collision_shape_2d.h @@ -51,9 +51,10 @@ protected: static void _bind_methods(); public: + virtual Rect2 _edit_get_rect() const; + void set_shape(const Ref<Shape2D> &p_shape); Ref<Shape2D> get_shape() const; - virtual Rect2 get_item_rect() const; void set_disabled(bool p_disabled); bool is_disabled() const; diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 516acefe2a..d2b987e037 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -32,21 +32,21 @@ #include "engine.h" #include "servers/visual_server.h" -void Light2D::edit_set_pivot(const Point2 &p_pivot) { +void Light2D::_edit_set_pivot(const Point2 &p_pivot) { set_texture_offset(p_pivot); } -Point2 Light2D::edit_get_pivot() const { +Point2 Light2D::_edit_get_pivot() const { return get_texture_offset(); } -bool Light2D::edit_has_pivot() const { +bool Light2D::_edit_use_pivot() const { return true; } -Rect2 Light2D::get_item_rect() const { +Rect2 Light2D::_edit_get_rect() const { if (texture.is_null()) return Rect2(0, 0, 1, 1); diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h index f6bc943adb..9b9da8379f 100644 --- a/scene/2d/light_2d.h +++ b/scene/2d/light_2d.h @@ -84,9 +84,10 @@ protected: static void _bind_methods(); public: - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; + virtual Rect2 _edit_get_rect() const; void set_enabled(bool p_enabled); bool is_enabled() const; @@ -151,8 +152,6 @@ public: void set_shadow_smooth(float p_amount); float get_shadow_smooth() const; - virtual Rect2 get_item_rect() const; - String get_configuration_warning() const; Light2D(); diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index c562a4652d..45f780e50e 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -34,35 +34,22 @@ #include "scene/main/viewport.h" #include "servers/visual_server.h" -void Node2D::edit_set_pivot(const Point2 &p_pivot) { -} - -Point2 Node2D::edit_get_pivot() const { - - return Point2(); -} -bool Node2D::edit_has_pivot() const { - - return false; -} +Dictionary Node2D::_edit_get_state() const { -Variant Node2D::edit_get_state() const { - - Array state; - state.push_back(get_position()); - state.push_back(get_rotation()); - state.push_back(get_scale()); + Dictionary state; + state["position"] = get_position(); + state["rotation"] = get_rotation(); + state["scale"] = get_scale(); return state; } -void Node2D::edit_set_state(const Variant &p_state) { +void Node2D::_edit_set_state(const Dictionary &p_state) { - Array state = p_state; - ERR_FAIL_COND(state.size() != 3); + Dictionary state = p_state; + pos = state["position"]; + angle = state["rotation"]; + _scale = state["scale"]; - pos = state[0]; - angle = state[1]; - _scale = state[2]; _update_transform(); _change_notify("rotation"); _change_notify("rotation_degrees"); @@ -70,9 +57,16 @@ void Node2D::edit_set_state(const Variant &p_state) { _change_notify("position"); } -void Node2D::edit_set_rect(const Rect2 &p_edit_rect) { +void Node2D::_edit_set_position(const Point2 &p_position) { + pos = p_position; +} + +Point2 Node2D::_edit_get_position() const { + return pos; +} - Rect2 r = get_item_rect(); +void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) { + Rect2 r = _edit_get_rect(); Vector2 zero_offset; if (r.size.x != 0) @@ -101,14 +95,25 @@ void Node2D::edit_set_rect(const Rect2 &p_edit_rect) { _change_notify("position"); } -void Node2D::edit_rotate(float p_rot) { +bool Node2D::_edit_use_rect() const { + return true; +} - angle += p_rot; +void Node2D::_edit_set_rotation(float p_rotation) { + angle = p_rotation; _update_transform(); _change_notify("rotation"); _change_notify("rotation_degrees"); } +float Node2D::_edit_get_rotation() const { + return angle; +} + +bool Node2D::_edit_use_rotation() const { + return true; +} + void Node2D::_update_xform_values() { pos = _mat.elements[2]; @@ -205,17 +210,6 @@ Transform2D Node2D::get_transform() const { return _mat; } -Rect2 Node2D::get_item_rect() const { - - if (get_script_instance()) { - Variant::CallError err; - Rect2 r = get_script_instance()->call("_get_item_rect", NULL, 0, err); - if (err.error == Variant::CallError::CALL_OK) - return r; - } - return Rect2(Point2(-32, -32), Size2(64, 64)); -} - void Node2D::rotate(float p_radians) { set_rotation(get_rotation() + p_radians); @@ -439,8 +433,6 @@ void Node2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_z_as_relative", "enable"), &Node2D::set_z_as_relative); ClassDB::bind_method(D_METHOD("is_z_relative"), &Node2D::is_z_relative); - ClassDB::bind_method(D_METHOD("edit_set_pivot", "pivot"), &Node2D::edit_set_pivot); - ClassDB::bind_method(D_METHOD("get_relative_transform_to_parent", "parent"), &Node2D::get_relative_transform_to_parent); ADD_GROUP("Transform", ""); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index eca1e96c82..e1e07f2895 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -56,13 +56,16 @@ protected: static void _bind_methods(); public: - virtual Variant edit_get_state() const; - virtual void edit_set_state(const Variant &p_state); - virtual void edit_set_rect(const Rect2 &p_edit_rect); - virtual void edit_rotate(float p_rot); - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual Dictionary _edit_get_state() const; + virtual void _edit_set_state(const Dictionary &p_state); + + virtual void _edit_set_position(const Point2 &p_position); + virtual Point2 _edit_get_position() const; + virtual void _edit_set_rect(const Rect2 &p_edit_rect); + virtual bool _edit_use_rect() const; + virtual void _edit_set_rotation(float p_rotation); + virtual float _edit_get_rotation() const; + virtual bool _edit_use_rotation() const; void set_position(const Point2 &p_pos); void set_rotation(float p_radians); @@ -85,7 +88,6 @@ public: float get_global_rotation() const; float get_global_rotation_degrees() const; Size2 get_global_scale() const; - virtual Rect2 get_item_rect() const; void set_transform(const Transform2D &p_transform); void set_global_transform(const Transform2D &p_transform); diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index a13ce6278e..b9012e37b2 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -47,10 +47,12 @@ void ParallaxBackground::_notification(int p_what) { } } -void ParallaxBackground::_camera_moved(const Transform2D &p_transform) { +void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset) { + + screen_offset = p_screen_offset; set_scroll_scale(p_transform.get_scale().dot(Vector2(0.5, 0.5))); - set_scroll_offset(p_transform.get_origin() / p_transform.get_scale()); + set_scroll_offset(p_transform.get_origin()); } void ParallaxBackground::set_scroll_scale(float p_scale) { @@ -106,9 +108,9 @@ void ParallaxBackground::_update_scroll() { continue; if (ignore_camera_zoom) - l->set_base_offset_and_scale(ofs, 1.0); + l->set_base_offset_and_scale(ofs, 1.0, screen_offset); else - l->set_base_offset_and_scale(ofs, scale); + l->set_base_offset_and_scale(ofs, scale, screen_offset); } } diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 0dad1daeab..e37ec0db99 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -42,6 +42,7 @@ class ParallaxBackground : public CanvasLayer { float scale; Point2 base_offset; Point2 base_scale; + Point2 screen_offset; String group_name; Point2 limit_begin; Point2 limit_end; @@ -51,7 +52,7 @@ class ParallaxBackground : public CanvasLayer { void _update_scroll(); protected: - void _camera_moved(const Transform2D &p_transform); + void _camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset); void _notification(int p_what); static void _bind_methods(); diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index 8fe651cb5f..4a69841975 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -40,7 +40,7 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { if (pb && is_inside_tree()) { Vector2 ofs = pb->get_final_offset(); float scale = pb->get_scroll_scale(); - set_base_offset_and_scale(ofs, scale); + set_base_offset_and_scale(ofs, scale, screen_offset); } } @@ -57,7 +57,7 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) { if (pb && is_inside_tree()) { Vector2 ofs = pb->get_final_offset(); float scale = pb->get_scroll_scale(); - set_base_offset_and_scale(ofs, scale); + set_base_offset_and_scale(ofs, scale, screen_offset); } } @@ -106,26 +106,28 @@ void ParallaxLayer::_notification(int p_what) { } } -void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale) { +void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset) { + screen_offset = p_screen_offset; if (!is_inside_tree()) return; if (Engine::get_singleton()->is_editor_hint()) return; - Point2 new_ofs = ((orig_offset + p_offset) * motion_scale) * p_scale + motion_offset; + + Point2 new_ofs = (screen_offset + (p_offset - screen_offset) * motion_scale) + motion_offset * p_scale + orig_offset * p_scale; + + Vector2 mirror = Vector2(1, 1); if (mirroring.x) { - double den = mirroring.x * p_scale; - new_ofs.x -= den * ceil(new_ofs.x / den); + mirror.x = -1; } if (mirroring.y) { - double den = mirroring.y * p_scale; - new_ofs.y -= den * ceil(new_ofs.y / den); + mirror.y = -1; } set_position(new_ofs); - set_scale(Vector2(1, 1) * p_scale); + set_scale(mirror * p_scale * orig_scale); } String ParallaxLayer::get_configuration_warning() const { diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index 95ca27c41a..6feb1fad67 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -43,6 +43,8 @@ class ParallaxLayer : public Node2D { Vector2 mirroring; void _update_mirroring(); + Point2 screen_offset; + protected: void _notification(int p_what); static void _bind_methods(); @@ -57,7 +59,7 @@ public: void set_mirroring(const Size2 &p_mirroring); Size2 get_mirroring() const; - void set_base_offset_and_scale(const Point2 &p_offset, float p_scale); + void set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset); virtual String get_configuration_warning() const; ParallaxLayer(); diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index c146ac08c2..aee5d89150 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -77,7 +77,7 @@ void Particles2D::set_randomness_ratio(float p_ratio) { void Particles2D::set_visibility_rect(const Rect2 &p_aabb) { visibility_rect = p_aabb; - Rect3 aabb; + AABB aabb; aabb.position.x = p_aabb.position.x; aabb.position.y = p_aabb.position.y; aabb.size.x = p_aabb.size.x; @@ -223,7 +223,7 @@ String Particles2D::get_configuration_warning() const { Rect2 Particles2D::capture_rect() const { - Rect3 aabb = VS::get_singleton()->particles_get_current_aabb(particles); + AABB aabb = VS::get_singleton()->particles_get_current_aabb(particles); Rect2 r; r.position.x = aabb.position.x; r.position.y = aabb.position.y; @@ -378,7 +378,7 @@ void Particles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); - ADD_PROPERTY(PropertyInfo(Variant::RECT3, "visibility_rect"), "set_visibility_rect", "get_visibility_rect"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "visibility_rect"), "set_visibility_rect", "get_visibility_rect"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime"), "set_draw_order", "get_draw_order"); ADD_GROUP("Process Material", "process_"); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 8413be1ca9..55c055e34f 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -107,28 +107,39 @@ void PathFollow2D::_update_transform() { if (!c.is_valid()) return; + if (delta_offset == 0) { + return; + } + float o = offset; if (loop) o = Math::fposmod(o, c->get_baked_length()); Vector2 pos = c->interpolate_baked(o, cubic); + Vector2 offset = Vector2(h_offset, v_offset); + + Transform2D t = get_transform(); + t.set_origin(pos); + if (rotate) { - Vector2 n = (c->interpolate_baked(o + lookahead, cubic) - pos).normalized(); - Vector2 t = -n.tangent(); - pos += n * h_offset; - pos += t * v_offset; + Vector2 t_prev = (pos - c->interpolate_baked(o - delta_offset, cubic)).normalized(); + Vector2 t_cur = (c->interpolate_baked(o + delta_offset, cubic) - pos).normalized(); + + float dot = t_prev.dot(t_cur); + float angle = Math::acos(CLAMP(dot, -1, 1)); + + t.rotate(angle); - set_rotation(t.angle()); + t.translate(offset); } else { - pos.x += h_offset; - pos.y += v_offset; + t.set_origin(t.get_origin() + offset); } - set_position(pos); + set_transform(t); } void PathFollow2D::_notification(int p_what) { @@ -176,8 +187,6 @@ bool PathFollow2D::_set(const StringName &p_name, const Variant &p_value) { set_cubic_interpolation(p_value); } else if (String(p_name) == "loop") { set_loop(p_value); - } else if (String(p_name) == "lookahead") { - set_lookahead(p_value); } else return false; @@ -200,8 +209,6 @@ bool PathFollow2D::_get(const StringName &p_name, Variant &r_ret) const { r_ret = cubic; } else if (String(p_name) == "loop") { r_ret = loop; - } else if (String(p_name) == "lookahead") { - r_ret = lookahead; } else return false; @@ -219,7 +226,6 @@ void PathFollow2D::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::BOOL, "rotate")); p_list->push_back(PropertyInfo(Variant::BOOL, "cubic_interp")); p_list->push_back(PropertyInfo(Variant::BOOL, "loop")); - p_list->push_back(PropertyInfo(Variant::REAL, "lookahead", PROPERTY_HINT_RANGE, "0.001,1024.0,0.001")); } String PathFollow2D::get_configuration_warning() const { @@ -259,7 +265,7 @@ void PathFollow2D::_bind_methods() { } void PathFollow2D::set_offset(float p_offset) { - + delta_offset = p_offset - offset; offset = p_offset; if (path) _update_transform(); @@ -310,16 +316,6 @@ float PathFollow2D::get_unit_offset() const { return 0; } -void PathFollow2D::set_lookahead(float p_lookahead) { - - lookahead = p_lookahead; -} - -float PathFollow2D::get_lookahead() const { - - return lookahead; -} - void PathFollow2D::set_rotate(bool p_rotate) { rotate = p_rotate; @@ -344,11 +340,11 @@ bool PathFollow2D::has_loop() const { PathFollow2D::PathFollow2D() { offset = 0; + delta_offset = 0; h_offset = 0; v_offset = 0; path = NULL; rotate = true; cubic = true; loop = true; - lookahead = 4; } diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h index 88a0abdea9..f5ba3a3d32 100644 --- a/scene/2d/path_2d.h +++ b/scene/2d/path_2d.h @@ -60,9 +60,9 @@ public: private: Path2D *path; real_t offset; + real_t delta_offset; // change in offset since last _update_transform real_t h_offset; real_t v_offset; - real_t lookahead; bool cubic; bool loop; bool rotate; @@ -90,9 +90,6 @@ public: void set_unit_offset(float p_unit_offset); float get_unit_offset() const; - void set_lookahead(float p_lookahead); - float get_lookahead() const; - void set_loop(bool p_loop); bool has_loop() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 1287a800e3..1f6127e6eb 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -1028,7 +1028,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const on_floor = true; floor_velocity = collision.collider_vel; - if (collision.travel.length() < 1 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) { + Vector2 rel_v = lv - floor_velocity; + Vector2 hv = rel_v - p_floor_direction * p_floor_direction.dot(rel_v); + + if (collision.travel.length() < 1 && hv.length() < p_slope_stop_min_velocity) { Transform2D gt = get_global_transform(); gt.elements[2] -= collision.travel; set_global_transform(gt); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index b5b5445684..3f2ad19e51 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "polygon_2d.h" -Rect2 Polygon2D::get_item_rect() const { +Rect2 Polygon2D::_edit_get_rect() const { if (rect_cache_dirty) { int l = polygon.size(); @@ -49,16 +49,16 @@ Rect2 Polygon2D::get_item_rect() const { return item_rect; } -void Polygon2D::edit_set_pivot(const Point2 &p_pivot) { +void Polygon2D::_edit_set_pivot(const Point2 &p_pivot) { set_offset(p_pivot); } -Point2 Polygon2D::edit_get_pivot() const { +Point2 Polygon2D::_edit_get_pivot() const { return get_offset(); } -bool Polygon2D::edit_has_pivot() const { +bool Polygon2D::_edit_use_pivot() const { return true; } diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h index 0c2c049c18..d09e22f5ff 100644 --- a/scene/2d/polygon_2d.h +++ b/scene/2d/polygon_2d.h @@ -99,11 +99,11 @@ public: //editor stuff - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; Polygon2D(); }; diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp index cde665d422..1e729bc179 100644 --- a/scene/2d/position_2d.cpp +++ b/scene/2d/position_2d.cpp @@ -38,7 +38,7 @@ void Position2D::_draw_cross() { draw_line(Point2(0, -10), Point2(0, +10), Color(0.5, 1, 0.5)); } -Rect2 Position2D::get_item_rect() const { +Rect2 Position2D::_edit_get_rect() const { return Rect2(Point2(-10, -10), Size2(20, 20)); } diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h index af54fb919a..5961e447df 100644 --- a/scene/2d/position_2d.h +++ b/scene/2d/position_2d.h @@ -42,7 +42,7 @@ protected: void _notification(int p_what); public: - virtual Rect2 get_item_rect() const; + virtual Rect2 _edit_get_rect() const; Position2D(); }; diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp index bf7c5a3ba4..d5fcda90d5 100644 --- a/scene/2d/screen_button.cpp +++ b/scene/2d/screen_button.cpp @@ -133,7 +133,7 @@ void TouchScreenButton::_notification(int p_what) { return; if (shape.is_valid()) { Color draw_col = get_tree()->get_debug_collisions_color(); - Vector2 pos = shape_centered ? get_item_rect().size * 0.5f : Vector2(); + Vector2 pos = shape_centered ? _edit_get_rect().size * 0.5f : Vector2(); draw_set_transform_matrix(get_canvas_transform().translated(pos)); shape->draw(get_canvas_item(), draw_col); } @@ -251,7 +251,7 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) { bool TouchScreenButton::_is_point_inside(const Point2 &p_point) { Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(p_point); - Rect2 item_rect = get_item_rect(); + Rect2 item_rect = _edit_get_rect(); bool touched = false; bool check_rect = true; @@ -322,13 +322,13 @@ void TouchScreenButton::_release(bool p_exiting_tree) { } } -Rect2 TouchScreenButton::get_item_rect() const { +Rect2 TouchScreenButton::_edit_get_rect() const { if (texture.is_null()) return Rect2(0, 0, 1, 1); /* if (texture.is_null()) - return CanvasItem::get_item_rect(); + return CanvasItem::_edit_get_rect(); */ return Rect2(Size2(), texture->get_size()); diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h index 7647070b26..2e674c20b4 100644 --- a/scene/2d/screen_button.h +++ b/scene/2d/screen_button.h @@ -102,7 +102,7 @@ public: bool is_pressed() const; - Rect2 get_item_rect() const; + Rect2 _edit_get_rect() const; TouchScreenButton(); }; diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index c53faab5f9..df2265aae9 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -33,16 +33,16 @@ #include "scene/main/viewport.h" #include "scene/scene_string_names.h" -void Sprite::edit_set_pivot(const Point2 &p_pivot) { +void Sprite::_edit_set_pivot(const Point2 &p_pivot) { set_offset(p_pivot); } -Point2 Sprite::edit_get_pivot() const { +Point2 Sprite::_edit_get_pivot() const { return get_offset(); } -bool Sprite::edit_has_pivot() const { +bool Sprite::_edit_use_pivot() const { return true; } @@ -257,13 +257,13 @@ int Sprite::get_hframes() const { return hframes; } -Rect2 Sprite::get_item_rect() const { +Rect2 Sprite::_edit_get_rect() const { if (texture.is_null()) return Rect2(0, 0, 1, 1); /* if (texture.is_null()) - return CanvasItem::get_item_rect(); + return CanvasItem::_edit_get_rect(); */ Size2i s; @@ -368,224 +368,3 @@ Sprite::Sprite() { vframes = 1; hframes = 1; } - -//////////////////////////// VPSPRITE -/// -/// -/// - -#if 0 -void ViewportSprite::edit_set_pivot(const Point2& p_pivot) { - - set_offset(p_pivot); -} - -Point2 ViewportSprite::edit_get_pivot() const { - - return get_offset(); -} -bool ViewportSprite::edit_has_pivot() const { - - return true; -} - -void ViewportSprite::_notification(int p_what) { - - switch(p_what) { - - case NOTIFICATION_ENTER_TREE: { - - if (!viewport_path.is_empty()) { - - Node *n = get_node(viewport_path); - ERR_FAIL_COND(!n); - Viewport *vp=Object::cast_to<Viewport>(n); - ERR_FAIL_COND(!vp); - - Ref<RenderTargetTexture> rtt = vp->get_render_target_texture(); - texture=rtt; - texture->connect("changed",this,"update"); - item_rect_changed(); - } - } break; - case NOTIFICATION_EXIT_TREE: { - - if (texture.is_valid()) { - - texture->disconnect("changed",this,"update"); - texture=Ref<Texture>(); - } - } break; - case NOTIFICATION_DRAW: { - - if (texture.is_null()) - return; - - RID ci = get_canvas_item(); - - /* - texture->draw(ci,Point2()); - break; - */ - - Size2i s; - Rect2i src_rect; - - s = texture->get_size(); - - src_rect.size=s; - - Point2 ofs=offset; - if (centered) - ofs-=s/2; - - if (OS::get_singleton()->get_use_pixel_snap()) { - ofs=ofs.floor(); - } - Rect2 dst_rect(ofs,s); - texture->draw_rect_region(ci,dst_rect,src_rect,modulate); - - } break; - } -} - -void ViewportSprite::set_viewport_path(const NodePath& p_viewport) { - - viewport_path=p_viewport; - update(); - if (!is_inside_tree()) - return; - - if (texture.is_valid()) { - texture->disconnect("changed",this,"update"); - texture=Ref<Texture>(); - } - - if (viewport_path.is_empty()) - return; - - - Node *n = get_node(viewport_path); - ERR_FAIL_COND(!n); - Viewport *vp=Object::cast_to<Viewport>(n); - ERR_FAIL_COND(!vp); - - Ref<RenderTargetTexture> rtt = vp->get_render_target_texture(); - texture=rtt; - - if (texture.is_valid()) { - texture->connect("changed",this,"update"); - } - - item_rect_changed(); - -} - -NodePath ViewportSprite::get_viewport_path() const { - - return viewport_path; -} - -void ViewportSprite::set_centered(bool p_center) { - - centered=p_center; - update(); - item_rect_changed(); -} - -bool ViewportSprite::is_centered() const { - - return centered; -} - -void ViewportSprite::set_offset(const Point2& p_offset) { - - offset=p_offset; - update(); - item_rect_changed(); -} -Point2 ViewportSprite::get_offset() const { - - return offset; -} -void ViewportSprite::set_modulate(const Color& p_color) { - - modulate=p_color; - update(); -} - -Color ViewportSprite::get_modulate() const{ - - return modulate; -} - - -Rect2 ViewportSprite::get_item_rect() const { - - if (texture.is_null()) - return Rect2(0,0,1,1); - /* - if (texture.is_null()) - return CanvasItem::get_item_rect(); - */ - - Size2i s; - - s = texture->get_size(); - Point2 ofs=offset; - if (centered) - ofs-=s/2; - - if (s==Size2(0,0)) - s=Size2(1,1); - - return Rect2(ofs,s); -} - -String ViewportSprite::get_configuration_warning() const { - - if (!has_node(viewport_path) || !Object::cast_to<Viewport>(get_node(viewport_path))) { - return TTR("Path property must point to a valid Viewport node to work. Such Viewport must be set to 'render target' mode."); - } else { - - Node *n = get_node(viewport_path); - if (n) { - Viewport *vp = Object::cast_to<Viewport>(n); - if (!vp->is_set_as_render_target()) { - - return TTR("The Viewport set in the path property must be set as 'render target' in order for this sprite to work."); - } - } - } - - return String(); - -} - -void ViewportSprite::_bind_methods() { - - ClassDB::bind_method(D_METHOD("set_viewport_path","path"),&ViewportSprite::set_viewport_path); - ClassDB::bind_method(D_METHOD("get_viewport_path"),&ViewportSprite::get_viewport_path); - - ClassDB::bind_method(D_METHOD("set_centered","centered"),&ViewportSprite::set_centered); - ClassDB::bind_method(D_METHOD("is_centered"),&ViewportSprite::is_centered); - - ClassDB::bind_method(D_METHOD("set_offset","offset"),&ViewportSprite::set_offset); - ClassDB::bind_method(D_METHOD("get_offset"),&ViewportSprite::get_offset); - - ClassDB::bind_method(D_METHOD("set_modulate","modulate"),&ViewportSprite::set_modulate); - ClassDB::bind_method(D_METHOD("get_modulate"),&ViewportSprite::get_modulate); - - ADD_PROPERTYNZ( PropertyInfo( Variant::NODE_PATH, "viewport"), "set_viewport_path","get_viewport_path"); - ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "centered"), "set_centered","is_centered"); - ADD_PROPERTYNZ( PropertyInfo( Variant::VECTOR2, "offset"), "set_offset","get_offset"); - ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), "set_modulate","get_modulate"); - -} - -ViewportSprite::ViewportSprite() { - - centered=true; - modulate=Color(1,1,1,1); -} -#endif diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index 64d30325f2..1bef73c0a5 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -62,9 +62,10 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: - virtual void edit_set_pivot(const Point2 &p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; + virtual Rect2 _edit_get_rect() const; void set_texture(const Ref<Texture> &p_texture); Ref<Texture> get_texture() const; @@ -102,53 +103,7 @@ public: void set_hframes(int p_amount); int get_hframes() const; - virtual Rect2 get_item_rect() const; - Sprite(); }; -#if 0 -class ViewportSprite : public Node2D { - - GDCLASS( ViewportSprite, Node2D ); - - Ref<Texture> texture; - NodePath viewport_path; - - bool centered; - Point2 offset; - Color modulate; - -protected: - - void _notification(int p_what); - - static void _bind_methods(); - -public: - - virtual void edit_set_pivot(const Point2& p_pivot); - virtual Point2 edit_get_pivot() const; - virtual bool edit_has_pivot() const; - - void set_viewport_path(const NodePath& p_viewport); - NodePath get_viewport_path() const; - - void set_centered(bool p_center); - bool is_centered() const; - - void set_offset(const Point2& p_offset); - Point2 get_offset() const; - - void set_modulate(const Color& p_color); - Color get_modulate() const; - - virtual Rect2 get_item_rect() const; - - virtual String get_configuration_warning() const; - - ViewportSprite(); -}; - -#endif #endif // SPRITE_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index dd4270ab26..f067b5a187 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -883,7 +883,7 @@ PoolVector<int> TileMap::_get_tile_data() const { return data; } -Rect2 TileMap::get_item_rect() const { +Rect2 TileMap::_edit_get_rect() const { const_cast<TileMap *>(this)->_update_dirty_quadrants(); return rect_cache; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 706b87cec3..9e14ec838a 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -229,7 +229,7 @@ public: void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false); int get_cellv(const Vector2 &p_pos) const; - Rect2 get_item_rect() const; + Rect2 _edit_get_rect() const; void set_collision_layer(uint32_t p_layer); uint32_t get_collision_layer() const; diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index b0fd57baf5..298bc2649e 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -83,7 +83,7 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) { _change_notify("rect"); } -Rect2 VisibilityNotifier2D::get_item_rect() const { +Rect2 VisibilityNotifier2D::_edit_get_rect() const { return rect; } diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h index ee5152978b..6e06833912 100644 --- a/scene/2d/visibility_notifier_2d.h +++ b/scene/2d/visibility_notifier_2d.h @@ -54,13 +54,13 @@ protected: static void _bind_methods(); public: + virtual Rect2 _edit_get_rect() const; + void set_rect(const Rect2 &p_rect); Rect2 get_rect() const; bool is_on_screen() const; - virtual Rect2 get_item_rect() const; - VisibilityNotifier2D(); }; diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp index 382cbb8f38..a6d812efec 100644 --- a/scene/3d/collision_polygon.cpp +++ b/scene/3d/collision_polygon.cpp @@ -117,7 +117,7 @@ Vector<Point2> CollisionPolygon::get_polygon() const { return polygon; } -Rect3 CollisionPolygon::get_item_rect() const { +AABB CollisionPolygon::get_item_rect() const { return aabb; } @@ -176,7 +176,7 @@ void CollisionPolygon::_bind_methods() { CollisionPolygon::CollisionPolygon() { - aabb = Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2)); + aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); depth = 1.0; set_notify_local_transform(true); parent = NULL; diff --git a/scene/3d/collision_polygon.h b/scene/3d/collision_polygon.h index dbed1d7154..14d8c3aba6 100644 --- a/scene/3d/collision_polygon.h +++ b/scene/3d/collision_polygon.h @@ -40,7 +40,7 @@ class CollisionPolygon : public Spatial { protected: float depth; - Rect3 aabb; + AABB aabb; Vector<Point2> polygon; uint32_t owner_id; @@ -64,7 +64,7 @@ public: void set_disabled(bool p_disabled); bool is_disabled() const; - virtual Rect3 get_item_rect() const; + virtual AABB get_item_rect() const; String get_configuration_warning() const; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index bc70feaffb..05d5d52d28 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -31,12 +31,12 @@ #include "mesh_instance.h" -void GIProbeData::set_bounds(const Rect3 &p_bounds) { +void GIProbeData::set_bounds(const AABB &p_bounds) { VS::get_singleton()->gi_probe_set_bounds(probe, p_bounds); } -Rect3 GIProbeData::get_bounds() const { +AABB GIProbeData::get_bounds() const { return VS::get_singleton()->gi_probe_get_bounds(probe); } @@ -180,7 +180,7 @@ void GIProbeData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_compress", "compress"), &GIProbeData::set_compress); ClassDB::bind_method(D_METHOD("is_compressed"), &GIProbeData::is_compressed); - ADD_PROPERTY(PropertyInfo(Variant::RECT3, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "cell_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_size", "get_cell_size"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "to_cell_xform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_to_cell_xform", "get_to_cell_xform"); @@ -542,7 +542,7 @@ static _FORCE_INLINE_ Vector2 get_uv(const Vector3 &p_pos, const Vector3 *p_vtx, return p_uv[0] * u + p_uv[1] * v + p_uv[2] * w; } -void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const Rect3 &p_aabb, Baker *p_baker) { +void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const AABB &p_aabb, Baker *p_baker) { if (p_level == p_baker->cell_subdiv - 1) { //plot the face by guessing it's albedo and emission value @@ -702,7 +702,7 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons int half = (1 << (p_baker->cell_subdiv - 1)) >> (p_level + 1); for (int i = 0; i < 8; i++) { - Rect3 aabb = p_aabb; + AABB aabb = p_aabb; aabb.size *= 0.5; int nx = p_x; @@ -726,7 +726,7 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons continue; { - Rect3 test_aabb = aabb; + AABB test_aabb = aabb; //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test @@ -1083,11 +1083,11 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { - Rect3 aabb = mesh->get_aabb(); + AABB aabb = mesh->get_aabb(); Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform(); - if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) { + if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { Baker::PlotMesh pm; pm.local_xform = xf; pm.mesh = mesh; @@ -1113,11 +1113,11 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { if (!mesh.is_valid()) continue; - Rect3 aabb = mesh->get_aabb(); + AABB aabb = mesh->get_aabb(); Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); - if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) { + if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) { Baker::PlotMesh pm; pm.local_xform = xf; pm.mesh = mesh; @@ -1151,7 +1151,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { baker.bake_cells.resize(1); //find out the actual real bounds, power of 2, which gets the highest subdivision - baker.po2_bounds = Rect3(-extents, extents * 2.0); + baker.po2_bounds = AABB(-extents, extents * 2.0); int longest_axis = baker.po2_bounds.get_longest_axis_index(); baker.axis_cell_size[longest_axis] = (1 << (baker.cell_subdiv - 1)); baker.leaf_voxel_count = 0; @@ -1286,7 +1286,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { Ref<GIProbeData> probe_data; probe_data.instance(); - probe_data->set_bounds(Rect3(-extents, extents * 2.0)); + probe_data->set_bounds(AABB(-extents, extents * 2.0)); probe_data->set_cell_size(baker.po2_bounds.size[longest_axis] / baker.axis_cell_size[longest_axis]); probe_data->set_dynamic_data(data); probe_data->set_dynamic_range(dynamic_range); @@ -1306,7 +1306,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { } } -void GIProbe::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, Baker *p_baker) { +void GIProbe::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, Baker *p_baker) { if (p_level == p_baker->cell_subdiv - 1) { @@ -1328,7 +1328,7 @@ void GIProbe::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, Ref<Multi if (p_baker->bake_cells[p_idx].childs[i] == Baker::CHILD_EMPTY) continue; - Rect3 aabb = p_aabb; + AABB aabb = p_aabb; aabb.size *= 0.5; if (i & 1) @@ -1440,9 +1440,9 @@ void GIProbe::_debug_bake() { bake(NULL, true); } -Rect3 GIProbe::get_aabb() const { +AABB GIProbe::get_aabb() const { - return Rect3(-extents, extents * 2); + return AABB(-extents, extents * 2); } PoolVector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const { diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h index 8f13960b67..324ff8e917 100644 --- a/scene/3d/gi_probe.h +++ b/scene/3d/gi_probe.h @@ -43,8 +43,8 @@ protected: static void _bind_methods(); public: - void set_bounds(const Rect3 &p_bounds); - Rect3 get_bounds() const; + void set_bounds(const AABB &p_bounds); + AABB get_bounds() const; void set_cell_size(float p_size); float get_cell_size() const; @@ -146,7 +146,7 @@ private: MaterialCache _get_material_cache(Ref<Material> p_material); int leaf_voxel_count; - Rect3 po2_bounds; + AABB po2_bounds; int axis_cell_size[3]; struct PlotMesh { @@ -180,12 +180,12 @@ private: Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add); Baker::MaterialCache _get_material_cache(Ref<Material> p_material, Baker *p_baker); - void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const Rect3 &p_aabb, Baker *p_baker); + void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const AABB &p_aabb, Baker *p_baker); void _plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material); void _find_meshes(Node *p_at_node, Baker *p_baker); void _fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, Baker *p_baker); - void _debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, Baker *p_baker); + void _debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx, Baker *p_baker); void _create_debug_mesh(Baker *p_baker); void _debug_bake(); @@ -230,7 +230,7 @@ public: void bake(Node *p_from_node = NULL, bool p_create_visual_debug = false); - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; GIProbe(); diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp index 11f7efe066..092ed8f0b2 100644 --- a/scene/3d/immediate_geometry.cpp +++ b/scene/3d/immediate_geometry.cpp @@ -85,7 +85,7 @@ void ImmediateGeometry::clear() { cached_textures.clear(); } -Rect3 ImmediateGeometry::get_aabb() const { +AABB ImmediateGeometry::get_aabb() const { return aabb; } diff --git a/scene/3d/immediate_geometry.h b/scene/3d/immediate_geometry.h index 93ef726c6d..1ff4e05e82 100644 --- a/scene/3d/immediate_geometry.h +++ b/scene/3d/immediate_geometry.h @@ -42,7 +42,7 @@ class ImmediateGeometry : public GeometryInstance { // in VisualServer from becoming invalid if the texture is no longer used List<Ref<Texture> > cached_textures; bool empty; - Rect3 aabb; + AABB aabb; protected: static void _bind_methods(); @@ -62,7 +62,7 @@ public: void add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv = true); - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; ImmediateGeometry(); diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 389d87cd90..126c07f0be 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -117,24 +117,24 @@ bool Light::get_shadow_reverse_cull_face() const { return reverse_cull; } -Rect3 Light::get_aabb() const { +AABB Light::get_aabb() const { if (type == VisualServer::LIGHT_DIRECTIONAL) { - return Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2)); + return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); } else if (type == VisualServer::LIGHT_OMNI) { - return Rect3(Vector3(-1, -1, -1) * param[PARAM_RANGE], Vector3(2, 2, 2) * param[PARAM_RANGE]); + return AABB(Vector3(-1, -1, -1) * param[PARAM_RANGE], Vector3(2, 2, 2) * param[PARAM_RANGE]); } else if (type == VisualServer::LIGHT_SPOT) { float len = param[PARAM_RANGE]; float size = Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE])) * len; - return Rect3(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); + return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); } - return Rect3(); + return AABB(); } PoolVector<Face3> Light::get_faces(uint32_t p_usage_flags) const { @@ -222,6 +222,7 @@ void Light::_bind_methods() { ADD_GROUP("Light", "light_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_color", "get_color"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_ENERGY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_indirect_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_INDIRECT_ENERGY); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "light_negative"), "set_negative", "is_negative"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "light_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SPECULAR); ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); @@ -236,6 +237,7 @@ void Light::_bind_methods() { ADD_GROUP("", ""); BIND_ENUM_CONSTANT(PARAM_ENERGY); + BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY); BIND_ENUM_CONSTANT(PARAM_SPECULAR); BIND_ENUM_CONSTANT(PARAM_RANGE); BIND_ENUM_CONSTANT(PARAM_ATTENUATION); @@ -273,6 +275,7 @@ Light::Light(VisualServer::LightType p_type) { set_cull_mask(0xFFFFFFFF); set_param(PARAM_ENERGY, 1); + set_param(PARAM_INDIRECT_ENERGY, 1); set_param(PARAM_SPECULAR, 0.5); set_param(PARAM_RANGE, 5); set_param(PARAM_ATTENUATION, 1); diff --git a/scene/3d/light.h b/scene/3d/light.h index 2f3ac8a5e7..8514b429ec 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -46,6 +46,7 @@ class Light : public VisualInstance { public: enum Param { PARAM_ENERGY = VS::LIGHT_PARAM_ENERGY, + PARAM_INDIRECT_ENERGY = VS::LIGHT_PARAM_INDIRECT_ENERGY, PARAM_SPECULAR = VS::LIGHT_PARAM_SPECULAR, PARAM_RANGE = VS::LIGHT_PARAM_RANGE, PARAM_ATTENUATION = VS::LIGHT_PARAM_ATTENUATION, @@ -113,7 +114,7 @@ public: void set_shadow_reverse_cull_face(bool p_enable); bool get_shadow_reverse_cull_face() const; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; Light(); diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp index c8215971c4..1e52ccc6e0 100644 --- a/scene/3d/mesh_instance.cpp +++ b/scene/3d/mesh_instance.cpp @@ -165,12 +165,12 @@ NodePath MeshInstance::get_skeleton_path() { return skeleton_path; } -Rect3 MeshInstance::get_aabb() const { +AABB MeshInstance::get_aabb() const { if (!mesh.is_null()) return mesh->get_aabb(); - return Rect3(); + return AABB(); } PoolVector<Face3> MeshInstance::get_faces(uint32_t p_usage_flags) const { diff --git a/scene/3d/mesh_instance.h b/scene/3d/mesh_instance.h index 8e8c12a592..970a10aaf3 100644 --- a/scene/3d/mesh_instance.h +++ b/scene/3d/mesh_instance.h @@ -85,7 +85,7 @@ public: void create_debug_tangents(); - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; MeshInstance(); diff --git a/scene/3d/multimesh_instance.cpp b/scene/3d/multimesh_instance.cpp index f90489f1f0..ce7b97be7f 100644 --- a/scene/3d/multimesh_instance.cpp +++ b/scene/3d/multimesh_instance.cpp @@ -55,10 +55,10 @@ PoolVector<Face3> MultiMeshInstance::get_faces(uint32_t p_usage_flags) const { return PoolVector<Face3>(); } -Rect3 MultiMeshInstance::get_aabb() const { +AABB MultiMeshInstance::get_aabb() const { if (multimesh.is_null()) - return Rect3(); + return AABB(); else return multimesh->get_aabb(); } diff --git a/scene/3d/multimesh_instance.h b/scene/3d/multimesh_instance.h index cd0e7b463c..9b2b1ff9a7 100644 --- a/scene/3d/multimesh_instance.h +++ b/scene/3d/multimesh_instance.h @@ -52,7 +52,7 @@ public: void set_multimesh(const Ref<MultiMesh> &p_multimesh); Ref<MultiMesh> get_multimesh() const; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; MultiMeshInstance(); ~MultiMeshInstance(); diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 6ac6e52367..2a032f5d96 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -31,9 +31,9 @@ #include "scene/resources/surface_tool.h" #include "servers/visual_server.h" -Rect3 Particles::get_aabb() const { +AABB Particles::get_aabb() const { - return Rect3(); + return AABB(); } PoolVector<Face3> Particles::get_faces(uint32_t p_usage_flags) const { @@ -82,7 +82,7 @@ void Particles::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; VS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio); } -void Particles::set_visibility_aabb(const Rect3 &p_aabb) { +void Particles::set_visibility_aabb(const AABB &p_aabb) { visibility_aabb = p_aabb; VS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb); @@ -140,7 +140,7 @@ float Particles::get_randomness_ratio() const { return randomness_ratio; } -Rect3 Particles::get_visibility_aabb() const { +AABB Particles::get_visibility_aabb() const { return visibility_aabb; } @@ -252,7 +252,7 @@ void Particles::restart() { VisualServer::get_singleton()->particles_restart(particles); } -Rect3 Particles::capture_aabb() const { +AABB Particles::capture_aabb() const { return VS::get_singleton()->particles_get_current_aabb(particles); } @@ -335,7 +335,7 @@ void Particles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); - ADD_PROPERTY(PropertyInfo(Variant::RECT3, "visibility_aabb"), "set_visibility_aabb", "get_visibility_aabb"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "visibility_aabb"), "set_visibility_aabb", "get_visibility_aabb"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "local_coords"), "set_use_local_coordinates", "get_use_local_coordinates"); ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_order", PROPERTY_HINT_ENUM, "Index,Lifetime,View Depth"), "set_draw_order", "get_draw_order"); ADD_GROUP("Process Material", ""); @@ -367,7 +367,7 @@ Particles::Particles() { set_pre_process_time(0); set_explosiveness_ratio(0); set_randomness_ratio(0); - set_visibility_aabb(Rect3(Vector3(-4, -4, -4), Vector3(8, 8, 8))); + set_visibility_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8))); set_use_local_coordinates(true); set_draw_passes(1); set_draw_order(DRAW_ORDER_INDEX); @@ -836,9 +836,15 @@ void ParticlesMaterial::_update_shader() { if (flags[FLAG_DISABLE_Z]) { - code += " TRANSFORM[0] = vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0);\n"; - code += " TRANSFORM[1] = vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0);\n"; - code += " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0);\n"; + if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + code += " if (length(VELOCITY) > 0.0) { TRANSFORM[1].xyz = normalize(VELOCITY); } else { TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz); }\n"; + code += " TRANSFORM[0].xyz = normalize(cross(TRANSFORM[1].xyz,TRANSFORM[2].xyz));\n"; + code += " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0);\n"; + } else { + code += " TRANSFORM[0] = vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0);\n"; + code += " TRANSFORM[1] = vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0);\n"; + code += " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0);\n"; + } } else { //orient particle Y towards velocity diff --git a/scene/3d/particles.h b/scene/3d/particles.h index e3109f470f..30080360bb 100644 --- a/scene/3d/particles.h +++ b/scene/3d/particles.h @@ -65,7 +65,7 @@ private: float explosiveness_ratio; float randomness_ratio; float speed_scale; - Rect3 visibility_aabb; + AABB visibility_aabb; bool local_coords; int fixed_fps; bool fractional_delta; @@ -82,7 +82,7 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: - Rect3 get_aabb() const; + AABB get_aabb() const; PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; void set_emitting(bool p_emitting); @@ -92,7 +92,7 @@ public: void set_pre_process_time(float p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); - void set_visibility_aabb(const Rect3 &p_aabb); + void set_visibility_aabb(const AABB &p_aabb); void set_use_local_coordinates(bool p_enable); void set_process_material(const Ref<Material> &p_material); void set_speed_scale(float p_scale); @@ -104,7 +104,7 @@ public: float get_pre_process_time() const; float get_explosiveness_ratio() const; float get_randomness_ratio() const; - Rect3 get_visibility_aabb() const; + AABB get_visibility_aabb() const; bool get_use_local_coordinates() const; Ref<Material> get_process_material() const; float get_speed_scale() const; @@ -128,7 +128,7 @@ public: void restart(); - Rect3 capture_aabb() const; + AABB capture_aabb() const; Particles(); ~Particles(); }; diff --git a/scene/3d/portal.cpp b/scene/3d/portal.cpp index 6c14f7dbc9..4fde29aab9 100644 --- a/scene/3d/portal.cpp +++ b/scene/3d/portal.cpp @@ -98,7 +98,7 @@ void Portal::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::REAL, "connect_range", PROPERTY_HINT_RANGE, "0.1,4096,0.01")); } -Rect3 Portal::get_aabb() const { +AABB Portal::get_aabb() const { return aabb; } diff --git a/scene/3d/portal.h b/scene/3d/portal.h index 6de3df8553..4ea208a718 100644 --- a/scene/3d/portal.h +++ b/scene/3d/portal.h @@ -53,7 +53,7 @@ class Portal : public VisualInstance { Color disabled_color; float connect_range; - Rect3 aabb; + AABB aabb; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -63,7 +63,7 @@ protected: static void _bind_methods(); public: - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; void set_enabled(bool p_enabled); diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index 46b105cd21..0e575ec152 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -178,9 +178,9 @@ ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const { return update_mode; } -Rect3 ReflectionProbe::get_aabb() const { +AABB ReflectionProbe::get_aabb() const { - Rect3 aabb; + AABB aabb; aabb.position = -origin_offset; aabb.size = origin_offset + extents; return aabb; diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index 7c328a8f16..26f17fdcf9 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -101,7 +101,7 @@ public: void set_update_mode(UpdateMode p_mode); UpdateMode get_update_mode() const; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; ReflectionProbe(); diff --git a/scene/3d/room_instance.cpp b/scene/3d/room_instance.cpp index 439b6bfdf8..47a7b8bfb9 100644 --- a/scene/3d/room_instance.cpp +++ b/scene/3d/room_instance.cpp @@ -66,12 +66,12 @@ void Room::_notification(int p_what) { } } -Rect3 Room::get_aabb() const { +AABB Room::get_aabb() const { if (room.is_null()) - return Rect3(); + return AABB(); - return Rect3(); + return AABB(); } PoolVector<Face3> Room::get_faces(uint32_t p_usage_flags) const { diff --git a/scene/3d/room_instance.h b/scene/3d/room_instance.h index b9a64b6670..3069ea2eba 100644 --- a/scene/3d/room_instance.h +++ b/scene/3d/room_instance.h @@ -71,7 +71,7 @@ public: NOTIFICATION_AREA_CHANGED = 60 }; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; void set_room(const Ref<RoomBounds> &p_room); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 49a3205f21..18ebc22c8b 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -188,7 +188,7 @@ void SpriteBase3D::_queue_update() { call_deferred(SceneStringNames::get_singleton()->_im_update); } -Rect3 SpriteBase3D::get_aabb() const { +AABB SpriteBase3D::get_aabb() const { return aabb; } @@ -407,7 +407,7 @@ void Sprite3D::_draw() { } } - Rect3 aabb; + AABB aabb; for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); @@ -698,7 +698,7 @@ void AnimatedSprite3D::_draw() { } } - Rect3 aabb; + AABB aabb; for (int i = 0; i < 4; i++) { VS::get_singleton()->immediate_normal(immediate, normal); diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 1165392cb2..d18553a504 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -71,7 +71,7 @@ private: Vector3::Axis axis; float pixel_size; - Rect3 aabb; + AABB aabb; RID immediate; @@ -87,7 +87,7 @@ protected: void _notification(int p_what); static void _bind_methods(); virtual void _draw() = 0; - _FORCE_INLINE_ void set_aabb(const Rect3 &p_aabb) { aabb = p_aabb; } + _FORCE_INLINE_ void set_aabb(const AABB &p_aabb) { aabb = p_aabb; } _FORCE_INLINE_ RID &get_immediate() { return immediate; } void _queue_update(); @@ -130,7 +130,7 @@ public: virtual Rect2 get_item_rect() const = 0; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const; SpriteBase3D(); diff --git a/scene/3d/visibility_notifier.cpp b/scene/3d/visibility_notifier.cpp index e60b32a92a..47144c4b78 100644 --- a/scene/3d/visibility_notifier.cpp +++ b/scene/3d/visibility_notifier.cpp @@ -60,7 +60,7 @@ void VisibilityNotifier::_exit_camera(Camera *p_camera) { } } -void VisibilityNotifier::set_aabb(const Rect3 &p_aabb) { +void VisibilityNotifier::set_aabb(const AABB &p_aabb) { if (aabb == p_aabb) return; @@ -74,7 +74,7 @@ void VisibilityNotifier::set_aabb(const Rect3 &p_aabb) { update_gizmo(); } -Rect3 VisibilityNotifier::get_aabb() const { +AABB VisibilityNotifier::get_aabb() const { return aabb; } @@ -108,7 +108,7 @@ void VisibilityNotifier::_bind_methods() { ClassDB::bind_method(D_METHOD("get_aabb"), &VisibilityNotifier::get_aabb); ClassDB::bind_method(D_METHOD("is_on_screen"), &VisibilityNotifier::is_on_screen); - ADD_PROPERTY(PropertyInfo(Variant::RECT3, "aabb"), "set_aabb", "get_aabb"); + ADD_PROPERTY(PropertyInfo(Variant::AABB, "aabb"), "set_aabb", "get_aabb"); ADD_SIGNAL(MethodInfo("camera_entered", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"))); ADD_SIGNAL(MethodInfo("camera_exited", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"))); @@ -118,7 +118,7 @@ void VisibilityNotifier::_bind_methods() { VisibilityNotifier::VisibilityNotifier() { - aabb = Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2)); + aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2)); set_notify_transform(true); } diff --git a/scene/3d/visibility_notifier.h b/scene/3d/visibility_notifier.h index 0b83e0534e..fc06cf5aec 100644 --- a/scene/3d/visibility_notifier.h +++ b/scene/3d/visibility_notifier.h @@ -39,7 +39,7 @@ class VisibilityNotifier : public Spatial { Set<Camera *> cameras; - Rect3 aabb; + AABB aabb; protected: virtual void _screen_enter() {} @@ -53,8 +53,8 @@ protected: void _exit_camera(Camera *p_camera); public: - void set_aabb(const Rect3 &p_aabb); - Rect3 get_aabb() const; + void set_aabb(const AABB &p_aabb); + AABB get_aabb() const; bool is_on_screen() const; VisibilityNotifier(); diff --git a/scene/3d/visual_instance.cpp b/scene/3d/visual_instance.cpp index fa35d982eb..b92e7ead04 100644 --- a/scene/3d/visual_instance.cpp +++ b/scene/3d/visual_instance.cpp @@ -33,7 +33,7 @@ #include "servers/visual_server.h" #include "skeleton.h" -Rect3 VisualInstance::get_transformed_aabb() const { +AABB VisualInstance::get_transformed_aabb() const { return get_global_transform().xform(get_aabb()); } diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index c405236d2c..5827f1e1fb 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -62,10 +62,10 @@ public: }; RID get_instance() const; - virtual Rect3 get_aabb() const = 0; + virtual AABB get_aabb() const = 0; virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const = 0; - virtual Rect3 get_transformed_aabb() const; // helper + virtual AABB get_transformed_aabb() const; // helper void set_base(const RID &p_base); diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index e0508cf147..40d06dc756 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -416,10 +416,10 @@ Variant Tween::_run_equation(InterpolateData &p_data) { result = r; } break; - case Variant::RECT3: { - Rect3 i = initial_val; - Rect3 d = delta_val; - Rect3 r; + case Variant::AABB: { + AABB i = initial_val; + AABB d = delta_val; + AABB r; APPLY_EQUATION(position.x); APPLY_EQUATION(position.y); @@ -956,10 +956,10 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final case Variant::QUAT: delta_val = final_val.operator Quat() - initial_val.operator Quat(); break; - case Variant::RECT3: { - Rect3 i = initial_val; - Rect3 f = final_val; - delta_val = Rect3(f.position - i.position, f.size - i.size); + case Variant::AABB: { + AABB i = initial_val; + AABB f = final_val; + delta_val = AABB(f.position - i.position, f.size - i.size); } break; case Variant::TRANSFORM: { Transform i = initial_val; diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index e73ada9f31..adca78d1d4 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -45,7 +45,7 @@ #endif #include <stdio.h> -Variant Control::edit_get_state() const { +Dictionary Control::_edit_get_state() const { Dictionary s; s["rect"] = get_rect(); @@ -59,22 +59,78 @@ Variant Control::edit_get_state() const { s["anchors"] = anchors; return s; } -void Control::edit_set_state(const Variant &p_state) { +void Control::_edit_set_state(const Dictionary &p_state) { - Dictionary s = p_state; + Dictionary state = p_state; - Rect2 state = s["rect"]; - set_position(state.position); - set_size(state.size); - set_rotation(s["rotation"]); - set_scale(s["scale"]); - Array anchors = s["anchors"]; + Rect2 rect = state["rect"]; + set_position(rect.position); + set_size(rect.size); + set_rotation(state["rotation"]); + set_scale(state["scale"]); + Array anchors = state["anchors"]; set_anchor(MARGIN_LEFT, anchors[0]); set_anchor(MARGIN_TOP, anchors[1]); set_anchor(MARGIN_RIGHT, anchors[2]); set_anchor(MARGIN_BOTTOM, anchors[3]); } +void Control::_edit_set_position(const Point2 &p_position) { + set_position(p_position); +}; + +Point2 Control::_edit_get_position() const { + return get_position(); +}; + +void Control::_edit_set_rect(const Rect2 &p_edit_rect) { + + Transform2D xform = _get_internal_transform(); + + Vector2 new_pos = xform.basis_xform(p_edit_rect.position); + + Vector2 pos = get_position() + new_pos; + + Rect2 new_rect = get_rect(); + new_rect.position = pos.snapped(Vector2(1, 1)); + new_rect.size = p_edit_rect.size.snapped(Vector2(1, 1)); + + set_position(new_rect.position); + set_size(new_rect.size); +} + +Rect2 Control::_edit_get_rect() const { + return Rect2(Point2(), get_size()); +} + +bool Control::_edit_use_rect() const { + return true; +} + +void Control::_edit_set_rotation(float p_rotation) { + set_rotation(p_rotation); +} + +float Control::_edit_get_rotation() const { + return get_rotation(); +} + +bool Control::_edit_use_rotation() const { + return true; +} + +void Control::_edit_set_pivot(const Point2 &p_pivot) { + set_pivot_offset(p_pivot); +} + +Point2 Control::_edit_get_pivot() const { + return get_pivot_offset(); +} + +bool Control::_edit_use_pivot() const { + return true; +} + void Control::set_custom_minimum_size(const Size2 &p_custom) { if (p_custom == data.custom_minimum_size) @@ -96,7 +152,7 @@ Size2 Control::get_combined_minimum_size() const { return minsize; } -Size2 Control::edit_get_minimum_size() const { +Size2 Control::_edit_get_minimum_size() const { return get_combined_minimum_size(); } @@ -110,23 +166,6 @@ Transform2D Control::_get_internal_transform() const { return offset.affine_inverse() * (rot_scale * offset); } -void Control::edit_set_rect(const Rect2 &p_edit_rect) { - - Transform2D xform = _get_internal_transform(); - - // xform[2] += get_position(); - - Vector2 new_pos = xform.basis_xform(p_edit_rect.position); - - Vector2 pos = get_position() + new_pos; - - Rect2 new_rect = get_rect(); - new_rect.position = pos.snapped(Vector2(1, 1)); - new_rect.size = p_edit_rect.size.snapped(Vector2(1, 1)); - - set_position(new_rect.position); - set_size(new_rect.size); -} bool Control::_set(const StringName &p_name, const Variant &p_value) { @@ -1210,7 +1249,7 @@ Size2 Control::get_parent_area_size() const { if (data.parent_canvas_item) { - parent_size = data.parent_canvas_item->get_item_rect().size; + parent_size = data.parent_canvas_item->_edit_get_rect().size; } else { parent_size = get_viewport()->get_visible_rect().size; @@ -1289,7 +1328,7 @@ float Control::_get_parent_range(int p_idx) const { } if (data.parent_canvas_item) { - return data.parent_canvas_item->get_item_rect().size[p_idx & 1]; + return data.parent_canvas_item->_edit_get_rect().size[p_idx & 1]; } else { return get_viewport()->get_visible_rect().size[p_idx & 1]; } @@ -1751,11 +1790,6 @@ Rect2 Control::get_rect() const { return Rect2(get_position(), get_size()); } -Rect2 Control::get_item_rect() const { - - return Rect2(Point2(), get_size()); -} - void Control::add_icon_override(const StringName &p_name, const Ref<Texture> &p_icon) { ERR_FAIL_COND(p_icon.is_null()); @@ -1847,6 +1881,25 @@ Control *Control::find_next_valid_focus() const { while (true) { + // If the focus property is manually overwritten, attempt to use it. + + if (!data.focus_next.is_empty()) { + Node *n = get_node(data.focus_next); + if (n) { + from = Object::cast_to<Control>(n); + + if (!from) { + + ERR_EXPLAIN("Next focus node is not a control: " + n->get_name()); + ERR_FAIL_V(NULL); + } + } else { + return NULL; + } + if (from->is_visible() && from->get_focus_mode() != FOCUS_NONE) + return from; + } + // find next child Control *next_child = NULL; @@ -1926,6 +1979,25 @@ Control *Control::find_prev_valid_focus() const { while (true) { + // If the focus property is manually overwritten, attempt to use it. + + if (!data.focus_prev.is_empty()) { + Node *n = get_node(data.focus_prev); + if (n) { + from = Object::cast_to<Control>(n); + + if (!from) { + + ERR_EXPLAIN("Prev focus node is not a control: " + n->get_name()); + ERR_FAIL_V(NULL); + } + } else { + return NULL; + } + if (from->is_visible() && from->get_focus_mode() != FOCUS_NONE) + return from; + } + // find prev child Control *prev_child = NULL; @@ -2157,6 +2229,26 @@ NodePath Control::get_focus_neighbour(Margin p_margin) const { return data.focus_neighbour[p_margin]; } +void Control::set_focus_next(const NodePath &p_next) { + + data.focus_next = p_next; +} + +NodePath Control::get_focus_next() const { + + return data.focus_next; +} + +void Control::set_focus_previous(const NodePath &p_prev) { + + data.focus_prev = p_prev; +} + +NodePath Control::get_focus_previous() const { + + return data.focus_prev; +} + #define MAX_NEIGHBOUR_SEARCH_COUNT 512 Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) { @@ -2172,7 +2264,7 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) { if (!c) { - ERR_EXPLAIN("Next focus node is not a control: " + n->get_name()); + ERR_EXPLAIN("Neighbour focus node is not a control: " + n->get_name()); ERR_FAIL_V(NULL); } } else { @@ -2196,7 +2288,7 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) { Point2 points[4]; Transform2D xform = get_global_transform(); - Rect2 rect = get_item_rect(); + Rect2 rect = _edit_get_rect(); points[0] = xform.xform(rect.position); points[1] = xform.xform(rect.position + Point2(rect.size.x, 0)); @@ -2255,7 +2347,7 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con Point2 points[4]; Transform2D xform = c->get_global_transform(); - Rect2 rect = c->get_item_rect(); + Rect2 rect = c->_edit_get_rect(); points[0] = xform.xform(rect.position); points[1] = xform.xform(rect.position + Point2(rect.size.x, 0)); @@ -2677,6 +2769,12 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("set_focus_neighbour", "margin", "neighbour"), &Control::set_focus_neighbour); ClassDB::bind_method(D_METHOD("get_focus_neighbour", "margin"), &Control::get_focus_neighbour); + ClassDB::bind_method(D_METHOD("set_focus_next", "next"), &Control::set_focus_next); + ClassDB::bind_method(D_METHOD("get_focus_next"), &Control::get_focus_next); + + ClassDB::bind_method(D_METHOD("set_focus_previous", "previous"), &Control::set_focus_previous); + ClassDB::bind_method(D_METHOD("get_focus_previous"), &Control::get_focus_previous); + ClassDB::bind_method(D_METHOD("force_drag", "data", "preview"), &Control::force_drag); ClassDB::bind_method(D_METHOD("set_mouse_filter", "filter"), &Control::set_mouse_filter); @@ -2737,6 +2835,8 @@ void Control::_bind_methods() { ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_top"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_TOP); ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_right"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_RIGHT); ADD_PROPERTYINZ(PropertyInfo(Variant::NODE_PATH, "focus_neighbour_bottom"), "set_focus_neighbour", "get_focus_neighbour", MARGIN_BOTTOM); + ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_next"), "set_focus_next", "get_focus_next"); + ADD_PROPERTYNZ(PropertyInfo(Variant::NODE_PATH, "focus_previous"), "set_focus_previous", "get_focus_previous"); ADD_GROUP("Mouse", "mouse_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mouse_filter", PROPERTY_HINT_ENUM, "Stop,Pass,Ignore"), "set_mouse_filter", "get_mouse_filter"); diff --git a/scene/gui/control.h b/scene/gui/control.h index 4d0e3934ad..92d1c969fc 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -191,6 +191,8 @@ private: ObjectID modal_prev_focus_owner; NodePath focus_neighbour[4]; + NodePath focus_next; + NodePath focus_prev; HashMap<StringName, Ref<Texture>, StringNameHasher> icon_override; HashMap<StringName, Ref<Shader>, StringNameHasher> shader_override; @@ -269,10 +271,25 @@ public: }; - virtual Variant edit_get_state() const; - virtual void edit_set_state(const Variant &p_state); - virtual void edit_set_rect(const Rect2 &p_edit_rect); - virtual Size2 edit_get_minimum_size() const; + virtual Dictionary _edit_get_state() const; + virtual void _edit_set_state(const Dictionary &p_state); + + virtual void _edit_set_position(const Point2 &p_position); + virtual Point2 _edit_get_position() const; + + virtual void _edit_set_rect(const Rect2 &p_edit_rect); + virtual Rect2 _edit_get_rect() const; + virtual bool _edit_use_rect() const; + + virtual void _edit_set_rotation(float p_rotation); + virtual float _edit_get_rotation() const; + virtual bool _edit_use_rotation() const; + + virtual void _edit_set_pivot(const Point2 &p_pivot); + virtual Point2 _edit_get_pivot() const; + virtual bool _edit_use_pivot() const; + + virtual Size2 _edit_get_minimum_size() const; void accept_event(); @@ -374,6 +391,11 @@ public: void set_focus_neighbour(Margin p_margin, const NodePath &p_neighbour); NodePath get_focus_neighbour(Margin p_margin) const; + void set_focus_next(const NodePath &p_next); + NodePath get_focus_next() const; + void set_focus_previous(const NodePath &p_prev); + NodePath get_focus_previous() const; + Control *get_focus_owner() const; void set_mouse_filter(MouseFilter p_filter); @@ -420,7 +442,6 @@ public: CursorShape get_default_cursor_shape() const; virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const; - virtual Rect2 get_item_rect() const; virtual Transform2D get_transform() const; bool is_toplevel_control() const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index e9e9dcc859..5e4dedcb48 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -525,6 +525,11 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) { return; } + if (mb->get_button_index() == BUTTON_RIGHT) { + emit_signal("rmb_clicked", mb->get_position()); + + return; + } } if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) { @@ -1397,6 +1402,7 @@ void ItemList::_bind_methods() { ADD_SIGNAL(MethodInfo("item_rmb_selected", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::VECTOR2, "at_position"))); ADD_SIGNAL(MethodInfo("multi_selected", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "selected"))); ADD_SIGNAL(MethodInfo("item_activated", PropertyInfo(Variant::INT, "index"))); + ADD_SIGNAL(MethodInfo("rmb_clicked", PropertyInfo(Variant::VECTOR2, "at_position"))); GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000); } diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 5d3e5ec0e8..f7bf1cd9ea 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -1309,6 +1309,7 @@ void LineEdit::set_expand_to_text_length(bool p_enabled) { expand_to_text_length = p_enabled; minimum_size_changed(); + set_window_pos(0); } bool LineEdit::get_expand_to_text_length() const { @@ -1428,7 +1429,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "max_length"), "set_max_length", "get_max_length"); ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "secret"), "set_secret", "is_secret"); - ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "expand_to_len"), "set_expand_to_text_length", "get_expand_to_text_length"); + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "expand_to_text_length"), "set_expand_to_text_length", "get_expand_to_text_length"); ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode"); ADD_GROUP("Placeholder", "placeholder_"); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder"); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 798acb9d52..71e02cb2f7 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -877,11 +877,13 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { if (main->first_invalid_line < main->lines.size()) return; + int line = 0; + Item *item = NULL; + bool outside; + _find_click(main, m->get_position(), &item, &line, &outside); + if (selection.click) { - int line = 0; - Item *item = NULL; - _find_click(main, m->get_position(), &item, &line); if (!item) return; // do not update @@ -912,6 +914,22 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { selection.active = true; update(); } + + Variant meta; + if (item && !outside && _find_meta(item, &meta)) { + if (meta_hovering != item) { + if (meta_hovering) { + emit_signal("meta_hover_ended", current_meta); + } + meta_hovering = static_cast<ItemMeta *>(item); + current_meta = meta; + emit_signal("meta_hover_started", meta); + } + } else if (meta_hovering) { + emit_signal("meta_hover_ended", current_meta); + meta_hovering = NULL; + current_meta = false; + } } } @@ -1968,6 +1986,8 @@ void RichTextLabel::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color"); ADD_SIGNAL(MethodInfo("meta_clicked", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); + ADD_SIGNAL(MethodInfo("meta_hover_started", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); + ADD_SIGNAL(MethodInfo("meta_hover_ended", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); BIND_ENUM_CONSTANT(ALIGN_LEFT); BIND_ENUM_CONSTANT(ALIGN_CENTER); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index f9e37b1094..1096e3f650 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -225,6 +225,9 @@ private: Align default_align; + ItemMeta *meta_hovering; + Variant current_meta; + void _invalidate_current_line(ItemFrame *p_frame); void _validate_line_caches(ItemFrame *p_frame); diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 49823e18fc..1fb0f84223 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -142,91 +142,107 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (rb_pressing && mb.is_valid() && - !mb->is_pressed() && - mb->get_button_index() == BUTTON_LEFT) { + if (mb.is_valid()) { - if (rb_hover != -1) { - //pressed - emit_signal("right_button_pressed", rb_hover); + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) { + + if (scrolling_enabled && buttons_visible) { + if (offset > 0) { + offset--; + update(); + } + } } - rb_pressing = false; - update(); - } + if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) { + if (scrolling_enabled && buttons_visible) { + if (missing_right) { + offset++; + update(); + } + } + } + + if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { - if (cb_pressing && mb.is_valid() && - !mb->is_pressed() && - mb->get_button_index() == BUTTON_LEFT) { + if (rb_hover != -1) { + //pressed + emit_signal("right_button_pressed", rb_hover); + } - if (cb_hover != -1) { - //pressed - emit_signal("tab_close", cb_hover); + rb_pressing = false; + update(); } - cb_pressing = false; - update(); - } + if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { - if (mb.is_valid() && - mb->is_pressed() && - mb->get_button_index() == BUTTON_LEFT) { + if (cb_hover != -1) { + //pressed + emit_signal("tab_close", cb_hover); + } - // clicks - Point2 pos(mb->get_position().x, mb->get_position().y); + cb_pressing = false; + update(); + } - if (buttons_visible) { + if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { - Ref<Texture> incr = get_icon("increment"); - Ref<Texture> decr = get_icon("decrement"); + // clicks + Point2 pos(mb->get_position().x, mb->get_position().y); - int limit = get_size().width - incr->get_width() - decr->get_width(); + if (buttons_visible) { - if (pos.x > limit + decr->get_width()) { - if (missing_right) { - offset++; - update(); - } - return; - } else if (pos.x > limit) { - if (offset > 0) { - offset--; - update(); + Ref<Texture> incr = get_icon("increment"); + Ref<Texture> decr = get_icon("decrement"); + + int limit = get_size().width - incr->get_width() - decr->get_width(); + + if (pos.x > limit + decr->get_width()) { + if (missing_right) { + offset++; + update(); + } + return; + } else if (pos.x > limit) { + if (offset > 0) { + offset--; + update(); + } + return; } - return; } - } - int found = -1; - for (int i = 0; i < tabs.size(); i++) { + int found = -1; + for (int i = 0; i < tabs.size(); i++) { - if (i < offset) - continue; + if (i < offset) + continue; - if (tabs[i].rb_rect.has_point(pos)) { - rb_pressing = true; - update(); - return; - } + if (tabs[i].rb_rect.has_point(pos)) { + rb_pressing = true; + update(); + return; + } - if (tabs[i].cb_rect.has_point(pos)) { - cb_pressing = true; - update(); - return; - } + if (tabs[i].cb_rect.has_point(pos)) { + cb_pressing = true; + update(); + return; + } - if (pos.x >= tabs[i].ofs_cache && pos.x < tabs[i].ofs_cache + tabs[i].size_cache) { - if (!tabs[i].disabled) { - found = i; + if (pos.x >= tabs[i].ofs_cache && pos.x < tabs[i].ofs_cache + tabs[i].size_cache) { + if (!tabs[i].disabled) { + found = i; + } + break; } - break; } - } - if (found != -1) { + if (found != -1) { - set_current_tab(found); - emit_signal("tab_clicked", found); + set_current_tab(found); + emit_signal("tab_clicked", found); + } } } } @@ -440,6 +456,14 @@ int Tabs::get_hovered_tab() const { return hover; } +int Tabs::get_tab_offset() const { + return offset; +} + +bool Tabs::get_offset_buttons_visible() const { + return buttons_visible; +} + void Tabs::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); @@ -484,6 +508,7 @@ void Tabs::set_tab_right_button(int p_tab, const Ref<Texture> &p_right_button) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs[p_tab].right_button = p_right_button; + _update_cache(); update(); minimum_size_changed(); } @@ -783,6 +808,14 @@ void Tabs::set_min_width(int p_width) { min_width = p_width; } +void Tabs::set_scrolling_enabled(bool p_enabled) { + scrolling_enabled = p_enabled; +} + +bool Tabs::get_scrolling_enabled() const { + return scrolling_enabled; +} + void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input); @@ -799,11 +832,15 @@ void Tabs::_bind_methods() { ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture>())); ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align); ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align); + ClassDB::bind_method(D_METHOD("get_tab_offset"), &Tabs::get_tab_offset); + ClassDB::bind_method(D_METHOD("get_offset_buttons_visible"), &Tabs::get_offset_buttons_visible); ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &Tabs::ensure_tab_visible); ClassDB::bind_method(D_METHOD("get_tab_rect", "tab_idx"), &Tabs::get_tab_rect); ClassDB::bind_method(D_METHOD("move_tab", "from", "to"), &Tabs::move_tab); ClassDB::bind_method(D_METHOD("set_tab_close_display_policy", "policy"), &Tabs::set_tab_close_display_policy); ClassDB::bind_method(D_METHOD("get_tab_close_display_policy"), &Tabs::get_tab_close_display_policy); + ClassDB::bind_method(D_METHOD("set_scrolling_enabled", "enabled"), &Tabs::set_scrolling_enabled); + ClassDB::bind_method(D_METHOD("get_scrolling_enabled"), &Tabs::get_scrolling_enabled); ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab"))); ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab"))); @@ -814,6 +851,7 @@ void Tabs::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab"); ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled"); BIND_ENUM_CONSTANT(ALIGN_LEFT); BIND_ENUM_CONSTANT(ALIGN_CENTER); @@ -841,4 +879,5 @@ Tabs::Tabs() { max_drawn_tab = 0; min_width = 0; + scrolling_enabled = true; } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 73fa40bbb8..4eb6be3435 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -88,6 +88,7 @@ private: int hover; // hovered tab int min_width; + bool scrolling_enabled; int get_tab_width(int p_idx) const; void _ensure_no_over_offset(); @@ -131,10 +132,16 @@ public: int get_current_tab() const; int get_hovered_tab() const; + int get_tab_offset() const; + bool get_offset_buttons_visible() const; + void remove_tab(int p_idx); void clear_tabs(); + void set_scrolling_enabled(bool p_enabled); + bool get_scrolling_enabled() const; + void ensure_tab_visible(int p_idx); void set_min_width(int p_width); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 1b87771fd4..21842d4d58 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -274,6 +274,7 @@ void TextEdit::Text::insert(int p_at, const String &p_text) { Line line; line.marked = false; line.breakpoint = false; + line.hidden = false; line.width_cache = -1; line.data = p_text; text.insert(p_at, line); @@ -297,9 +298,11 @@ void TextEdit::_update_scrollbars() { int hscroll_rows = ((hmin.height - 1) / get_row_height()) + 1; int visible_rows = get_visible_rows(); - int total_rows = text.size(); + int num_rows = MAX(visible_rows, num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(visible_rows, text.size() - 1 - cursor.line_ofs))); + + int total_rows = (is_hiding_enabled() ? get_total_unhidden_rows() : text.size()); if (scroll_past_end_of_file_enabled) { - total_rows += get_visible_rows() - 1; + total_rows += visible_rows - 1; } int vscroll_pixels = v_scroll->get_combined_minimum_size().width; @@ -313,6 +316,10 @@ void TextEdit::_update_scrollbars() { total_width += cache.breakpoint_gutter_width; } + if (draw_fold_gutter) { + total_width += cache.fold_gutter_width; + } + bool use_hscroll = true; bool use_vscroll = true; @@ -347,12 +354,11 @@ void TextEdit::_update_scrollbars() { v_scroll->set_step(1); } - if (fabs(v_scroll->get_value() - (double)cursor.line_ofs) >= 1) { - v_scroll->set_value(cursor.line_ofs); - } - + update_line_scroll_pos(); } else { cursor.line_ofs = 0; + line_scroll_pos = 0; + v_scroll->set_value(0); v_scroll->hide(); } @@ -551,6 +557,13 @@ void TextEdit::_notification(int p_what) { cache.breakpoint_gutter_width = 0; } + if (draw_fold_gutter) { + fold_gutter_width = (get_row_height() * 55) / 100; + cache.fold_gutter_width = fold_gutter_width; + } else { + cache.fold_gutter_width = 0; + } + int line_number_char_count = 0; { @@ -573,7 +586,7 @@ void TextEdit::_notification(int p_what) { RID ci = get_canvas_item(); VisualServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true); - int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width; + int xmargin_beg = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width; int xmargin_end = cache.size.width - cache.style_normal->get_margin(MARGIN_RIGHT); //let's do it easy for now: cache.style_normal->draw(ci, Rect2(Point2(), cache.size)); @@ -780,10 +793,22 @@ void TextEdit::_notification(int p_what) { String highlighted_text = get_selection_text(); String line_num_padding = line_numbers_zero_padded ? "0" : " "; + update_line_scroll_pos(); + int line = cursor.line_ofs - 1; for (int i = 0; i < visible_rows; i++) { - int line = i + cursor.line_ofs; + line++; + + if (line < 0 || line >= (int)text.size()) + continue; + + while (is_line_hidden(line)) { + line++; + if (line < 0 || line >= (int)text.size()) { + break; + } + } if (line < 0 || line >= (int)text.size()) continue; @@ -794,7 +819,7 @@ void TextEdit::_notification(int p_what) { int char_ofs = 0; int ofs_y = (i * get_row_height() + cache.line_spacing / 2); if (smooth_scroll_enabled) { - ofs_y -= (v_scroll->get_value() - cursor.line_ofs) * get_row_height(); + ofs_y -= (v_scroll->get_value() - get_line_scroll_pos()) * get_row_height(); } bool prev_is_char = false; @@ -857,6 +882,21 @@ void TextEdit::_notification(int p_what) { } } + // draw fold markers + if (draw_fold_gutter) { + int horizontal_gap = (cache.fold_gutter_width * 30) / 100; + int gutter_left = cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width + cache.line_number_w; + if (is_folded(line)) { + int xofs = horizontal_gap - (cache.can_fold_icon->get_width()) / 2; + int yofs = (get_row_height() - cache.folded_icon->get_height()) / 2; + cache.folded_icon->draw(ci, Point2(gutter_left + xofs, ofs_y + yofs), Color(0.8f, 0.8f, 0.8f, 0.8f)); + } else if (can_fold(line)) { + int xofs = -cache.can_fold_icon->get_width() / 2 - horizontal_gap + 3; + int yofs = (get_row_height() - cache.can_fold_icon->get_height()) / 2; + cache.can_fold_icon->draw(ci, Point2(gutter_left + xofs, ofs_y + yofs), Color(0.8f, 0.8f, 0.8f, 0.8f)); + } + } + if (cache.line_number_w) { String fc = String::num(line + 1); while (fc.length() < line_number_char_count) { @@ -1196,6 +1236,12 @@ void TextEdit::_notification(int p_what) { } char_ofs += char_w; + + if (j == str.length() - 1 && is_folded(line)) { + int yofs = (get_row_height() - cache.folded_eol_icon->get_height()) / 2; + int xofs = cache.folded_eol_icon->get_width() / 2; + cache.folded_eol_icon->draw(ci, Point2(char_ofs + char_margin + xofs, ofs_y + yofs), Color(1, 1, 1, 1)); + } } if (cursor.column == str.length() && cursor.line == line && (char_ofs + char_margin) >= xmargin_beg) { @@ -1538,6 +1584,12 @@ void TextEdit::backspace_at_cursor() { int prev_line = cursor.column ? cursor.line : cursor.line - 1; int prev_column = cursor.column ? (cursor.column - 1) : (text[cursor.line - 1].length()); + + if (is_line_hidden(cursor.line)) + set_line_as_hidden(prev_line, true); + if (is_line_set_as_breakpoint(cursor.line)) + set_line_as_breakpoint(prev_line, true); + if (auto_brace_completion_enabled && cursor.column > 0 && _is_pair_left_symbol(text[cursor.line][cursor.column - 1])) { @@ -1577,7 +1629,7 @@ void TextEdit::backspace_at_cursor() { } } - cursor_set_line(prev_line); + cursor_set_line(prev_line, true, true); cursor_set_column(prev_column); } @@ -1651,10 +1703,18 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co float rows = p_mouse.y; rows -= cache.style_normal->get_margin(MARGIN_TOP); rows /= get_row_height(); - int row = cursor.line_ofs + (rows + (v_scroll->get_value() - cursor.line_ofs)); + int lsp = get_line_scroll_pos(true); + int row = cursor.line_ofs + (rows + (v_scroll->get_value() - lsp)); + + if (is_hiding_enabled()) { + // row will be offset by the hidden rows + int f_ofs = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(rows + 1, text.size() - cursor.line_ofs)) - 1; + row = cursor.line_ofs + (f_ofs + (v_scroll->get_value() - lsp)); + row = CLAMP(row, 0, text.size() - num_lines_from(text.size() - 1, -1)); + } if (row < 0) - row = 0; + row = 0; //todo int col = 0; @@ -1664,7 +1724,7 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co col = text[row].size(); } else { - col = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width); + col = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width); col += cursor.x_ofs; col = get_char_pos_for(col, get_line(row)); } @@ -1717,10 +1777,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (mb->is_pressed()) { if (mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) { + float scroll_factor = 3 * mb->get_factor(); if (scrolling) { - target_v_scroll = (target_v_scroll - (3 * mb->get_factor())); + target_v_scroll = (target_v_scroll - scroll_factor); } else { - target_v_scroll = (v_scroll->get_value() - (3 * mb->get_factor())); + target_v_scroll = (v_scroll->get_value() - scroll_factor); } if (smooth_scroll_enabled) { @@ -1734,16 +1795,18 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) { + float scroll_factor = 3 * mb->get_factor(); if (scrolling) { - target_v_scroll = (target_v_scroll + (3 * mb->get_factor())); + target_v_scroll = (target_v_scroll + scroll_factor); } else { - target_v_scroll = (v_scroll->get_value() + (3 * mb->get_factor())); + target_v_scroll = (v_scroll->get_value() + scroll_factor); } if (smooth_scroll_enabled) { - int max_v_scroll = get_line_count() - 1; + int max_v_scroll = get_total_unhidden_rows(); if (!scroll_past_end_of_file_enabled) { - max_v_scroll -= get_visible_rows() - 1; + max_v_scroll -= get_visible_rows(); + max_v_scroll = CLAMP(max_v_scroll, 0, get_total_unhidden_rows()); } if (target_v_scroll > max_v_scroll) { @@ -1766,6 +1829,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { _reset_caret_blink_timer(); int row, col; + update_line_scroll_pos(); _get_mouse_pos(Point2i(mb->get_position().x, mb->get_position().y), row, col); if (mb->get_command() && highlighted_word != String()) { @@ -1784,10 +1848,35 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } + // toggle fold on gutter click if can + if (draw_fold_gutter) { + + int left_margin = cache.style_normal->get_margin(MARGIN_LEFT); + int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.line_number_w; + if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.fold_gutter_width - 3) { + if (is_folded(row)) { + unfold_line(row); + } else if (can_fold(row)) { + fold_line(row); + } + return; + } + } + + // unfold on folded icon click + if (is_folded(row)) { + int line_width = text.get_line_width(row); + line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width - cursor.x_ofs; + if (mb->get_position().x > line_width - 3 && mb->get_position().x <= line_width + cache.folded_eol_icon->get_width() + 3) { + unfold_line(row); + return; + } + } + int prev_col = cursor.column; int prev_line = cursor.line; - cursor_set_line(row); + cursor_set_line(row, true, false); cursor_set_column(col); if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) { @@ -2026,22 +2115,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { return; } - if (k->get_scancode() == KEY_DOWN) { - - if (completion_index < completion_options.size() - 1) { - completion_index++; - completion_current = completion_options[completion_index]; - update(); - } - accept_event(); - return; - } - if (k->get_scancode() == KEY_KP_ENTER || k->get_scancode() == KEY_ENTER || k->get_scancode() == KEY_TAB) { _confirm_completion(); accept_event(); - emit_signal("request_completion"); return; } @@ -2191,7 +2268,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { selection.active = false; update(); _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column); - cursor_set_line(selection.from_line); + cursor_set_line(selection.from_line, true, false); cursor_set_column(selection.from_column); update(); } @@ -2241,6 +2318,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } + if (is_folded(cursor.line)) + unfold_line(cursor.line); + bool brace_indent = false; // no need to indent if we are going upwards. @@ -2391,6 +2471,8 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { cursor_set_column(column); } else { + if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) + unfold_line(cursor.line - 1); backspace_at_cursor(); } @@ -2449,7 +2531,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } else if (cursor.column == 0) { if (cursor.line > 0) { - cursor_set_line(cursor.line - 1); + cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1)); cursor_set_column(text[cursor.line].length()); } } else { @@ -2512,7 +2594,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } else if (cursor.column == text[cursor.line].length()) { if (cursor.line < text.size() - 1) { - cursor_set_line(cursor.line + 1); + cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false); cursor_set_column(0); } } else { @@ -2553,7 +2635,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { cursor_set_line(0); else #endif - cursor_set_line(cursor_get_line() - 1); + cursor_set_line(cursor_get_line() - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1)); if (k->get_shift()) _post_shift_selection(); @@ -2587,10 +2669,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } if (k->get_command()) - cursor_set_line(text.size() - 1); + cursor_set_line(text.size() - 1, true, false); else #endif - cursor_set_line(cursor_get_line() + 1); + cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false); if (k->get_shift()) _post_shift_selection(); @@ -2737,7 +2819,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (k->get_shift()) _pre_shift_selection(); - cursor_set_line(text.size() - 1); + cursor_set_line(text.size() - 1, true, false); if (k->get_shift()) _post_shift_selection(); @@ -2752,7 +2834,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { _pre_shift_selection(); if (k->get_command()) - cursor_set_line(text.size() - 1); + cursor_set_line(text.size() - 1, true, false); cursor_set_column(text[cursor.line].length()); if (k->get_shift()) @@ -2777,7 +2859,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (k->get_shift()) _pre_shift_selection(); - cursor_set_line(cursor_get_line() - get_visible_rows()); + cursor_set_line(cursor_get_line() - num_lines_from(cursor.line, -get_visible_rows()), true, false); if (k->get_shift()) _post_shift_selection(); @@ -2798,7 +2880,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (k->get_shift()) _pre_shift_selection(); - cursor_set_line(cursor_get_line() + get_visible_rows()); + cursor_set_line(cursor_get_line() + num_lines_from(cursor.line, get_visible_rows()), true, false); if (k->get_shift()) _post_shift_selection(); @@ -3016,8 +3098,9 @@ void TextEdit::_scroll_lines_up() { } // adjust the cursor - if (cursor_get_line() >= (get_visible_rows() + get_v_scroll()) && !selection.active) { - cursor_set_line((get_visible_rows() + get_v_scroll()) - 1, false); + int num_lines = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), get_visible_rows()) - 1; + if (cursor.line >= cursor.line_ofs + num_lines && !selection.active) { + cursor_set_line(cursor.line_ofs + num_lines, false, false); } } @@ -3025,9 +3108,10 @@ void TextEdit::_scroll_lines_down() { scrolling = false; // calculate the maximum vertical scroll position - int max_v_scroll = get_line_count() - 1; + int max_v_scroll = get_total_unhidden_rows(); if (!scroll_past_end_of_file_enabled) { - max_v_scroll -= get_visible_rows() - 1; + max_v_scroll -= get_visible_rows(); + max_v_scroll = CLAMP(max_v_scroll, 0, get_total_unhidden_rows()); } // adjust the vertical scroll @@ -3036,8 +3120,8 @@ void TextEdit::_scroll_lines_down() { } // adjust the cursor - if ((cursor_get_line()) <= get_v_scroll() - 1 && !selection.active) { - cursor_set_line(get_v_scroll(), false); + if (cursor.line <= cursor.line_ofs - 1 && !selection.active) { + cursor_set_line(cursor.line_ofs, false, false); } } @@ -3082,6 +3166,15 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i } } + // if we are just making a new empty line, reset breakpoints and hidden status + if (p_char == 0 && p_text.replace("\r", "") == "\n") { + + text.set_breakpoint(p_line + 1, text.is_breakpoint(p_line)); + text.set_hidden(p_line + 1, text.is_hidden(p_line)); + text.set_breakpoint(p_line, false); + text.set_hidden(p_line, false); + } + r_end_line = p_line + substrings.size() - 1; r_end_column = text[r_end_line].length() - postinsert_text.length(); @@ -3280,6 +3373,7 @@ Size2 TextEdit::get_minimum_size() const { return cache.style_normal->get_minimum_size(); } + int TextEdit::get_visible_rows() const { int total = cache.size.height; @@ -3287,31 +3381,81 @@ int TextEdit::get_visible_rows() const { total /= get_row_height(); return total; } + +int TextEdit::get_total_unhidden_rows() const { + if (!is_hiding_enabled()) + return text.size(); + + int total_unhidden = 0; + for (int i = 0; i < text.size(); i++) { + if (!text.is_hidden(i)) + total_unhidden++; + } + return total_unhidden; +} + +double TextEdit::get_line_scroll_pos(bool p_recalculate) const { + + if (!is_hiding_enabled()) + return cursor.line_ofs; + if (!p_recalculate) + return line_scroll_pos; + + // count num unhidden lines to the cursor line ofs + double new_line_scroll_pos = 0; + int to = CLAMP(cursor.line_ofs, 0, text.size() - 1); + for (int i = 0; i < to; i++) { + if (!text.is_hidden(i)) + new_line_scroll_pos++; + } + return new_line_scroll_pos; +} + +void TextEdit::update_line_scroll_pos() { + + if (!is_hiding_enabled()) { + line_scroll_pos = cursor.line_ofs; + return; + } + + // count num unhidden lines to the cursor line ofs + double new_line_scroll_pos = 0; + int to = CLAMP(cursor.line_ofs, 0, text.size() - 1); + for (int i = 0; i < to; i++) { + if (!text.is_hidden(i)) + new_line_scroll_pos++; + } + line_scroll_pos = new_line_scroll_pos; +} + void TextEdit::adjust_viewport_to_cursor() { scrolling = false; - if (cursor.line_ofs > cursor.line) + if (cursor.line_ofs > cursor.line) { cursor.line_ofs = cursor.line; + } - int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width; + int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width; if (v_scroll->is_visible_in_tree()) visible_width -= v_scroll->get_combined_minimum_size().width; visible_width -= 20; // give it a little more space - //printf("rowofs %i, visrows %i, cursor.line %i\n",cursor.line_ofs,get_visible_rows(),cursor.line); - int visible_rows = get_visible_rows(); if (h_scroll->is_visible_in_tree()) visible_rows -= ((h_scroll->get_combined_minimum_size().height - 1) / get_row_height()); + int num_rows = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(visible_rows, text.size() - 1 - cursor.line_ofs)); - if (cursor.line >= (cursor.line_ofs + visible_rows)) - cursor.line_ofs = cursor.line - visible_rows; - if (cursor.line < cursor.line_ofs) + // if the cursor is off the screen + if (cursor.line >= (cursor.line_ofs + MAX(num_rows, visible_rows))) { + cursor.line_ofs = cursor.line - (num_lines_from(CLAMP(cursor.line, 0, text.size() - 1), -visible_rows) - 1); + } + if (cursor.line < cursor.line_ofs) { cursor.line_ofs = cursor.line; + } - if (cursor.line_ofs + visible_rows > text.size() && !scroll_past_end_of_file_enabled) { - cursor.line_ofs = text.size() - visible_rows; - v_scroll->set_value(text.size() - visible_rows); + // fixes deleting lines from moving the line ofs in a bad way + if (!scroll_past_end_of_file_enabled && get_total_unhidden_rows() > visible_rows && num_rows < visible_rows) { + cursor.line_ofs = text.size() - 1 - (num_lines_from(text.size() - 1, -visible_rows) - 1); } int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]); @@ -3322,6 +3466,8 @@ void TextEdit::adjust_viewport_to_cursor() { if (cursor_x < cursor.x_ofs) cursor.x_ofs = cursor_x; + update_line_scroll_pos(); + v_scroll->set_value(get_line_scroll_pos() + 1); update(); /* get_range()->set_max(text.size()); @@ -3338,7 +3484,10 @@ void TextEdit::center_viewport_to_cursor() { if (cursor.line_ofs > cursor.line) cursor.line_ofs = cursor.line; - int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width; + if (is_line_hidden(cursor.line)) + unfold_line(cursor.line); + + int visible_width = cache.size.width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width; if (v_scroll->is_visible_in_tree()) visible_width -= v_scroll->get_combined_minimum_size().width; visible_width -= 20; // give it a little more space @@ -3347,9 +3496,8 @@ void TextEdit::center_viewport_to_cursor() { if (h_scroll->is_visible_in_tree()) visible_rows -= ((h_scroll->get_combined_minimum_size().height - 1) / get_row_height()); - int max_ofs = text.size() - (scroll_past_end_of_file_enabled ? 1 : visible_rows); - cursor.line_ofs = CLAMP(cursor.line - (visible_rows / 2), 0, max_ofs); - + int max_ofs = text.size() - (scroll_past_end_of_file_enabled ? 1 : num_lines_from(text.size() - 1, -visible_rows)); + cursor.line_ofs = CLAMP(cursor.line - num_lines_from(cursor.line - visible_rows / 2, -visible_rows / 2), 0, max_ofs); int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]); if (cursor_x > (cursor.x_ofs + visible_width)) @@ -3358,6 +3506,9 @@ void TextEdit::center_viewport_to_cursor() { if (cursor_x < cursor.x_ofs) cursor.x_ofs = cursor_x; + update_line_scroll_pos(); + v_scroll->set_value(get_line_scroll_pos()); + update(); } @@ -3382,7 +3533,7 @@ void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) { } } -void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) { +void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport, bool p_can_be_hidden) { if (setting_row) return; @@ -3394,6 +3545,21 @@ void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport) { if (p_row >= (int)text.size()) p_row = (int)text.size() - 1; + if (!p_can_be_hidden) { + if (is_line_hidden(CLAMP(p_row, 0, text.size() - 1))) { + int move_down = num_lines_from(p_row, 1) - 1; + if (p_row + move_down <= text.size() - 1 && !is_line_hidden(p_row + move_down)) { + p_row += move_down; + } else { + int move_up = num_lines_from(p_row, -1) - 1; + if (p_row - move_up > 0 && !is_line_hidden(p_row - move_up)) { + p_row -= move_up; + } else { + WARN_PRINTS(("Cursor set to hidden line " + itos(p_row) + " and there are no nonhidden lines.")); + } + } + } + } cursor.line = p_row; cursor.column = get_char_pos_for(cursor.last_fit_x, get_line(cursor.line)); @@ -3463,8 +3629,11 @@ void TextEdit::_scroll_moved(double p_to_val) { if (h_scroll->is_visible_in_tree()) cursor.x_ofs = h_scroll->get_value(); - if (v_scroll->is_visible_in_tree()) - cursor.line_ofs = v_scroll->get_value(); + if (v_scroll->is_visible_in_tree()) { + double val = v_scroll->get_value(); + cursor.line_ofs = num_lines_from(0, (int)floor(val)) - 1; + line_scroll_pos = (int)floor(val); + } update(); } @@ -3553,10 +3722,43 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const { if (highlighted_word != String()) return CURSOR_POINTING_HAND; - int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width; - if ((completion_active && completion_rect.has_point(p_pos)) || p_pos.x < gutter) { + int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width; + if ((completion_active && completion_rect.has_point(p_pos))) { + return CURSOR_ARROW; + } + if (p_pos.x < gutter) { + + int row, col; + _get_mouse_pos(p_pos, row, col); + int left_margin = cache.style_normal->get_margin(MARGIN_LEFT); + + // breakpoint icon + if (draw_breakpoint_gutter && p_pos.x > left_margin && p_pos.x <= left_margin + cache.breakpoint_gutter_width + 3) { + return CURSOR_POINTING_HAND; + } + + // fold icon + int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.line_number_w; + if (draw_fold_gutter && p_pos.x > gutter_left - 6 && p_pos.x <= gutter_left + cache.fold_gutter_width - 3) { + if (is_folded(row) || can_fold(row)) + return CURSOR_POINTING_HAND; + else + return CURSOR_ARROW; + } return CURSOR_ARROW; + } else { + int row, col; + _get_mouse_pos(p_pos, row, col); + // eol fold icon + if (is_folded(row)) { + int line_width = text.get_line_width(row); + line_width += cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width - cursor.x_ofs; + if (p_pos.x > line_width - 3 && p_pos.x <= line_width + cache.folded_eol_icon->get_width() + 3) { + return CURSOR_POINTING_HAND; + } + } } + return CURSOR_IBEAM; } @@ -3570,6 +3772,7 @@ void TextEdit::set_text(String p_text) { cursor.line = 0; cursor.x_ofs = 0; cursor.line_ofs = 0; + line_scroll_pos = 0; cursor.last_fit_x = 0; cursor_set_line(0); cursor_set_column(0); @@ -3655,6 +3858,7 @@ void TextEdit::_clear() { cursor.line = 0; cursor.x_ofs = 0; cursor.line_ofs = 0; + line_scroll_pos = 0; cursor.last_fit_x = 0; } @@ -3733,6 +3937,9 @@ void TextEdit::_update_caches() { cache.line_spacing = get_constant("line_spacing"); cache.row_height = cache.font->get_height() + cache.line_spacing; cache.tab_icon = get_icon("tab"); + cache.folded_icon = get_icon("GuiTreeArrowRight", "EditorIcons"); + cache.can_fold_icon = get_icon("GuiTreeArrowDown", "EditorIcons"); + cache.folded_eol_icon = get_icon("GuiEllipsis", "EditorIcons"); text.set_font(cache.font); } @@ -4179,6 +4386,198 @@ void TextEdit::get_breakpoints(List<int> *p_breakpoints) const { } } +void TextEdit::set_line_as_hidden(int p_line, bool p_hidden) { + + ERR_FAIL_INDEX(p_line, text.size()); + if (is_hiding_enabled() || !p_hidden) + text.set_hidden(p_line, p_hidden); + update(); +} + +bool TextEdit::is_line_hidden(int p_line) const { + + ERR_FAIL_INDEX_V(p_line, text.size(), false); + return text.is_hidden(p_line); +} + +void TextEdit::fold_all_lines() { + + for (int i = 0; i < text.size(); i++) { + fold_line(i); + } + _update_scrollbars(); + update(); +} + +void TextEdit::unhide_all_lines() { + + for (int i = 0; i < text.size(); i++) { + text.set_hidden(i, false); + } + _update_scrollbars(); + update(); +} + +int TextEdit::num_lines_from(int p_line_from, int unhidden_amount) const { + + // returns the number of hidden and unhidden lines from p_line_from to p_line_from + amount of visible lines + ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(unhidden_amount)); + + if (!is_hiding_enabled()) + return unhidden_amount; + int num_visible = 0; + int num_total = 0; + if (unhidden_amount >= 0) { + for (int i = p_line_from; i < text.size(); i++) { + num_total++; + if (!is_line_hidden(i)) + num_visible++; + if (num_visible >= unhidden_amount) + break; + } + } else { + unhidden_amount = ABS(unhidden_amount); + for (int i = p_line_from; i >= 0; i--) { + num_total++; + if (!is_line_hidden(i)) + num_visible++; + if (num_visible >= unhidden_amount) + break; + } + } + return num_total; +} + +int TextEdit::get_whitespace_level(int p_line) const { + + ERR_FAIL_INDEX_V(p_line, text.size(), 0); + + // counts number of tabs and spaces before line starts + int whitespace_count = 0; + int line_length = text[p_line].size(); + for (int i = 0; i < line_length - 1; i++) { + if (text[p_line][i] == '\t') { + whitespace_count++; + } else if (text[p_line][i] == ' ') { + whitespace_count++; + } else if (text[p_line][i] == '#') { + break; + } else { + break; + } + } + return whitespace_count; +} + +bool TextEdit::can_fold(int p_line) const { + + ERR_FAIL_INDEX_V(p_line, text.size(), false); + if (!is_hiding_enabled()) + return false; + if (p_line + 1 >= text.size()) + return false; + if (text[p_line].size() == 0) + return false; + if (is_folded(p_line)) + return false; + if (is_line_hidden(p_line)) + return false; + + int start_indent = get_whitespace_level(p_line); + + for (int i = p_line + 1; i < text.size(); i++) { + if (text[i].size() == 0) + continue; + int next_indent = get_whitespace_level(i); + if (next_indent > start_indent) + return true; + else + return false; + } + + return false; +} + +bool TextEdit::is_folded(int p_line) const { + + ERR_FAIL_INDEX_V(p_line, text.size(), false); + if (p_line + 1 >= text.size() - 1) + return false; + if (!is_line_hidden(p_line) && is_line_hidden(p_line + 1)) + return true; + return false; +} + +void TextEdit::fold_line(int p_line) { + + ERR_FAIL_INDEX(p_line, text.size()); + if (!is_hiding_enabled()) + return; + if (!can_fold(p_line)) + return; + + // hide lines below this one + int start_indent = get_whitespace_level(p_line); + for (int i = p_line + 1; i < text.size(); i++) { + int cur_indent = get_whitespace_level(i); + if (text[i].size() == 0 || cur_indent > start_indent) { + set_line_as_hidden(i, true); + } else { + // exclude trailing empty lines + for (int trail_i = i - 1; trail_i > p_line; trail_i--) { + if (text[trail_i].size() == 0) + set_line_as_hidden(trail_i, false); + else + break; + } + break; + } + } + + // fix selection + if (is_selection_active()) { + if (is_line_hidden(selection.from_line) && is_line_hidden(selection.to_line)) { + deselect(); + } else if (is_line_hidden(selection.from_line)) { + select(p_line, 9999, selection.to_line, selection.to_column); + } else if (is_line_hidden(selection.to_line)) { + select(selection.from_line, selection.from_column, p_line, 9999); + } + } + + // reset cursor + if (is_line_hidden(cursor.line)) { + cursor_set_line(p_line, false, false); + cursor_set_column(get_line(p_line).length(), false); + } + _update_scrollbars(); + update(); +} + +void TextEdit::unfold_line(int p_line) { + + ERR_FAIL_INDEX(p_line, text.size()); + + if (!is_folded(p_line) && !is_line_hidden(p_line)) + return; + int fold_start = p_line; + for (fold_start = p_line; fold_start > 0; fold_start--) { + if (is_folded(fold_start)) + break; + } + fold_start = is_folded(fold_start) ? fold_start : p_line; + + for (int i = fold_start + 1; i < text.size(); i++) { + if (is_line_hidden(i)) { + set_line_as_hidden(i, false); + } else { + break; + } + } + _update_scrollbars(); + update(); +} + int TextEdit::get_line_count() const { return text.size(); @@ -4405,12 +4804,14 @@ void TextEdit::set_v_scroll(int p_scroll) { p_scroll = 0; } if (!scroll_past_end_of_file_enabled) { - if (p_scroll + get_visible_rows() > get_line_count()) { - p_scroll = get_line_count() - get_visible_rows(); + if (p_scroll + get_visible_rows() > get_total_unhidden_rows()) { + int num_rows = num_lines_from(CLAMP(p_scroll, 0, text.size() - 1), MIN(get_visible_rows(), text.size() - 1 - p_scroll)); + p_scroll = text.size() - num_rows; } } v_scroll->set_value(p_scroll); - cursor.line_ofs = p_scroll; + cursor.line_ofs = num_lines_from(0, p_scroll); + line_scroll_pos = p_scroll; } int TextEdit::get_h_scroll() const { @@ -4772,7 +5173,7 @@ void TextEdit::set_line(int line, String new_text) { void TextEdit::insert_at(const String &p_text, int at) { cursor_set_column(0); - cursor_set_line(at); + cursor_set_line(at, false, true); _insert_text(at, 0, p_text + "\n"); } @@ -4820,6 +5221,35 @@ int TextEdit::get_breakpoint_gutter_width() const { return cache.breakpoint_gutter_width; } +void TextEdit::set_draw_fold_gutter(bool p_draw) { + draw_fold_gutter = p_draw; + update(); +} + +bool TextEdit::is_drawing_fold_gutter() const { + return draw_fold_gutter; +} + +void TextEdit::set_fold_gutter_width(int p_gutter_width) { + fold_gutter_width = p_gutter_width; + update(); +} + +int TextEdit::get_fold_gutter_width() const { + return cache.fold_gutter_width; +} + +void TextEdit::set_hiding_enabled(int p_enabled) { + if (!p_enabled) + unhide_all_lines(); + hiding_enabled = p_enabled; + update(); +} + +int TextEdit::is_hiding_enabled() const { + return hiding_enabled; +} + void TextEdit::set_highlight_current_line(bool p_enabled) { highlight_current_line = p_enabled; update(); @@ -4914,7 +5344,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line); ClassDB::bind_method(D_METHOD("cursor_set_column", "column", "adjust_viewport"), &TextEdit::cursor_set_column, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport"), &TextEdit::cursor_set_line, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("cursor_set_line", "line", "adjust_viewport", "can_be_hidden"), &TextEdit::cursor_set_line, DEFVAL(true), DEFVAL(true)); ClassDB::bind_method(D_METHOD("cursor_get_column"), &TextEdit::cursor_get_column); ClassDB::bind_method(D_METHOD("cursor_get_line"), &TextEdit::cursor_get_line); @@ -4955,6 +5385,17 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_show_line_numbers", "enable"), &TextEdit::set_show_line_numbers); ClassDB::bind_method(D_METHOD("is_show_line_numbers_enabled"), &TextEdit::is_show_line_numbers_enabled); + ClassDB::bind_method(D_METHOD("set_hiding_enabled", "enable"), &TextEdit::set_hiding_enabled); + ClassDB::bind_method(D_METHOD("is_hiding_enabled"), &TextEdit::is_hiding_enabled); + ClassDB::bind_method(D_METHOD("set_line_as_hidden", "line", "enable"), &TextEdit::set_line_as_hidden); + ClassDB::bind_method(D_METHOD("is_line_hidden"), &TextEdit::is_line_hidden); + ClassDB::bind_method(D_METHOD("fold_all_lines"), &TextEdit::fold_all_lines); + ClassDB::bind_method(D_METHOD("unhide_all_lines"), &TextEdit::unhide_all_lines); + ClassDB::bind_method(D_METHOD("fold_line", "line"), &TextEdit::fold_line); + ClassDB::bind_method(D_METHOD("unfold_line", "line"), &TextEdit::unfold_line); + ClassDB::bind_method(D_METHOD("can_fold", "line"), &TextEdit::can_fold); + ClassDB::bind_method(D_METHOD("is_folded", "line"), &TextEdit::is_folded); + ClassDB::bind_method(D_METHOD("set_highlight_all_occurrences", "enable"), &TextEdit::set_highlight_all_occurrences); ClassDB::bind_method(D_METHOD("is_highlight_all_occurrences_enabled"), &TextEdit::is_highlight_all_occurrences_enabled); @@ -4988,6 +5429,7 @@ void TextEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled"); ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_block_mode"), "cursor_set_block_mode", "cursor_is_block_mode"); @@ -5029,6 +5471,8 @@ TextEdit::TextEdit() { cache.line_number_w = 1; cache.breakpoint_gutter_width = 0; breakpoint_gutter_width = 0; + cache.fold_gutter_width = 0; + fold_gutter_width = 0; indent_size = 4; text.set_indent_size(indent_size); @@ -5098,6 +5542,8 @@ TextEdit::TextEdit() { line_length_guideline = false; line_length_guideline_col = 80; draw_breakpoint_gutter = false; + draw_fold_gutter = false; + hiding_enabled = false; next_operation_is_complex = false; scroll_past_end_of_file_enabled = false; auto_brace_completion_enabled = false; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 50f005ed6a..b1c7b14e58 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -73,6 +73,9 @@ class TextEdit : public Control { struct Cache { Ref<Texture> tab_icon; + Ref<Texture> can_fold_icon; + Ref<Texture> folded_icon; + Ref<Texture> folded_eol_icon; Ref<StyleBox> style_normal; Ref<StyleBox> style_focus; Ref<Font> font; @@ -105,6 +108,7 @@ class TextEdit : public Control { int line_spacing; int line_number_w; int breakpoint_gutter_width; + int fold_gutter_width; Size2 size; } cache; @@ -136,6 +140,7 @@ class TextEdit : public Control { int width_cache : 24; bool marked : 1; bool breakpoint : 1; + bool hidden : 1; Map<int, ColorRegionInfo> region_info; String data; }; @@ -160,6 +165,8 @@ class TextEdit : public Control { bool is_marked(int p_line) const { return text[p_line].marked; } void set_breakpoint(int p_line, bool p_breakpoint) { text[p_line].breakpoint = p_breakpoint; } bool is_breakpoint(int p_line) const { return text[p_line].breakpoint; } + void set_hidden(int p_line, bool p_hidden) { text[p_line].hidden = p_hidden; } + bool is_hidden(int p_line) const { return text[p_line].hidden; } void insert(int p_at, const String &p_text); void remove(int p_at); int size() const { return text.size(); } @@ -251,6 +258,9 @@ class TextEdit : public Control { int line_length_guideline_col; bool draw_breakpoint_gutter; int breakpoint_gutter_width; + bool draw_fold_gutter; + int fold_gutter_width; + bool hiding_enabled; bool highlight_all_occurrences; bool scroll_past_end_of_file_enabled; @@ -293,9 +303,14 @@ class TextEdit : public Control { int search_result_line; int search_result_col; + double line_scroll_pos; + bool context_menu_enabled; int get_visible_rows() const; + int get_total_unhidden_rows() const; + double get_line_scroll_pos(bool p_recalculate = false) const; + void update_line_scroll_pos(); int get_char_count(); @@ -303,6 +318,7 @@ class TextEdit : public Control { int get_column_x_offset(int p_char, String p_str); void adjust_viewport_to_cursor(); + double get_scroll_line_diff() const; void _scroll_moved(double); void _update_scrollbars(); void _v_scroll_input(); @@ -405,6 +421,18 @@ public: void set_line_as_breakpoint(int p_line, bool p_breakpoint); bool is_line_set_as_breakpoint(int p_line) const; void get_breakpoints(List<int> *p_breakpoints) const; + + void set_line_as_hidden(int p_line, bool p_hidden); + bool is_line_hidden(int p_line) const; + void fold_all_lines(); + void unhide_all_lines(); + int num_lines_from(int p_line_from, int unhidden_amount) const; + int get_whitespace_level(int p_line) const; + bool can_fold(int p_line) const; + bool is_folded(int p_line) const; + void fold_line(int p_line); + void unfold_line(int p_line); + String get_text(); String get_line(int line) const; void set_line(int line, String new_text); @@ -433,7 +461,7 @@ public: void center_viewport_to_cursor(); void cursor_set_column(int p_col, bool p_adjust_viewport = true); - void cursor_set_line(int p_row, bool p_adjust_viewport = true); + void cursor_set_line(int p_row, bool p_adjust_viewport = true, bool p_can_be_hidden = true); int cursor_get_column() const; int cursor_get_line() const; @@ -538,6 +566,15 @@ public: void set_breakpoint_gutter_width(int p_gutter_width); int get_breakpoint_gutter_width() const; + void set_draw_fold_gutter(bool p_draw); + bool is_drawing_fold_gutter() const; + + void set_fold_gutter_width(int p_gutter_width); + int get_fold_gutter_width() const; + + void set_hiding_enabled(int p_enabled); + int is_hiding_enabled() const; + void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata); void set_completion(bool p_enabled, const Vector<String> &p_prefixes); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index f2e5919b5f..749ff51f57 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "tree.h" +#include <limits.h> #include "os/input.h" #include "os/keyboard.h" @@ -154,8 +155,17 @@ void TreeItem::set_text(int p_column, String p_text) { if (cells[p_column].mode == TreeItem::CELL_MODE_RANGE || cells[p_column].mode == TreeItem::CELL_MODE_RANGE_EXPRESSION) { - cells[p_column].min = 0; - cells[p_column].max = p_text.get_slice_count(","); + Vector<String> strings = p_text.split(","); + cells[p_column].min = INT_MAX; + cells[p_column].max = INT_MIN; + for (int i = 0; i < strings.size(); i++) { + int value = i; + if (!strings[i].get_slicec(':', 1).empty()) { + value = strings[i].get_slicec(':', 1).to_int(); + } + cells[p_column].min = MIN(cells[p_column].min, value); + cells[p_column].max = MAX(cells[p_column].max, value); + } cells[p_column].step = 0; } _changed_notify(p_column); @@ -1231,8 +1241,18 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 int option = (int)p_item->cells[i].val; - String s = p_item->cells[i].text; - s = s.get_slicec(',', option); + String s = RTR("(Other)"); + Vector<String> strings = p_item->cells[i].text.split(","); + for (int i = 0; i < strings.size(); i++) { + int value = i; + if (!strings[i].get_slicec(':', 1).empty()) { + value = strings[i].get_slicec(':', 1).to_int(); + } + if (option == value) { + s = strings[i].get_slicec(':', 0); + break; + } + } if (p_item->cells[i].suffix != String()) s += " " + p_item->cells[i].suffix; @@ -1776,7 +1796,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool for (int i = 0; i < c.text.get_slice_count(","); i++) { String s = c.text.get_slicec(',', i); - popup_menu->add_item(s, i); + popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).empty() ? i : s.get_slicec(':', 1).to_int()); } popup_menu->set_size(Size2(col_width, 0)); @@ -2634,7 +2654,7 @@ bool Tree::edit_selected() { for (int i = 0; i < c.text.get_slice_count(","); i++) { String s = c.text.get_slicec(',', i); - popup_menu->add_item(s, i); + popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).empty() ? i : s.get_slicec(':', 1).to_int()); } popup_menu->set_size(Size2(rect.size.width, 0)); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index d38c688241..253084dd99 100755 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -2067,7 +2067,7 @@ int Node::get_position_in_parent() const { return data.pos; } -Node *Node::duplicate(int p_flags) const { +Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const { Node *node = NULL; @@ -2084,7 +2084,12 @@ Node *Node::duplicate(int p_flags) const { Ref<PackedScene> res = ResourceLoader::load(get_filename()); ERR_FAIL_COND_V(res.is_null(), NULL); - node = res->instance(); + PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED; +#ifdef TOOLS_ENABLED + if (p_flags & DUPLICATE_FROM_EDITOR) + ges = PackedScene::GEN_EDIT_STATE_INSTANCE; +#endif + node = res->instance(ges); ERR_FAIL_COND_V(!node, NULL); instanced = true; @@ -2099,10 +2104,6 @@ Node *Node::duplicate(int p_flags) const { ERR_FAIL_COND_V(!node, NULL); } - if (get_filename() != "") { //an instance - node->set_filename(get_filename()); - } - List<PropertyInfo> plist; get_property_list(&plist); @@ -2138,18 +2139,25 @@ Node *Node::duplicate(int p_flags) const { node->set_name(get_name()); +#ifdef TOOLS_ENABLED + if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) + r_duplimap->insert(this, node); +#endif + if (p_flags & DUPLICATE_GROUPS) { List<GroupInfo> gi; get_groups(&gi); for (List<GroupInfo>::Element *E = gi.front(); E; E = E->next()) { +#ifdef TOOLS_ENABLED + if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent) + continue; +#endif + node->add_to_group(E->get().name, E->get().persistent); } } - if (p_flags & DUPLICATE_SIGNALS) - _duplicate_signals(this, node); - for (int i = 0; i < get_child_count(); i++) { if (get_child(i)->data.parent_owned) @@ -2157,7 +2165,7 @@ Node *Node::duplicate(int p_flags) const { if (instanced && get_child(i)->data.owner == this) continue; //part of instance - Node *dup = get_child(i)->duplicate(p_flags); + Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap); if (!dup) { memdelete(node); @@ -2170,6 +2178,31 @@ Node *Node::duplicate(int p_flags) const { return node; } +Node *Node::duplicate(int p_flags) const { + + Node *dupe = _duplicate(p_flags); + + if (dupe && (p_flags & DUPLICATE_SIGNALS)) { + _duplicate_signals(this, dupe); + } + + return dupe; +} + +#ifdef TOOLS_ENABLED +Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const { + + Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap); + + // Duplication of signals must happen after all the node descendants have been copied, + // because re-targeting of connections from some descendant to another is not possible + // if the emitter node comes later in tree order than the receiver + _duplicate_signals(this, dupe); + + return dupe; +} +#endif + void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const { if (get_owner() != get_parent()->get_owner()) @@ -2240,6 +2273,9 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p } } +// Duplication of signals must happen after all the node descendants have been copied, +// because re-targeting of connections from some descendant to another is not possible +// if the emitter node comes later in tree order than the receiver void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { if (this != p_original && (get_owner() != p_original && get_owner() != p_original->get_owner())) @@ -2262,6 +2298,12 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const { NodePath ptarget = p_original->get_path_to(target); Node *copytarget = p_copy->get_node(ptarget); + // Cannot find a path to the duplicate target, so it seems it's not part + // of the duplicated and not yet parented hierarchy, so at least try to connect + // to the same target as the original + if (!copytarget) + copytarget = target; + if (copy && copytarget) { copy->connect(E->get().signal, copytarget, E->get().method, E->get().binds, CONNECT_PERSIST); } @@ -2308,6 +2350,9 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const { get_child(i)->_duplicate_and_reown(node, p_reown_map); } + // Duplication of signals must happen after all the node descendants have been copied, + // because re-targeting of connections from some descendant to another is not possible + // if the emitter node comes later in tree order than the receiver _duplicate_signals(this, node); return node; } diff --git a/scene/main/node.h b/scene/main/node.h index e8901f7b6e..bd0b18c87a 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -58,7 +58,10 @@ public: DUPLICATE_SIGNALS = 1, DUPLICATE_GROUPS = 2, DUPLICATE_SCRIPTS = 4, - DUPLICATE_USE_INSTANCING = 8 + DUPLICATE_USE_INSTANCING = 8, +#ifdef TOOLS_ENABLED + DUPLICATE_FROM_EDITOR = 16, +#endif }; enum RPCMode { @@ -169,6 +172,7 @@ private: void _duplicate_signals(const Node *p_original, Node *p_copy) const; void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const; + Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = NULL) const; Array _get_children() const; Array _get_groups() const; @@ -325,6 +329,9 @@ public: Node *duplicate(int p_flags = DUPLICATE_GROUPS | DUPLICATE_SIGNALS | DUPLICATE_SCRIPTS) const; Node *duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const; +#ifdef TOOLS_ENABLED + Node *duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const; +#endif //Node *clone_tree() const; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 21e4a85cd1..8192074c17 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1125,14 +1125,14 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a return a.cubic_slerp(b, pa, pb, p_c); } break; - case Variant::RECT3: { + case Variant::AABB: { - Rect3 a = p_a; - Rect3 b = p_b; - Rect3 pa = p_pre_a; - Rect3 pb = p_post_b; + AABB a = p_a; + AABB b = p_b; + AABB pa = p_pre_a; + AABB pb = p_post_b; - return Rect3( + return AABB( a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c), a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c)); } break; diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp index bbc85ce0f6..4b9843f3f5 100644 --- a/scene/resources/box_shape.cpp +++ b/scene/resources/box_shape.cpp @@ -33,7 +33,7 @@ Vector<Vector3> BoxShape::_gen_debug_mesh_lines() { Vector<Vector3> lines; - Rect3 aabb; + AABB aabb; aabb.position = -get_extents(); aabb.size = aabb.position * -2; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 3e86daf3a7..0a886c25b1 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -594,9 +594,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } ERR_FAIL_COND_V(!d.has("aabb"), false); - Rect3 aabb = d["aabb"]; + AABB aabb = d["aabb"]; - Vector<Rect3> bone_aabb; + Vector<AABB> bone_aabb; if (d.has("skeleton_aabb")) { Array baabb = d["skeleton_aabb"]; bone_aabb.resize(baabb.size()); @@ -676,7 +676,7 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { d["format"] = VS::get_singleton()->mesh_surface_get_format(mesh, idx); d["aabb"] = VS::get_singleton()->mesh_surface_get_aabb(mesh, idx); - Vector<Rect3> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx); + Vector<AABB> skel_aabb = VS::get_singleton()->mesh_surface_get_skeleton_aabb(mesh, idx); Array arr; for (int i = 0; i < skel_aabb.size(); i++) { arr[i] = skel_aabb[i]; @@ -725,13 +725,13 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { } } - p_list->push_back(PropertyInfo(Variant::RECT3, "custom_aabb/custom_aabb")); + p_list->push_back(PropertyInfo(Variant::AABB, "custom_aabb/custom_aabb")); } void ArrayMesh::_recompute_aabb() { // regenerate AABB - aabb = Rect3(); + aabb = AABB(); for (int i = 0; i < surfaces.size(); i++) { @@ -742,7 +742,7 @@ void ArrayMesh::_recompute_aabb() { } } -void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) { +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) { Surface s; s.aabb = p_aabb; @@ -772,7 +772,7 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & const Vector3 *vtx = r.ptr(); // check AABB - Rect3 aabb; + AABB aabb; for (int i = 0; i < len; i++) { if (i == 0) @@ -926,7 +926,7 @@ void ArrayMesh::surface_update_region(int p_surface, int p_offset, const PoolVec VS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data); } -void ArrayMesh::surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb) { +void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) { ERR_FAIL_INDEX(p_idx, surfaces.size()); surfaces[p_idx].aabb = p_aabb; @@ -942,7 +942,7 @@ Ref<Material> ArrayMesh::surface_get_material(int p_idx) const { void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) { VisualServer::get_singleton()->mesh_add_surface_from_mesh_data(mesh, p_mesh_data); - Rect3 aabb; + AABB aabb; for (int i = 0; i < p_mesh_data.vertices.size(); i++) { if (i == 0) @@ -970,18 +970,18 @@ RID ArrayMesh::get_rid() const { return mesh; } -Rect3 ArrayMesh::get_aabb() const { +AABB ArrayMesh::get_aabb() const { return aabb; } -void ArrayMesh::set_custom_aabb(const Rect3 &p_custom) { +void ArrayMesh::set_custom_aabb(const AABB &p_custom) { custom_aabb = p_custom; VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb); } -Rect3 ArrayMesh::get_custom_aabb() const { +AABB ArrayMesh::get_custom_aabb() const { return custom_aabb; } @@ -1097,11 +1097,13 @@ void ArrayMesh::_bind_methods() { } void ArrayMesh::reload_from_file() { - for (int i = 0; i < get_surface_count(); i++) { - surface_remove(i); - } + VisualServer::get_singleton()->mesh_clear(mesh); + surfaces.clear(); + clear_blend_shapes(); + Resource::reload_from_file(); - String path = get_path(); + + _change_notify(); } ArrayMesh::ArrayMesh() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 75927079c7..b85a6a84af 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -136,7 +136,7 @@ public: Ref<Mesh> create_outline(float p_margin) const; - virtual Rect3 get_aabb() const = 0; + virtual AABB get_aabb() const = 0; Mesh(); }; @@ -149,16 +149,16 @@ class ArrayMesh : public Mesh { private: struct Surface { String name; - Rect3 aabb; + AABB aabb; Ref<Material> material; bool is_2d; }; Vector<Surface> surfaces; RID mesh; - Rect3 aabb; + AABB aabb; BlendShapeMode blend_shape_mode; Vector<StringName> blend_shapes; - Rect3 custom_aabb; + AABB custom_aabb; void _recompute_aabb(); @@ -173,7 +173,7 @@ protected: public: void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); - void add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>()); + void add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()); Array surface_get_arrays(int p_surface) const; Array surface_get_blend_shape_arrays(int p_surface) const; @@ -191,7 +191,7 @@ public: int get_surface_count() const; void surface_remove(int p_idx); - void surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb); //only recognized by driver + void surface_set_custom_aabb(int p_idx, const AABB &p_aabb); //only recognized by driver int surface_get_array_len(int p_idx) const; int surface_get_array_index_len(int p_idx) const; @@ -207,10 +207,10 @@ public: void add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data); - void set_custom_aabb(const Rect3 &p_custom); - Rect3 get_custom_aabb() const; + void set_custom_aabb(const AABB &p_custom); + AABB get_custom_aabb() const; - Rect3 get_aabb() const; + AABB get_aabb() const; virtual RID get_rid() const; void center_geometry(); diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 15f1e15542..ee6efa6e85 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -155,7 +155,7 @@ Color MultiMesh::get_instance_color(int p_instance) const { return VisualServer::get_singleton()->multimesh_instance_get_color(multimesh, p_instance); } -Rect3 MultiMesh::get_aabb() const { +AABB MultiMesh::get_aabb() const { return VisualServer::get_singleton()->multimesh_get_aabb(multimesh); } diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 7ca66b0b46..0a5310f641 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -84,7 +84,7 @@ public: void set_instance_color(int p_instance, const Color &p_color); Color get_instance_color(int p_instance) const; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual RID get_rid() const; diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 8e3899315c..3b80db291c 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -42,7 +42,7 @@ void PrimitiveMesh::_update() const { PoolVector<Vector3> points = arr[VS::ARRAY_VERTEX]; - aabb = Rect3(); + aabb = AABB(); int pc = points.size(); ERR_FAIL_COND(pc == 0); @@ -141,7 +141,7 @@ StringName PrimitiveMesh::get_blend_shape_name(int p_index) const { return StringName(); } -Rect3 PrimitiveMesh::get_aabb() const { +AABB PrimitiveMesh::get_aabb() const { if (pending_request) { _update(); } diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index f0c8935261..b38c247827 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -47,7 +47,7 @@ class PrimitiveMesh : public Mesh { private: RID mesh; - mutable Rect3 aabb; + mutable AABB aabb; Ref<Material> material; @@ -73,7 +73,7 @@ public: virtual Ref<Material> surface_get_material(int p_idx) const; virtual int get_blend_shape_count() const; virtual StringName get_blend_shape_name(int p_index) const; - virtual Rect3 get_aabb() const; + virtual AABB get_aabb() const; virtual RID get_rid() const; void set_material(const Ref<Material> &p_material); diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index f0304bfaa5..fe23fbf6b3 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -33,7 +33,7 @@ #include "project_settings.h" #include "version.h" -//version 2: changed names for basis, rect3, poolvectors, etc. +//version 2: changed names for basis, aabb, poolvectors, etc. #define FORMAT_VERSION 2 #include "os/dir_access.h" diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index af159975ca..86b32a5cdd 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -41,7 +41,7 @@ struct SpatialIndexer { struct NotifierData { - Rect3 aabb; + AABB aabb; OctreeElementID id; }; @@ -63,7 +63,7 @@ struct SpatialIndexer { uint64_t pass; uint64_t last_frame; - void _notifier_add(VisibilityNotifier *p_notifier, const Rect3 &p_rect) { + void _notifier_add(VisibilityNotifier *p_notifier, const AABB &p_rect) { ERR_FAIL_COND(notifiers.has(p_notifier)); notifiers[p_notifier].aabb = p_rect; @@ -71,7 +71,7 @@ struct SpatialIndexer { changed = true; } - void _notifier_update(VisibilityNotifier *p_notifier, const Rect3 &p_rect) { + void _notifier_update(VisibilityNotifier *p_notifier, const AABB &p_rect) { Map<VisibilityNotifier *, NotifierData>::Element *E = notifiers.find(p_notifier); ERR_FAIL_COND(!E); @@ -229,14 +229,14 @@ void World::_remove_camera(Camera *p_camera) { #endif } -void World::_register_notifier(VisibilityNotifier *p_notifier, const Rect3 &p_rect) { +void World::_register_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect) { #ifndef _3D_DISABLED indexer->_notifier_add(p_notifier, p_rect); #endif } -void World::_update_notifier(VisibilityNotifier *p_notifier, const Rect3 &p_rect) { +void World::_update_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect) { #ifndef _3D_DISABLED indexer->_notifier_update(p_notifier, p_rect); diff --git a/scene/resources/world.h b/scene/resources/world.h index 767d1b5b6e..e0f1de1fd0 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -60,8 +60,8 @@ protected: void _update_camera(Camera *p_camera); void _remove_camera(Camera *p_camera); - void _register_notifier(VisibilityNotifier *p_notifier, const Rect3 &p_rect); - void _update_notifier(VisibilityNotifier *p_notifier, const Rect3 &p_rect); + void _register_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect); + void _update_notifier(VisibilityNotifier *p_notifier, const AABB &p_rect); void _remove_notifier(VisibilityNotifier *p_notifier); friend class Viewport; void _update(uint64_t p_frame); diff --git a/servers/physics/broad_phase_basic.cpp b/servers/physics/broad_phase_basic.cpp index c6565ac2e9..e4eae09c61 100644 --- a/servers/physics/broad_phase_basic.cpp +++ b/servers/physics/broad_phase_basic.cpp @@ -46,7 +46,7 @@ BroadPhaseSW::ID BroadPhaseBasic::create(CollisionObjectSW *p_object, int p_subi return current; } -void BroadPhaseBasic::move(ID p_id, const Rect3 &p_aabb) { +void BroadPhaseBasic::move(ID p_id, const AABB &p_aabb) { Map<ID, Element>::Element *E = element_map.find(p_id); ERR_FAIL_COND(!E); @@ -109,7 +109,7 @@ int BroadPhaseBasic::cull_point(const Vector3 &p_point, CollisionObjectSW **p_re for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect3 aabb = E->get().aabb; + const AABB aabb = E->get().aabb; if (aabb.has_point(p_point)) { p_results[rc] = E->get().owner; @@ -129,7 +129,7 @@ int BroadPhaseBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, Co for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect3 aabb = E->get().aabb; + const AABB aabb = E->get().aabb; if (aabb.intersects_segment(p_from, p_to)) { p_results[rc] = E->get().owner; @@ -142,13 +142,13 @@ int BroadPhaseBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, Co return rc; } -int BroadPhaseBasic::cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { +int BroadPhaseBasic::cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { int rc = 0; for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) { - const Rect3 aabb = E->get().aabb; + const AABB aabb = E->get().aabb; if (aabb.intersects(p_aabb)) { p_results[rc] = E->get().owner; diff --git a/servers/physics/broad_phase_basic.h b/servers/physics/broad_phase_basic.h index 5c124c1792..ee683ed840 100644 --- a/servers/physics/broad_phase_basic.h +++ b/servers/physics/broad_phase_basic.h @@ -39,7 +39,7 @@ class BroadPhaseBasic : public BroadPhaseSW { CollisionObjectSW *owner; bool _static; - Rect3 aabb; + AABB aabb; int subindex; }; @@ -83,7 +83,7 @@ class BroadPhaseBasic : public BroadPhaseSW { public: // 0 is an invalid ID virtual ID create(CollisionObjectSW *p_object, int p_subindex = 0); - virtual void move(ID p_id, const Rect3 &p_aabb); + virtual void move(ID p_id, const AABB &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); @@ -93,7 +93,7 @@ public: virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics/broad_phase_octree.cpp b/servers/physics/broad_phase_octree.cpp index e7111d9580..3b18a270f0 100644 --- a/servers/physics/broad_phase_octree.cpp +++ b/servers/physics/broad_phase_octree.cpp @@ -32,11 +32,11 @@ BroadPhaseSW::ID BroadPhaseOctree::create(CollisionObjectSW *p_object, int p_subindex) { - ID oid = octree.create(p_object, Rect3(), p_subindex, false, 1 << p_object->get_type(), 0); + ID oid = octree.create(p_object, AABB(), p_subindex, false, 1 << p_object->get_type(), 0); return oid; } -void BroadPhaseOctree::move(ID p_id, const Rect3 &p_aabb) { +void BroadPhaseOctree::move(ID p_id, const AABB &p_aabb) { octree.move(p_id, p_aabb); } @@ -76,7 +76,7 @@ int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, C return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); } -int BroadPhaseOctree::cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { +int BroadPhaseOctree::cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) { return octree.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); } diff --git a/servers/physics/broad_phase_octree.h b/servers/physics/broad_phase_octree.h index d28f2da13f..f894d6ca5a 100644 --- a/servers/physics/broad_phase_octree.h +++ b/servers/physics/broad_phase_octree.h @@ -48,7 +48,7 @@ class BroadPhaseOctree : public BroadPhaseSW { public: // 0 is an invalid ID virtual ID create(CollisionObjectSW *p_object, int p_subindex = 0); - virtual void move(ID p_id, const Rect3 &p_aabb); + virtual void move(ID p_id, const AABB &p_aabb); virtual void set_static(ID p_id, bool p_static); virtual void remove(ID p_id); @@ -58,7 +58,7 @@ public: virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); - virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); + virtual int cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL); virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata); virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata); diff --git a/servers/physics/broad_phase_sw.h b/servers/physics/broad_phase_sw.h index 2b5ed629fe..5ad3f9a261 100644 --- a/servers/physics/broad_phase_sw.h +++ b/servers/physics/broad_phase_sw.h @@ -30,8 +30,8 @@ #ifndef BROAD_PHASE_SW_H #define BROAD_PHASE_SW_H +#include "aabb.h" #include "math_funcs.h" -#include "rect3.h" class CollisionObjectSW; @@ -49,7 +49,7 @@ public: // 0 is an invalid ID virtual ID create(CollisionObjectSW *p_object_, int p_subindex = 0) = 0; - virtual void move(ID p_id, const Rect3 &p_aabb) = 0; + virtual void move(ID p_id, const AABB &p_aabb) = 0; virtual void set_static(ID p_id, bool p_static) = 0; virtual void remove(ID p_id) = 0; @@ -59,7 +59,7 @@ public: virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; - virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; + virtual int cull_aabb(const AABB &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0; virtual void set_pair_callback(PairCallback p_pair_callback, void *p_userdata) = 0; virtual void set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) = 0; diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index 3af8b542fa..126f8141ff 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -149,7 +149,7 @@ void CollisionObjectSW::_update_shapes() { } //not quite correct, should compute the next matrix.. - Rect3 shape_aabb = s.shape->get_aabb(); + AABB shape_aabb = s.shape->get_aabb(); Transform xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); s.aabb_cache = shape_aabb; @@ -176,10 +176,10 @@ void CollisionObjectSW::_update_shapes_with_motion(const Vector3 &p_motion) { } //not quite correct, should compute the next matrix.. - Rect3 shape_aabb = s.shape->get_aabb(); + AABB shape_aabb = s.shape->get_aabb(); Transform xform = transform * s.xform; shape_aabb = xform.xform(shape_aabb); - shape_aabb = shape_aabb.merge(Rect3(shape_aabb.position + p_motion, shape_aabb.size)); //use motion + shape_aabb = shape_aabb.merge(AABB(shape_aabb.position + p_motion, shape_aabb.size)); //use motion s.aabb_cache = shape_aabb; space->get_broadphase()->move(s.bpid, shape_aabb); diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index 67a8a44944..254947060b 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -61,7 +61,7 @@ private: Transform xform; Transform xform_inv; BroadPhaseSW::ID bpid; - Rect3 aabb_cache; //for rayqueries + AABB aabb_cache; //for rayqueries real_t area_cache; ShapeSW *shape; bool disabled; @@ -123,7 +123,7 @@ public: _FORCE_INLINE_ ShapeSW *get_shape(int p_index) const { return shapes[p_index].shape; } _FORCE_INLINE_ const Transform &get_shape_transform(int p_index) const { return shapes[p_index].xform; } _FORCE_INLINE_ const Transform &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; } - _FORCE_INLINE_ const Rect3 &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; } + _FORCE_INLINE_ const AABB &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; } _FORCE_INLINE_ const real_t get_shape_area(int p_index) const { return shapes[p_index].area_cache; } _FORCE_INLINE_ Transform get_transform() const { return transform; } diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp index 7bef208237..a9431dc6d8 100644 --- a/servers/physics/collision_solver_sw.cpp +++ b/servers/physics/collision_solver_sw.cpp @@ -152,7 +152,7 @@ bool CollisionSolverSW::solve_concave(const ShapeSW *p_shape_A, const Transform //quickly compute a local AABB - Rect3 local_aabb; + AABB local_aabb; for (int i = 0; i < 3; i++) { Vector3 axis(p_transform_B.basis.get_axis(i)); @@ -291,7 +291,7 @@ bool CollisionSolverSW::solve_distance_plane(const ShapeSW *p_shape_A, const Tra return collided; } -bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const Rect3 &p_concave_hint, Vector3 *r_sep_axis) { +bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) { if (p_shape_A->is_concave()) return false; @@ -328,14 +328,14 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform //quickly compute a local AABB - bool use_cc_hint = p_concave_hint != Rect3(); - Rect3 cc_hint_aabb; + bool use_cc_hint = p_concave_hint != AABB(); + AABB cc_hint_aabb; if (use_cc_hint) { cc_hint_aabb = p_concave_hint; cc_hint_aabb.position -= p_transform_B.origin; } - Rect3 local_aabb; + AABB local_aabb; for (int i = 0; i < 3; i++) { Vector3 axis(p_transform_B.basis.get_axis(i)); diff --git a/servers/physics/collision_solver_sw.h b/servers/physics/collision_solver_sw.h index 1e38b1b54e..a40b665ff0 100644 --- a/servers/physics/collision_solver_sw.h +++ b/servers/physics/collision_solver_sw.h @@ -46,7 +46,7 @@ private: public: static bool solve_static(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis = NULL, real_t p_margin_A = 0, real_t p_margin_B = 0); - static bool solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const Rect3 &p_concave_hint, Vector3 *r_sep_axis = NULL); + static bool solve_distance(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis = NULL); }; #endif // COLLISION_SOLVER__SW_H diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp index 6dafaac115..b204ff7a33 100644 --- a/servers/physics/shape_sw.cpp +++ b/servers/physics/shape_sw.cpp @@ -37,7 +37,7 @@ #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002 #define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.9998 -void ShapeSW::configure(const Rect3 &p_aabb) { +void ShapeSW::configure(const AABB &p_aabb) { aabb = p_aabb; configured = true; for (Map<ShapeOwnerSW *, int>::Element *E = owners.front(); E; E = E->next()) { @@ -141,7 +141,7 @@ Vector3 PlaneShapeSW::get_moment_of_inertia(real_t p_mass) const { void PlaneShapeSW::_setup(const Plane &p_plane) { plane = p_plane; - configure(Rect3(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2))); + configure(AABB(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2))); } void PlaneShapeSW::set_data(const Variant &p_data) { @@ -223,7 +223,7 @@ Vector3 RayShapeSW::get_moment_of_inertia(real_t p_mass) const { void RayShapeSW::_setup(real_t p_length) { length = p_length; - configure(Rect3(Vector3(0, 0, 0), Vector3(0.1, 0.1, length))); + configure(AABB(Vector3(0, 0, 0), Vector3(0.1, 0.1, length))); } void RayShapeSW::set_data(const Variant &p_data) { @@ -299,7 +299,7 @@ Vector3 SphereShapeSW::get_moment_of_inertia(real_t p_mass) const { void SphereShapeSW::_setup(real_t p_radius) { radius = p_radius; - configure(Rect3(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0))); + configure(AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0))); } void SphereShapeSW::set_data(const Variant &p_data) { @@ -430,7 +430,7 @@ void BoxShapeSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_sup bool BoxShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { - Rect3 aabb(-half_extents, half_extents * 2.0); + AABB aabb(-half_extents, half_extents * 2.0); return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal); } @@ -504,7 +504,7 @@ void BoxShapeSW::_setup(const Vector3 &p_half_extents) { half_extents = p_half_extents.abs(); - configure(Rect3(-half_extents, half_extents * 2)); + configure(AABB(-half_extents, half_extents * 2)); } void BoxShapeSW::set_data(const Variant &p_data) { @@ -684,7 +684,7 @@ void CapsuleShapeSW::_setup(real_t p_height, real_t p_radius) { height = p_height; radius = p_radius; - configure(Rect3(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0))); + configure(AABB(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0))); } void CapsuleShapeSW::set_data(const Variant &p_data) { @@ -957,7 +957,7 @@ void ConvexPolygonShapeSW::_setup(const Vector<Vector3> &p_vertices) { if (err != OK) ERR_PRINT("Failed to build QuickHull"); - Rect3 _aabb; + AABB _aabb; for (int i = 0; i < mesh.vertices.size(); i++) { @@ -1102,7 +1102,7 @@ Vector3 FaceShapeSW::get_moment_of_inertia(real_t p_mass) const { FaceShapeSW::FaceShapeSW() { - configure(Rect3()); + configure(AABB()); } PoolVector<Vector3> ConcavePolygonShapeSW::get_faces() const { @@ -1300,13 +1300,13 @@ void ConcavePolygonShapeSW::_cull(int p_idx, _CullParams *p_params) const { } } -void ConcavePolygonShapeSW::cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const { +void ConcavePolygonShapeSW::cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const { // make matrix local to concave if (faces.size() == 0) return; - Rect3 local_aabb = p_local_aabb; + AABB local_aabb = p_local_aabb; // unlock data PoolVector<Face>::Read fr = faces.read(); @@ -1341,7 +1341,7 @@ Vector3 ConcavePolygonShapeSW::get_moment_of_inertia(real_t p_mass) const { struct _VolumeSW_BVH_Element { - Rect3 aabb; + AABB aabb; Vector3 center; int face_index; }; @@ -1372,7 +1372,7 @@ struct _VolumeSW_BVH_CompareZ { struct _VolumeSW_BVH { - Rect3 aabb; + AABB aabb; _VolumeSW_BVH *left; _VolumeSW_BVH *right; @@ -1396,7 +1396,7 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz bvh->face_index = -1; } - Rect3 aabb; + AABB aabb; for (int i = 0; i < p_size; i++) { if (i == 0) @@ -1467,7 +1467,7 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) { int src_face_count = p_faces.size(); if (src_face_count == 0) { - configure(Rect3()); + configure(AABB()); return; } ERR_FAIL_COND(src_face_count % 3); @@ -1491,7 +1491,7 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) { PoolVector<Vector3>::Write vw = vertices.write(); Vector3 *verticesw = vw.ptr(); - Rect3 _aabb; + AABB _aabb; for (int i = 0; i < src_face_count; i++) { @@ -1588,7 +1588,7 @@ Vector3 HeightMapShapeSW::get_closest_point_to(const Vector3 &p_point) const { return Vector3(); } -void HeightMapShapeSW::cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const { +void HeightMapShapeSW::cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const { } Vector3 HeightMapShapeSW::get_moment_of_inertia(real_t p_mass) const { @@ -1611,7 +1611,7 @@ void HeightMapShapeSW::_setup(PoolVector<real_t> p_heights, int p_width, int p_d PoolVector<real_t>::Read r = heights.read(); - Rect3 aabb; + AABB aabb; for (int i = 0; i < depth; i++) { diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h index 151b84c054..48832affc9 100644 --- a/servers/physics/shape_sw.h +++ b/servers/physics/shape_sw.h @@ -58,14 +58,14 @@ public: class ShapeSW : public RID_Data { RID self; - Rect3 aabb; + AABB aabb; bool configured; real_t custom_bias; Map<ShapeOwnerSW *, int> owners; protected: - void configure(const Rect3 &p_aabb); + void configure(const AABB &p_aabb); public: enum { @@ -79,7 +79,7 @@ public: virtual PhysicsServer::ShapeType get_type() const = 0; - _FORCE_INLINE_ Rect3 get_aabb() const { return aabb; } + _FORCE_INLINE_ AABB get_aabb() const { return aabb; } _FORCE_INLINE_ bool is_configured() const { return configured; } virtual bool is_concave() const { return false; } @@ -114,7 +114,7 @@ public: typedef void (*Callback)(void *p_userdata, ShapeSW *p_convex); virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; } - virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; + virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const = 0; ConcaveShapeSW() {} }; @@ -299,7 +299,7 @@ struct ConcavePolygonShapeSW : public ConcaveShapeSW { struct BVH { - Rect3 aabb; + AABB aabb; int left; int right; @@ -310,7 +310,7 @@ struct ConcavePolygonShapeSW : public ConcaveShapeSW { struct _CullParams { - Rect3 aabb; + AABB aabb; Callback callback; void *userdata; const Face *faces; @@ -353,7 +353,7 @@ public: virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; - virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const; + virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const; virtual Vector3 get_moment_of_inertia(real_t p_mass) const; @@ -389,7 +389,7 @@ public: virtual bool intersect_point(const Vector3 &p_point) const; virtual Vector3 get_closest_point_to(const Vector3 &p_point) const; - virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const; + virtual void cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const; virtual Vector3 get_moment_of_inertia(real_t p_mass) const; @@ -462,7 +462,7 @@ struct MotionShapeSW : public ShapeSW { virtual void set_data(const Variant &p_data) {} virtual Variant get_data() const { return Variant(); } - MotionShapeSW() { configure(Rect3()); } + MotionShapeSW() { configure(AABB()); } }; struct _ShapeTestConvexBSPSW { diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 7fac56f3d7..a6426b7ee0 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -176,7 +176,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); - Rect3 aabb = p_xform.xform(shape->get_aabb()); + AABB aabb = p_xform.xform(shape->get_aabb()); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -224,8 +224,8 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, false); - Rect3 aabb = p_xform.xform(shape->get_aabb()); - aabb = aabb.merge(Rect3(aabb.position + p_motion, aabb.size)); //motion + AABB aabb = p_xform.xform(shape->get_aabb()); + aabb = aabb.merge(AABB(aabb.position + p_motion, aabb.size)); //motion aabb = aabb.grow(p_margin); /* @@ -341,7 +341,7 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); - Rect3 aabb = p_shape_xform.xform(shape->get_aabb()); + AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -417,7 +417,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_ ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape); ERR_FAIL_COND_V(!shape, 0); - Rect3 aabb = p_shape_xform.xform(shape->get_aabb()); + AABB aabb = p_shape_xform.xform(shape->get_aabb()); aabb = aabb.grow(p_margin); int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results); @@ -514,7 +514,7 @@ PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() { //////////////////////////////////////////////////////////////////////////////////////////////////////////// -int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb) { +int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const AABB &p_aabb) { int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results); @@ -561,7 +561,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve r_result->collider_id = 0; r_result->collider_shape = 0; } - Rect3 body_aabb; + AABB body_aabb; for (int i = 0; i < p_body->get_shape_count(); i++) { @@ -648,7 +648,7 @@ bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Ve { // STEP 2 ATTEMPT MOTION - Rect3 motion_aabb = body_aabb; + AABB motion_aabb = body_aabb; motion_aabb.position += p_motion; motion_aabb = motion_aabb.merge(body_aabb); diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index 270e4ef1bd..fd7e6d16a9 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -122,7 +122,7 @@ private: friend class PhysicsDirectSpaceStateSW; - int _cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb); + int _cull_aabb_for_body(BodySW *p_body, const AABB &p_aabb); public: _FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 333fe1e72a..21d059c48e 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -234,7 +234,7 @@ public: virtual RID mesh_create() = 0; - virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>()) = 0; + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, VS::PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) = 0; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount) = 0; virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; @@ -256,17 +256,17 @@ public: virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const = 0; virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const = 0; - virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; + virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const = 0; - virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; + virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; virtual void mesh_remove_surface(RID p_mesh, int p_index) = 0; virtual int mesh_get_surface_count(RID p_mesh) const = 0; - virtual void mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb) = 0; - virtual Rect3 mesh_get_custom_aabb(RID p_mesh) const = 0; + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; + virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; - virtual Rect3 mesh_get_aabb(RID p_mesh, RID p_skeleton) const = 0; + virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton) const = 0; virtual void mesh_clear(RID p_mesh) = 0; /* MULTIMESH API */ @@ -290,7 +290,7 @@ public: virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0; virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0; - virtual Rect3 multimesh_get_aabb(RID p_multimesh) const = 0; + virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; /* IMMEDIATE API */ @@ -306,7 +306,7 @@ public: virtual void immediate_clear(RID p_immediate) = 0; virtual void immediate_set_material(RID p_immediate, RID p_material) = 0; virtual RID immediate_get_material(RID p_immediate) const = 0; - virtual Rect3 immediate_get_aabb(RID p_immediate) const = 0; + virtual AABB immediate_get_aabb(RID p_immediate) const = 0; /* SKELETON API */ @@ -350,7 +350,7 @@ public: virtual bool light_has_shadow(RID p_light) const = 0; virtual VS::LightType light_get_type(RID p_light) const = 0; - virtual Rect3 light_get_aabb(RID p_light) const = 0; + virtual AABB light_get_aabb(RID p_light) const = 0; virtual float light_get_param(RID p_light, VS::LightParam p_param) = 0; virtual Color light_get_color(RID p_light) = 0; virtual uint64_t light_get_version(RID p_light) const = 0; @@ -372,7 +372,7 @@ public: virtual void reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) = 0; virtual void reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) = 0; - virtual Rect3 reflection_probe_get_aabb(RID p_probe) const = 0; + virtual AABB reflection_probe_get_aabb(RID p_probe) const = 0; virtual VS::ReflectionProbeUpdateMode reflection_probe_get_update_mode(RID p_probe) const = 0; virtual uint32_t reflection_probe_get_cull_mask(RID p_probe) const = 0; virtual Vector3 reflection_probe_get_extents(RID p_probe) const = 0; @@ -390,8 +390,8 @@ public: virtual RID gi_probe_create() = 0; - virtual void gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds) = 0; - virtual Rect3 gi_probe_get_bounds(RID p_probe) const = 0; + virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) = 0; + virtual AABB gi_probe_get_bounds(RID p_probe) const = 0; virtual void gi_probe_set_cell_size(RID p_probe, float p_range) = 0; virtual float gi_probe_get_cell_size(RID p_probe) const = 0; @@ -446,7 +446,7 @@ public: virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; - virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) = 0; + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0; virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0; virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; @@ -460,8 +460,8 @@ public: virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0; virtual void particles_request_process(RID p_particles) = 0; - virtual Rect3 particles_get_current_aabb(RID p_particles) = 0; - virtual Rect3 particles_get_aabb(RID p_particles) const = 0; + virtual AABB particles_get_current_aabb(RID p_particles) = 0; + virtual AABB particles_get_aabb(RID p_particles) const = 0; virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; @@ -882,7 +882,7 @@ public: case Item::Command::TYPE_MESH: { const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c); - Rect3 aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton); + AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); @@ -890,7 +890,7 @@ public: case Item::Command::TYPE_MULTIMESH: { const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c); - Rect3 aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); + AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); @@ -899,7 +899,7 @@ public: const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c); if (particles_cmd->particles.is_valid()) { - Rect3 aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); + AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles); r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y); } diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 67375e81b6..7551485919 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -77,8 +77,8 @@ class VisualServerRaster : public VisualServer { static void _changes_changed() {} public: -//if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() -//#define DEBUG_CHANGES + //if editor is redrawing when it shouldn't, enable this and put a breakpoint in _changes_changed() + //#define DEBUG_CHANGES #ifdef DEBUG_CHANGES _FORCE_INLINE_ static void redraw_request() { @@ -96,7 +96,7 @@ public: #define DISPLAY_CHANGED \ changes++; #endif -// print_line(String("CHANGED: ") + __FUNCTION__); + // print_line(String("CHANGED: ") + __FUNCTION__); #define BIND0R(m_r, m_name) \ m_r m_name() { return BINDBASE->m_name(); } @@ -203,7 +203,7 @@ public: BIND0R(RID, mesh_create) - BIND10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const Rect3 &, const Vector<PoolVector<uint8_t> > &, const Vector<Rect3> &) + BIND10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const AABB &, const Vector<PoolVector<uint8_t> > &, const Vector<AABB> &) BIND2(mesh_set_blend_shape_count, RID, int) BIND1RC(int, mesh_get_blend_shape_count, RID) @@ -225,15 +225,15 @@ public: BIND2RC(uint32_t, mesh_surface_get_format, RID, int) BIND2RC(PrimitiveType, mesh_surface_get_primitive_type, RID, int) - BIND2RC(Rect3, mesh_surface_get_aabb, RID, int) + BIND2RC(AABB, mesh_surface_get_aabb, RID, int) BIND2RC(Vector<PoolVector<uint8_t> >, mesh_surface_get_blend_shapes, RID, int) - BIND2RC(Vector<Rect3>, mesh_surface_get_skeleton_aabb, RID, int) + BIND2RC(Vector<AABB>, mesh_surface_get_skeleton_aabb, RID, int) BIND2(mesh_remove_surface, RID, int) BIND1RC(int, mesh_get_surface_count, RID) - BIND2(mesh_set_custom_aabb, RID, const Rect3 &) - BIND1RC(Rect3, mesh_get_custom_aabb, RID) + BIND2(mesh_set_custom_aabb, RID, const AABB &) + BIND1RC(AABB, mesh_get_custom_aabb, RID) BIND1(mesh_clear, RID) @@ -250,7 +250,7 @@ public: BIND3(multimesh_instance_set_color, RID, int, const Color &) BIND1RC(RID, multimesh_get_mesh, RID) - BIND1RC(Rect3, multimesh_get_aabb, RID) + BIND1RC(AABB, multimesh_get_aabb, RID) BIND2RC(Transform, multimesh_instance_get_transform, RID, int) BIND2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) @@ -327,8 +327,8 @@ public: BIND0R(RID, gi_probe_create) - BIND2(gi_probe_set_bounds, RID, const Rect3 &) - BIND1RC(Rect3, gi_probe_get_bounds, RID) + BIND2(gi_probe_set_bounds, RID, const AABB &) + BIND1RC(AABB, gi_probe_get_bounds, RID) BIND2(gi_probe_set_cell_size, RID, float) BIND1RC(float, gi_probe_get_cell_size, RID) @@ -371,7 +371,7 @@ public: BIND2(particles_set_pre_process_time, RID, float) BIND2(particles_set_explosiveness_ratio, RID, float) BIND2(particles_set_randomness_ratio, RID, float) - BIND2(particles_set_custom_aabb, RID, const Rect3 &) + BIND2(particles_set_custom_aabb, RID, const AABB &) BIND2(particles_set_speed_scale, RID, float) BIND2(particles_set_use_local_coordinates, RID, bool) BIND2(particles_set_process_material, RID, RID) @@ -384,7 +384,7 @@ public: BIND2(particles_set_draw_passes, RID, int) BIND3(particles_set_draw_pass_mesh, RID, int, RID) - BIND1R(Rect3, particles_get_current_aabb, RID) + BIND1R(AABB, particles_get_current_aabb, RID) BIND2(particles_set_emission_transform, RID, const Transform &) #undef BINDBASE @@ -449,7 +449,7 @@ public: BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo) BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw) -/* ENVIRONMENT API */ + /* ENVIRONMENT API */ #undef BINDBASE //from now on, calls forwarded to this singleton @@ -479,7 +479,7 @@ public: BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float) BIND5(environment_set_fog_height, RID, bool, float, float, float) -/* SCENARIO API */ + /* SCENARIO API */ #undef BINDBASE #define BINDBASE VSG::scene @@ -504,13 +504,15 @@ public: BIND3(instance_set_surface_material, RID, int, RID) BIND2(instance_set_visible, RID, bool) + BIND2(instance_set_custom_aabb, RID, AABB) + BIND2(instance_attach_skeleton, RID, RID) BIND2(instance_set_exterior, RID, bool) BIND2(instance_set_extra_visibility_margin, RID, real_t) // don't use these in a game! - BIND2RC(Vector<ObjectID>, instances_cull_aabb, const Rect3 &, RID) + BIND2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) BIND3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) BIND2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index e49baf0763..5b1eb8357d 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -587,6 +587,36 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) { } } +inline bool is_geometry_instance(VisualServer::InstanceType p_type) { + return p_type == VS::INSTANCE_MESH || p_type == VS::INSTANCE_MULTIMESH || p_type == VS::INSTANCE_PARTICLES || p_type == VS::INSTANCE_IMMEDIATE; +} + +void VisualServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { + + Instance *instance = instance_owner.get(p_instance); + ERR_FAIL_COND(!instance); + ERR_FAIL_COND(!is_geometry_instance(instance->base_type)); + + if(p_aabb != AABB()) { + + // Set custom AABB + if (instance->custom_aabb == NULL) + instance->custom_aabb = memnew(AABB); + *instance->custom_aabb = p_aabb; + + } else { + + // Clear custom AABB + if (instance->custom_aabb != NULL) { + memdelete(instance->custom_aabb); + instance->custom_aabb = NULL; + } + } + + if (instance->scenario) + _instance_queue_update(instance, true, false); +} + void VisualServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) { Instance *instance = instance_owner.get(p_instance); @@ -614,7 +644,7 @@ void VisualServerScene::instance_set_exterior(RID p_instance, bool p_enabled) { void VisualServerScene::instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) { } -Vector<ObjectID> VisualServerScene::instances_cull_aabb(const Rect3 &p_aabb, RID p_scenario) const { +Vector<ObjectID> VisualServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const { Vector<ObjectID> instances; Scenario *scenario = scenario_owner.get(p_scenario); @@ -772,7 +802,7 @@ void VisualServerScene::_update_instance(Instance *p_instance) { p_instance->mirror = p_instance->transform.basis.determinant() < 0.0; - Rect3 new_aabb; + AABB new_aabb; new_aabb = p_instance->transform.xform(p_instance->aabb); @@ -817,7 +847,7 @@ void VisualServerScene::_update_instance(Instance *p_instance) { void VisualServerScene::_update_instance_aabb(Instance *p_instance) { - Rect3 new_aabb; + AABB new_aabb; ERR_FAIL_COND(p_instance->base_type != VS::INSTANCE_NONE && !p_instance->base.is_valid()); @@ -828,23 +858,35 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) { } break; case VisualServer::INSTANCE_MESH: { - new_aabb = VSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton); } break; case VisualServer::INSTANCE_MULTIMESH: { - new_aabb = VSG::storage->multimesh_get_aabb(p_instance->base); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->multimesh_get_aabb(p_instance->base); } break; case VisualServer::INSTANCE_IMMEDIATE: { - new_aabb = VSG::storage->immediate_get_aabb(p_instance->base); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->immediate_get_aabb(p_instance->base); } break; case VisualServer::INSTANCE_PARTICLES: { - new_aabb = VSG::storage->particles_get_aabb(p_instance->base); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->particles_get_aabb(p_instance->base); } break; case VisualServer::INSTANCE_LIGHT: { @@ -866,6 +908,7 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) { default: {} } + // <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs if (p_instance->extra_margin) new_aabb.grow_by(p_instance->extra_margin); @@ -1863,7 +1906,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { probe->dynamic.enabled = true; Transform cell_to_xform = VSG::storage->gi_probe_get_to_cell_xform(p_instance->base); - Rect3 bounds = VSG::storage->gi_probe_get_bounds(p_instance->base); + AABB bounds = VSG::storage->gi_probe_get_bounds(p_instance->base); float cell_size = VSG::storage->gi_probe_get_cell_size(p_instance->base); probe->dynamic.light_to_cell_xform = cell_to_xform * p_instance->transform.affine_inverse(); @@ -2562,7 +2605,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) { InstanceGIProbeData::LightCache lc; lc.type = VSG::storage->light_get_type(E->get()->base); lc.color = VSG::storage->light_get_color(E->get()->base); - lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY); + lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY) * VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_INDIRECT_ENERGY); lc.radius = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_RANGE); lc.attenuation = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ATTENUATION); lc.spot_angle = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_SPOT_ANGLE); @@ -2582,7 +2625,7 @@ bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) { InstanceGIProbeData::LightCache lc; lc.type = VSG::storage->light_get_type(E->get()->base); lc.color = VSG::storage->light_get_color(E->get()->base); - lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY); + lc.energy = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ENERGY) * VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_INDIRECT_ENERGY); lc.radius = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_RANGE); lc.attenuation = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_ATTENUATION); lc.spot_angle = VSG::storage->light_get_param(E->get()->base, VS::LIGHT_PARAM_SPOT_ANGLE); diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index d30a2108a5..d075be76ca 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -195,8 +195,9 @@ public: SelfList<Instance> update_item; - Rect3 aabb; - Rect3 transformed_aabb; + AABB aabb; + AABB transformed_aabb; + AABB *custom_aabb; // <Zylann> would using aabb directly with a bool be better? float extra_margin; uint32_t object_ID; @@ -251,12 +252,16 @@ public: last_frame_pass = 0; version = 1; base_data = NULL; + + custom_aabb = NULL; } ~Instance() { if (base_data) memdelete(base_data); + if (custom_aabb) + memdelete(custom_aabb); } }; @@ -460,13 +465,15 @@ public: virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material); virtual void instance_set_visible(RID p_instance, bool p_visible); + virtual void instance_set_custom_aabb(RID p_insatnce, AABB aabb); + virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton); virtual void instance_set_exterior(RID p_instance, bool p_enabled); virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin); // don't use these in a game! - virtual Vector<ObjectID> instances_cull_aabb(const Rect3 &p_aabb, RID p_scenario = RID()) const; + virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const; diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 1dddef7bd4..e120eb5ad3 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -63,7 +63,7 @@ class VisualServerWrapMT : public VisualServer { int pool_max_size; -//#define DEBUG_SYNC + //#define DEBUG_SYNC #ifdef DEBUG_SYNC #define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__)); @@ -136,7 +136,7 @@ public: FUNCRID(mesh) - FUNC10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const Rect3 &, const Vector<PoolVector<uint8_t> > &, const Vector<Rect3> &) + FUNC10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const AABB &, const Vector<PoolVector<uint8_t> > &, const Vector<AABB> &) FUNC2(mesh_set_blend_shape_count, RID, int) FUNC1RC(int, mesh_get_blend_shape_count, RID) @@ -158,15 +158,15 @@ public: FUNC2RC(uint32_t, mesh_surface_get_format, RID, int) FUNC2RC(PrimitiveType, mesh_surface_get_primitive_type, RID, int) - FUNC2RC(Rect3, mesh_surface_get_aabb, RID, int) + FUNC2RC(AABB, mesh_surface_get_aabb, RID, int) FUNC2RC(Vector<PoolVector<uint8_t> >, mesh_surface_get_blend_shapes, RID, int) - FUNC2RC(Vector<Rect3>, mesh_surface_get_skeleton_aabb, RID, int) + FUNC2RC(Vector<AABB>, mesh_surface_get_skeleton_aabb, RID, int) FUNC2(mesh_remove_surface, RID, int) FUNC1RC(int, mesh_get_surface_count, RID) - FUNC2(mesh_set_custom_aabb, RID, const Rect3 &) - FUNC1RC(Rect3, mesh_get_custom_aabb, RID) + FUNC2(mesh_set_custom_aabb, RID, const AABB &) + FUNC1RC(AABB, mesh_get_custom_aabb, RID) FUNC1(mesh_clear, RID) @@ -183,7 +183,7 @@ public: FUNC3(multimesh_instance_set_color, RID, int, const Color &) FUNC1RC(RID, multimesh_get_mesh, RID) - FUNC1RC(Rect3, multimesh_get_aabb, RID) + FUNC1RC(AABB, multimesh_get_aabb, RID) FUNC2RC(Transform, multimesh_instance_get_transform, RID, int) FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int) @@ -260,8 +260,8 @@ public: FUNCRID(gi_probe) - FUNC2(gi_probe_set_bounds, RID, const Rect3 &) - FUNC1RC(Rect3, gi_probe_get_bounds, RID) + FUNC2(gi_probe_set_bounds, RID, const AABB &) + FUNC1RC(AABB, gi_probe_get_bounds, RID) FUNC2(gi_probe_set_cell_size, RID, float) FUNC1RC(float, gi_probe_get_cell_size, RID) @@ -304,7 +304,7 @@ public: FUNC2(particles_set_pre_process_time, RID, float) FUNC2(particles_set_explosiveness_ratio, RID, float) FUNC2(particles_set_randomness_ratio, RID, float) - FUNC2(particles_set_custom_aabb, RID, const Rect3 &) + FUNC2(particles_set_custom_aabb, RID, const AABB &) FUNC2(particles_set_speed_scale, RID, float) FUNC2(particles_set_use_local_coordinates, RID, bool) FUNC2(particles_set_process_material, RID, RID) @@ -318,7 +318,7 @@ public: FUNC3(particles_set_draw_pass_mesh, RID, int, RID) FUNC2(particles_set_emission_transform, RID, const Transform &) - FUNC1R(Rect3, particles_get_current_aabb, RID) + FUNC1R(AABB, particles_get_current_aabb, RID) /* CAMERA API */ @@ -424,6 +424,7 @@ public: FUNC3(instance_set_blend_shape_weight, RID, int, float) FUNC3(instance_set_surface_material, RID, int, RID) FUNC2(instance_set_visible, RID, bool) + FUNC2(instance_set_custom_aabb, RID, AABB) FUNC2(instance_attach_skeleton, RID, RID) FUNC2(instance_set_exterior, RID, bool) @@ -431,7 +432,7 @@ public: FUNC2(instance_set_extra_visibility_margin, RID, real_t) // don't use these in a game! - FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const Rect3 &, RID) + FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const AABB &, RID) FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID) FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID) diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 039bbedbcc..10f350d667 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -308,7 +308,7 @@ RID VisualServer::get_white_texture() { #define SMALL_VEC2 Vector2(0.00001, 0.00001) #define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001) -Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb) { +Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> r_bone_aabb) { PoolVector<uint8_t>::Write vw = r_vertex_array.write(); @@ -373,7 +373,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ } } - r_aabb = Rect3(Vector3(aabb.position.x, aabb.position.y, 0), Vector3(aabb.size.x, aabb.size.y, 0)); + r_aabb = AABB(Vector3(aabb.position.x, aabb.position.y, 0), Vector3(aabb.size.x, aabb.size.y, 0)); } else { PoolVector<Vector3> array = p_arrays[ai]; @@ -383,7 +383,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ const Vector3 *src = read.ptr(); // setting vertices means regenerating the AABB - Rect3 aabb; + AABB aabb; if (p_format & ARRAY_COMPRESS_VERTEX) { @@ -395,7 +395,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ if (i == 0) { - aabb = Rect3(src[i], SMALL_VEC3); + aabb = AABB(src[i], SMALL_VEC3); } else { aabb.expand_to(src[i]); @@ -411,7 +411,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ if (i == 0) { - aabb = Rect3(src[i], SMALL_VEC3); + aabb = AABB(src[i], SMALL_VEC3); } else { aabb.expand_to(src[i]); @@ -728,7 +728,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ PoolVector<int>::Read rb = bones.read(); PoolVector<float>::Read rw = weights.read(); - Rect3 *bptr = r_bone_aabb.ptr(); + AABB *bptr = r_bone_aabb.ptr(); for (int i = 0; i < vs; i++) { @@ -743,7 +743,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_ if (bptr->size.x < 0) { //first - bptr[idx] = Rect3(v, SMALL_VEC3); + bptr[idx] = AABB(v, SMALL_VEC3); any_valid = true; } else { bptr[idx].expand_to(v); @@ -975,8 +975,8 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim PoolVector<uint8_t> index_array; index_array.resize(index_array_size); - Rect3 aabb; - Vector<Rect3> bone_aabb; + AABB aabb; + Vector<AABB> bone_aabb; Error err = _surface_set_data(p_arrays, format, offsets, total_elem_size, vertex_array, array_len, index_array, index_array_len, aabb, bone_aabb); @@ -993,7 +993,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim vertex_array_shape.resize(array_size); PoolVector<uint8_t> noindex; - Rect3 laabb; + AABB laabb; Error err = _surface_set_data(p_blend_shapes[i], format & ~ARRAY_FORMAT_INDEX, offsets, total_elem_size, vertex_array_shape, array_len, noindex, 0, laabb, bone_aabb); aabb.merge_with(laabb); if (err) { @@ -1470,7 +1470,7 @@ Array VisualServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surfac Array VisualServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const { - Vector<Rect3> vec = VS::get_singleton()->mesh_surface_get_skeleton_aabb(p_mesh, p_surface); + Vector<AABB> vec = VS::get_singleton()->mesh_surface_get_skeleton_aabb(p_mesh, p_surface); Array arr; for (int i = 0; i < vec.size(); i++) { arr[i] = vec[i]; diff --git a/servers/visual_server.h b/servers/visual_server.h index a36ba4a50a..c4b1583009 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -60,7 +60,7 @@ protected: RID white_texture; RID test_material; - Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, Rect3 &r_aabb, Vector<Rect3> r_bone_aabb); + Error _surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, PoolVector<uint8_t> &r_vertex_array, int p_vertex_array_len, PoolVector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> r_bone_aabb); static VisualServer *(*create_func)(); static void _bind_methods(); @@ -247,7 +247,7 @@ public: virtual RID mesh_create() = 0; virtual void mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), uint32_t p_compress_format = ARRAY_COMPRESS_DEFAULT); - virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<Rect3> &p_bone_aabbs = Vector<Rect3>()) = 0; + virtual void mesh_add_surface(RID p_mesh, uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes = Vector<PoolVector<uint8_t> >(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>()) = 0; virtual void mesh_set_blend_shape_count(RID p_mesh, int p_amount) = 0; virtual int mesh_get_blend_shape_count(RID p_mesh) const = 0; @@ -277,16 +277,16 @@ public: virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const = 0; virtual PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const = 0; - virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; + virtual AABB mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0; virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const = 0; - virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; + virtual Vector<AABB> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0; Array _mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const; virtual void mesh_remove_surface(RID p_mesh, int p_index) = 0; virtual int mesh_get_surface_count(RID p_mesh) const = 0; - virtual void mesh_set_custom_aabb(RID p_mesh, const Rect3 &p_aabb) = 0; - virtual Rect3 mesh_get_custom_aabb(RID p_mesh) const = 0; + virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; + virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; virtual void mesh_clear(RID p_mesh) = 0; @@ -314,7 +314,7 @@ public: virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) = 0; virtual RID multimesh_get_mesh(RID p_multimesh) const = 0; - virtual Rect3 multimesh_get_aabb(RID p_multimesh) const = 0; + virtual AABB multimesh_get_aabb(RID p_multimesh) const = 0; virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const = 0; virtual Transform2D multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const = 0; @@ -360,6 +360,7 @@ public: enum LightParam { LIGHT_PARAM_ENERGY, + LIGHT_PARAM_INDIRECT_ENERGY, LIGHT_PARAM_SPECULAR, LIGHT_PARAM_RANGE, LIGHT_PARAM_ATTENUATION, @@ -449,8 +450,8 @@ public: virtual RID gi_probe_create() = 0; - virtual void gi_probe_set_bounds(RID p_probe, const Rect3 &p_bounds) = 0; - virtual Rect3 gi_probe_get_bounds(RID p_probe) const = 0; + virtual void gi_probe_set_bounds(RID p_probe, const AABB &p_bounds) = 0; + virtual AABB gi_probe_get_bounds(RID p_probe) const = 0; virtual void gi_probe_set_cell_size(RID p_probe, float p_range) = 0; virtual float gi_probe_get_cell_size(RID p_probe) const = 0; @@ -493,7 +494,7 @@ public: virtual void particles_set_pre_process_time(RID p_particles, float p_time) = 0; virtual void particles_set_explosiveness_ratio(RID p_particles, float p_ratio) = 0; virtual void particles_set_randomness_ratio(RID p_particles, float p_ratio) = 0; - virtual void particles_set_custom_aabb(RID p_particles, const Rect3 &p_aabb) = 0; + virtual void particles_set_custom_aabb(RID p_particles, const AABB &p_aabb) = 0; virtual void particles_set_speed_scale(RID p_particles, float p_scale) = 0; virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; @@ -512,7 +513,7 @@ public: virtual void particles_set_draw_passes(RID p_particles, int p_count) = 0; virtual void particles_set_draw_pass_mesh(RID p_particles, int p_pass, RID p_mesh) = 0; - virtual Rect3 particles_get_current_aabb(RID p_particles) = 0; + virtual AABB particles_get_current_aabb(RID p_particles) = 0; virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0; //this is only used for 2D, in 3D it's automatic @@ -752,13 +753,15 @@ public: virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0; virtual void instance_set_visible(RID p_instance, bool p_visible) = 0; + virtual void instance_set_custom_aabb(RID p_instance, AABB aabb) = 0; + virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0; virtual void instance_set_exterior(RID p_instance, bool p_enabled) = 0; virtual void instance_set_extra_visibility_margin(RID p_instance, real_t p_margin) = 0; // don't use these in a game! - virtual Vector<ObjectID> instances_cull_aabb(const Rect3 &p_aabb, RID p_scenario = RID()) const = 0; + virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0; virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0; |