diff options
276 files changed, 6430 insertions, 3348 deletions
diff --git a/DONORS.md b/DONORS.md new file mode 100644 index 0000000000..57902fb2fc --- /dev/null +++ b/DONORS.md @@ -0,0 +1,141 @@ +# Donors to the Godot Engine project + +Godot Engine is a non-profit project developed by a community of voluntary +contributors, as well as occasional paid contributors thanks to the financial +support of generous donors. + +The ways to donate to the project, as well as details on how the funds are +used, are described on [Godot's website](https://godotengine.org/donate). + +The following is a list of the current monthly donors, to be have their +generous deed immortalized in the next stable release of Godot Engine. + +## Platinum sponsors + +None so far, but your company could be the first! :) + +## Gold sponsors + + Gamblify <https://www.gamblify.com> + +## Mini sponsors + + Arron Washington + Chris Phyffer + Christian Uldall Pedersen + Hein-Pieter van Braam + Matthieu Huvé + Neal Gompa (Conan Kudo) + Olimpiu Metiu + Ruslan Mustakov + +## Gold donors + + Alexander Otto + Jake Bo + Javier + Nathan Warden + Ranoller + Rémi Verschelde + Stephan Lanfermann + + Andreas Schüle + Bernhard Liebl + Jordan M Lucas + + BanjoNode2D + Chris Serino + Conrad Curry + Craig Smith + David Churchill + Dean Harmon + Guilherme Felipe de C. G. da Silva + Henrique Alves + Laurence Bannister + Leo + Przemysław Gołąb (n-pigeon) + Robert Willes + Robin Arys + summerblind + Testus Maximus + Thomas Bjarnelöf + + Amanda Haldy + Andreas Haas + Bryanna M + Cody Parker + D + Ezra Theunissen + flesk + François Cantin + Hendrik Mans + Jeppe Zapp + Johannes Wuensch + Justin Arnold + Justo Delgado Baudà + Leandro Voltolino + Myles + Robert Podgorski + Scott Beacon + x1212 + +## Silver donors + + Alex Barsukov + Avencherus + Bastian Böhm + Ben Vercammen + Bryan Stevenson + Collin Shooltz + Fabian Becker + fengjiongmax + Geequlim + Gerrit Großkopf + Guldoman + hatniX + HeartBeast + Heribert Hirth + Hunter Jones + imekon + Jacob McKenney + Jonathon + Josh 'Cheeseness' Bush + Julian Murgia + Juraj Móza + Kevin Boyer + Klavdij Voncina + Lisandro Lorea + magodev + Martin Novák + Matthew Fitzpatrick + Matthew Valancy + Matthias Hölzl + Max R.R. Collada + Michael Gringauz + Mikael Olsson + Moritz Laass + nee + nvgrod + Pablo Seibelt + Pan Ip + Paul Mason + Paweł Kowal + Pietro Vertechi + rayos + Richman Stewart + Roger Smith + Sam Van Campenhout + Sam Vila + Sasori Olkof + Sootstone + Tavo Tell + Tom Larrow + Trent McPheron + Troy Bonneau + UltyX + Xananax & karroffel + +## Bronze donors + +There are even more donors that support the project with a small monthly donation. +Every bit counts and we thank every one of them for their amazing support! diff --git a/core/array.cpp b/core/array.cpp index c35bf5bf0c..2e3fbf858d 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -210,6 +210,17 @@ const Variant &Array::get(int p_idx) const { return operator[](p_idx); } +Array Array::duplicate() const { + + Array new_arr; + int element_count = size(); + new_arr.resize(element_count); + for (int i = 0; i < element_count; i++) { + new_arr[i] = get(i); + } + + return new_arr; +} struct _ArrayVariantSort { _FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const { diff --git a/core/array.h b/core/array.h index 777116ab56..8a647dd13b 100644 --- a/core/array.h +++ b/core/array.h @@ -84,6 +84,8 @@ public: Variant pop_back(); Variant pop_front(); + Array duplicate() const; + Array(const Array &p_from); Array(); ~Array(); diff --git a/core/class_db.cpp b/core/class_db.cpp index 872e466e72..f5ddd9c761 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -536,11 +536,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b minfo.return_val = method->get_return_info(); minfo.flags = method->get_hint_flags(); - int defval_count = method->get_default_argument_count(); - minfo.default_arguments.resize(defval_count); - - for (int i = 0; i < defval_count; i++) { - minfo.default_arguments[i] = method->get_default_argument(defval_count - i - 1); + for (int i = 0; i < method->get_argument_count(); i++) { + if (method->has_default_argument(i)) + minfo.default_arguments.push_back(method->get_default_argument(i)); } p_methods->push_back(minfo); diff --git a/core/color.cpp b/core/color.cpp index ab264d31d4..259a4988b1 100644 --- a/core/color.cpp +++ b/core/color.cpp @@ -34,7 +34,7 @@ #include "math_funcs.h" #include "print_string.h" -uint32_t Color::to_ARGB32() const { +uint32_t Color::to_argb32() const { uint32_t c = (uint8_t)(a * 255); c <<= 8; @@ -47,7 +47,7 @@ uint32_t Color::to_ARGB32() const { return c; } -uint32_t Color::to_ABGR32() const { +uint32_t Color::to_abgr32() const { uint32_t c = (uint8_t)(a * 255); c <<= 8; c |= (uint8_t)(b * 255); @@ -59,15 +59,15 @@ uint32_t Color::to_ABGR32() const { return c; } -uint32_t Color::to_32() const { +uint32_t Color::to_rgba32() const { - uint32_t c = (uint8_t)(a * 255); - c <<= 8; - c |= (uint8_t)(r * 255); + uint32_t c = (uint8_t)(r * 255); c <<= 8; c |= (uint8_t)(g * 255); c <<= 8; c |= (uint8_t)(b * 255); + c <<= 8; + c |= (uint8_t)(a * 255); return c; } diff --git a/core/color.h b/core/color.h index cd5510cf01..d3d5db09f9 100644 --- a/core/color.h +++ b/core/color.h @@ -51,9 +51,9 @@ struct Color { bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); } bool operator!=(const Color &p_color) const { return (r != p_color.r || g != p_color.g || b != p_color.b || a != p_color.a); } - uint32_t to_32() const; - uint32_t to_ARGB32() const; - uint32_t to_ABGR32() const; + uint32_t to_rgba32() const; + uint32_t to_argb32() const; + uint32_t to_abgr32() const; float gray() const; float get_h() const; float get_s() const; diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index d8b8c8c200..58ca2d4c58 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -87,6 +87,8 @@ void FileAccessNetworkClient::_thread_func() { DEBUG_PRINT("SEM WAIT - " + itos(sem->get())); Error err = sem->wait(); + if (err != OK) + ERR_PRINT("sem->wait() failed"); DEBUG_TIME("sem_unlock"); //DEBUG_PRINT("semwait returned "+itos(werr)); DEBUG_PRINT("MUTEX LOCK " + itos(lockcount)); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index e36ff28220..e511085ac5 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -166,9 +166,9 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) { uint32_t ver_rev = f->get_32(); ERR_EXPLAIN("Pack version unsupported: " + itos(version)); - ERR_FAIL_COND_V(version != PACK_VERSION, ERR_INVALID_DATA); + ERR_FAIL_COND_V(version != PACK_VERSION, false); ERR_EXPLAIN("Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "." + itos(ver_rev)); - ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), ERR_INVALID_DATA); + ERR_FAIL_COND_V(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false); for (int i = 0; i < 16; i++) { //reserved diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index c5909981ea..16ec6cd3c5 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -37,7 +37,7 @@ #include "core/version.h" //#define print_bl(m_what) print_line(m_what) -#define print_bl(m_what) +#define print_bl(m_what) (void)(m_what) enum { @@ -854,12 +854,6 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { } bool big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - bool use_real64 = f->get_32(); f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian @@ -869,7 +863,11 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { uint32_t ver_format = f->get_32(); print_bl("big endian: " + itos(big_endian)); - print_bl("endian swap: " + itos(endian_swap)); +#ifdef BIG_ENDIAN_ENABLED + print_bl("endian swap: " + itos(!big_endian)); +#else + print_bl("endian swap: " + itos(big_endian)); +#endif print_bl("real64: " + itos(use_real64)); print_bl("major: " + itos(ver_major)); print_bl("minor: " + itos(ver_minor)); @@ -964,18 +962,12 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) { } bool big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - - bool use_real64 = f->get_32(); + f->get_32(); // use_real64 f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian uint32_t ver_major = f->get_32(); - uint32_t ver_minor = f->get_32(); + f->get_32(); // ver_minor uint32_t ver_format = f->get_32(); if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) { @@ -993,8 +985,6 @@ ResourceInteractiveLoaderBinary::ResourceInteractiveLoaderBinary() { f = NULL; stage = 0; - endian_swap = false; - use_real64 = false; error = OK; translation_remapped = false; } @@ -1117,19 +1107,20 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons memdelete(f); } ERR_FAIL_COND_V(!fw, ERR_CANT_CREATE); + + uint8_t magic[4] = { 'R', 'S', 'R', 'C' }; + fw->store_buffer(magic, 4); } bool big_endian = f->get_32(); -#ifdef BIG_ENDIAN_ENABLED - endian_swap = !big_endian; -#else - bool endian_swap = big_endian; -#endif - bool use_real64 = f->get_32(); f->set_endian_swap(big_endian != 0); //read big endian if saved as big endian - fw->store_32(endian_swap); +#ifdef BIG_ENDIAN_ENABLED + fw->store_32(!big_endian); +#else + fw->store_32(big_endian); +#endif fw->set_endian_swap(big_endian != 0); fw->store_32(use_real64); //use real64 @@ -1790,8 +1781,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p } save_unicode_string(p_resource->get_class()); - uint64_t md_at = f->get_pos(); - f->store_64(0); //offset to impoty metadata + f->store_64(0); //offset to import metadata for (int i = 0; i < 14; i++) f->store_32(0); // reserved @@ -1811,11 +1801,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p if (skip_editor && F->get().name.begins_with("__editor")) continue; - if (F->get().usage & PROPERTY_USAGE_STORAGE) { + if ((F->get().usage & PROPERTY_USAGE_STORAGE)) { Property p; p.name_idx = get_string_index(F->get().name); p.value = E->get()->get(F->get().name); - if ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && p.value.is_zero()) || (F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE && p.value.is_one())) + if (((F->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && p.value.is_zero()) || ((F->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && p.value.is_one())) continue; p.pi = F->get(); diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index ab77c2c9d3..2316f05b3c 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -44,8 +44,6 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { FileAccess *f; - bool endian_swap; - bool use_real64; uint64_t importmd_ofs; Vector<char> str_buf; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 1006158003..f4f81f0807 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -446,6 +446,7 @@ Error StreamPeerBuffer::get_data(uint8_t *p_buffer, int p_bytes) { return OK; } + Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) { if (pointer + p_bytes > data.size()) { @@ -463,6 +464,8 @@ Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_ pointer += r_received; // FIXME: return what? OK or ERR_* + // return OK for now so we don't maybe return garbage + return OK; } int StreamPeerBuffer::get_available_bytes() const { diff --git a/core/list.h b/core/list.h index a67287a9ab..da201e9868 100644 --- a/core/list.h +++ b/core/list.h @@ -291,6 +291,54 @@ public: erase(_data->first); } + Element *insert_after(Element *p_element, const T &p_value) { + CRASH_COND(p_element && (!_data || p_element->data != _data)); + + if (!p_element) { + return push_back(p_value); + } + + Element *n = memnew_allocator(Element, A); + n->value = (T &)p_value; + n->prev_ptr = p_element; + n->next_ptr = p_element->next_ptr; + n->data = _data; + + if (!p_element->next_ptr) { + _data->last = n; + } + + p_element->next_ptr = n; + + _data->size_cache++; + + return n; + } + + Element *insert_before(Element *p_element, const T &p_value) { + CRASH_COND(p_element && (!_data || p_element->data != _data)); + + if (!p_element) { + return push_back(p_value); + } + + Element *n = memnew_allocator(Element, A); + n->value = (T &)p_value; + n->prev_ptr = p_element->prev_ptr; + n->next_ptr = p_element; + n->data = _data; + + if (!p_element->prev_ptr) { + _data->first = n; + } + + p_element->prev_ptr = n; + + _data->size_cache++; + + return n; + } + /** * find an element in the list, */ diff --git a/core/map.h b/core/map.h index 75a38a3440..a37d898a9c 100644 --- a/core/map.h +++ b/core/map.h @@ -453,8 +453,9 @@ private: if (!rp) rp = _data._nil; Element *node = (rp->left == _data._nil) ? rp->right : rp->left; + node->parent = rp->parent; - if (_data._root == (node->parent = rp->parent)) { + if (_data._root == node->parent) { _data._root->left = node; } else { if (rp == rp->parent->left) { diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index 21516ac768..d1afcec18f 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -129,6 +129,16 @@ bool AStar::has_point(int p_id) const { return points.has(p_id); } +Array AStar::get_points() { + Array point_list; + + for (const Map<int, Point *>::Element *E = points.front(); E; E = E->next()) { + point_list.push_back(E->key()); + } + + return point_list; +} + bool AStar::are_points_connected(int p_id, int p_with_id) const { Segment s(p_id, p_with_id); @@ -407,6 +417,7 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("get_point_weight_scale", "id"), &AStar::get_point_weight_scale); ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point); ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point); + ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points); ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true)); ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); diff --git a/core/math/a_star.h b/core/math/a_star.h index 75b860d0a4..38d13d510b 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -105,6 +105,7 @@ public: real_t get_point_weight_scale(int p_id) const; void remove_point(int p_id); bool has_point(int p_id) const; + Array get_points(); void connect_points(int p_id, int p_with_id, bool bidirectional = true); void disconnect_points(int p_id, int p_with_id); diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 0512cdd798..7132b6573e 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -131,7 +131,6 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { // we first calculate our base frustum on our values without taking our lens magnification into account. - real_t display_to_eye = 2.0 * p_display_to_lens; real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens; real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens; real_t f3 = (p_display_width / 4.0) / p_display_to_lens; @@ -265,75 +264,26 @@ void CameraMatrix::get_viewport_size(real_t &r_width, real_t &r_height) const { bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const { - const real_t *matrix = (const real_t *)this->matrix; - - ///////--- Near Plane ---/////// - Plane near_plane = Plane(matrix[3] + matrix[2], - matrix[7] + matrix[6], - matrix[11] + matrix[10], - -matrix[15] - matrix[14]); - near_plane.normalize(); - - ///////--- Far Plane ---/////// - Plane far_plane = Plane(matrix[2] - matrix[3], - matrix[6] - matrix[7], - matrix[10] - matrix[11], - matrix[15] - matrix[14]); - far_plane.normalize(); - - ///////--- Right Plane ---/////// - Plane right_plane = Plane(matrix[0] - matrix[3], - matrix[4] - matrix[7], - matrix[8] - matrix[11], - -matrix[15] + matrix[12]); - right_plane.normalize(); - - ///////--- Top Plane ---/////// - Plane top_plane = Plane(matrix[1] - matrix[3], - matrix[5] - matrix[7], - matrix[9] - matrix[11], - -matrix[15] + matrix[13]); - top_plane.normalize(); - - Vector3 near_endpoint_left, near_endpoint_right; - Vector3 far_endpoint_left, far_endpoint_right; - - bool res = near_plane.intersect_3(right_plane, top_plane, &near_endpoint_right); - ERR_FAIL_COND_V(!res, false); - - res = far_plane.intersect_3(right_plane, top_plane, &far_endpoint_right); - ERR_FAIL_COND_V(!res, false); - - if ((matrix[8] == 0) && (matrix[9] == 0)) { - near_endpoint_left = near_endpoint_right; - near_endpoint_left.x = -near_endpoint_left.x; - - far_endpoint_left = far_endpoint_right; - far_endpoint_left.x = -far_endpoint_left.x; - } else { - ///////--- Left Plane ---/////// - Plane left_plane = Plane(matrix[0] + matrix[3], - matrix[4] + matrix[7], - matrix[8] + matrix[11], - -matrix[15] - matrix[12]); - left_plane.normalize(); + Vector<Plane> planes = get_projection_planes(Transform()); + const Planes intersections[8][3] = { + { PLANE_FAR, PLANE_LEFT, PLANE_TOP }, + { PLANE_FAR, PLANE_LEFT, PLANE_BOTTOM }, + { PLANE_FAR, PLANE_RIGHT, PLANE_TOP }, + { PLANE_FAR, PLANE_RIGHT, PLANE_BOTTOM }, + { PLANE_NEAR, PLANE_LEFT, PLANE_TOP }, + { PLANE_NEAR, PLANE_LEFT, PLANE_BOTTOM }, + { PLANE_NEAR, PLANE_RIGHT, PLANE_TOP }, + { PLANE_NEAR, PLANE_RIGHT, PLANE_BOTTOM }, + }; - res = near_plane.intersect_3(left_plane, top_plane, &near_endpoint_left); - ERR_FAIL_COND_V(!res, false); + for (int i = 0; i < 8; i++) { - res = far_plane.intersect_3(left_plane, top_plane, &far_endpoint_left); + Vector3 point; + bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]], planes[intersections[i][2]], &point); ERR_FAIL_COND_V(!res, false); + p_8points[i] = p_transform.xform(point); } - p_8points[0] = p_transform.xform(Vector3(near_endpoint_right.x, near_endpoint_right.y, near_endpoint_right.z)); - p_8points[1] = p_transform.xform(Vector3(near_endpoint_right.x, -near_endpoint_right.y, near_endpoint_right.z)); - p_8points[2] = p_transform.xform(Vector3(near_endpoint_left.x, near_endpoint_left.y, near_endpoint_left.z)); - p_8points[3] = p_transform.xform(Vector3(near_endpoint_left.x, -near_endpoint_left.y, near_endpoint_left.z)); - p_8points[4] = p_transform.xform(Vector3(far_endpoint_right.x, far_endpoint_right.y, far_endpoint_right.z)); - p_8points[5] = p_transform.xform(Vector3(far_endpoint_right.x, -far_endpoint_right.y, far_endpoint_right.z)); - p_8points[6] = p_transform.xform(Vector3(far_endpoint_left.x, far_endpoint_left.y, far_endpoint_left.z)); - p_8points[7] = p_transform.xform(Vector3(far_endpoint_left.x, -far_endpoint_left.y, far_endpoint_left.z)); - return true; } @@ -610,6 +560,11 @@ int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const { return int((result.x * 0.5 + 0.5) * p_for_pixel_width); } +bool CameraMatrix::is_orthogonal() const { + + return matrix[3][3] == 1.0; +} + real_t CameraMatrix::get_fov() const { const real_t *matrix = (const real_t *)this->matrix; diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 175d0cdb1b..3145d73356 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -69,6 +69,7 @@ struct CameraMatrix { real_t get_z_near() const; real_t get_aspect() const; real_t get_fov() const; + bool is_orthogonal() const; Vector<Plane> get_projection_planes(const Transform &p_transform) const; diff --git a/core/math/matrix3.cpp b/core/math/matrix3.cpp index 9732a1ff37..4051de7afb 100644 --- a/core/math/matrix3.cpp +++ b/core/math/matrix3.cpp @@ -234,7 +234,22 @@ Basis Basis::scaled(const Vector3 &p_scale) const { return m; } +void Basis::set_scale(const Vector3 &p_scale) { + + set_axis(0, get_axis(0).normalized() * p_scale.x); + set_axis(1, get_axis(1).normalized() * p_scale.y); + set_axis(2, get_axis(2).normalized() * p_scale.z); +} + Vector3 Basis::get_scale() const { + + return Vector3( + Vector3(elements[0][0], elements[1][0], elements[2][0]).length(), + Vector3(elements[0][1], elements[1][1], elements[2][1]).length(), + Vector3(elements[0][2], elements[1][2], elements[2][2]).length()); +} + +Vector3 Basis::get_signed_scale() const { // FIXME: We are assuming M = R.S (R is rotation and S is scaling), and use polar decomposition to extract R and S. // A polar decomposition is M = O.P, where O is an orthogonal matrix (meaning rotation and reflection) and // P is a positive semi-definite matrix (meaning it contains absolute values of scaling along its diagonal). diff --git a/core/math/matrix3.h b/core/math/matrix3.h index 9c9080ac46..23429888e0 100644 --- a/core/math/matrix3.h +++ b/core/math/matrix3.h @@ -97,7 +97,9 @@ public: void scale(const Vector3 &p_scale); Basis scaled(const Vector3 &p_scale) const; + void set_scale(const Vector3 &p_scale); Vector3 get_scale() const; + Vector3 get_signed_scale() const; // transposed dot products _FORCE_INLINE_ real_t tdotx(const Vector3 &v) const { diff --git a/core/math/transform.cpp b/core/math/transform.cpp index 60df69a509..638a39ab73 100644 --- a/core/math/transform.cpp +++ b/core/math/transform.cpp @@ -118,17 +118,17 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) /* not sure if very "efficient" but good enough? */ - Vector3 src_scale = basis.get_scale(); - Quat src_rot = basis; + Vector3 src_scale = basis.get_signed_scale(); + Quat src_rot = basis.orthonormalized(); Vector3 src_loc = origin; - Vector3 dst_scale = p_transform.basis.get_scale(); + Vector3 dst_scale = p_transform.basis.get_signed_scale(); Quat dst_rot = p_transform.basis; Vector3 dst_loc = p_transform.origin; - Transform dst; - dst.basis = src_rot.slerp(dst_rot, p_c); - dst.basis.scale(src_scale.linear_interpolate(dst_scale, p_c)); + Transform dst; //this could be made faster by using a single function in Basis.. + dst.basis = src_rot.slerp(dst_rot, p_c).normalized(); + dst.basis.set_scale(src_scale.linear_interpolate(dst_scale, p_c)); dst.origin = src_loc.linear_interpolate(dst_loc, p_c); return dst; diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 614104f698..3b246cb183 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -158,7 +158,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { max_depth = 0; int max_alloc = fc; - int max = _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc); + _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc); bw = PoolVector<BVH>::Write(); //clearup bvh.resize(max_alloc); //resize back diff --git a/core/object.h b/core/object.h index 6e1ed4308e..644e2b8270 100644 --- a/core/object.h +++ b/core/object.h @@ -567,12 +567,6 @@ public: template <class T> static T *cast_to(Object *p_object) { -#ifdef DEBUG_ENABLED - // TODO there are some legitimate reasons to pass NULL as p_object. - // we need to figure out how to deal with that in debug mode. - // This code will return NULL for a NULL input in release mode also. - ERR_FAIL_COND_V(p_object == NULL, NULL); -#endif #ifndef NO_SAFE_CAST return dynamic_cast<T *>(p_object); #else @@ -587,12 +581,6 @@ public: template <class T> static const T *cast_to(const Object *p_object) { -#ifdef DEBUG_ENABLED - // TODO there are some legitimate reasons to pass NULL as p_object. - // we need to figure out how to deal with that in debug mode. - // This code will return NULL for a NULL input in release mode also. - ERR_FAIL_COND_V(p_object == NULL, NULL); -#endif #ifndef NO_SAFE_CAST return dynamic_cast<const T *>(p_object); #else diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h index 3e619d2b2e..9e95f963e1 100644 --- a/core/ordered_hash_map.h +++ b/core/ordered_hash_map.h @@ -55,8 +55,8 @@ public: friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>; typename InternalList::Element *list_element; - typename InternalList::Element *next_element; typename InternalList::Element *prev_element; + typename InternalList::Element *next_element; Element(typename InternalList::Element *p_element) { list_element = p_element; @@ -69,7 +69,7 @@ public: public: _FORCE_INLINE_ Element() - : list_element(NULL), next_element(NULL), prev_element(NULL) { + : list_element(NULL), prev_element(NULL), next_element(NULL) { } Element next() const { @@ -312,4 +312,4 @@ bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH return (first.list_element != second.list_element); } -#endif // ORDERED_HASH_MAP_H
\ No newline at end of file +#endif // ORDERED_HASH_MAP_H diff --git a/core/project_settings.cpp b/core/project_settings.cpp index a74917162b..23e4961138 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -114,7 +114,15 @@ String ProjectSettings::globalize_path(const String &p_path) const { return p_path.replace("res:/", resource_path); }; return p_path.replace("res://", ""); - }; + } else if (p_path.begins_with("user://")) { + + String data_dir = OS::get_singleton()->get_data_dir(); + if (data_dir != "") { + + return p_path.replace("user:/", data_dir); + }; + return p_path.replace("user://", ""); + } return p_path; } diff --git a/core/resource.cpp b/core/resource.cpp index 37d42226b4..78e20bada4 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -69,12 +69,11 @@ void Resource::set_path(const String &p_path, bool p_take_over) { ResourceCache::resources.get(p_path)->set_name(""); ResourceCache::lock->write_unlock(); } else { - ERR_EXPLAIN("Another resource is loaded from path: " + p_path); - ResourceCache::lock->read_lock(); bool exists = ResourceCache::resources.has(p_path); ResourceCache::lock->read_unlock(); + ERR_EXPLAIN("Another resource is loaded from path: " + p_path); ERR_FAIL_COND(exists); } } diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 8875732b8e..f0097054b1 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -125,6 +125,9 @@ void ScriptDebuggerRemote::_put_variable(const String &p_name, const Variant &p_ packet_peer_stream->put_var(p_name); int len = 0; Error err = encode_variant(p_variable, NULL, len); + if (err != OK) + ERR_PRINT("Failed to encode variant"); + if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size packet_peer_stream->put_var(Variant()); } else { diff --git a/core/script_language.cpp b/core/script_language.cpp index bde80a30bc..5ead91f26e 100644 --- a/core/script_language.cpp +++ b/core/script_language.cpp @@ -184,7 +184,6 @@ void ScriptInstance::call_multilevel(const StringName &p_method, VARIANT_ARG_DEC argc++; } - Variant::CallError error; call_multilevel(p_method, argptr, argc); } diff --git a/core/script_language.h b/core/script_language.h index 342d8c8072..2261737f9a 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -206,6 +206,7 @@ public: virtual int find_function(const String &p_function, const String &p_code) const = 0; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const = 0; virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } + virtual bool overrides_external_editor() { return false; } virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } diff --git a/core/set.h b/core/set.h index 317e180869..f68d78cea1 100644 --- a/core/set.h +++ b/core/set.h @@ -438,8 +438,9 @@ private: if (!rp) rp = _data._nil; Element *node = (rp->left == _data._nil) ? rp->right : rp->left; + node->parent = rp->parent; - if (_data._root == (node->parent = rp->parent)) { + if (_data._root == node->parent) { _data._root->left = node; } else { if (rp == rp->parent->left) { diff --git a/core/string_buffer.cpp b/core/string_buffer.cpp new file mode 100644 index 0000000000..195068f887 --- /dev/null +++ b/core/string_buffer.cpp @@ -0,0 +1,102 @@ +/*************************************************************************/ +/* string_buffer.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 "string_buffer.h" + +#include <string.h> + +StringBuffer &StringBuffer::append(CharType p_char) { + reserve(string_length + 2); + current_buffer_ptr()[string_length++] = p_char; + return *this; +} + +StringBuffer &StringBuffer::append(const String &p_string) { + return append(p_string.c_str()); +} + +StringBuffer &StringBuffer::append(const char *p_str) { + int len = strlen(p_str); + reserve(string_length + len + 1); + + CharType *buf = current_buffer_ptr(); + for (const char *c_ptr = p_str; c_ptr; ++c_ptr) { + buf[string_length++] = *c_ptr; + } + return *this; +} + +StringBuffer &StringBuffer::append(const CharType *p_str, int p_clip_to_len) { + int len = 0; + while ((p_clip_to_len < 0 || len < p_clip_to_len) && p_str[len]) { + ++len; + } + reserve(string_length + len + 1); + memcpy(&(current_buffer_ptr()[string_length]), p_str, len * sizeof(CharType)); + string_length += len; + + return *this; +} + +StringBuffer &StringBuffer::reserve(int p_size) { + if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size()) + return *this; + + bool need_copy = string_length > 0 && buffer.empty(); + buffer.resize(next_power_of_2(p_size)); + if (need_copy) { + memcpy(buffer.ptr(), short_buffer, string_length * sizeof(CharType)); + } + + return *this; +} + +int StringBuffer::length() const { + return string_length; +} + +String StringBuffer::as_string() { + current_buffer_ptr()[string_length] = '\0'; + if (buffer.empty()) { + return String(short_buffer); + } else { + buffer.resize(string_length + 1); + return buffer; + } +} + +double StringBuffer::as_double() { + current_buffer_ptr()[string_length] = '\0'; + return String::to_double(current_buffer_ptr()); +} + +int64_t StringBuffer::as_int() { + current_buffer_ptr()[string_length] = '\0'; + return String::to_int(current_buffer_ptr()); +} diff --git a/core/string_buffer.h b/core/string_buffer.h new file mode 100644 index 0000000000..3f36249148 --- /dev/null +++ b/core/string_buffer.h @@ -0,0 +1,82 @@ +/*************************************************************************/ +/* string_buffer.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 STRING_BUFFER_H +#define STRING_BUFFER_H + +#include "ustring.h" + +class StringBuffer { + static const int SHORT_BUFFER_SIZE = 64; + + CharType short_buffer[SHORT_BUFFER_SIZE]; + String buffer; + int string_length = 0; + + _FORCE_INLINE_ CharType *current_buffer_ptr() { + return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptr(); + } + +public: + StringBuffer &append(CharType p_char); + StringBuffer &append(const String &p_string); + StringBuffer &append(const char *p_str); + StringBuffer &append(const CharType *p_str, int p_clip_to_len = -1); + + _FORCE_INLINE_ void operator+=(CharType p_char) { + append(p_char); + } + + _FORCE_INLINE_ void operator+=(const String &p_string) { + append(p_string); + } + + _FORCE_INLINE_ void operator+=(const char *p_str) { + append(p_str); + } + + _FORCE_INLINE_ void operator+=(const CharType *p_str) { + append(p_str); + } + + StringBuffer &reserve(int p_size); + + int length() const; + + String as_string(); + + double as_double(); + int64_t as_int(); + + _FORCE_INLINE_ operator String() { + return as_string(); + } +}; + +#endif diff --git a/core/string_builder.cpp b/core/string_builder.cpp new file mode 100644 index 0000000000..18c710ed2d --- /dev/null +++ b/core/string_builder.cpp @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* string_builder.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 "string_builder.h" + +#include <string.h> + +StringBuilder &StringBuilder::append(const String &p_string) { + + strings.push_back(p_string); + appended_strings.push_back(-1); + + string_length += p_string.length(); + + return *this; +} + +StringBuilder &StringBuilder::append(const char *p_cstring) { + + int32_t len = strlen(p_cstring); + + c_strings.push_back(p_cstring); + appended_strings.push_back(len); + + string_length += len; + + return *this; +} + +String StringBuilder::as_string() const { + + CharType *buffer = memnew_arr(CharType, string_length); + + int current_position = 0; + + int godot_string_elem = 0; + int c_string_elem = 0; + + for (int i = 0; i < appended_strings.size(); i++) { + if (appended_strings[i] == -1) { + // Godot string + const String &s = strings[godot_string_elem]; + + memcpy(buffer + current_position, s.ptr(), s.length() * sizeof(CharType)); + + current_position += s.length(); + + godot_string_elem++; + } else { + + const char *s = c_strings[c_string_elem]; + + for (int32_t j = 0; j < appended_strings[i]; j++) { + buffer[current_position + j] = s[j]; + } + + current_position += appended_strings[i]; + + c_string_elem++; + } + } + + String final_string = String(buffer, string_length); + + memdelete_arr(buffer); + + return final_string; +} diff --git a/scene/gui/button_group.h b/core/string_builder.h index 6ebc0575d2..7cf2f07872 100644 --- a/scene/gui/button_group.h +++ b/core/string_builder.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* button_group.h */ +/* string_builder.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,42 +27,53 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef BUTTON_GROUP_H -#define BUTTON_GROUP_H +#ifndef STRING_BUILDER_H +#define STRING_BUILDER_H -#include "scene/gui/box_container.h" +#include "core/ustring.h" -#if 0 -class BaseButton; +#include "core/vector.h" -class ButtonGroup : public BoxContainer { +class StringBuilder { - GDCLASS(ButtonGroup,BoxContainer); + uint32_t string_length = 0; + Vector<String> strings; + Vector<const char *> c_strings; - Set<BaseButton*> buttons; + // -1 means it's a Godot String + // a natural number means C string. + Vector<int32_t> appended_strings; +public: + StringBuilder &append(const String &p_string); + StringBuilder &append(const char *p_cstring); - Array _get_button_list() const; - void _pressed(Object *p_button); + _FORCE_INLINE_ StringBuilder &operator+(const String &p_string) { + return append(p_string); + } -protected: -friend class BaseButton; + _FORCE_INLINE_ StringBuilder &operator+(const char *p_cstring) { + return append(p_cstring); + } - void _add_button(BaseButton *p_button); - void _remove_button(BaseButton *p_button); + _FORCE_INLINE_ void operator+=(const String &p_string) { + append(p_string); + } - static void _bind_methods(); -public: + _FORCE_INLINE_ void operator+=(const char *p_cstring) { + append(p_cstring); + } + + _FORCE_INLINE_ int num_strings_appended() const { + return appended_strings.size(); + } - void get_button_list(List<BaseButton*> *p_buttons) const; - BaseButton *get_pressed_button() const; - BaseButton *get_focused_button() const; - void set_pressed_button(BaseButton *p_button); - int get_pressed_button_index() const; + String as_string() const; - ButtonGroup(); + _FORCE_INLINE_ operator String() const { + return as_string(); + } }; -#endif -#endif // BUTTON_GROUP_H +#endif // STRING_BUILDER_H diff --git a/core/type_info.h b/core/type_info.h index da6047450c..9fb80af0eb 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -39,28 +39,27 @@ struct TypeInherits { template <class T, typename = void> struct GetTypeInfo { - enum { VARIANT_TYPE = Variant::NIL }; - + static const Variant::Type VARIANT_TYPE = Variant::NIL; static inline PropertyInfo get_class_info() { ERR_PRINT("GetTypeInfo fallback. Bug!"); return PropertyInfo(); // Not "Nil", this is an error } }; -#define MAKE_TYPE_INFO(m_type, m_var_type) \ - template <> \ - struct GetTypeInfo<m_type> { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \ - } \ - }; \ - template <> \ - struct GetTypeInfo<const m_type &> { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \ - } \ +#define MAKE_TYPE_INFO(m_type, m_var_type) \ + template <> \ + struct GetTypeInfo<m_type> { \ + static const Variant::Type VARIANT_TYPE = m_var_type; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, String()); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<const m_type &> { \ + static const Variant::Type VARIANT_TYPE = m_var_type; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, String()); \ + } \ }; MAKE_TYPE_INFO(bool, Variant::BOOL) @@ -108,14 +107,14 @@ MAKE_TYPE_INFO(BSP_Tree, Variant::DICTIONARY) //for RefPtr template <> struct GetTypeInfo<RefPtr> { - enum { VARIANT_TYPE = Variant::OBJECT }; + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference"); } }; template <> struct GetTypeInfo<const RefPtr &> { - enum { VARIANT_TYPE = Variant::OBJECT }; + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::OBJECT, String(), PROPERTY_HINT_RESOURCE_TYPE, "Reference"); } @@ -124,7 +123,7 @@ struct GetTypeInfo<const RefPtr &> { //for variant template <> struct GetTypeInfo<Variant> { - enum { VARIANT_TYPE = Variant::NIL }; + static const Variant::Type VARIANT_TYPE = Variant::NIL; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } @@ -132,26 +131,26 @@ struct GetTypeInfo<Variant> { template <> struct GetTypeInfo<const Variant &> { - enum { VARIANT_TYPE = Variant::NIL }; + static const Variant::Type VARIANT_TYPE = Variant::NIL; static inline PropertyInfo get_class_info() { return PropertyInfo(Variant::NIL, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT); } }; -#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \ - template <> \ - struct GetTypeInfo<m_template<m_type> > { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \ - } \ - }; \ - template <> \ - struct GetTypeInfo<const m_template<m_type> &> { \ - enum { VARIANT_TYPE = m_var_type }; \ - static inline PropertyInfo get_class_info() { \ - return PropertyInfo((Variant::Type)VARIANT_TYPE, String()); \ - } \ +#define MAKE_TEMPLATE_TYPE_INFO(m_template, m_type, m_var_type) \ + template <> \ + struct GetTypeInfo<m_template<m_type> > { \ + static const Variant::Type VARIANT_TYPE = m_var_type; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, String()); \ + } \ + }; \ + template <> \ + struct GetTypeInfo<const m_template<m_type> &> { \ + static const Variant::Type VARIANT_TYPE = m_var_type; \ + static inline PropertyInfo get_class_info() { \ + return PropertyInfo(VARIANT_TYPE, String()); \ + } \ }; MAKE_TEMPLATE_TYPE_INFO(Vector, uint8_t, Variant::POOL_BYTE_ARRAY) @@ -171,8 +170,7 @@ MAKE_TEMPLATE_TYPE_INFO(PoolVector, Face3, Variant::POOL_VECTOR3_ARRAY) template <typename T> struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> { - enum { VARIANT_TYPE = Variant::OBJECT }; - + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(StringName(T::get_class_static())); } @@ -180,8 +178,7 @@ struct GetTypeInfo<T *, typename EnableIf<TypeInherits<Object, T>::value>::type> template <typename T> struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>::type> { - enum { VARIANT_TYPE = Variant::OBJECT }; - + static const Variant::Type VARIANT_TYPE = Variant::OBJECT; static inline PropertyInfo get_class_info() { return PropertyInfo(StringName(T::get_class_static())); } @@ -190,7 +187,7 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>: #define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \ template <> \ struct GetTypeInfo<m_impl> { \ - enum { VARIANT_TYPE = Variant::INT }; \ + static const Variant::Type VARIANT_TYPE = Variant::INT; \ static inline PropertyInfo get_class_info() { \ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, String(#m_enum).replace("::", ".")); \ } \ diff --git a/core/variant_call.cpp b/core/variant_call.cpp index ad15f8f5cb..19d9b0297f 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -428,8 +428,8 @@ struct _VariantCall { VCALL_LOCALMEM2R(Quat, slerpni); VCALL_LOCALMEM4R(Quat, cubic_slerp); - VCALL_LOCALMEM0R(Color, to_32); - VCALL_LOCALMEM0R(Color, to_ARGB32); + VCALL_LOCALMEM0R(Color, to_rgba32); + VCALL_LOCALMEM0R(Color, to_argb32); VCALL_LOCALMEM0R(Color, gray); VCALL_LOCALMEM0R(Color, inverted); VCALL_LOCALMEM0R(Color, contrasted); @@ -481,6 +481,7 @@ struct _VariantCall { VCALL_LOCALMEM1(Array, erase); VCALL_LOCALMEM0(Array, sort); VCALL_LOCALMEM2(Array, sort_custom); + VCALL_LOCALMEM0R(Array, duplicate); VCALL_LOCALMEM0(Array, invert); static void _call_PoolByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) { @@ -1523,8 +1524,8 @@ void register_variant_methods() { ADDFUNC2(QUAT, QUAT, Quat, slerpni, QUAT, "b", REAL, "t", varray()); ADDFUNC4(QUAT, QUAT, Quat, cubic_slerp, QUAT, "b", QUAT, "pre_a", QUAT, "post_b", REAL, "t", varray()); - ADDFUNC0(COLOR, INT, Color, to_32, varray()); - ADDFUNC0(COLOR, INT, Color, to_ARGB32, varray()); + ADDFUNC0(COLOR, INT, Color, to_rgba32, varray()); + ADDFUNC0(COLOR, INT, Color, to_argb32, varray()); ADDFUNC0(COLOR, REAL, Color, gray, varray()); ADDFUNC0(COLOR, COLOR, Color, inverted, varray()); ADDFUNC0(COLOR, COLOR, Color, contrasted, varray()); @@ -1575,6 +1576,7 @@ void register_variant_methods() { ADDFUNC0(ARRAY, NIL, Array, sort, varray()); ADDFUNC2(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray()); ADDFUNC0(ARRAY, NIL, Array, invert, varray()); + ADDFUNC0(ARRAY, ARRAY, Array, duplicate, varray()); ADDFUNC0(POOL_BYTE_ARRAY, INT, PoolByteArray, size, varray()); ADDFUNC2(POOL_BYTE_ARRAY, NIL, PoolByteArray, set, INT, "idx", INT, "byte", varray()); @@ -1621,7 +1623,7 @@ void register_variant_methods() { ADDFUNC2(POOL_STRING_ARRAY, INT, PoolStringArray, insert, INT, "idx", STRING, "string", varray()); ADDFUNC1(POOL_STRING_ARRAY, NIL, PoolStringArray, resize, INT, "idx", varray()); ADDFUNC0(POOL_STRING_ARRAY, NIL, PoolStringArray, invert, varray()); - ADDFUNC1(POOL_STRING_ARRAY, STRING, PoolStringArray, join, STRING, "string", varray()); + ADDFUNC1(POOL_STRING_ARRAY, STRING, PoolStringArray, join, STRING, "delimiter", varray()); ADDFUNC0(POOL_VECTOR2_ARRAY, INT, PoolVector2Array, size, varray()); ADDFUNC2(POOL_VECTOR2_ARRAY, NIL, PoolVector2Array, set, INT, "idx", VECTOR2, "vector2", varray()); diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 65c7b7cfec..d60d10cd3a 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "variant_parser.h" +#include "core/string_buffer.h" #include "io/resource_loader.h" #include "os/input_event.h" #include "os/keyboard.h" @@ -176,14 +177,15 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri }; case '#': { - String color_str = "#"; + StringBuffer color_str; + color_str += '#'; while (true) { CharType ch = p_stream->get_char(); if (p_stream->is_eof()) { r_token.type = TK_EOF; return OK; } else if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) { - color_str += String::chr(ch); + color_str += ch; } else { p_stream->saved = ch; @@ -191,7 +193,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri } } - r_token.value = Color::html(color_str); + r_token.value = Color::html(color_str.as_string()); r_token.type = TK_COLOR; return OK; }; @@ -296,7 +298,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (cchar == '-' || (cchar >= '0' && cchar <= '9')) { //a number - String num; + StringBuffer num; #define READING_SIGN 0 #define READING_INT 1 #define READING_DEC 2 @@ -359,7 +361,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri if (reading == READING_DONE) break; - num += String::chr(c); + num += c; c = p_stream->get_char(); } @@ -368,19 +370,19 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri r_token.type = TK_NUMBER; if (is_float) - r_token.value = num.to_double(); + r_token.value = num.as_double(); else - r_token.value = num.to_int(); + r_token.value = num.as_int(); return OK; } else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') { - String id; + StringBuffer id; bool first = true; while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) { - id += String::chr(cchar); + id += cchar; cchar = p_stream->get_char(); first = false; } @@ -388,7 +390,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri p_stream->saved = cchar; r_token.type = TK_IDENTIFIER; - r_token.value = id; + r_token.value = id.as_string(); return OK; } else { r_err_str = "Unexpected character."; diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 96d515de5e..a8e877ccd5 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -20,7 +20,14 @@ <argument index="3" name="a8" type="int"> </argument> <description> - Make a color from red, green, blue and alpha. Arguments can range from 0 to 255. + Returns a 32 bit color with red, green, blue and alpha channels. Each channel has 8bits of information ranging from 0 to 255. + 'r8' red channel + 'g8' green channel + 'b8' blue channel + 'a8' alpha channel + [codeblock] + red = Color8(255, 0, 0) + [/codeblock] </description> </method> <method name="ColorN"> @@ -31,6 +38,10 @@ <argument index="1" name="alpha" type="float"> </argument> <description> + Returns color 'name' with alpha ranging from 0 to 1. Note: 'name' is defined in color_names.inc. + [codeblock] + red = ColorN('red') + [/codeblock] </description> </method> <method name="abs"> @@ -39,7 +50,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the absolute value of parameter s (i.e. unsigned value, works for integer and float). + Returns the absolute value of parameter 's' (i.e. unsigned value, works for integer and float). + [codeblock] + # a is 1 + a = abs(-1) + [/codeblock] </description> </method> <method name="acos"> @@ -48,7 +63,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the principal value of the arc cosine of s, expressed in radians. In trigonometrics, arc cosine is the inverse operation of cosine. + Returns the arc cosine of 's' in radians. Use to get the angle of cosine 's'. + [codeblock] + # c is 0.523599 or 30 degrees if converted with rad2deg(s) + c = acos(0.866025) + [/codeblock] </description> </method> <method name="asin"> @@ -57,7 +76,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the principal value of the arc sine of s, expressed in radians. In trigonometrics, arc sine is the inverse operation of sine. + Returns the arc sine of 's' in radians. Use to get the angle of sine 's'. + [codeblock] + # s is 0.523599 or 30 degrees if converted with rad2deg(s) + s = asin(0.5) + [/codeblock] </description> </method> <method name="assert"> @@ -66,7 +89,18 @@ <argument index="0" name="condition" type="bool"> </argument> <description> - Assert that the condition is true. If the condition is false, generates an error. + Assert that the condition is true. If the condition is false a fatal error is generated and the program is halted. + Useful for debugging to make sure a value is always true. + [codeblock] + # Speed should always be between 0 and 20 + speed = -10 + # Is true + assert(speed < 20) + # Is false and program stops + assert(speed >= 0) + # or simply + assert(speed >= 0 && speed < 20) + [/codeblock] </description> </method> <method name="atan"> @@ -75,7 +109,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the principal value of the arc tangent of s, expressed in radians. In trigonometrics, arc tangent is the inverse operation of tangent. Notice that because of the sign ambiguity, the function cannot determine with certainty in which quadrant the angle falls only by its tangent value. See [method atan2] for an alternative that takes a fractional argument instead. + Returns the arc tangent of 's' in radians. Use to get the angle of tangent 's'. Notice that because of the sign ambiguity, the function cannot determine with certainty in which quadrant the angle falls only by its tangent value. See [method atan2] for an alternative that takes a fractional argument instead. + [codeblock] + # a is 0.463648 + a = atan(0.5) + [/codeblock] </description> </method> <method name="atan2"> @@ -86,7 +124,11 @@ <argument index="1" name="y" type="float"> </argument> <description> - Returns the principal value of the arc tangent of y/x, expressed in radians. To compute the value, the function takes into account the sign of both arguments in order to determine the quadrant. + Returns the arc tangent of y/x in radians. Use to get the angle of tangent y/x. To compute the value, the function takes into account the sign of both arguments in order to determine the quadrant. + [codeblock] + # a is 3.141593 + a = atan(0,-1) + [/codeblock] </description> </method> <method name="bytes2var"> @@ -104,7 +146,13 @@ <argument index="0" name="s" type="float"> </argument> <description> - Rounds s upward, returning the smallest integral value that is not less than s. + Rounds 's' upward, returning the smallest integral value that is not less than 's'. + [codeblock] + # i is 2 + i = ceil(1.45) + # i is 2 + i = ceil(1.001) + [/codeblock] </description> </method> <method name="char"> @@ -113,6 +161,13 @@ <argument index="0" name="ascii" type="int"> </argument> <description> + Returns a character as String of the given ASCII code. + [codeblock] + # a is 'A' + a = char(65) + # a is 'a' + a = char(65+32) + [/codeblock] </description> </method> <method name="clamp"> @@ -125,7 +180,16 @@ <argument index="2" name="max" type="float"> </argument> <description> - Clamps a value between a minimum and maximum value. + Clamp 'val' and return a value not less than 'min' and not more than 'max'. + [codeblock] + speed = 1000 + # a is 20 + a = clamp(speed, 1, 20) + + speed = -10 + # a is 1 + a = clamp(speed, 1, 20) + [/codeblock] </description> </method> <method name="convert"> @@ -137,6 +201,15 @@ </argument> <description> Convert from a type to another in the best way possible. The "type" parameter uses the enum TYPE_* in [@Global Scope]. + [codeblock] + a = Vector2(1, 0) + # prints 1 + print(a.length()) + a = convert(a, TYPE_STRING) + # prints 6 + # (1, 0) is 6 characters + print(a.length()) + [/codeblock] </description> </method> <method name="cos"> @@ -145,7 +218,12 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the cosine of an angle of s radians. + Returns the cosine of angle 's' in radians. + [codeblock] + # prints 1 and -1 + print(cos(PI*2)) + print(cos(PI)) + [/codeblock] </description> </method> <method name="cosh"> @@ -154,7 +232,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the hyperbolic cosine of s. + Returns the hyperbolic cosine of 's' in radians. + [codeblock] + # prints 1.543081 + print(cosh(1)) + [/codeblock] </description> </method> <method name="db2linear"> @@ -172,7 +254,11 @@ <argument index="0" name="step" type="float"> </argument> <description> - Return the amount of decimals in the floating point value. + Returns the number of digit places after the decimal that the first non-zero digit occurs. + [codeblock] + # n is 2 + n = decimals(0.035) + [/codeblock] </description> </method> <method name="dectime"> @@ -185,7 +271,11 @@ <argument index="2" name="step" type="float"> </argument> <description> - Decreases time by a specified amount. + Returns the result of 'value' decreased by 'step' * 'amount'. + [codeblock] + # a = 59 + a = dectime(60, 10, 0.1)) + [/codeblock] </description> </method> <method name="deg2rad"> @@ -194,7 +284,11 @@ <argument index="0" name="deg" type="float"> </argument> <description> - Convert from degrees to radians. + Returns degrees converted to radians. + [codeblock] + # r is 3.141593 + r = deg2rad(180) + [/codeblock] </description> </method> <method name="dict2inst"> @@ -203,7 +297,7 @@ <argument index="0" name="dict" type="Dictionary"> </argument> <description> - Convert a previously converted instances to dictionary back into an instance. Useful for deserializing. + Convert a previously converted instance to dictionary back into an instance. Useful for deserializing. </description> </method> <method name="ease"> @@ -223,8 +317,12 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns the base-e exponential function of s, which is e raised to the power s: e^s. + Returns [b]e[/b] raised to the power of 's'. [b]e[/b] sometimes called "Euler's number" is a mathematical constant whose value is approximately 2.71828. </description> + [codeblock] + # a is 2.71828 + a = exp(2) + [/codeblock] </method> <method name="floor"> <return type="float"> @@ -232,8 +330,14 @@ <argument index="0" name="s" type="float"> </argument> <description> - Rounds s downward, returning the largest integral value that is not greater than s. + Returns the largest integer value (rounded down) that is less than or equal to 's'. </description> + [codeblock] + # a is 2 + a = floor(2.99) + # a is -3 + a = floor(-2.99) + [/codeblock] </method> <method name="fmod"> <return type="float"> @@ -258,7 +362,26 @@ <argument index="1" name="y" type="float"> </argument> <description> - Module (remainder of x/y) that wraps equally in positive and negative. + Returns the floating-point remainder of x/y that wraps equally in positive and negative. + [codeblock] + var i = -10; + while i < 0: + prints(i, fposmod(i, 10)) + i += 1 + [/codeblock] + Produces: + [codeblock] + -10 10 + -9 1 + -8 2 + -7 3 + -6 4 + -5 5 + -4 6 + -3 7 + -2 8 + -1 9 + [/codeblock] </description> </method> <method name="funcref"> @@ -269,7 +392,15 @@ <argument index="1" name="funcname" type="String"> </argument> <description> - Return a reference to the specified function. + Returns a reference to the specified function 'funcname' in object 'instance'. + [codeblock] + a = funcref(self, "foo") + a.call_func() + + func foo(): + print("bar") + [/codeblock] + Prints out "bar". This is a trivial example, the real power is that variable 'a' can be passed around to functions. </description> </method> <method name="hash"> @@ -278,7 +409,11 @@ <argument index="0" name="var" type="Variant"> </argument> <description> - Hash the variable passed and return an integer. + Returns the integer hash of the variable passed. + [codeblock] + # print 177670 + print(hash("a")) + [/codeblock] </description> </method> <method name="inst2dict"> @@ -287,7 +422,19 @@ <argument index="0" name="inst" type="Object"> </argument> <description> - Convert a script class instance to a dictionary (useful for serializing). + Returns the passed instance converted a dictionary (useful for serializing). + [codeblock] + var foo = "bar" + func _ready(): + var d = inst2dict(self) + print(d.keys()) + print(d.values()) + [/codeblock] + Prints out: + [codeblock] + [@subpath, @path, foo] + [, res://test.gd, bar] + [/codeblock] </description> </method> <method name="instance_from_id"> @@ -296,7 +443,15 @@ <argument index="0" name="instance_id" type="int"> </argument> <description> - Get an object by its ID. + Returns the Object that corresponds to 'instance_id'. All Objects have a unique instance ID. + [codeblock] + var foo = "bar" + func _ready(): + var id = get_instance_id() + var inst = instance_from_id(id) + print(inst.foo) + [/codeblock] + Prints "bar" </description> </method> <method name="inverse_lerp"> @@ -309,6 +464,10 @@ <argument index="2" name="value" type="float"> </argument> <description> + Returns a normalized value considering the given range. + [codeblock] + inverse_lerp(3, 5, 4) # return 0.5 + [/codeblock] </description> </method> <method name="is_inf"> @@ -317,7 +476,7 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns whether s is an infinity value (either positive infinity or negative infinity). + Returns True/False whether 's' is an infinity value (either positive infinity or negative infinity). </description> </method> <method name="is_nan"> @@ -326,7 +485,7 @@ <argument index="0" name="s" type="float"> </argument> <description> - Returns whether s is a NaN (Not-A-Number) value. + Returns True/False whether 's' is a NaN (Not-A-Number) value. </description> </method> <method name="len"> @@ -335,6 +494,16 @@ <argument index="0" name="var" type="Variant"> </argument> <description> +<<<<<<< HEAD + Returns length of Variant 'var'. Length is the character count of String, element count of Array, size of Dictionary, etc. Note: Generates a fatal error if Variant can not provide a length. +======= + Returns length of Variant 'var'. Length is the element count of an Array, size of a Dictionary, etc. Note: Generates a fatal error if Variant can not provide a length. +>>>>>>> 75b92e809dc95aefd3afab5a9efbd582a1a8d953 + [codeblock] + a = [1, 2, 3, 4] + print(len(a)) + [/codeblock] + Prints 4 </description> </method> <method name="lerp"> @@ -365,7 +534,11 @@ <argument index="0" name="path" type="String"> </argument> <description> - Load a resource from the filesystem, pass a valid path as argument. + Load a resource from the filesystem located at 'path'. Note: resource paths can be obtained by right clicking on a resource in the Assets Pannel and choosing "Copy Path". + [codeblock] + # load a scene called main located in the root of the project directory + var main = load("res://main.tscn") + [/codeblock] </description> </method> <method name="log"> @@ -374,7 +547,11 @@ <argument index="0" name="s" type="float"> </argument> <description> - Natural logarithm. + Natural logarithm. The amount of time needed to reach a certain level of continuous growth. Note: This is not the same as the log funcation on your calculator which is a base 10 logarithm. + [codeblock] + # a is 2.302585 + a = log(10) + [/codeblock] </description> </method> <method name="max"> @@ -385,7 +562,13 @@ <argument index="1" name="b" type="float"> </argument> <description> - Return the maximum of two values. + Returns the maximum of two values. + [codeblock] + # a is 2 + a = max(1,2) + # a is -3.99 + a = max(-3.99, -4) + [/codeblock] </description> </method> <method name="min"> @@ -396,7 +579,13 @@ <argument index="1" name="b" type="float"> </argument> <description> - Return the minimum of two values. + Returns the minimum of two values. + [codeblock] + # a is 1 + a = min(1,2) + # a is -4 + a = min(-3.99, -4) + [/codeblock] </description> </method> <method name="nearest_po2"> @@ -405,7 +594,15 @@ <argument index="0" name="val" type="int"> </argument> <description> - Return the nearest larger power of 2 for an integer. + Returns the nearest larger power of 2 for an integer. + [codeblock] + # a is 4 + a = nearest_po2(3) + # a is 4 + a = nearest_po2(4) + # a is 8 + a = nearest_po2(5) + [/codeblock] </description> </method> <method name="parse_json"> @@ -416,6 +613,13 @@ <description> Parse JSON text to a Variant (use [method typeof] to check if it is what you expect). Be aware that the JSON specification does not define integer or float types, but only a number type. Therefore, parsing a JSON text will convert every numerical values to [float] types. + [codeblock] + p = parse_json('["a", "b", "c"]') + if typeof(p) == TYPE_ARRAY: + print(p[0]) + else: + print("unexpected results") + [/codeblock] </description> </method> <method name="pow"> @@ -426,7 +630,11 @@ <argument index="1" name="y" type="float"> </argument> <description> - Power function, x elevate to y. + Returns the result of 'x' raised to the power of 'y'. + [codeblock] + # a is 32 + a = pow(2,5) + [/codeblock] </description> </method> <method name="preload"> @@ -435,14 +643,22 @@ <argument index="0" name="path" type="String"> </argument> <description> - Preload a resource from the filesystem. The resource is loaded during script parsing. + Returns a resource from the filesystem that is loaded during script parsing. Note: resource paths can be obtained by right clicking on a resource in the Assets Pannel and choosing "Copy Path". + [codeblock] + # load a scene called main located in the root of the project directory + var main = preload("res://main.tscn") </description> </method> <method name="print" qualifiers="vararg"> <return type="void"> </return> <description> - Print one or more arguments to strings in the best way possible to a console line. + Converts one or more arguments to strings in the best way possible and prints them to the console. + [codeblock] + a = [1,2,3] + print("a","b",a) + [/codeblock] + Prints ab[1, 2, 3] </description> </method> <method name="print_stack"> @@ -551,6 +767,10 @@ <argument index="4" name="ostop" type="float"> </argument> <description> + Maps a value from range [istart, istop] to [ostart, ostop]. + [codeblock] + range_lerp(75, 0, 100, -1, 1) # returns 0.5 + [/codeblock] </description> </method> <method name="round"> @@ -667,6 +887,11 @@ <argument index="0" name="type" type="String"> </argument> <description> + Returns whether the given class is exist in [ClassDB]. + [codeblock] + type_exists("Sprite") # returns true + type_exists("Variant") # returns false + [/codeblock] </description> </method> <method name="typeof"> @@ -753,6 +978,7 @@ </methods> <members> <member name="ARVRServer" type="ARVRServer" setter="" getter="" brief=""> + [ARVRServer] singleton </member> <member name="AudioServer" type="AudioServer" setter="" getter="" brief=""> [AudioServer] singleton @@ -1944,18 +2170,25 @@ Variable is of type [Array]. </constant> <constant name="TYPE_RAW_ARRAY" value="20"> + Variable is of type [PoolByteArray]. </constant> <constant name="TYPE_INT_ARRAY" value="21"> + Variable is of type [PoolIntArray]. </constant> <constant name="TYPE_REAL_ARRAY" value="22"> + Variable is of type [PoolRealArray]. </constant> <constant name="TYPE_STRING_ARRAY" value="23"> + Variable is of type [PoolStringArray]. </constant> <constant name="TYPE_VECTOR2_ARRAY" value="24"> + Variable is of type [PoolVector2Array]. </constant> <constant name="TYPE_VECTOR3_ARRAY" value="25"> + Variable is of type [PoolVector3Array]. </constant> <constant name="TYPE_COLOR_ARRAY" value="26"> + Variable is of type [PoolColorArray]. </constant> <constant name="TYPE_MAX" value="27"> </constant> @@ -1983,32 +2216,40 @@ </class> <class name="ARVRAnchor" inherits="Spatial" category="Core"> <brief_description> + Anchor point in AR Space </brief_description> <description> + The ARVR Anchor point is a spatial node that maps a real world location identified by the AR platform to a position within the game world. For example, as long as plane detection in ARKit is on, ARKit will identify and update the position of planes (tables, floors, etc) and create anchors for them. + This node is mapped to one of the anchors through its unique id. When you receive a signal that a new anchor is available you should add this node to your scene for that anchor. You can predefine nodes and set the id and the nodes will simply remain on 0,0,0 until a plane is recognised. + Keep in mind that as long as plane detection is enable the size, placing and orientation of an anchor will be updates as the detection logic learns more about the real world out there especially if only part of the surface is in view. </description> <methods> <method name="get_anchor_id" qualifiers="const"> <return type="int"> </return> <description> + Returns the anchor id for this anchor. </description> </method> <method name="get_anchor_name" qualifiers="const"> <return type="String"> </return> <description> + Returns the name given to this anchor. </description> </method> <method name="get_is_active" qualifiers="const"> <return type="bool"> </return> <description> + Returns true if the anchor is being tracked and false if no anchor with this id is currently known. </description> </method> <method name="get_size" qualifiers="const"> <return type="Vector3"> </return> <description> + Returns the estimated size of the plane that was detected. Say when the anchor relates to a table in the real world, this is the estimated size of the surface of that table. </description> </method> <method name="set_anchor_id"> @@ -2017,6 +2258,7 @@ <argument index="0" name="anchor_id" type="int"> </argument> <description> + Binds this anchor node to an anchor with this id. You can set this before the anchor itself exists. The first anchor that is identified gets id 1, the second id 2, etc. When anchors get removed that slot remains free and can be assigned to the next anchor that is identified. The most common situation where anchors 'disappear' is when the AR server identifies that two anchors represent different parts of the same plane and merge them. </description> </method> </methods> @@ -2029,8 +2271,11 @@ </class> <class name="ARVRCamera" inherits="Camera" category="Core"> <brief_description> + A camera node with a few overrules for AR/VR applied such as location tracking. </brief_description> <description> + This is a helper spatial node for our camera, note that if stereoscopic rendering is applicable (VR-HMD) most of the camera properties are ignored as the HMD information overrides them. The only properties that can be trusted are the near and far planes. + The position and orientation of this node is automatically updated by the ARVR Server to represent the location of the HMD if such tracking is available and can thus be used by game logic. Note that in contrast to the ARVR Controller the render thread has access to the most up to date tracking data of the HMD and the location of the ARVRCamera can lag a few milliseconds behind what is used for rendering as a result. </description> <methods> </methods> @@ -2039,26 +2284,33 @@ </class> <class name="ARVRController" inherits="Spatial" category="Core"> <brief_description> + A spatial node representing a spatially tracked controller. </brief_description> <description> + This is a helper spatial node that is linked to the tracking of controllers. It also offers several handy pass throughs to the state of buttons and such on the controllers. + Controllers are linked by their id. You can create controller nodes before the controllers are available. Say your game always uses two controllers (one for each hand) you can predefine the controllers with id 1 and 2 and they will become active as soon as the controllers are identified. If you expect additional controllers to be used you should react to the signals and add ARVRController nodes to your scene. + The position of the controller node is automatically updated by the ARVR Server. This makes this node ideal to add child nodes to visualise the controller. </description> <methods> <method name="get_controller_id" qualifiers="const"> <return type="int"> </return> <description> + Returns the controller id currently assigned to this node. </description> </method> <method name="get_controller_name" qualifiers="const"> <return type="String"> </return> <description> + If active, returns the name of the associated controller if provided by the AR/VR SDK used. </description> </method> <method name="get_is_active" qualifiers="const"> <return type="bool"> </return> <description> + Returns true if the controller bound to this node is currently active and being tracked. </description> </method> <method name="get_joystick_axis" qualifiers="const"> @@ -2067,12 +2319,14 @@ <argument index="0" name="axis" type="int"> </argument> <description> + Returns the value of the given axis for things like triggers, touchpads, etc. that are embedded into the controller. </description> </method> <method name="get_joystick_id" qualifiers="const"> <return type="int"> </return> <description> + Returns the ID of the joystick object bound to this. Every controller tracked by the ARVR Server that has buttons and axis will also be registered as a joystick within Godot. This means that all the normal joystick tracking and input mapping will work for buttons and axis found on the AR/VR controllers. This ID is purely offered as information so you can link up the controller with its joystick entry. </description> </method> <method name="is_button_pressed" qualifiers="const"> @@ -2081,6 +2335,7 @@ <argument index="0" name="button" type="int"> </argument> <description> + Is the given button currently pressed? </description> </method> <method name="set_controller_id"> @@ -2089,6 +2344,7 @@ <argument index="0" name="controller_id" type="int"> </argument> <description> + Changes the id that identifies the controller bound to this node. The first controller that the ARVR Server detects will have id 1, the second id 2, the third id 3, etc. When a controller is turned off that slot is freed ensuring that controllers will keep the same id while it is turned on even when controllers with lower ids are turned off. </description> </method> </methods> @@ -2101,12 +2357,14 @@ <argument index="0" name="button" type="int"> </argument> <description> + When a button on this controller is pressed, this signal is given. </description> </signal> <signal name="button_release"> <argument index="0" name="button" type="int"> </argument> <description> + When a button on this controller is released, this signal is given. </description> </signal> </signals> @@ -2115,50 +2373,64 @@ </class> <class name="ARVRInterface" inherits="Reference" category="Core"> <brief_description> + Base class for ARVR interface implementation. </brief_description> <description> + This class needs to be implemented to make an AR or VR platform available to Godot and these should be implemented as C++ modules or GDNative modules (note that for GDNative the subclass ARVRScriptInterface should be used). Part of the interface is exposed to GDScript so you can detect, enable and configure an AR or VR platform. + Interfaces should be written in such a way that simply enabling them will give us a working setup. You can query the available interfaces through ARVRServer. </description> <methods> <method name="get_name" qualifiers="const"> <return type="String"> </return> <description> + Returns the name of this interface (OpenVR, OpenHMD, ARKit, etc). </description> </method> <method name="get_recommended_render_targetsize"> <return type="Vector2"> </return> <description> + Returns the resolution at which we should render our intermediate results before things like lens distortion are applied by the VR platform. </description> </method> <method name="hmd_is_present"> <return type="bool"> </return> <description> + Returns true if an HMD is available for this interface. </description> </method> <method name="initialize"> <return type="bool"> </return> <description> + Call this to initialize this interface. The first interface that is initialized is identified as the primary interface and it will be used for rendering output. + After initializing the interface you want to use you then need to enable the AR/VR mode of a viewport and rendering should commence. + Note that you must enable the AR/VR mode on the main viewport for any device that uses the main output of Godot such as for mobile VR. + If you do this for a platform that handles its own output (such as OpenVR) Godot will show just one eye without distortion on screen. Alternatively you can add a separate viewport node to your scene and enable AR/VR on that viewport and it will be used to output to the HMD leaving you free to do anything you like in the main window such as using a separate camera as a spectator camera or render out something completely different. + While currently not used you can activate additional interfaces, you may wish to do this if you want to track controllers from other platforms. However at this point in time only one interface can render to an HMD. </description> </method> <method name="is_initialized"> <return type="bool"> </return> <description> + Returns true if this interface is active. </description> </method> <method name="is_installed"> <return type="bool"> </return> <description> + Returns true if this interface has been installed. Say your game is designed to work with OpenVR so you are using the OpenVR interface but the user hasn't installed SteamVR, this would return false. </description> </method> <method name="is_primary"> <return type="bool"> </return> <description> + Returns true if this interface is currently the primary interface (the interface responsible for showing the output). </description> </method> <method name="set_is_primary"> @@ -2167,18 +2439,21 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + Set this interface to the primary interface (unset the old one). </description> </method> <method name="supports_hmd"> <return type="bool"> </return> <description> + Returns true if this interface supports HMDs and by extension uses stereo scopic rendering. </description> </method> <method name="uninitialize"> <return type="void"> </return> <description> + Turns the interface off. </description> </method> </methods> @@ -2188,23 +2463,32 @@ </members> <constants> <constant name="EYE_MONO" value="0"> + Mono output, this is mostly used internally when retrieving positioning information for our camera node or when stereo scopic rendering is not supported. </constant> <constant name="EYE_LEFT" value="1"> + Left eye output, this is mostly used internally when rendering the image for the left eye and obtaining positioning and projection information. </constant> <constant name="EYE_RIGHT" value="2"> + Right eye output, this is mostly used internally when rendering the image for the right eye and obtaining positioning and projection information. </constant> </constants> </class> <class name="ARVROrigin" inherits="Spatial" category="Core"> <brief_description> + Our origin point in AR/VR. </brief_description> <description> + This is a special node within the AR/VR system that maps the physical location of the center of our tracking space to the virtual location within our game world. + There should be only one of these nodes in your scene and you must have one. All the ARVRCamera, ARVRController and ARVRAnchor nodes should be direct children of this node for spatial tracking to work correctly. + It is the position of this node that you update when you're character needs to move through your game world while we're not moving in the real world. Movement in the real world is always in relation to this origin point. + So say that your character is driving a car, the ARVROrigin node should be a child node of this car. If you implement a teleport system to move your character, you change the position of this node. Etc. </description> <methods> <method name="get_world_scale" qualifiers="const"> <return type="float"> </return> <description> + Get the world scale applied to our positioning. </description> </method> <method name="set_world_scale"> @@ -2213,6 +2497,9 @@ <argument index="0" name="world_scale" type="float"> </argument> <description> + Changes the world scaling factor. + Most AR/VR platforms will assume a unit size of 1 unit in your game world = 1 meter in the real world. This scale allows you to adjust this to the unit system you use in your game. + Note that this method is a passthrough to the ARVRServer itself. </description> </method> </methods> @@ -2225,44 +2512,54 @@ </class> <class name="ARVRPositionalTracker" inherits="Object" category="Core"> <brief_description> + A tracked object </brief_description> <description> + An instance of this object represents a device that is tracked such as a controller or anchor point. HMDs aren't represented here as they are fully handled internally. + As controllers are turned on and the AR/VR interface detects them instances of this object are automatically added to this list of active tracking objects accessible through the ARVRServer + The ARVRController and ARVRAnchor both consume objects of this type and should be the objects you use in game. The positional trackers are just the under the hood objects that make this all work and are mostly exposed so GDNative based interfaces can interact with them. </description> <methods> <method name="get_joy_id" qualifiers="const"> <return type="int"> </return> <description> + If this is a controller that is being tracked the controller will also be represented by a joystick entry with this id. </description> </method> <method name="get_name" qualifiers="const"> <return type="String"> </return> <description> + If available this returns the name of the controller or anchor point. </description> </method> <method name="get_orientation" qualifiers="const"> <return type="Basis"> </return> <description> + Returns the orientation matrix of the controller. </description> </method> <method name="get_position" qualifiers="const"> <return type="Vector3"> </return> <description> + Returns the position of the controller adjusted by world scale. </description> </method> <method name="get_tracks_orientation" qualifiers="const"> <return type="bool"> </return> <description> + Returns true if the orientation of this device is being tracked. </description> </method> <method name="get_tracks_position" qualifiers="const"> <return type="bool"> </return> <description> + Returns true if the position of this device is being tracked. </description> </method> <method name="get_transform" qualifiers="const"> @@ -2271,12 +2568,14 @@ <argument index="0" name="adjust_by_reference_frame" type="bool"> </argument> <description> + Returns the transform combining the orientation and position of this device. </description> </method> <method name="get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="ARVRServer.TrackerType"> </return> <description> + Type of tracker. </description> </method> </methods> @@ -2285,14 +2584,17 @@ </class> <class name="ARVRScriptInterface" inherits="ARVRInterface" category="Core"> <brief_description> + Base class for GDNative based ARVR interfaces. </brief_description> <description> + This class is used as a base class/interface class for implementing GDNative based ARVR interfaces and as a result exposes more of the internals of the ARVR server. </description> <methods> <method name="_get_projection_for_eye" qualifiers="virtual"> <return type="void"> </return> <description> + Should return the projection 4x4 matrix for the requested eye. </description> </method> <method name="commit_for_eye" qualifiers="virtual"> @@ -2303,12 +2605,14 @@ <argument index="1" name="render_target" type="RID"> </argument> <description> + Outputs a finished render buffer to the AR/VR device for the given eye. </description> </method> <method name="get_recommended_render_targetsize" qualifiers="virtual"> <return type="Vector2"> </return> <description> + Returns the size at which we should render our scene to get optimal quality on the output device. </description> </method> <method name="get_transform_for_eye" qualifiers="virtual"> @@ -2319,54 +2623,63 @@ <argument index="1" name="cam_transform" type="Transform"> </argument> <description> + Get the location and orientation transform used when rendering a specific eye. </description> </method> <method name="hmd_is_present" qualifiers="virtual"> <return type="bool"> </return> <description> + Return true is an HMD is available. </description> </method> <method name="initialize" qualifiers="virtual"> <return type="bool"> </return> <description> + Initialize this interface. </description> </method> <method name="is_initialized" qualifiers="virtual"> <return type="bool"> </return> <description> + Returns true if this interface has been initialized and is active. </description> </method> <method name="is_installed" qualifiers="virtual"> <return type="bool"> </return> <description> + Returns true if the required middleware is installed. </description> </method> <method name="is_stereo" qualifiers="virtual"> <return type="bool"> </return> <description> + Returns true if we require stereoscopic rendering for this interface. </description> </method> <method name="process" qualifiers="virtual"> <return type="void"> </return> <description> + Gets called before rendering each frame so tracking data gets updated in time. </description> </method> <method name="supports_hmd" qualifiers="virtual"> <return type="bool"> </return> <description> + Returns true if this interface supports HMDs. </description> </method> <method name="uninitialize" qualifiers="virtual"> <return type="void"> </return> <description> + Turn this interface off. </description> </method> </methods> @@ -2375,8 +2688,10 @@ </class> <class name="ARVRServer" inherits="Object" category="Core"> <brief_description> + This is our AR/VR Server. </brief_description> <description> + The AR/VR Server is the heart of our AR/VR solution and handles all the processing. </description> <methods> <method name="add_interface"> @@ -2385,6 +2700,7 @@ <argument index="0" name="arg0" type="ARVRInterface"> </argument> <description> + Mostly exposed for GDNative based interfaces, this is called to register an available interface with the AR/VR server. </description> </method> <method name="find_interface" qualifiers="const"> @@ -2393,6 +2709,7 @@ <argument index="0" name="name" type="String"> </argument> <description> + Find an interface by its name. Say that you're making a game that uses specific capabilities of an AR/VR platform you can find the interface for that platform by name and initialize it. </description> </method> <method name="get_interface" qualifiers="const"> @@ -2401,18 +2718,21 @@ <argument index="0" name="idx" type="int"> </argument> <description> + Get the interface registered at a given index in our list of interfaces. </description> </method> <method name="get_interface_count" qualifiers="const"> <return type="int"> </return> <description> + Get the number of interfaces currently registered with the AR/VR server. If you're game supports multiple AR/VR platforms you can look throught the available interface and either present the user with a selection or simply try an initialize each interface and use the first one that returns true. </description> </method> <method name="get_reference_frame" qualifiers="const"> <return type="Transform"> </return> <description> + Gets our reference frame transform, mostly used internally and exposed for GDNative build interfaces. </description> </method> <method name="get_tracker" qualifiers="const"> @@ -2421,18 +2741,21 @@ <argument index="0" name="idx" type="int"> </argument> <description> + Get the positional tracker at the given ID. </description> </method> <method name="get_tracker_count" qualifiers="const"> <return type="int"> </return> <description> + Get the number of trackers currently registered. </description> </method> <method name="get_world_scale" qualifiers="const"> <return type="float"> </return> <description> + Returns our world scale (see ARVROrigin for more information). </description> </method> <method name="remove_interface"> @@ -2441,16 +2764,28 @@ <argument index="0" name="arg0" type="ARVRInterface"> </argument> <description> + Removes a registered interface, again exposed mostly for GDNative based interfaces. </description> </method> <method name="request_reference_frame"> <return type="void"> </return> <argument index="0" name="ignore_tilt" type="bool"> + If true we ignore the tilt of the device and we don't reset the tilt. This means that when the player is looking down we don't counter this and the player will still look down in game. If this is false the player will look straight ahead even when looking down. + The direction in which the player looks is centered so the player looks to negative Z regardless of where the player is looking in the real world. </argument> <argument index="1" name="keep_height" type="bool"> + This is a really important setting. When true we keep the height information given by our tracking. + You should set this to true when you are using room scale tracking and want your player to freely walk around the room, be able to crouch, etc. Your ARVROrigin should be placed on the floor of your scene in this scenario. + You should set this to false in all other situations. The current location of the HMD will become your 0,0,0 location and you should place your ARVROrigin point where your player currently is positioned. Use this when room scale is not available or when your making a driving or flying sim and you want to ensure the HMD is centered in your cockpit. </argument> <description> + This is a really important function to understand correctly. AR and VR platforms all handle positioning slightly differently. + For platforms that do not offer spatial tracking our origin point (0,0,0) is the location of our HMD but you have little control over the direction the player is facing in the real world. + For platforms that do offer spatial tracking our origin point depends very much on the system. For OpenVR our origin point is usually the center of the tracking space, on the ground. For other platforms its often the location of the tracking camera. + This method allows you to create a reference frame, it will take the current location of the HMD and use that to adjust all our tracking data in essence realigning the real world to your players current position in your game world. + For this method to produce usable results tracking information should be available and this often takes a few frames after starting your game. + You should call this method after a few seconds have passed, when the user requests a realignment of the display holding a designated button on a controller for a short period of time, and when implementing a teleport mechanism. </description> </method> <method name="set_primary_interface"> @@ -2459,6 +2794,7 @@ <argument index="0" name="arg0" type="ARVRInterface"> </argument> <description> + Changes the primary interface to the specified interface. Again mostly exposed for GDNative interfaces. </description> </method> <method name="set_world_scale"> @@ -2467,6 +2803,7 @@ <argument index="0" name="arg0" type="float"> </argument> <description> + Changing the world scale, see the ARVROrigin documentation for more information. </description> </method> </methods> @@ -2479,12 +2816,14 @@ <argument index="0" name="name" type="String"> </argument> <description> + Signal send when a new interface has been added. </description> </signal> <signal name="interface_removed"> <argument index="0" name="name" type="String"> </argument> <description> + Signal send when an interface is removed. </description> </signal> <signal name="tracker_added"> @@ -2493,27 +2832,35 @@ <argument index="1" name="type" type="int"> </argument> <description> + Signal send when a new tracker has been added. If you don't use a fixed number of controllers or if you're using ARVRAnchors for an AR solution it is important to react to this signal and add the appropriate ARVRController or ARVRAnchor node related to this new tracker. </description> </signal> <signal name="tracker_removed"> <argument index="0" name="name" type="String"> </argument> <description> + Signal send when a tracker is removed, you should remove any ARVRController or ARVRAnchor points if applicable. This is not mandatory, the nodes simply become inactive and will be made active again when a new tracker becomes available (i.e. a new controller is switched on that takes the place of the previous one). </description> </signal> </signals> <constants> <constant name="TRACKER_CONTROLLER" value="1"> + Our tracker tracks the location of a controller. </constant> <constant name="TRACKER_BASESTATION" value="2"> + Our tracker tracks the location of a base station. </constant> <constant name="TRACKER_ANCHOR" value="4"> + Our tracker tracks the location and size of an AR anchor. </constant> <constant name="TRACKER_UNKNOWN" value="128"> + Used internally if we haven't set the tracker type yet. </constant> <constant name="TRACKER_ANY_KNOWN" value="127"> + Used internally to filter trackers of any known type. </constant> <constant name="TRACKER_ANY" value="255"> + Used interally to select all trackers. </constant> </constants> </class> @@ -2534,6 +2881,7 @@ <argument index="1" name="to_id" type="int"> </argument> <description> + Called when computing the cost between two connected points. </description> </method> <method name="_estimate_cost" qualifiers="virtual"> @@ -2544,6 +2892,7 @@ <argument index="1" name="to_id" type="int"> </argument> <description> + Called when estimating the cost between a point and the path's ending point. </description> </method> <method name="add_point"> @@ -2553,10 +2902,15 @@ </argument> <argument index="1" name="pos" type="Vector3"> </argument> - <argument index="2" name="weight_scale" type="float" default="null"> + <argument index="2" name="weight_scale" type="float" default="1.0"> </argument> <description> - Add a new point at the given position [code]pos[/code] with the given identifier [code]id[/code]. The [code]weight_scale[/code] has to be 1 or larger. + Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger. + [codeblock] + var as = AStar.new() + + as.add_point(1, Vector3(1,0,0), 4) # Adds the point (1,0,0) with weight_scale=4 and id=1 + [/codeblock] </description> </method> <method name="are_points_connected" qualifiers="const"> @@ -2567,14 +2921,14 @@ <argument index="1" name="to_id" type="int"> </argument> <description> - Returns if there is a connection/segment between points [code]id[/code] and [code]from_id[/code] + Returns whether there is a connection/segment between the given points. </description> </method> <method name="clear"> <return type="void"> </return> <description> - Clear all the points and segments from AStar instance. + Clears all the points and segments. </description> </method> <method name="connect_points"> @@ -2584,10 +2938,19 @@ </argument> <argument index="1" name="to_id" type="int"> </argument> - <argument index="2" name="bidirectional" type="bool" default="null"> + <argument index="2" name="bidirectional" type="bool" default="true"> </argument> <description> - Create a segment between points [code]id[/code] and [code]to_id[/code]. + Creates a segment between the given points. + [codeblock] + var as = AStar.new() + + as.add_point(1, Vector3(1,1,0)) + as.add_point(2, Vector3(0,5,0)) + + as.connect_points(1, 2, false) # If bidirectional=false it's only possible to go from point 1 to point 2 + # and not from point 2 to point 1. + [/codeblock] </description> </method> <method name="disconnect_points"> @@ -2598,13 +2961,14 @@ <argument index="1" name="to_id" type="int"> </argument> <description> - Deletes a segment between points [code]id[/code] and [code]to_id[/code]. + Deletes the segment between the given points. </description> </method> <method name="get_available_point_id" qualifiers="const"> <return type="int"> </return> <description> + Returns an id with no point associated to it. </description> </method> <method name="get_closest_point" qualifiers="const"> @@ -2613,7 +2977,7 @@ <argument index="0" name="to_pos" type="Vector3"> </argument> <description> - Returns the id of closest point of given point. -1 is returned if there are no points on AStar. + Returns the id of the closest point to [code]to_pos[/code]. Returns -1 if there are no points in the points pool. </description> </method> <method name="get_closest_pos_in_segment" qualifiers="const"> @@ -2622,7 +2986,18 @@ <argument index="0" name="to_pos" type="Vector3"> </argument> <description> - Returns the position of closest point that has segments. + Returns the closest position to [code]to_pos[/code] that resides inside a segment between two connected points. + [codeblock] + var as = AStar.new() + + as.add_point(1, Vector3(0,0,0)) + as.add_point(2, Vector3(0,5,0)) + + as.connect_points(1, 2) + + var res = as.get_closest_pos_in_segment(Vector3(3,3,0)) # returns (0, 3, 0) + [/codeblock] + The result is in the segment that goes from [code]y=0[/code] to [code]y=5[/code]. It's the closest position in the segment to the given point. </description> </method> <method name="get_id_path"> @@ -2633,7 +3008,24 @@ <argument index="1" name="to_id" type="int"> </argument> <description> - Returns an array with the point ids of path found by AStar between two given points. + Returns an array with the ids of the points that form the path found by AStar between the given points. The array is ordered from the starting point to the ending point of the path. + [codeblock] + var as = AStar.new() + + as.add_point(1, Vector3(0,0,0)) + as.add_point(2, Vector3(0,1,0), 1) # default weight is 1 + as.add_point(3, Vector3(1,1,0)) + as.add_point(4, Vector3(2,0,0)) + + as.connect_points(1, 2, false) + as.connect_points(2, 3, false) + as.connect_points(4, 3, false) + as.connect_points(1, 4, false) + as.connect_points(5, 4, false) + + var res = as.get_id_path(1, 3) # returns [1, 2, 3] + [/codeblock] + If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2. </description> </method> <method name="get_point_path"> @@ -2644,7 +3036,7 @@ <argument index="1" name="to_id" type="int"> </argument> <description> - Returns an array with the points of path found by AStar between two given points. + Returns an array with the points that are in the path found by AStar between the given points. The array is ordered from the starting point to the ending point of the path. </description> </method> <method name="get_point_pos" qualifiers="const"> @@ -2653,7 +3045,7 @@ <argument index="0" name="id" type="int"> </argument> <description> - Returns the position of point with given id. + Returns the position of the point associated with the given id. </description> </method> <method name="get_point_weight_scale" qualifiers="const"> @@ -2662,7 +3054,7 @@ <argument index="0" name="id" type="int"> </argument> <description> - Returns the weight scale of point with given id. + Returns the weight scale of the point associated with the given id. </description> </method> <method name="has_point" qualifiers="const"> @@ -2671,7 +3063,7 @@ <argument index="0" name="id" type="int"> </argument> <description> - Returns if the point with given id exists on AStar; + Returns whether a point associated with the given id exists. </description> </method> <method name="remove_point"> @@ -2680,7 +3072,7 @@ <argument index="0" name="id" type="int"> </argument> <description> - Removes the point with given id. + Removes the point associated with the given id from the points pool. </description> </method> </methods> @@ -2702,7 +3094,7 @@ </argument> <argument index="1" name="right" type="bool" default="false"> </argument> - <argument index="2" name="action" type="String" default="null"> + <argument index="2" name="action" type="String" default=""""> </argument> <description> Add custom button to the dialog and return the created button. @@ -3086,7 +3478,7 @@ </return> <argument index="0" name="type" type="int" enum="Animation.TrackType"> </argument> - <argument index="1" name="at_pos" type="int" default="null"> + <argument index="1" name="at_pos" type="int" default="-1"> </argument> <description> Add a track to the Animation. The track type must be specified as any of the values in the TYPE_* enumeration. @@ -3214,7 +3606,7 @@ </argument> <argument index="1" name="time" type="float"> </argument> - <argument index="2" name="exact" type="bool" default="null"> + <argument index="2" name="exact" type="bool" default="false"> </argument> <description> Find the key index by time in a given track. Optionally, only find it if the exact time is given. @@ -3229,7 +3621,7 @@ </description> </method> <method name="track_get_interpolation_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Animation.InterpolationType"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -3289,7 +3681,7 @@ </description> </method> <method name="track_get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Animation.TrackType"> </return> <argument index="0" name="idx" type="int"> </argument> @@ -3306,7 +3698,7 @@ </argument> <argument index="2" name="key" type="Variant"> </argument> - <argument index="3" name="transition" type="float" default="null"> + <argument index="3" name="transition" type="float" default="1"> </argument> <description> Insert a generic key in a given track. @@ -3472,11 +3864,12 @@ </description> </method> <method name="value_track_get_update_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Animation.UpdateMode"> </return> <argument index="0" name="idx" type="int"> </argument> <description> + Return the update mode of a value track. </description> </method> <method name="value_track_set_update_mode"> @@ -3487,6 +3880,7 @@ <argument index="1" name="mode" type="int" enum="Animation.UpdateMode"> </argument> <description> + Set the update mode (UPDATE_*) of a value track. </description> </method> </methods> @@ -3510,10 +3904,13 @@ Cubic interpolation. </constant> <constant name="UPDATE_CONTINUOUS" value="0"> + Update between keyframes. </constant> <constant name="UPDATE_DISCRETE" value="1"> + Update at the keyframes and hold the value. </constant> <constant name="UPDATE_TRIGGER" value="2"> + Update at the keyframes. </constant> </constants> </class> @@ -3526,7 +3923,7 @@ </description> <methods> <method name="add_animation"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="name" type="String"> </argument> @@ -3551,6 +3948,7 @@ <argument index="0" name="anim_from" type="String"> </argument> <description> + Return the name of the next animation in the queue. </description> </method> <method name="animation_set_next"> @@ -3561,6 +3959,7 @@ <argument index="1" name="anim_to" type="String"> </argument> <description> + Set the name of an animation that will be played after. </description> </method> <method name="clear_caches"> @@ -3603,7 +4002,7 @@ </description> </method> <method name="get_animation_process_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="AnimationPlayer.AnimationProcessMode"> </return> <description> Return the mode in which the animation player processes. See [method set_animation_process_mode]. @@ -3702,13 +4101,13 @@ <method name="play"> <return type="void"> </return> - <argument index="0" name="name" type="String" default="false"> + <argument index="0" name="name" type="String" default=""""> </argument> - <argument index="1" name="custom_blend" type="float" default="1.0"> + <argument index="1" name="custom_blend" type="float" default="-1"> </argument> - <argument index="2" name="custom_speed" type="float" default="-1"> + <argument index="2" name="custom_speed" type="float" default="1.0"> </argument> - <argument index="3" name="from_end" type="bool" default=""""> + <argument index="3" name="from_end" type="bool" default="false"> </argument> <description> Play a given animation by the animation name. Custom speed and blend times can be set. If custom speed is negative (-1), 'from_end' being true can play the animation backwards. @@ -3717,9 +4116,9 @@ <method name="play_backwards"> <return type="void"> </return> - <argument index="0" name="name" type="String" default="-1"> + <argument index="0" name="name" type="String" default=""""> </argument> - <argument index="1" name="custom_blend" type="float" default=""""> + <argument index="1" name="custom_blend" type="float" default="-1"> </argument> <description> Play a given animation by the animation name in reverse. @@ -3759,7 +4158,7 @@ </return> <argument index="0" name="pos_sec" type="float"> </argument> - <argument index="1" name="update" type="bool" default="null"> + <argument index="1" name="update" type="bool" default="false"> </argument> <description> Seek the animation to a given position in time (in seconds). If 'update' is true, the animation will be updated too, otherwise it will be updated at process time. @@ -3933,6 +4332,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns an animation given its name. </description> </method> <method name="animation_node_get_master_animation" qualifiers="const"> @@ -3986,6 +4386,7 @@ <argument index="2" name="dst_input_idx" type="int"> </argument> <description> + Returns whether node [code]id[/code] and [code]dst_id[/code] are connected at the specified slot. </description> </method> <method name="blend2_node_get_amount" qualifiers="const"> @@ -3994,6 +4395,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns the blend amount of a Blend2 node given its name. </description> </method> <method name="blend2_node_set_amount"> @@ -4004,6 +4406,7 @@ <argument index="1" name="blend" type="float"> </argument> <description> + Sets the blend amount of a Blend2 node given its name and value. </description> </method> <method name="blend2_node_set_filter_path"> @@ -4024,6 +4427,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns the blend amount of a Blend3 node given its name. </description> </method> <method name="blend3_node_set_amount"> @@ -4034,6 +4438,7 @@ <argument index="1" name="blend" type="float"> </argument> <description> + Sets the blend amount of a Blend3 node given its name and value. </description> </method> <method name="blend4_node_get_amount" qualifiers="const"> @@ -4042,6 +4447,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns the blend amount of a Blend4 node given its name. </description> </method> <method name="blend4_node_set_amount"> @@ -4052,10 +4458,11 @@ <argument index="1" name="blend" type="Vector2"> </argument> <description> + Sets the blend amount of a Blend4 node given its name and value. </description> </method> <method name="connect_nodes"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="id" type="String"> </argument> @@ -4064,6 +4471,7 @@ <argument index="2" name="dst_input_idx" type="int"> </argument> <description> + Connects node [code]id[/code] to [code]dst_id[/code] at the specified input slot. </description> </method> <method name="disconnect_nodes"> @@ -4074,12 +4482,14 @@ <argument index="1" name="dst_input_idx" type="int"> </argument> <description> + Disconnects nodes connected to [code]id[/code] at the specified input slot. </description> </method> <method name="get_animation_process_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="AnimationTreePlayer.AnimationProcessMode"> </return> <description> + Returns playback process mode of this AnimationTreePlayer. </description> </method> <method name="get_base_path" qualifiers="const"> @@ -4098,12 +4508,14 @@ <return type="PoolStringArray"> </return> <description> + Returns a PoolStringArray containing the name of all nodes. </description> </method> <method name="is_active" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether this AnimationTreePlayer is active. </description> </method> <method name="mix_node_get_amount" qualifiers="const"> @@ -4112,6 +4524,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns mix amount of a Mix node given its name. </description> </method> <method name="mix_node_set_amount"> @@ -4122,6 +4535,7 @@ <argument index="1" name="ratio" type="float"> </argument> <description> + Sets mix amount of a Mix node given its name and value. </description> </method> <method name="node_exists" qualifiers="const"> @@ -4159,10 +4573,11 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns position of a node in the graph given its name. </description> </method> <method name="node_get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="AnimationTreePlayer.NodeType"> </return> <argument index="0" name="id" type="String"> </argument> @@ -4171,7 +4586,7 @@ </description> </method> <method name="node_rename"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="node" type="String"> </argument> @@ -4189,6 +4604,7 @@ <argument index="1" name="screen_pos" type="Vector2"> </argument> <description> + Sets position of a node in the graph given its name and position. </description> </method> <method name="oneshot_node_get_autorestart_delay" qualifiers="const"> @@ -4197,6 +4613,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns autostart delay of a OneShot node given its name. </description> </method> <method name="oneshot_node_get_autorestart_random_delay" qualifiers="const"> @@ -4205,6 +4622,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns autostart random delay of a OneShot node given its name. </description> </method> <method name="oneshot_node_get_fadein_time" qualifiers="const"> @@ -4213,6 +4631,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns fade in time of a OneShot node given its name. </description> </method> <method name="oneshot_node_get_fadeout_time" qualifiers="const"> @@ -4221,6 +4640,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns fade out time of a OneShot node given its name. </description> </method> <method name="oneshot_node_has_autorestart" qualifiers="const"> @@ -4229,6 +4649,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns whether a OneShot node will auto restart given its name. </description> </method> <method name="oneshot_node_is_active" qualifiers="const"> @@ -4237,6 +4658,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns whether a OneShot node is active given its name. </description> </method> <method name="oneshot_node_set_autorestart"> @@ -4247,6 +4669,7 @@ <argument index="1" name="enable" type="bool"> </argument> <description> + Sets autorestart property of a OneShot node given its name and value. </description> </method> <method name="oneshot_node_set_autorestart_delay"> @@ -4257,6 +4680,7 @@ <argument index="1" name="delay_sec" type="float"> </argument> <description> + Sets autorestart delay of a OneShot node given its name and value in seconds. </description> </method> <method name="oneshot_node_set_autorestart_random_delay"> @@ -4267,6 +4691,7 @@ <argument index="1" name="rand_sec" type="float"> </argument> <description> + Sets autorestart random delay of a OneShot node given its name and value in seconds. </description> </method> <method name="oneshot_node_set_fadein_time"> @@ -4277,6 +4702,7 @@ <argument index="1" name="time_sec" type="float"> </argument> <description> + Sets fade in time of a OneShot node given its name and value in seconds. </description> </method> <method name="oneshot_node_set_fadeout_time"> @@ -4287,6 +4713,7 @@ <argument index="1" name="time_sec" type="float"> </argument> <description> + Sets fade out time of a OneShot node given its name and value in seconds. </description> </method> <method name="oneshot_node_set_filter_path"> @@ -4307,6 +4734,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Starts a OneShot node given its name. </description> </method> <method name="oneshot_node_stop"> @@ -4315,6 +4743,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Stops a OneShot node given its name. </description> </method> <method name="recompute_caches"> @@ -4335,6 +4764,7 @@ <return type="void"> </return> <description> + Resets this AnimationTreePlayer. </description> </method> <method name="set_active"> @@ -4343,6 +4773,7 @@ <argument index="0" name="enabled" type="bool"> </argument> <description> + Sets whether this AnimationTreePlayer is active. AnimationTreePlayer will start processing if set to active. </description> </method> <method name="set_animation_process_mode"> @@ -4351,6 +4782,7 @@ <argument index="0" name="mode" type="int" enum="AnimationTreePlayer.AnimationProcessMode"> </argument> <description> + Sets process mode (ANIMATION_PROCESS_*) of this AnimationTreePlayer. </description> </method> <method name="set_base_path"> @@ -4359,6 +4791,7 @@ <argument index="0" name="path" type="NodePath"> </argument> <description> + Sets base path of this AnimationTreePlayer. </description> </method> <method name="set_master_player"> @@ -4375,6 +4808,7 @@ <argument index="0" name="id" type="String"> </argument> <description> + Returns time scale value of a TimeScale node given its name. </description> </method> <method name="timescale_node_set_scale"> @@ -4385,6 +4819,7 @@ <argument index="1" name="scale" type="float"> </argument> <description> + Sets time scale value of a TimeScale node given its name and value. </description> </method> <method name="timeseek_node_seek"> @@ -4395,6 +4830,7 @@ <argument index="1" name="pos_sec" type="float"> </argument> <description> + Sets time seek value of a TimeSeek node given its name and value. </description> </method> <method name="transition_node_delete_input"> @@ -4490,24 +4926,34 @@ </members> <constants> <constant name="NODE_OUTPUT" value="0"> + Output node. </constant> <constant name="NODE_ANIMATION" value="1"> + Animation node. </constant> <constant name="NODE_ONESHOT" value="2"> + OneShot node. </constant> <constant name="NODE_MIX" value="3"> + Mix node. </constant> <constant name="NODE_BLEND2" value="4"> + Blend2 node. </constant> <constant name="NODE_BLEND3" value="5"> + Blend3 node. </constant> <constant name="NODE_BLEND4" value="6"> + Blend4 node. </constant> <constant name="NODE_TIMESCALE" value="7"> + TimeScale node. </constant> <constant name="NODE_TIMESEEK" value="8"> + TimeSeek node. </constant> <constant name="NODE_TRANSITION" value="9"> + Transition node. </constant> </constants> </class> @@ -4632,7 +5078,7 @@ </description> </method> <method name="get_space_override_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Area.SpaceOverride"> </return> <description> Return the space override mode. @@ -5005,10 +5451,10 @@ </class> <class name="Area2D" inherits="CollisionObject2D" category="Core"> <brief_description> - General purpose area detection and influence for 2D physics. + 2D area that detects nodes that enter or exit it. Can override 2D physics properties within range. </brief_description> <description> - General purpose area detection for 2D physics. Areas can be used for detection of objects that enter/exit them, as well as overriding space parameters (changing gravity, damping, etc). For this, use any space override different from AREA_SPACE_OVERRIDE_DISABLE and point gravity at the center of mass. + 2D area that detects nodes that enter or exit it. Change the 'space_override' property SPACE_OVERRIDE_* to override physics parameters for nodes like [Rigidbody2D]. E.g. gravity, damping... See [CollisionObject2D] for usage. </description> <methods> <method name="get_angular_damp" qualifiers="const"> @@ -5037,14 +5483,14 @@ <argument index="0" name="bit" type="int"> </argument> <description> - Return an individual bit on the layer mask. + Return an individual bit on the layer mask. Describes whether other areas will collide with this one on the given layer. </description> </method> <method name="get_collision_mask" qualifiers="const"> <return type="int"> </return> <description> - Return the physics layers this area can scan for collisions. + Return the physics layers this area will scan to determine collisions. </description> </method> <method name="get_collision_mask_bit" qualifiers="const"> @@ -5053,7 +5499,7 @@ <argument index="0" name="bit" type="int"> </argument> <description> - Return an individual bit on the collision mask. + Return an individual bit on the collision mask. Describes whether this area will collide with others on the given layer. </description> </method> <method name="get_gravity" qualifiers="const"> @@ -5088,14 +5534,14 @@ <return type="Array"> </return> <description> - Return a list of the areas that are totally or partially inside this area. + Returns a list of the [Area2D]s that intersect with this area. </description> </method> <method name="get_overlapping_bodies" qualifiers="const"> <return type="Array"> </return> <description> - Return a list of the bodies ([PhysicsBody2D]) that are totally or partially inside this area. + Return a list of the [PhysicsBody2D]s that intersect with this area. </description> </method> <method name="get_priority" qualifiers="const"> @@ -5106,7 +5552,7 @@ </description> </method> <method name="get_space_override_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Area2D.SpaceOverride"> </return> <description> Return the space override mode. @@ -5317,33 +5763,50 @@ </method> </methods> <members> - <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief=""> + <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief="rate of spin loss"> + The rate at which objects stop spinning in this area. Represents the amount of speed lost per second. If 1.0, physics bodies in the area stop rotating immediately. If 0.0, they never slow down. Does not incorporate external forces. The physics-update's rate affects 'angular_damp'. </member> - <member name="audio_bus_name" type="String" setter="set_audio_bus" getter="get_audio_bus" brief=""> + <member name="audio_bus_name" type="String" setter="set_audio_bus" getter="get_audio_bus" brief="name of audio bus"> + The name of the Area2D's audio bus. </member> - <member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus" brief=""> + <member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus" brief="Whether to override audio bus"> + If [code]true[/code], overrides the default audio bus with the Area2D's. Defaults to [code]false[/code]. </member> - <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief=""> + <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="others-collide-with-this layers"> + The physics layer this Area2D is in. + Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask]. + A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. </member> - <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief=""> + <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief="this-collides-with-others layers"> + The physics layers this Area2D scans to determine collision detections. </member> - <member name="gravity" type="float" setter="set_gravity" getter="get_gravity" brief=""> + <member name="gravity" type="float" setter="set_gravity" getter="get_gravity" brief="internal gravity intensity"> + The gravity intensity within the Area2D (ranges -1024 to 1024). This is useful to alter the force of gravity without altering its direction. + This value multiplies the gravity vector, whether it is the given vector ([method set_gravity_vector]), or a calculated one (when using a center of gravity). </member> - <member name="gravity_distance_scale" type="float" setter="set_gravity_distance_scale" getter="get_gravity_distance_scale" brief=""> + <member name="gravity_distance_scale" type="float" setter="set_gravity_distance_scale" getter="get_gravity_distance_scale" brief="gravity drop rate"> + The falloff factor for point gravity. The greater this value is, the faster the strength of gravity decreases with the square of distance. </member> - <member name="gravity_point" type="bool" setter="set_gravity_is_point" getter="is_gravity_a_point" brief=""> + <member name="gravity_point" type="bool" setter="set_gravity_is_point" getter="is_gravity_a_point" brief="is gravity a point?"> + If [code]true[/code], calculates gravity from a particular point during a space override (see [method set_space_override_mode]). If a point, [Vector2] position is set with [method set_gravity_vector]. Defaults to [code]false[/code]. </member> - <member name="gravity_vec" type="Vector2" setter="set_gravity_vector" getter="get_gravity_vector" brief=""> + <member name="gravity_vec" type="Vector2" setter="set_gravity_vector" getter="get_gravity_vector" brief="gravity non-normalized vector or center-point"> + The gravitational direction/strength as a vector (not normalized). If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center. </member> - <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" brief=""> + <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" brief="rate of movement loss"> + The rate at which objects stop spinning in this area. Represents the amount of speed lost per second. If 1.0, physics bodies in the area stop rotating immediately. If 0.0, they never slow down. Does not incorporate external forces. The physics-update's rate affects 'angular_damp'. </member> - <member name="monitorable" type="bool" setter="set_monitorable" getter="is_monitorable" brief=""> + <member name="monitorable" type="bool" setter="set_monitorable" getter="is_monitorable" brief="others cannot detect this?"> + If [code]true[/code], other monitoring areas can detect this Area2D (is it undetectable at the moment?). Defaults to [code]true[/code]. </member> - <member name="monitoring" type="bool" setter="set_monitoring" getter="is_monitoring" brief=""> + <member name="monitoring" type="bool" setter="set_monitoring" getter="is_monitoring" brief="this cannot detect others?"> + If [code]true[/code], this detects bodies/areas entering/exiting it (can it detect others at the moment?). Defaults to [code]true[/code]. </member> - <member name="priority" type="float" setter="set_priority" getter="get_priority" brief=""> + <member name="priority" type="float" setter="set_priority" getter="get_priority" brief="(high) process before others (low)"> + The processing order for this priority. Ranges from 0 to 128. Defaults to 0. Higher priorities are processed first. </member> - <member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="" enum="Area2D.SpaceOverride"> + <member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="how to override gravity/damping" enum="Area2D.SpaceOverride"> + How to override gravity and damping calculations within this Area2D, if at all. Consult the SPACE_OVERRIDE_* constants for available options. </member> </members> <signals> @@ -5429,6 +5892,11 @@ </signal> </signals> <constants> + <constant name="SPACE_OVERRIDE_DISABLED" value="0" enum="Area2D.SpaceOverride">This area does not affect gravity/damp. These are areas that exist only to detect collisions and objects entering or exiting them.</constant> + <constant name="SPACE_OVERRIDE_COMBINE" value="1" enum="Area2D.SpaceOverride">This area adds its gravity/damp values to whatever has been calculated so far. This way, many overlapping areas can combine their physics to make interesting effects.</constant> + <constant name="SPACE_OVERRIDE_COMBINE_REPLACE" value="2" enum="Area2D.SpaceOverride">This area adds its gravity/damp values to whatever has been calculated so far. Then stops taking into account the rest of the areas, even the default one.</constant> + <constant name="SPACE_OVERRIDE_REPLACE" value="3" enum="Area2D.SpaceOverride">This area replaces any gravity/damp, even the default one, and stops taking into account the rest of the areas.</constant> + <constant name="SPACE_OVERRIDE_REPLACE_COMBINE" value="4" enum="Area2D.SpaceOverride">This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one.</constant> </constants> </class> <class name="Array" category="Built-In Types"> @@ -5670,7 +6138,7 @@ <argument index="1" name="func" type="String"> </argument> <description> - Sort the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return true if the first argument is less than the second, and return false otherwise. + Sort the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return true if the first argument is less than the second, and return false otherwise. Note: you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior. </description> </method> </methods> @@ -5698,9 +6166,9 @@ </argument> <argument index="1" name="arrays" type="Array"> </argument> - <argument index="2" name="blend_shapes" type="Array" default="null"> + <argument index="2" name="blend_shapes" type="Array" default="[ ]"> </argument> - <argument index="3" name="compress_flags" type="int" default="null"> + <argument index="3" name="compress_flags" type="int" default="97792"> </argument> <description> Create a new surface ([method get_surface_count] that will become surf_idx for this. @@ -5726,7 +6194,7 @@ </description> </method> <method name="get_blend_shape_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Mesh.BlendShapeMode"> </return> <description> </description> @@ -5819,7 +6287,7 @@ </description> </method> <method name="surface_get_primitive_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Mesh.PrimitiveType"> </return> <argument index="0" name="surf_idx" type="int"> </argument> @@ -5995,8 +6463,10 @@ </class> <class name="AudioEffect" inherits="Resource" category="Core"> <brief_description> + Audio Effect For Audio. </brief_description> <description> + Base resource for audio bus. Applies an audio effect on the bus that the resource is applied on. </description> <methods> </methods> @@ -6005,14 +6475,17 @@ </class> <class name="AudioEffectAmplify" inherits="AudioEffect" category="Core"> <brief_description> + Amplifies the volume of an audio source. </brief_description> <description> + Amplifies the volume of an audio source. Increase gain of the audio being routed through the bus. </description> <methods> <method name="get_volume_db" qualifiers="const"> <return type="float"> </return> <description> + Returns the set maximum volume. </description> </method> <method name="set_volume_db"> @@ -6021,11 +6494,13 @@ <argument index="0" name="volume" type="float"> </argument> <description> + Sets the maximum volume. </description> </method> </methods> <members> <member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" brief=""> + The effect's volume limit. </member> </members> <constants> @@ -6053,20 +6528,24 @@ </class> <class name="AudioEffectChorus" inherits="AudioEffect" category="Core"> <brief_description> + Adds a chorus audio effect. </brief_description> <description> + Adds a chorus audio effect. The effect applies a filter with voices to duplicate the audio source and manipulate it through the filter. </description> <methods> <method name="get_dry" qualifiers="const"> <return type="float"> </return> <description> + Returns the set dry ratio. </description> </method> <method name="get_voice_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the set voice count. </description> </method> <method name="get_voice_cutoff_hz" qualifiers="const"> @@ -6075,6 +6554,7 @@ <argument index="0" name="voice_idx" type="int"> </argument> <description> + Returns the voice's set cutoff frequency. </description> </method> <method name="get_voice_delay_ms" qualifiers="const"> @@ -6083,6 +6563,7 @@ <argument index="0" name="voice_idx" type="int"> </argument> <description> + Returns the voice's set delay. </description> </method> <method name="get_voice_depth_ms" qualifiers="const"> @@ -6091,6 +6572,7 @@ <argument index="0" name="voice_idx" type="int"> </argument> <description> + Returns the voice's set filter depth. </description> </method> <method name="get_voice_level_db" qualifiers="const"> @@ -6099,6 +6581,7 @@ <argument index="0" name="voice_idx" type="int"> </argument> <description> + Returns the voice's set maximum volume. </description> </method> <method name="get_voice_pan" qualifiers="const"> @@ -6107,6 +6590,7 @@ <argument index="0" name="voice_idx" type="int"> </argument> <description> + Returns the voice's set pan. </description> </method> <method name="get_voice_rate_hz" qualifiers="const"> @@ -6115,12 +6599,14 @@ <argument index="0" name="voice_idx" type="int"> </argument> <description> + Returns the voice filter's set rate in cycles. </description> </method> <method name="get_wet" qualifiers="const"> <return type="float"> </return> <description> + Returns the set applied wetness of the effect. </description> </method> <method name="set_dry"> @@ -6129,6 +6615,7 @@ <argument index="0" name="amount" type="float"> </argument> <description> + Returns the set applied dryness of the effect. </description> </method> <method name="set_voice_count"> @@ -6137,6 +6624,7 @@ <argument index="0" name="voices" type="int"> </argument> <description> + Set the number of voices in the effect's filter. </description> </method> <method name="set_voice_cutoff_hz"> @@ -6147,6 +6635,7 @@ <argument index="1" name="cutoff_hz" type="float"> </argument> <description> + Set the cutoff frequency of the voice. The maximum frequency the voice may affect. </description> </method> <method name="set_voice_delay_ms"> @@ -6157,6 +6646,7 @@ <argument index="1" name="delay_ms" type="float"> </argument> <description> + Set the delay of the voice's signal. </description> </method> <method name="set_voice_depth_ms"> @@ -6167,6 +6657,7 @@ <argument index="1" name="depth_ms" type="float"> </argument> <description> + Set the filter depth of the voice's signal. </description> </method> <method name="set_voice_level_db"> @@ -6177,6 +6668,7 @@ <argument index="1" name="level_db" type="float"> </argument> <description> + Set the volume level of the voice. </description> </method> <method name="set_voice_pan"> @@ -6187,6 +6679,7 @@ <argument index="1" name="pan" type="float"> </argument> <description> + Set the pan level of the voice. </description> </method> <method name="set_voice_rate_hz"> @@ -6197,6 +6690,7 @@ <argument index="1" name="rate_hz" type="float"> </argument> <description> + Set the voice filter's rate. </description> </method> <method name="set_wet"> @@ -6205,63 +6699,91 @@ <argument index="0" name="amount" type="float"> </argument> <description> + Set the amount of effect. </description> </method> </methods> <members> <member name="dry" type="float" setter="set_dry" getter="get_dry" brief=""> + The effect's raw signal. </member> <member name="voice/1/cutoff_hz" type="float" setter="set_voice_cutoff_hz" getter="get_voice_cutoff_hz" brief=""> + The voice's cutoff frequency. </member> <member name="voice/1/delay_ms" type="float" setter="set_voice_delay_ms" getter="get_voice_delay_ms" brief=""> + The voice's signal delay. </member> <member name="voice/1/depth_ms" type="float" setter="set_voice_depth_ms" getter="get_voice_depth_ms" brief=""> + The voice filter's depth. </member> <member name="voice/1/level_db" type="float" setter="set_voice_level_db" getter="get_voice_level_db" brief=""> + The voice's volume. </member> <member name="voice/1/pan" type="float" setter="set_voice_pan" getter="get_voice_pan" brief=""> + The voice's pan level. </member> <member name="voice/1/rate_hz" type="float" setter="set_voice_rate_hz" getter="get_voice_rate_hz" brief=""> + The voice's filter rate. </member> <member name="voice/2/cutoff_hz" type="float" setter="set_voice_cutoff_hz" getter="get_voice_cutoff_hz" brief=""> + The voice's cutoff frequency. </member> <member name="voice/2/delay_ms" type="float" setter="set_voice_delay_ms" getter="get_voice_delay_ms" brief=""> + The voice's signal delay. </member> <member name="voice/2/depth_ms" type="float" setter="set_voice_depth_ms" getter="get_voice_depth_ms" brief=""> + The voice filter's depth. </member> <member name="voice/2/level_db" type="float" setter="set_voice_level_db" getter="get_voice_level_db" brief=""> + The voice's volume. </member> <member name="voice/2/pan" type="float" setter="set_voice_pan" getter="get_voice_pan" brief=""> + The voice's pan level. </member> <member name="voice/2/rate_hz" type="float" setter="set_voice_rate_hz" getter="get_voice_rate_hz" brief=""> + The voice's filter rate. </member> <member name="voice/3/cutoff_hz" type="float" setter="set_voice_cutoff_hz" getter="get_voice_cutoff_hz" brief=""> + The voice's cutoff frequency. </member> <member name="voice/3/delay_ms" type="float" setter="set_voice_delay_ms" getter="get_voice_delay_ms" brief=""> + The voice's signal delay. </member> <member name="voice/3/depth_ms" type="float" setter="set_voice_depth_ms" getter="get_voice_depth_ms" brief=""> + The voice filter's depth. </member> <member name="voice/3/level_db" type="float" setter="set_voice_level_db" getter="get_voice_level_db" brief=""> + The voice's volume. </member> <member name="voice/3/pan" type="float" setter="set_voice_pan" getter="get_voice_pan" brief=""> + The voice's pan level. </member> <member name="voice/3/rate_hz" type="float" setter="set_voice_rate_hz" getter="get_voice_rate_hz" brief=""> + The voice's filter rate. </member> <member name="voice/4/cutoff_hz" type="float" setter="set_voice_cutoff_hz" getter="get_voice_cutoff_hz" brief=""> + The voice's cutoff frequency. </member> <member name="voice/4/delay_ms" type="float" setter="set_voice_delay_ms" getter="get_voice_delay_ms" brief=""> + The voice's signal delay. </member> <member name="voice/4/depth_ms" type="float" setter="set_voice_depth_ms" getter="get_voice_depth_ms" brief=""> + The voice filter's depth. </member> <member name="voice/4/level_db" type="float" setter="set_voice_level_db" getter="get_voice_level_db" brief=""> + The voice's volume. </member> <member name="voice/4/pan" type="float" setter="set_voice_pan" getter="get_voice_pan" brief=""> + The voice's pan level. </member> <member name="voice/4/rate_hz" type="float" setter="set_voice_rate_hz" getter="get_voice_rate_hz" brief=""> + The voice's filter rate. </member> <member name="voice_count" type="int" setter="set_voice_count" getter="get_voice_count" brief=""> + The amount of voices in the effect. </member> <member name="wet" type="float" setter="set_wet" getter="get_wet" brief=""> + The effect's processed signal. </member> </members> <constants> @@ -6630,7 +7152,7 @@ </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioEffectDistortion.Mode"> </return> <description> </description> @@ -6780,7 +7302,7 @@ </description> </method> <method name="get_db" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioEffectFilter.FilterDB"> </return> <description> </description> @@ -7340,7 +7862,7 @@ </argument> <argument index="1" name="effect" type="AudioEffect"> </argument> - <argument index="2" name="at_pos" type="int" default="null"> + <argument index="2" name="at_pos" type="int" default="-1"> </argument> <description> </description> @@ -7434,7 +7956,7 @@ </description> </method> <method name="get_speaker_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioServer.SpeakerMode"> </return> <description> </description> @@ -7720,7 +8242,7 @@ </description> </method> <method name="get_mix_target" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioStreamPlayer.MixTarget"> </return> <description> </description> @@ -8032,7 +8554,7 @@ </description> </method> <method name="get_attenuation_model" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioStreamPlayer3D.AttenuationModel"> </return> <description> </description> @@ -8044,7 +8566,7 @@ </description> </method> <method name="get_doppler_tracking" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioStreamPlayer3D.DopplerTracking"> </return> <description> </description> @@ -8074,7 +8596,7 @@ </description> </method> <method name="get_out_of_range_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioStreamPlayer3D.OutOfRangeMode"> </return> <description> </description> @@ -8390,7 +8912,7 @@ </description> </method> <method name="get_format" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioStreamSample.Format"> </return> <description> </description> @@ -8408,7 +8930,7 @@ </description> </method> <method name="get_loop_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="AudioStreamSample.LoopMode"> </return> <description> </description> @@ -8510,7 +9032,7 @@ </description> <methods> <method name="get_copy_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="BackBufferCopy.CopyMode"> </return> <description> Return the copy mode currently applied to the BackBufferCopy (refer to constants section). @@ -8585,7 +9107,7 @@ </description> </method> <method name="get_action_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="BaseButton.ActionMode"> </return> <description> Return the current mode of action (see [method set_action_mode]) (one of the ACTION_MODE_* constants). @@ -8598,14 +9120,14 @@ </description> </method> <method name="get_draw_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="BaseButton.DrawMode"> </return> <description> Return the visual state used to draw the button. This is useful mainly when implementing your own draw code by either overriding _draw() or connecting to "draw" signal. The visual state of the button is defined by the DRAW_* enum. </description> </method> <method name="get_enabled_focus_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.FocusMode"> </return> <description> Returns focus access mode used when switching between enabled/disabled (see [method Control.set_focus_mode] and [method set_disabled]). @@ -8947,8 +9469,10 @@ </class> <class name="BitMap" inherits="Resource" category="Core"> <brief_description> + Boolean matrix. </brief_description> <description> + A two-dimensional array of boolean values, can be used to efficiently store a binary matrix (every matrix element takes only one bit) and query the values using natural cartesian coordinates. </description> <methods> <method name="create"> @@ -8957,6 +9481,7 @@ <argument index="0" name="size" type="Vector2"> </argument> <description> + Creates a bitmap with the specified size, filled with false. </description> </method> <method name="create_from_image_alpha"> @@ -8965,6 +9490,7 @@ <argument index="0" name="image" type="Image"> </argument> <description> + Creates a bitmap that matches the given image dimensions, every element of the bitmap is set to false if the alpha value of the image at that position is 0, and true in other case. </description> </method> <method name="get_bit" qualifiers="const"> @@ -8973,18 +9499,21 @@ <argument index="0" name="pos" type="Vector2"> </argument> <description> + Returns bitmap's value at the specified position. </description> </method> <method name="get_size" qualifiers="const"> <return type="Vector2"> </return> <description> + Returns bitmap's dimensions. </description> </method> <method name="get_true_bit_count" qualifiers="const"> <return type="int"> </return> <description> + Returns the amount of bitmap elements that are set to true. </description> </method> <method name="set_bit"> @@ -8995,6 +9524,7 @@ <argument index="1" name="bit" type="bool"> </argument> <description> + Sets the bitmap's element at the specified position, to the specified value. </description> </method> <method name="set_bit_rect"> @@ -9005,6 +9535,7 @@ <argument index="1" name="bit" type="bool"> </argument> <description> + Sets a rectangular portion of the bitmap to the specified value. </description> </method> </methods> @@ -9030,9 +9561,9 @@ </argument> <argument index="2" name="rect" type="Rect2"> </argument> - <argument index="3" name="align" type="Vector2" default="null"> + <argument index="3" name="align" type="Vector2" default="Vector2( 0, 0 )"> </argument> - <argument index="4" name="advance" type="float" default="null"> + <argument index="4" name="advance" type="float" default="-1"> </argument> <description> Add a character to the font, where [i]character[/i] is the unicode value, [i]texture[/i] is the texture index, [i]rect[/i] is the region in the texture (in pixels!), [i]align[/i] is the (optional) alignment for the character and [i]advance[/i] is the (optional) advance. @@ -9068,7 +9599,7 @@ </description> </method> <method name="create_from_fnt"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -9080,7 +9611,7 @@ </return> <argument index="0" name="char" type="int"> </argument> - <argument index="1" name="next" type="int" default="null"> + <argument index="1" name="next" type="int" default="0"> </argument> <description> Return the size of a character, optionally taking kerning into account if the next character is provided. @@ -9183,6 +9714,7 @@ <return type="String"> </return> <description> + Returns the name of the bone node attached to. </description> </method> <method name="set_bone_name"> @@ -9191,6 +9723,7 @@ <argument index="0" name="bone_name" type="String"> </argument> <description> + Changes the name of the bone node </description> </method> </methods> @@ -9216,7 +9749,7 @@ </description> </method> <method name="get_alignment" qualifiers="const"> - <return type="int"> + <return type="int" enum="BoxContainer.AlignMode"> </return> <description> Return the alignment of children in the container. @@ -9292,35 +9825,30 @@ <return type="Texture"> </return> <description> - Return the button icon. </description> </method> <method name="get_clip_text" qualifiers="const"> <return type="bool"> </return> <description> - Return the state of the [i]clip_text[/i] property (see [method set_clip_text]) </description> </method> <method name="get_text" qualifiers="const"> <return type="String"> </return> <description> - Return the button text. </description> </method> <method name="get_text_align" qualifiers="const"> - <return type="int"> + <return type="int" enum="Button.TextAlign"> </return> <description> - Return the text alignment policy. </description> </method> <method name="is_flat" qualifiers="const"> <return type="bool"> </return> <description> - Return the state of the [i]flat[/i] property (see [method set_flat]). </description> </method> <method name="set_button_icon"> @@ -9329,7 +9857,6 @@ <argument index="0" name="texture" type="Texture"> </argument> <description> - Set the icon that will be displayed next to the text inside the button area. </description> </method> <method name="set_clip_text"> @@ -9338,7 +9865,6 @@ <argument index="0" name="enabled" type="bool"> </argument> <description> - Set the [i]clip_text[/i] property of a Button. When this property is enabled, text that is too large to fit the button is clipped, when disabled (default) the Button will always be wide enough to hold the text. </description> </method> <method name="set_flat"> @@ -9347,7 +9873,6 @@ <argument index="0" name="enabled" type="bool"> </argument> <description> - Set the [i]flat[/i] property of a Button. Flat buttons don't display decoration unless hovered or pressed. </description> </method> <method name="set_text"> @@ -9356,7 +9881,6 @@ <argument index="0" name="text" type="String"> </argument> <description> - Set the button text, which will be displayed inside the button area. </description> </method> <method name="set_text_align"> @@ -9365,20 +9889,24 @@ <argument index="0" name="align" type="int" enum="Button.TextAlign"> </argument> <description> - Set the text alignment policy, using one of the ALIGN_* constants. </description> </method> </methods> <members> <member name="align" type="int" setter="set_text_align" getter="get_text_align" brief="" enum="Button.TextAlign"> + Text alignment policy for the button's text, use one of the ALIGN_* constants. </member> <member name="clip_text" type="bool" setter="set_clip_text" getter="get_clip_text" brief=""> + When this property is enabled, text that is too large to fit the button is clipped, when disabled the Button will always be wide enough to hold the text. This property is disabled by default. </member> - <member name="flat" type="bool" setter="set_flat" getter="is_flat" brief=""> + <member name="flat" type="bool" setter="set_flat" getter="is_flat" brief="button decoration mode"> + Flat buttons don't display decoration. </member> <member name="icon" type="Texture" setter="set_button_icon" getter="get_button_icon" brief=""> + Button's icon, if text is present the icon will be placed before the text. </member> <member name="text" type="String" setter="set_text" getter="get_text" brief=""> + The button's text that will be displayed inside the button's area. </member> </members> <constants> @@ -9386,7 +9914,7 @@ Align the text to the left. </constant> <constant name="ALIGN_CENTER" value="1"> - Center the text. + Align the text to the center. </constant> <constant name="ALIGN_RIGHT" value="2"> Align the text to the right. @@ -9468,7 +9996,7 @@ </description> </method> <method name="get_doppler_tracking" qualifiers="const"> - <return type="int"> + <return type="int" enum="Camera.DopplerTracking"> </return> <description> </description> @@ -9492,13 +10020,13 @@ </description> </method> <method name="get_keep_aspect_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Camera.KeepAspect"> </return> <description> </description> </method> <method name="get_projection" qualifiers="const"> - <return type="int"> + <return type="int" enum="Camera.Projection"> </return> <description> </description> @@ -9716,7 +10244,7 @@ </description> </method> <method name="get_anchor_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Camera2D.AnchorMode"> </return> <description> </description> @@ -10086,7 +10614,7 @@ </argument> <argument index="3" name="next" type="String"> </argument> - <argument index="4" name="modulate" type="Color" default="null"> + <argument index="4" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <description> Draw a string character using a custom font. Returns the advance, depending on the char width and kerning with an optional next char. @@ -10112,13 +10640,13 @@ </argument> <argument index="1" name="color" type="Color"> </argument> - <argument index="2" name="uvs" type="PoolVector2Array" default="null"> + <argument index="2" name="uvs" type="PoolVector2Array" default="PoolVector2Array( )"> </argument> - <argument index="3" name="texture" type="Texture" default="PoolVector2Array( )"> + <argument index="3" name="texture" type="Texture" default="null"> </argument> <argument index="4" name="normal_map" type="Texture" default="null"> </argument> - <argument index="5" name="antialiased" type="bool" default="null"> + <argument index="5" name="antialiased" type="bool" default="false"> </argument> <description> Draw a colored polygon of any amount of points, convex or concave. @@ -10133,9 +10661,9 @@ </argument> <argument index="2" name="color" type="Color"> </argument> - <argument index="3" name="width" type="float" default="null"> + <argument index="3" name="width" type="float" default="1.0"> </argument> - <argument index="4" name="antialiased" type="bool" default="null"> + <argument index="4" name="antialiased" type="bool" default="false"> </argument> <description> Draw a line from a 2D point to another, with a given color and width. It can be optionally antialiased. @@ -10148,13 +10676,13 @@ </argument> <argument index="1" name="colors" type="PoolColorArray"> </argument> - <argument index="2" name="uvs" type="PoolVector2Array" default="null"> + <argument index="2" name="uvs" type="PoolVector2Array" default="PoolVector2Array( )"> </argument> - <argument index="3" name="texture" type="Texture" default="PoolVector2Array( )"> + <argument index="3" name="texture" type="Texture" default="null"> </argument> <argument index="4" name="normal_map" type="Texture" default="null"> </argument> - <argument index="5" name="antialiased" type="bool" default="null"> + <argument index="5" name="antialiased" type="bool" default="false"> </argument> <description> Draw a polygon of any amount of points, convex or concave. @@ -10167,9 +10695,9 @@ </argument> <argument index="1" name="color" type="Color"> </argument> - <argument index="2" name="width" type="float" default="null"> + <argument index="2" name="width" type="float" default="1.0"> </argument> - <argument index="3" name="antialiased" type="bool" default="null"> + <argument index="3" name="antialiased" type="bool" default="false"> </argument> <description> </description> @@ -10181,9 +10709,9 @@ </argument> <argument index="1" name="colors" type="PoolColorArray"> </argument> - <argument index="2" name="width" type="float" default="null"> + <argument index="2" name="width" type="float" default="1.0"> </argument> - <argument index="3" name="antialiased" type="bool" default="null"> + <argument index="3" name="antialiased" type="bool" default="false"> </argument> <description> </description> @@ -10199,7 +10727,7 @@ </argument> <argument index="3" name="texture" type="Texture" default="null"> </argument> - <argument index="4" name="width" type="float" default="null"> + <argument index="4" name="width" type="float" default="1.0"> </argument> <argument index="5" name="normal_map" type="Texture" default="null"> </argument> @@ -10214,7 +10742,7 @@ </argument> <argument index="1" name="color" type="Color"> </argument> - <argument index="2" name="filled" type="bool" default="null"> + <argument index="2" name="filled" type="bool" default="true"> </argument> <description> Draw a colored rectangle. @@ -10250,9 +10778,9 @@ </argument> <argument index="2" name="text" type="String"> </argument> - <argument index="3" name="modulate" type="Color" default="null"> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="4" name="clip_w" type="int" default="null"> + <argument index="4" name="clip_w" type="int" default="-1"> </argument> <description> Draw a string using a custom font. @@ -10276,7 +10804,7 @@ </argument> <argument index="1" name="pos" type="Vector2"> </argument> - <argument index="2" name="modulate" type="Color" default="null"> + <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <argument index="3" name="normal_map" type="Texture" default="null"> </argument> @@ -10293,9 +10821,9 @@ </argument> <argument index="2" name="tile" type="bool"> </argument> - <argument index="3" name="modulate" type="Color" default="null"> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="4" name="transpose" type="bool" default="null"> + <argument index="4" name="transpose" type="bool" default="false"> </argument> <argument index="5" name="normal_map" type="Texture" default="null"> </argument> @@ -10314,11 +10842,11 @@ </argument> <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="4" name="transpose" type="bool" default="null"> + <argument index="4" name="transpose" type="bool" default="false"> </argument> <argument index="5" name="normal_map" type="Texture" default="null"> </argument> - <argument index="6" name="clip_uv" type="bool" default="null"> + <argument index="6" name="clip_uv" type="bool" default="true"> </argument> <description> Draw a textured rectangle region at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture. @@ -10729,13 +11257,13 @@ </description> <methods> <method name="get_blend_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="CanvasItemMaterial.BlendMode"> </return> <description> </description> </method> <method name="get_light_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="CanvasItemMaterial.LightMode"> </return> <description> </description> @@ -10955,8 +11483,10 @@ </class> <class name="CapsuleMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Class representing a capsule-shaped [PrimitiveMesh]. </brief_description> <description> + Class representing a capsule-shaped [PrimitiveMesh]. </description> <methods> <method name="get_mid_height" qualifiers="const"> @@ -11018,12 +11548,16 @@ </methods> <members> <member name="mid_height" type="float" setter="set_mid_height" getter="get_mid_height" brief=""> + Height of the capsule mesh from the center point. Defaults to 1.0. </member> <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" brief=""> + Number of radial segments on the capsule mesh. Defaults to 64. </member> <member name="radius" type="float" setter="set_radius" getter="get_radius" brief=""> + Radius of the capsule mesh. Defaults to 1.0. </member> <member name="rings" type="int" setter="set_rings" getter="get_rings" brief=""> + Number of rings along the height of the capsule. Defaults to 8. </member> </members> <constants> @@ -11326,7 +11860,7 @@ </return> <argument index="0" name="class" type="String"> </argument> - <argument index="1" name="no_inheritance" type="bool" default="null"> + <argument index="1" name="no_inheritance" type="bool" default="false"> </argument> <description> </description> @@ -11336,7 +11870,7 @@ </return> <argument index="0" name="class" type="String"> </argument> - <argument index="1" name="no_inheritance" type="bool" default="null"> + <argument index="1" name="no_inheritance" type="bool" default="false"> </argument> <description> </description> @@ -11356,7 +11890,7 @@ </return> <argument index="0" name="class" type="String"> </argument> - <argument index="1" name="no_inheritance" type="bool" default="null"> + <argument index="1" name="no_inheritance" type="bool" default="false"> </argument> <description> </description> @@ -11376,7 +11910,7 @@ </return> <argument index="0" name="class" type="String"> </argument> - <argument index="1" name="no_inheritance" type="bool" default="null"> + <argument index="1" name="no_inheritance" type="bool" default="false"> </argument> <description> </description> @@ -11398,7 +11932,7 @@ </argument> <argument index="1" name="method" type="String"> </argument> - <argument index="2" name="no_inheritance" type="bool" default="null"> + <argument index="2" name="no_inheritance" type="bool" default="false"> </argument> <description> </description> @@ -11414,7 +11948,7 @@ </description> </method> <method name="class_set_property" qualifiers="const"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="object" type="Object"> </argument> @@ -12001,7 +12535,7 @@ </description> <methods> <method name="get_build_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="CollisionPolygon2D.BuildMode"> </return> <description> Return whether the polygon is a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]). @@ -12077,8 +12611,10 @@ </class> <class name="CollisionShape" inherits="Spatial" category="Core"> <brief_description> + Node that represents collision shape data in 3D space. </brief_description> <description> + Editor facility for creating and editing collision shapes in 3D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area] to give it a detection shape, or add it to a [PhysicsBody] to give create solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape. </description> <methods> <method name="get_shape" qualifiers="const"> @@ -12097,6 +12633,7 @@ <return type="void"> </return> <description> + Sets the collision shape's shape to the addition of all its convexed [MeshInstance] siblings geometry. </description> </method> <method name="resource_changed"> @@ -12105,6 +12642,7 @@ <argument index="0" name="resource" type="Resource"> </argument> <description> + If this method exists within a script it will be called whenever the shape resource has been modified. </description> </method> <method name="set_disabled"> @@ -12126,8 +12664,10 @@ </methods> <members> <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief=""> + A disabled collision shape has no effect in the world. </member> <member name="shape" type="Shape" setter="set_shape" getter="get_shape" brief=""> + The actual shape owned by this collision shape. </member> </members> <constants> @@ -12135,17 +12675,16 @@ </class> <class name="CollisionShape2D" inherits="Node2D" category="Core"> <brief_description> - Editor-only class for easy editing of shapes. + Node that represents collision shape data in 2D space. </brief_description> <description> - Editor-only class. This is not present when running the game. It's used in the editor to properly edit and position collision shapes in [CollisionObject2D]. This is not accessible from regular code. + Editor facility for creating and editing collision shapes in 2D space. You can use this node to represent all sorts of collision shapes, for example, add this to an [Area2D] to give it a detection shape, or add it to a [PhysicsBody2D] to give create solid object. [b]IMPORTANT[/b]: this is an Editor-only helper to create shapes, use [method get_shape] to get the actual shape. </description> <methods> <method name="get_shape" qualifiers="const"> <return type="Shape2D"> </return> <description> - Return this shape's [Shape2D]. </description> </method> <method name="is_disabled" qualifiers="const"> @@ -12182,16 +12721,18 @@ <argument index="0" name="shape" type="Shape2D"> </argument> <description> - Set this shape's [Shape2D]. This will not appear as a node, but can be directly edited as a property. </description> </method> </methods> <members> <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief=""> + A disabled collision shape has no effect in the world. </member> <member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled" brief=""> + Sets whether this collision shape should only detect collision on one side (top or bottom). </member> <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape" brief=""> + The actual shape owned by this collision shape. </member> </members> <constants> @@ -12199,10 +12740,10 @@ </class> <class name="Color" category="Built-In Types"> <brief_description> - Color in RGBA format. + Color in RGBA format with some support for ARGB format. </brief_description> <description> - A color is represented as red, green and blue (r,g,b) components. Additionally, "a" represents the alpha component, often used for transparency. Values are in floating point and usually range from 0 to 1. Some methods (such as set_modulate() ) may accept values > 1. + A color is represented as red, green and blue (r,g,b) components. Additionally, "a" represents the alpha component, often used for transparency. Values are in floating point and usually range from 0 to 1. Some methods (such as set_modulate(color)) may accept values > 1. </description> <methods> <method name="Color"> @@ -12217,7 +12758,10 @@ <argument index="3" name="a" type="float"> </argument> <description> - Construct the color from an RGBA profile. + Constructs a color from an RGBA profile using values between 0 and 1 (float). + [codeblock] + var c = Color(0.2, 1.0, .7, .8) # a color of an RGBA(51, 255, 178, 204) + [/codeblock] </description> </method> <method name="Color"> @@ -12230,7 +12774,10 @@ <argument index="2" name="b" type="float"> </argument> <description> - Construct the color from an RGBA profile. + Constructs a color from an RGB profile using values between 0 and 1 (float). Alpha will always be 1. + [codeblock] + var c = Color(0.2, 1.0, .7) # a color of an RGBA(51, 255, 178, 255) + [/codeblock] </description> </method> <method name="Color"> @@ -12239,7 +12786,10 @@ <argument index="0" name="from" type="int"> </argument> <description> - Construct the color from an RGBA profile. + Constructs a color from a 32-bit integer (each byte represents a component of the RGBA profile). + [codeblock] + var c = Color(274) # a color of an RGBA(0, 0, 1, 18) + [/codeblock] </description> </method> <method name="Color"> @@ -12248,7 +12798,19 @@ <argument index="0" name="from" type="String"> </argument> <description> - Construct the color from an RGBA profile. + Constructs a color from an HTML hexadecimal color string in ARGB or RGB format. + The following string formats are supported: + [code]"#ff00ff00"[/code] - ARGB format with '#' + [code]"ff00ff00"[/code] - ARGB format + [code]"#ff00ff"[/code] - RGB format with '#' + [code]"ff00ff"[/code] - RGB format + [codeblock] + # The following code creates the same color of an RGBA(178, 217, 10, 255) + var c1 = Color("#ffb2d90a") # ARGB format with '#' + var c2 = Color("ffb2d90a") # ARGB format + var c3 = Color("#b2d90a") # RGB format with '#' + var c4 = Color("b2d90a") # RGB format + [/codeblock] </description> </method> <method name="blend"> @@ -12257,28 +12819,46 @@ <argument index="0" name="over" type="Color"> </argument> <description> - Return a new color blended with anothor one. + Returns a new color resulting from blending this color over another color. If the color is opaque, the result would also be opaque. The other color could then take a range of values with different alpha values. + [codeblock] + var bg = Color(0.0, 1.0, 0.0, 0.5) # Green with alpha of 50% + var fg = Color(1.0, 0.0, 0.0, .5) # Red with alpha of 50% + var blendedColor = bg.blend(fg) # Brown with alpha of 75% + [/codeblock] </description> </method> <method name="contrasted"> <return type="Color"> </return> <description> - Return the most contrasting color with this one. + Returns the most contrasting color. + [codeblock] + var c = Color(.3, .4, .9) + var contrastedColor = c.contrasted() # a color of an RGBA(204, 229, 102, 255) + [/codeblock] </description> </method> <method name="gray"> <return type="float"> </return> <description> - Convert the color to gray. + Returns the color's grayscale. + The gray is calculated by (r + g + b) / 3. + [codeblock] + var c = Color(0.2, 0.45, 0.82) + var gray = c.gray() # a value of 0.466667 + [/codeblock] </description> </method> <method name="inverted"> <return type="Color"> </return> <description> - Return the inverted color (1-r, 1-g, 1-b, 1-a). + Returns the inverted color (1-r, 1-g, 1-b, 1-a). + [codeblock] + var c = Color(.3, .4, .9) + var invertedColor = c.inverted() # a color of an RGBA(178, 153, 26, 255) + [/codeblock] </description> </method> <method name="linear_interpolate"> @@ -12289,21 +12869,36 @@ <argument index="1" name="t" type="float"> </argument> <description> - Return the linear interpolation with another color. + Returns the color of the linear interpolation with another color. The value t is between 0 and 1 (float). + [codeblock] + var c1 = Color(1.0, 0.0, 0.0) + var c2 = Color(0.0, 1.0, 0.0) + var li_c = c1.linear_interpolate(c2, 0.5) # a color of an RGBA(128, 128, 0, 255) + [/codeblock] </description> </method> - <method name="to_32"> + <method name="to_rgba32"> <return type="int"> </return> <description> - Convert the color to a 32 its integer (each byte represents a RGBA). + Returns the color's 32-bit integer in ARGB format (each byte represents a component of the ARGB profile). + [codeblock] + var c = Color(1, .5, .2) + print(str(c.to_32())) # prints 4294934323 + [/codeblock] + + [i]This is same as [method to_ARGB32] but may be changed later to support RGBA format instead[/i]. </description> </method> - <method name="to_ARGB32"> + <method name="to_argb32"> <return type="int"> </return> <description> - Convert color to ARGB32, more compatible with DirectX. + Returns the color's 32-bit integer in ARGB format (each byte represents a component of the ARGB profile). More compatible with DirectX. + [codeblock] + var c = Color(1, .5, .2) + print(str(c.to_32())) # prints 4294934323 + [/codeblock] </description> </method> <method name="to_html"> @@ -12312,7 +12907,13 @@ <argument index="0" name="with_alpha" type="bool" default="True"> </argument> <description> - Return the HTML hexadecimal color string. + Returns the color's HTML hexadecimal color string in ARGB format (ex: [code]ff34f822[/code]). + Optionally flag 'false' to not include alpha in hexadecimal string. + [codeblock] + var c = Color(1, 1, 1, .5) + var s1 = c.to_html() # Results "7fffffff" + var s2 = c.to_html(false) # Results 'ffffff' + [/codeblock] </description> </method> </methods> @@ -12494,6 +13095,12 @@ <argument index="0" name="color" type="Color"> </argument> <description> + Set new color to ColorRect. + + [codeblock] + var cr = get_node("colorrect_node") + cr.set_frame_color(Color(1, 0, 0, 1)) # Set color rect node to red + [/codeblock] </description> </method> </methods> @@ -12541,14 +13148,21 @@ </class> <class name="ColorRect" inherits="Control" category="Core"> <brief_description> + Colored rect for canvas. </brief_description> <description> + An object that is represented on the canvas as a rect with color. [Color] is used to set or get color info for the rect. </description> <methods> <method name="get_frame_color" qualifiers="const"> <return type="Color"> </return> <description> + Return the color in RGBA format. + [codeblock] + var cr = get_node("colorrect_node") + var c = cr.get_frame_color() # Default color is white + [/codeblock] </description> </method> <method name="set_frame_color"> @@ -12557,6 +13171,11 @@ <argument index="0" name="color" type="Color"> </argument> <description> + Set new color to ColorRect. + [codeblock] + var cr = get_node("colorrect_node") + cr.set_frame_color(Color(1, 0, 0, 1)) # Set color rect node to red + [/codeblock] </description> </method> </methods> @@ -12759,7 +13378,7 @@ </description> </method> <method name="load"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -12768,7 +13387,7 @@ </description> </method> <method name="save"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -12856,23 +13475,23 @@ </class> <class name="Control" inherits="CanvasItem" category="Core"> <brief_description> - Control is the base node for all the GUI components. + Base node for all User Interface components. </brief_description> <description> - Control is the base class Node for all the GUI components. Every GUI component inherits from it, directly or indirectly. In this way, sections of the scene tree made of contiguous control nodes, become user interfaces. - Controls are relative to the parent position and size by using anchors and margins. This ensures that they can adapt easily in most situation to changing dialog and screen sizes. When more flexibility is desired, [Container] derived nodes can be used. + The base class Node for all User Interface components. Every UI node inherits from it. Any scene or portion of a scene tree composed of Control nodes is a User Interface. + Controls use anchors and margins to place themselves relative to their parent. They adapt automatically when their parent or the screen size changes. To build flexible UIs, use built-in [Container] nodes or create your own. Anchors work by defining which margin do they follow, and a value relative to it. Allowed anchoring modes are ANCHOR_BEGIN, where the margin is relative to the top or left margins of the parent (in pixels), ANCHOR_END for the right and bottom margins of the parent and ANCHOR_RATIO, which is a ratio from 0 to 1 in the parent range. - Input device events are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [method MainLoop._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event]. - Only one control can hold the keyboard focus (receiving keyboard events), for that the control must define the focus mode with [method set_focus_mode]. Focus is lost when another control gains it, or the current focus owner is hidden. - It is sometimes desired for a control to ignore mouse/pointer events. This is often the case when placing other controls on top of a button, in such cases. Calling [method set_ignore_mouse] enables this function. - Finally, controls are skinned according to a [Theme]. Setting a [Theme] on a control will propagate all the skinning down the tree. Optionally, skinning can be overridden per each control by calling the add_*_override functions, or from the editor. + Godot sends Input events to the root node first, via [method Node._input]. The method distributes it through the node tree and delivers the input events to the node under the mouse cursor or on focus with the keyboard. To do so, it calls [method MainLoop._input_event]. No need to enable [method Node.set_process_input] on Controls to receive input events. Call [method accept_event] to ensure no other node receives the event, not even [method Node._unhandled_input]. + Only the one Control node in focus receives keyboard events. To do so, the Control must get the focus mode with [method set_focus_mode]. It loses focus when another Control gets it, or if the current Control in focus is hidden. + You'll sometimes want Controls to ignore mouse or touch events. For example, if you place an icon on top of a button. Call [method set_ignore_mouse] for that. + [Theme] resources change the Control's appearance. If you change the [Theme] on a parent Control node, it will propagate to all of its children. You can override parts of the theme on each Control with the add_*_override methods, like [method add_font_override]. You can also override the theme from the editor. </description> <methods> <method name="_get_minimum_size" qualifiers="virtual"> <return type="Vector2"> </return> <description> - Return the minimum size this Control can shrink to. A control will never be displayed or resized smaller than its minimum size. + Returns the minimum size this Control can shrink to. A control will never be displayed or resized smaller than its minimum size. </description> </method> <method name="_gui_input" qualifiers="virtual"> @@ -12887,7 +13506,7 @@ <return type="void"> </return> <description> - Handles the event, no other control will receive it and it will not be sent to nodes waiting on [method Node._unhandled_input] or [method Node._unhandled_key_input]. + Marks the input event as handled. No other Control will receive it, and the input event will not propagate. Not even to nodes listening to [method Node._unhandled_input] or [method Node._unhandled_key_input]. </description> </method> <method name="add_color_override"> @@ -13004,7 +13623,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13020,13 +13639,13 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> </method> <method name="get_cursor_shape" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.CursorShape"> </return> <argument index="0" name="pos" type="Vector2" default="Vector2( 0, 0 )"> </argument> @@ -13041,7 +13660,7 @@ </description> </method> <method name="get_default_cursor_shape" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.CursorShape"> </return> <description> Return the default cursor shape for this control. See enum CURSOR_* for the list of shapes. @@ -13063,7 +13682,7 @@ </description> </method> <method name="get_focus_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.FocusMode"> </return> <description> Returns the focus access mode for the control (FOCUS_NONE, FOCUS_CLICK, FOCUS_ALL) (see [method set_focus_mode]). @@ -13090,7 +13709,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13110,7 +13729,7 @@ </description> </method> <method name="get_h_grow_direction" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.GrowDirection"> </return> <description> </description> @@ -13127,7 +13746,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13149,7 +13768,7 @@ </description> </method> <method name="get_mouse_filter" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.MouseFilter"> </return> <description> Return when the control is ignoring mouse events (even touchpad events send mouse events). @@ -13226,7 +13845,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13248,7 +13867,7 @@ </description> </method> <method name="get_v_grow_direction" qualifiers="const"> - <return type="int"> + <return type="int" enum="Control.GrowDirection"> </return> <description> </description> @@ -13278,7 +13897,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13296,7 +13915,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13321,7 +13940,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13339,7 +13958,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13365,7 +13984,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="type" type="String" default="null"> + <argument index="1" name="type" type="String" default=""""> </argument> <description> </description> @@ -13404,9 +14023,9 @@ </argument> <argument index="1" name="anchor" type="float"> </argument> - <argument index="2" name="keep_margin" type="bool" default="null"> + <argument index="2" name="keep_margin" type="bool" default="false"> </argument> - <argument index="3" name="push_opposite_anchor" type="bool" default="null"> + <argument index="3" name="push_opposite_anchor" type="bool" default="true"> </argument> <description> </description> @@ -13420,7 +14039,7 @@ </argument> <argument index="2" name="offset" type="float"> </argument> - <argument index="3" name="push_opposite_anchor" type="bool" default="null"> + <argument index="3" name="push_opposite_anchor" type="bool" default="false"> </argument> <description> </description> @@ -13430,7 +14049,7 @@ </return> <argument index="0" name="preset" type="int" enum="Control.LayoutPreset"> </argument> - <argument index="1" name="keep_margin" type="bool" default="null"> + <argument index="1" name="keep_margin" type="bool" default="false"> </argument> <description> </description> @@ -13742,12 +14361,12 @@ <signals> <signal name="focus_entered"> <description> - Emitted when keyboard focus is gained. + Emitted when the node gains keyboard focus. </description> </signal> <signal name="focus_exited"> <description> - Emitted when the keyboard focus is lost. + Emitted when the node loses keyboard focus. </description> </signal> <signal name="gui_input"> @@ -13758,7 +14377,7 @@ </signal> <signal name="minimum_size_changed"> <description> - Emitted when the minimum size of the control changed. + Emitted when the node's minimum size changes. </description> </signal> <signal name="modal_closed"> @@ -13767,22 +14386,22 @@ </signal> <signal name="mouse_entered"> <description> - Emitted when the mouse enters the control area. + Emitted when the mouse enters the control's area. </description> </signal> <signal name="mouse_exited"> <description> - Emitted when the mouse left the control area. + Emitted when the mouse leaves the control's area. </description> </signal> <signal name="resized"> <description> - Emitted when the control changed size. + Emitted when the control changes size. </description> </signal> <signal name="size_flags_changed"> <description> - Emitted when the size flags changed. + Emitted when the size flags change. </description> </signal> </signals> @@ -14016,7 +14635,7 @@ </description> </method> <method name="get_storage" qualifiers="const"> - <return type="int"> + <return type="int" enum="CubeMap.Storage"> </return> <description> </description> @@ -14093,8 +14712,10 @@ </class> <class name="CubeMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Generate an axis-aligned cuboid [PrimitiveMesh]. </brief_description> <description> + Generate an axis-aligned cuboid [PrimitiveMesh]. </description> <methods> <method name="get_size" qualifiers="const"> @@ -14156,12 +14777,16 @@ </methods> <members> <member name="size" type="Vector3" setter="set_size" getter="get_size" brief=""> + Size of the cuboid mesh. Defaults to (2, 2, 2). </member> <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief=""> + Number of extra edge loops inserted along the z-axis. Defaults to 0. </member> <member name="subdivide_height" type="int" setter="set_subdivide_height" getter="get_subdivide_height" brief=""> + Number of extra edge loops inserted along the y-axis. Defaults to 0. </member> <member name="subdivide_width" type="int" setter="set_subdivide_width" getter="get_subdivide_width" brief=""> + Number of extra edge loops inserted along the x-axis. Defaults to 0. </member> </members> <constants> @@ -14184,7 +14809,7 @@ </argument> <argument index="3" name="left_mode" type="int" enum="Curve.TangentMode" default="0"> </argument> - <argument index="4" name="right_mode" type="int" enum="Curve.TangentMode" default="null"> + <argument index="4" name="right_mode" type="int" enum="Curve.TangentMode" default="0"> </argument> <description> </description> @@ -14226,7 +14851,7 @@ </description> </method> <method name="get_point_left_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Curve.TangentMode"> </return> <argument index="0" name="index" type="int"> </argument> @@ -14250,7 +14875,7 @@ </description> </method> <method name="get_point_right_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Curve.TangentMode"> </return> <argument index="0" name="index" type="int"> </argument> @@ -14411,7 +15036,7 @@ </argument> <argument index="2" name="out" type="Vector2" default="Vector2( 0, 0 )"> </argument> - <argument index="3" name="atpos" type="int" default="null"> + <argument index="3" name="atpos" type="int" default="-1"> </argument> <description> Adds a point to a curve, at position "pos", with control points "in" and "out". @@ -14496,7 +15121,7 @@ </return> <argument index="0" name="offset" type="float"> </argument> - <argument index="1" name="cubic" type="bool" default="null"> + <argument index="1" name="cubic" type="bool" default="false"> </argument> <description> Returns a point within the curve at position "offset", where "offset" is measured as a pixel distance along the curve. @@ -14567,9 +15192,9 @@ <method name="tessellate" qualifiers="const"> <return type="PoolVector2Array"> </return> - <argument index="0" name="max_stages" type="int" default="4"> + <argument index="0" name="max_stages" type="int" default="5"> </argument> - <argument index="1" name="tolerance_degrees" type="float" default="5"> + <argument index="1" name="tolerance_degrees" type="float" default="4"> </argument> <description> Returns a list of points along the curve, with a curvature controlled point density. That is, the curvier parts will have more points than the straighter parts. @@ -14606,7 +15231,7 @@ </argument> <argument index="2" name="out" type="Vector3" default="Vector3( 0, 0, 0 )"> </argument> - <argument index="3" name="atpos" type="int" default="null"> + <argument index="3" name="atpos" type="int" default="-1"> </argument> <description> Adds a point to a curve, at position "pos", with control points "in" and "out". @@ -14707,7 +15332,7 @@ </return> <argument index="0" name="offset" type="float"> </argument> - <argument index="1" name="cubic" type="bool" default="null"> + <argument index="1" name="cubic" type="bool" default="false"> </argument> <description> Returns a point within the curve at position "offset", where "offset" is measured as a distance in 3D units along the curve. @@ -14790,9 +15415,9 @@ <method name="tessellate" qualifiers="const"> <return type="PoolVector3Array"> </return> - <argument index="0" name="max_stages" type="int" default="4"> + <argument index="0" name="max_stages" type="int" default="5"> </argument> - <argument index="1" name="tolerance_degrees" type="float" default="5"> + <argument index="1" name="tolerance_degrees" type="float" default="4"> </argument> <description> Returns a list of points along the curve, with a curvature controlled point density. That is, the curvier parts will have more points than the straighter parts. @@ -14851,8 +15476,10 @@ </class> <class name="CylinderMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Class representing a cylindrical [PrimitiveMesh]. </brief_description> <description> + Class representing a cylindrical [PrimitiveMesh]. </description> <methods> <method name="get_bottom_radius" qualifiers="const"> @@ -14928,14 +15555,19 @@ </methods> <members> <member name="bottom_radius" type="float" setter="set_bottom_radius" getter="get_bottom_radius" brief=""> + Bottom radius of the cylinder. Defaults to 1.0. </member> <member name="height" type="float" setter="set_height" getter="get_height" brief=""> + Full height of the cylinder. Defaults to 2.0. </member> <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" brief=""> + Number of radial segments on the cylinder. Defaults to 64. </member> <member name="rings" type="int" setter="set_rings" getter="get_rings" brief=""> + Number of edge rings along the height of the cylinder. Defaults to 4. </member> <member name="top_radius" type="float" setter="set_top_radius" getter="get_top_radius" brief=""> + Top radius of the cylinder. Defaults to 1.0. </member> </members> <constants> @@ -15113,7 +15745,7 @@ </description> <methods> <method name="get_shadow_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="DirectionalLight.ShadowMode"> </return> <description> </description> @@ -15191,7 +15823,7 @@ </description> <methods> <method name="change_dir"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="todir" type="String"> </argument> @@ -15201,7 +15833,7 @@ </description> </method> <method name="copy"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="from" type="String"> </argument> @@ -15282,7 +15914,7 @@ </description> </method> <method name="list_dir_begin"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="skip_navigational" type="bool" default="false"> </argument> @@ -15302,7 +15934,7 @@ </description> </method> <method name="make_dir"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -15312,7 +15944,7 @@ </description> </method> <method name="make_dir_recursive"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -15322,7 +15954,7 @@ </description> </method> <method name="open"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -15332,7 +15964,7 @@ </description> </method> <method name="remove"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -15342,7 +15974,7 @@ </description> </method> <method name="rename"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="from" type="String"> </argument> @@ -15556,7 +16188,7 @@ </description> </method> <method name="get_access" qualifiers="const"> - <return type="int"> + <return type="int" enum="EditorFileDialog.Access"> </return> <description> </description> @@ -15580,13 +16212,13 @@ </description> </method> <method name="get_display_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="EditorFileDialog.DisplayMode"> </return> <description> </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="EditorFileDialog.Mode"> </return> <description> </description> @@ -16070,7 +16702,7 @@ </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="for_property" type="String" default="null"> + <argument index="1" name="for_property" type="String" default=""""> </argument> <description> </description> @@ -16102,7 +16734,7 @@ </description> </method> <method name="save_scene"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> </description> @@ -16112,7 +16744,7 @@ </return> <argument index="0" name="path" type="String"> </argument> - <argument index="1" name="with_preview" type="bool" default="null"> + <argument index="1" name="with_preview" type="bool" default="true"> </argument> <description> </description> @@ -16842,7 +17474,7 @@ </argument> <argument index="1" name="billboard" type="bool" default="false"> </argument> - <argument index="2" name="secondary" type="bool" default="null"> + <argument index="2" name="secondary" type="bool" default="false"> </argument> <description> Add a list of handles (points) which can be used to deform the object being edited. @@ -16856,7 +17488,7 @@ </argument> <argument index="1" name="material" type="Material"> </argument> - <argument index="2" name="billboard" type="bool" default="null"> + <argument index="2" name="billboard" type="bool" default="false"> </argument> <description> Add lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. Call this function during [method redraw]. @@ -16869,7 +17501,7 @@ </argument> <argument index="1" name="billboard" type="bool" default="false"> </argument> - <argument index="2" name="skeleton" type="RID" default="null"> + <argument index="2" name="skeleton" type="RID"> </argument> <description> </description> @@ -16879,7 +17511,7 @@ </return> <argument index="0" name="material" type="Material"> </argument> - <argument index="1" name="default_scale" type="float" default="null"> + <argument index="1" name="default_scale" type="float" default="1"> </argument> <description> Add an unscaled billboard for visualization. Call this function during [method redraw]. @@ -17139,7 +17771,7 @@ </description> </method> <method name="get_background" qualifiers="const"> - <return type="int"> + <return type="int" enum="Environment.BGMode"> </return> <description> </description> @@ -17175,7 +17807,7 @@ </description> </method> <method name="get_dof_blur_far_quality" qualifiers="const"> - <return type="int"> + <return type="int" enum="Environment.DOFBlurQuality"> </return> <description> </description> @@ -17199,7 +17831,7 @@ </description> </method> <method name="get_dof_blur_near_quality" qualifiers="const"> - <return type="int"> + <return type="int" enum="Environment.DOFBlurQuality"> </return> <description> </description> @@ -17265,7 +17897,7 @@ </description> </method> <method name="get_glow_blend_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Environment.GlowBlendMode"> </return> <description> </description> @@ -17421,7 +18053,7 @@ </description> </method> <method name="get_tonemapper" qualifiers="const"> - <return type="int"> + <return type="int" enum="Environment.ToneMapper"> </return> <description> </description> @@ -18370,7 +19002,7 @@ </description> </method> <method name="get_error" qualifiers="const"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Get the last error that happened when trying to perform operations. Compare with the [code]ERR_FILE_*[/code] constants from [@Global Scope]. @@ -18459,7 +19091,7 @@ </description> </method> <method name="open"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -18470,20 +19102,20 @@ </description> </method> <method name="open_compressed"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> <argument index="1" name="mode_flags" type="int"> </argument> - <argument index="2" name="compression_mode" type="int" default="null"> + <argument index="2" name="compression_mode" type="int" default="0"> </argument> <description> Open a compressed file for reading or writing. The compression_mode can be set as one of the COMPRESSION_* constants. </description> </method> <method name="open_encrypted"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -18496,7 +19128,7 @@ </description> </method> <method name="open_encrypted_with_pass"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -18696,7 +19328,7 @@ </description> </method> <method name="get_access" qualifiers="const"> - <return type="int"> + <return type="int" enum="FileDialog.Access"> </return> <description> Return the file access permission of the dialog. @@ -18730,7 +19362,7 @@ </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="FileDialog.Mode"> </return> <description> Get the file dialog mode from the MODE_* enum. @@ -18905,9 +19537,9 @@ </argument> <argument index="2" name="string" type="String"> </argument> - <argument index="3" name="modulate" type="Color" default="null"> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="4" name="clip_w" type="int" default="null"> + <argument index="4" name="clip_w" type="int" default="-1"> </argument> <description> Draw "string" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. @@ -18922,9 +19554,9 @@ </argument> <argument index="2" name="char" type="int"> </argument> - <argument index="3" name="next" type="int" default="null"> + <argument index="3" name="next" type="int" default="-1"> </argument> - <argument index="4" name="modulate" type="Color" default="null"> + <argument index="4" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> <description> Draw character "char" into a canvas item using the font at a given "pos" position, with "modulate" color, and optionally kerning if "next" is passed. clipping the width. "pos" specifies the baseline, not the top. To draw from the top, [i]ascent[/i] must be added to the Y axis. The width used by the character is returned, making this function useful for drawing strings character by character. @@ -19137,6 +19769,12 @@ <description> </description> </method> + <method name="is_singleton_gdnative" qualifiers="const"> + <return type="bool"> + </return> + <description> + </description> + </method> <method name="set_library_path"> <return type="void"> </return> @@ -19147,26 +19785,49 @@ <description> </description> </method> + <method name="set_singleton_gdnative"> + <return type="void"> + </return> + <argument index="0" name="singleton" type="bool"> + </argument> + <description> + </description> + </method> </methods> + <members> + <member name="singleton_gdnative" type="bool" setter="set_singleton_gdnative" getter="is_singleton_gdnative" brief=""> + </member> + </members> <constants> </constants> </class> <class name="GDScript" inherits="Script" category="Core"> <brief_description> + A script implemented in the GDScript programming language. </brief_description> <description> + A script implemented in the GDScript programming language. The script exends the functionality of all objects that instance it. + [method new] creates a new instance of the script. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. </description> <methods> <method name="get_as_byte_code" qualifiers="const"> <return type="PoolByteArray"> </return> <description> + Returns byte code for the script source code. </description> </method> <method name="new" qualifiers="vararg"> <return type="Object"> </return> <description> + Returns a new instance of the script. + For example: + [codeblock] + var MyClass = load("myclass.gd") + var instance = MyClass.new() + assert(instance.get_script() == MyClass) + [/codeblock] </description> </method> </methods> @@ -19182,9 +19843,9 @@ <method name="bake"> <return type="void"> </return> - <argument index="0" name="from_node" type="Node" default="false"> + <argument index="0" name="from_node" type="Node" default="null"> </argument> - <argument index="1" name="create_visual_debug" type="bool" default="null"> + <argument index="1" name="create_visual_debug" type="bool" default="false"> </argument> <description> </description> @@ -19238,7 +19899,7 @@ </description> </method> <method name="get_subdiv" qualifiers="const"> - <return type="int"> + <return type="int" enum="GIProbe.Subdiv"> </return> <description> </description> @@ -19842,7 +20503,7 @@ </argument> <argument index="3" name="lats" type="int"> </argument> - <argument index="4" name="axis" type="int" enum="Vector3.Axis" default="null"> + <argument index="4" name="axis" type="int" enum="Vector3.Axis" default="2"> </argument> <description> </description> @@ -19856,7 +20517,7 @@ </argument> <argument index="2" name="sides" type="int"> </argument> - <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="null"> + <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="2"> </argument> <description> </description> @@ -20088,7 +20749,7 @@ </description> <methods> <method name="get_cast_shadows_setting" qualifiers="const"> - <return type="int"> + <return type="int" enum="GeometryInstance.ShadowCastingSetting"> </return> <description> </description> @@ -20365,8 +21026,10 @@ </class> <class name="GradientTexture" inherits="Texture" category="Core"> <brief_description> + Gradient filled texture. </brief_description> <description> + Uses a [Gradient] to fill the texture data, the gradient will be filled from left to right using colors obtained from the gradient, this means that the texture does not necessarily represent an exact copy of the gradient, but instead an interpolation of samples obtained from the gradient at fixed steps (see [method set_width]). </description> <methods> <method name="get_gradient" qualifiers="const"> @@ -20394,8 +21057,10 @@ </methods> <members> <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient" brief=""> + The [Gradient] that will be used to fill the texture. </member> <member name="width" type="int" setter="set_width" getter="get_width" brief=""> + The number of color samples that will be obtained from the [Gradient]. </member> </members> <constants> @@ -20411,7 +21076,7 @@ </description> <methods> <method name="connect_node"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="from" type="String"> </argument> @@ -20746,7 +21411,7 @@ </description> </method> <method name="get_overlay" qualifiers="const"> - <return type="int"> + <return type="int" enum="GraphNode.Overlay"> </return> <description> </description> @@ -20807,7 +21472,7 @@ <description> </description> </method> - <method name="is_resizeable" qualifiers="const"> + <method name="is_resizable" qualifiers="const"> <return type="bool"> </return> <description> @@ -20862,10 +21527,10 @@ <description> </description> </method> - <method name="set_resizeable"> + <method name="set_resizable"> <return type="void"> </return> - <argument index="0" name="resizeable" type="bool"> + <argument index="0" name="resizable" type="bool"> </argument> <description> </description> @@ -20922,7 +21587,7 @@ </method> </methods> <members> - <member name="resizeable" type="bool" setter="set_resizeable" getter="is_resizeable" brief=""> + <member name="resizable" type="bool" setter="set_resizable" getter="is_resizable" brief=""> </member> <member name="show_close" type="bool" setter="set_show_close_button" getter="is_close_button_visible" brief=""> </member> @@ -21141,7 +21806,7 @@ </argument> <argument index="3" name="item" type="int"> </argument> - <argument index="4" name="orientation" type="int" default="null"> + <argument index="4" name="orientation" type="int" default="0"> </argument> <description> </description> @@ -21183,11 +21848,11 @@ </return> <argument index="0" name="enabled" type="bool"> </argument> - <argument index="1" name="clipabove" type="bool" default="0"> + <argument index="1" name="clipabove" type="bool" default="true"> </argument> - <argument index="2" name="floor" type="int" default="true"> + <argument index="2" name="floor" type="int" default="0"> </argument> - <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="null"> + <argument index="3" name="axis" type="int" enum="Vector3.Axis" default="0"> </argument> <description> </description> @@ -21399,15 +22064,15 @@ </description> </method> <method name="connect_to_host"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="host" type="String"> </argument> <argument index="1" name="port" type="int"> </argument> - <argument index="2" name="use_ssl" type="bool" default="null"> + <argument index="2" name="use_ssl" type="bool" default="false"> </argument> - <argument index="3" name="verify_host" type="bool" default="null"> + <argument index="3" name="verify_host" type="bool" default="true"> </argument> <description> Connect to a host. This needs to be done before any requests are sent. @@ -21453,7 +22118,7 @@ </description> </method> <method name="get_status" qualifiers="const"> - <return type="int"> + <return type="int" enum="HTTPClient.Status"> </return> <description> Returns a STATUS_* enum constant. Need to call [method poll] in order to get status updates. @@ -21481,7 +22146,7 @@ </description> </method> <method name="poll"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> This needs to be called in order to have any request processed. Check results with [method get_status] @@ -21509,7 +22174,7 @@ </description> </method> <method name="request"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="method" type="int" enum="HTTPClient.Method"> </argument> @@ -21517,7 +22182,7 @@ </argument> <argument index="2" name="headers" type="PoolStringArray"> </argument> - <argument index="3" name="body" type="String" default="null"> + <argument index="3" name="body" type="String" default=""""> </argument> <description> Sends a request to the connected host. The url is what is normally behind the hostname, i.e. in [code]http://somehost.com/index.php[/code], url would be "index.php". @@ -21532,7 +22197,7 @@ </description> </method> <method name="request_raw"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="method" type="int" enum="HTTPClient.Method"> </argument> @@ -21549,7 +22214,7 @@ </description> </method> <method name="send_body_data"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="body" type="PoolByteArray"> </argument> @@ -21558,7 +22223,7 @@ </description> </method> <method name="send_body_text"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="body" type="String"> </argument> @@ -21778,7 +22443,7 @@ </description> </method> <method name="get_http_client_status" qualifiers="const"> - <return type="int"> + <return type="int" enum="HTTPClient.Status"> </return> <description> Return the current status of the underlying [HTTPClient]. @@ -21799,17 +22464,17 @@ </description> </method> <method name="request"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="url" type="String"> </argument> - <argument index="1" name="custom_headers" type="PoolStringArray" default="0"> + <argument index="1" name="custom_headers" type="PoolStringArray" default="PoolStringArray( )"> </argument> <argument index="2" name="ssl_validate_domain" type="bool" default="true"> </argument> - <argument index="3" name="method" type="int" enum="HTTPClient.Method" default="PoolStringArray( )"> + <argument index="3" name="method" type="int" enum="HTTPClient.Method" default="0"> </argument> - <argument index="4" name="request_data" type="String" default="null"> + <argument index="4" name="request_data" type="String" default=""""> </argument> <description> </description> @@ -22009,7 +22674,7 @@ IP Protocol support functions. </brief_description> <description> - IP contains some support functions for the IPv4 protocol. TCP/IP support is in different classes (see [StreamPeerTCP] and [TCP_Server]). IP provides hostname resolution support, both blocking and threaded. + IP contains support functions for the IPv4 protocol. TCP/IP support is in different classes (see [StreamPeerTCP] and [TCP_Server]). IP provides hostname resolution support, both blocking and threaded. </description> <methods> <method name="clear_cache"> @@ -22018,6 +22683,7 @@ <argument index="0" name="hostname" type="String" default=""""> </argument> <description> + Removes all of a "hostname"'s cached references. If no "hostname" is given then all cached IP addresses are removed. </description> </method> <method name="erase_resolve_item"> @@ -22026,13 +22692,14 @@ <argument index="0" name="id" type="int"> </argument> <description> - Erase a queue ID, removing it from the queue if needed. This should be used after a queue is completed to free it and enable more queries to happen. + Removes a given item "id" from the queue. This should be used to free a queue after it has completed to enable more queries to happen. </description> </method> - <method name="get_local_addresses" qualifiers="const"> + <method name="get_local_addresses" qualifiers="const"> <return type="Array"> </return> <description> + Returns all of the user's current IPv4 and IPv6 addresses as an array. </description> </method> <method name="get_resolve_item_address" qualifiers="const"> @@ -22041,16 +22708,16 @@ <argument index="0" name="id" type="int"> </argument> <description> - Return a resolved item address, or an empty string if an error happened or resolution didn't happen yet (see [method get_resolve_item_status]). + Returns a queued hostname's IP address, given its queue "id". Returns an empty string on error or if resolution hasn't happened yet (see [method get_resolve_item_status]). </description> </method> <method name="get_resolve_item_status" qualifiers="const"> - <return type="int"> + <return type="int" enum="IP.ResolverStatus"> </return> <argument index="0" name="id" type="int"> </argument> <description> - Return the status of hostname queued for resolving, given its queue ID. Returned status can be any of the RESOLVER_STATUS_* enumeration. + Returns a queued hostname's status as a RESOLVER_STATUS_* constant, given its queue "id". </description> </method> <method name="resolve_hostname"> @@ -22058,10 +22725,10 @@ </return> <argument index="0" name="host" type="String"> </argument> - <argument index="1" name="ip_type" type="int" enum="IP.Type" default="null"> + <argument index="1" name="ip_type" type="int" enum="IP.Type" default="3"> </argument> <description> - Resolve a given hostname, blocking. Resolved hostname is returned as an IPv4 or IPv6 depending on "ip_type". + Returns a given hostname's IPv4 or IPv6 address when resolved (blocking-type method). The address type returned depends on the TYPE_* constant given as "ip_type". </description> </method> <method name="resolve_hostname_queue_item"> @@ -22069,10 +22736,10 @@ </return> <argument index="0" name="host" type="String"> </argument> - <argument index="1" name="ip_type" type="int" enum="IP.Type" default="null"> + <argument index="1" name="ip_type" type="int" enum="IP.Type" default="3"> </argument> <description> - Create a queue item for resolving a given hostname to an IPv4 or IPv6 depending on "ip_type". The queue ID is returned, or RESOLVER_INVALID_ID on error. + Creates a queue item to resolve a hostname to an IPv4 or IPv6 address depending on the TYPE_* constant given as "ip_type". Returns the queue ID if successful, or RESOLVER_INVALID_ID on error. </description> </method> </methods> @@ -22180,7 +22847,7 @@ </description> </method> <method name="compress"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="mode" type="int" enum="Image.CompressMode"> </argument> @@ -22249,13 +22916,13 @@ </description> </method> <method name="decompress"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> </description> </method> <method name="detect_alpha" qualifiers="const"> - <return type="int"> + <return type="int" enum="Image.AlphaMode"> </return> <description> </description> @@ -22294,7 +22961,7 @@ </description> </method> <method name="generate_mipmaps"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> </description> @@ -22307,7 +22974,7 @@ </description> </method> <method name="get_format" qualifiers="const"> - <return type="int"> + <return type="int" enum="Image.Format"> </return> <description> Return the format of the [Image], one of [Image].FORMAT_*. @@ -22392,7 +23059,7 @@ </description> </method> <method name="load"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -22425,7 +23092,7 @@ </argument> <argument index="1" name="height" type="int"> </argument> - <argument index="2" name="interpolation" type="int" enum="Image.Interpolation" default="null"> + <argument index="2" name="interpolation" type="int" enum="Image.Interpolation" default="1"> </argument> <description> </description> @@ -22439,7 +23106,7 @@ </description> </method> <method name="save_png" qualifiers="const"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -22606,7 +23273,7 @@ </argument> <argument index="2" name="format" type="int" enum="Image.Format"> </argument> - <argument index="3" name="flags" type="int" default="null"> + <argument index="3" name="flags" type="int" default="7"> </argument> <description> Create a new [ImageTexture] with "width" and "height". @@ -22619,14 +23286,14 @@ </return> <argument index="0" name="image" type="Image"> </argument> - <argument index="1" name="flags" type="int" default="null"> + <argument index="1" name="flags" type="int" default="7"> </argument> <description> Create a new [ImageTexture] from an [Image] with "flags" from [Texture].FLAG_*. </description> </method> <method name="get_format" qualifiers="const"> - <return type="int"> + <return type="int" enum="Image.Format"> </return> <description> Return the format of the [ImageTexture], one of [Image].FORMAT_*. @@ -22640,7 +23307,7 @@ </description> </method> <method name="get_storage" qualifiers="const"> - <return type="int"> + <return type="int" enum="ImageTexture.Storage"> </return> <description> Return the storage type. One of [ImageTexture].STORAGE_*. @@ -22719,7 +23386,7 @@ </argument> <argument index="2" name="radius" type="float"> </argument> - <argument index="3" name="add_uv" type="bool" default="null"> + <argument index="3" name="add_uv" type="bool" default="true"> </argument> <description> Simple helper to draw a uvsphere, with given latitudes, longitude and radius. @@ -22840,7 +23507,7 @@ </return> <argument index="0" name="mapping" type="String"> </argument> - <argument index="1" name="update_existing" type="bool" default="null"> + <argument index="1" name="update_existing" type="bool" default="false"> </argument> <description> Add a new mapping entry (in SDL2 format) to the mapping database. Optionally update already connected devices. @@ -22974,7 +23641,7 @@ </description> </method> <method name="get_mouse_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Input.MouseMode"> </return> <description> Return the mouse mode. See the constants for more information. @@ -23065,7 +23732,7 @@ </return> <argument index="0" name="image" type="Resource"> </argument> - <argument index="1" name="hotspot" type="Vector2" default="null"> + <argument index="1" name="hotspot" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> </description> @@ -23088,7 +23755,7 @@ </argument> <argument index="2" name="strong_magnitude" type="float"> </argument> - <argument index="3" name="duration" type="float" default="null"> + <argument index="3" name="duration" type="float" default="0"> </argument> <description> Starts to vibrate the joypad. Joypads usually come with two rumble motors, a strong and a weak one. weak_magnitude is the strength of the weak motor (between 0 and 1) and strong_magnitude is the strength of the strong motor (between 0 and 1). duration is the duration of the effect in seconds (a duration of 0 will try to play the vibration indefinitely). @@ -23153,6 +23820,7 @@ </class> <class name="InputEvent" inherits="Resource" category="Core"> <brief_description> + Generic input event </brief_description> <description> </description> @@ -23163,24 +23831,28 @@ <argument index="0" name="event" type="InputEvent"> </argument> <description> + Returns true if this input event matches the event passed. </description> </method> <method name="as_text" qualifiers="const"> <return type="String"> </return> <description> + Returns a [String] representation of the event. </description> </method> <method name="get_device" qualifiers="const"> <return type="int"> </return> <description> + Returns the id of the device that generated the event. </description> </method> <method name="get_id" qualifiers="const"> <return type="int"> </return> <description> + Returns the id of the event. </description> </method> <method name="is_action" qualifiers="const"> @@ -23189,7 +23861,7 @@ <argument index="0" name="action" type="String"> </argument> <description> - Return if this input event matches a pre-defined action, no matter the type. + Returns true if this input event matches a pre-defined action, no matter the type. </description> </method> <method name="is_action_pressed" qualifiers="const"> @@ -23198,7 +23870,7 @@ <argument index="0" name="action" type="String"> </argument> <description> - Return whether the given action is being pressed (and is not an echo event for KEY events). Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE. + Returns true if the given action is being pressed (and is not an echo event for KEY events). Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE. </description> </method> <method name="is_action_released" qualifiers="const"> @@ -23207,7 +23879,7 @@ <argument index="0" name="action" type="String"> </argument> <description> - Return whether the given action is released (i.e. not pressed). Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE. + Returns true if the given action is released (i.e. not pressed). Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE. </description> </method> <method name="is_action_type" qualifiers="const"> @@ -23220,14 +23892,14 @@ <return type="bool"> </return> <description> - Return if this input event is an echo event (only for events of type KEY, it will return false for other types). + Returns true if this input event is an echo event (only for events of type KEY, it will return false for other types). </description> </method> <method name="is_pressed" qualifiers="const"> <return type="bool"> </return> <description> - Return if this input event is pressed. Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE. + Returns true if this input event is pressed. Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE. </description> </method> <method name="set_device"> @@ -23259,7 +23931,7 @@ </return> <argument index="0" name="xform" type="Transform2D"> </argument> - <argument index="1" name="local_ofs" type="Vector2" default="null"> + <argument index="1" name="local_ofs" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> </description> @@ -24139,7 +24811,7 @@ </return> <argument index="0" name="icon" type="Texture"> </argument> - <argument index="1" name="selectable" type="bool" default="null"> + <argument index="1" name="selectable" type="bool" default="true"> </argument> <description> Adds an item to the item list with no text, only an icon. @@ -24152,7 +24824,7 @@ </argument> <argument index="1" name="icon" type="Texture" default="null"> </argument> - <argument index="2" name="selectable" type="bool" default="null"> + <argument index="2" name="selectable" type="bool" default="true"> </argument> <description> Adds an item to the item list with specified text. Specify an icon of null for a list item with no icon. @@ -24194,7 +24866,7 @@ </description> </method> <method name="get_icon_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="ItemList.IconMode"> </return> <description> </description> @@ -24210,7 +24882,7 @@ </return> <argument index="0" name="pos" type="Vector2"> </argument> - <argument index="1" name="exact" type="bool" default="null"> + <argument index="1" name="exact" type="bool" default="false"> </argument> <description> Given a position within the control return the item (if any) at that point. @@ -24288,7 +24960,7 @@ </description> </method> <method name="get_select_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="ItemList.SelectMode"> </return> <description> </description> @@ -24370,7 +25042,7 @@ </return> <argument index="0" name="idx" type="int"> </argument> - <argument index="1" name="single" type="bool" default="null"> + <argument index="1" name="single" type="bool" default="true"> </argument> <description> Select the item at the specified index. @@ -24844,108 +25516,28 @@ Kinematic Characters: KinematicBody also has an api for moving objects (the [method move] method) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics. </description> <methods> - <method name="get_collision_collider" qualifiers="const"> - <return type="Object"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_collider_id" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_collider_metadata" qualifiers="const"> - <return type="Variant"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_collider_shape" qualifiers="const"> - <return type="Object"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_collider_shape_index" qualifiers="const"> - <return type="int"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_collider_velocity" qualifiers="const"> - <return type="Vector3"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_count" qualifiers="const"> - <return type="int"> - </return> - <description> - </description> - </method> - <method name="get_collision_local_shape" qualifiers="const"> - <return type="Object"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_normal" qualifiers="const"> - <return type="Vector3"> - </return> - <argument index="0" name="collision" type="int"> - </argument> - <description> - </description> - </method> - <method name="get_collision_position" qualifiers="const"> + <method name="get_floor_velocity" qualifiers="const"> <return type="Vector3"> </return> - <argument index="0" name="collision" type="int"> - </argument> <description> </description> </method> - <method name="get_collision_remainder" qualifiers="const"> - <return type="Vector3"> + <method name="get_safe_margin" qualifiers="const"> + <return type="float"> </return> - <argument index="0" name="collision" type="int"> - </argument> <description> </description> </method> - <method name="get_collision_travel" qualifiers="const"> - <return type="Vector3"> + <method name="get_slide_collision"> + <return type="KinematicCollision"> </return> - <argument index="0" name="collision" type="int"> + <argument index="0" name="slide_idx" type="int"> </argument> <description> </description> </method> - <method name="get_floor_velocity" qualifiers="const"> - <return type="Vector3"> - </return> - <description> - </description> - </method> - <method name="get_safe_margin" qualifiers="const"> - <return type="float"> + <method name="get_slide_count" qualifiers="const"> + <return type="int"> </return> <description> </description> @@ -24968,22 +25560,12 @@ <description> </description> </method> - <method name="move"> - <return type="Dictionary"> + <method name="move_and_collide"> + <return type="KinematicCollision"> </return> <argument index="0" name="rel_vec" type="Vector3"> </argument> <description> - Move the body in the given direction, stopping if there is an obstacle. If as a result of a movement there will be any collision then informations about this collision will be in returned dictionary. Dictionary will contains those keys: - - "position" - collision position - - "normal" - collision normal - - "local_shape" - id of this kinematic body shape that took part in a collision - - "travel" - traveled movement before being stopped - - "remainder" - remaining movement before being stopped - - "collider_id" - id of the collider, it can be used when dealing with [PhysicsServer] - - "collider" - colliding body - - "collider_shape_index" - index of the colliding shape, inside collider body "collider_metadata" - If the body did not intersect anything, then an empty dictionary (dir.empty()==true) is returned instead. Please note that this method is less user friendly than [method move_and_slide]. If you don't want to program each edge case manually, then it's recommended to use [method move_and_slide] instead. </description> </method> <method name="move_and_slide"> @@ -24991,13 +25573,13 @@ </return> <argument index="0" name="linear_velocity" type="Vector3"> </argument> - <argument index="1" name="floor_normal" type="Vector3" default="4"> + <argument index="1" name="floor_normal" type="Vector3" default="Vector3( 0, 0, 0 )"> </argument> <argument index="2" name="slope_stop_min_velocity" type="float" default="0.05"> </argument> - <argument index="3" name="max_bounces" type="int" default="Vector3( 0, 0, 0 )"> + <argument index="3" name="max_slides" type="int" default="4"> </argument> - <argument index="4" name="floor_max_angle" type="float" default="null"> + <argument index="4" name="floor_max_angle" type="float" default="0.785398"> </argument> <description> </description> @@ -25186,13 +25768,13 @@ </return> <argument index="0" name="linear_velocity" type="Vector2"> </argument> - <argument index="1" name="floor_normal" type="Vector2" default="4"> + <argument index="1" name="floor_normal" type="Vector2" default="Vector2( 0, 0 )"> </argument> <argument index="2" name="slope_stop_min_velocity" type="float" default="5"> </argument> - <argument index="3" name="max_bounces" type="int" default="Vector2( 0, 0 )"> + <argument index="3" name="max_bounces" type="int" default="4"> </argument> - <argument index="4" name="floor_max_angle" type="float" default="null"> + <argument index="4" name="floor_max_angle" type="float" default="0.785398"> </argument> <description> </description> @@ -25224,6 +25806,106 @@ <constants> </constants> </class> +<class name="KinematicCollision" inherits="Reference" category="Core"> + <brief_description> + </brief_description> + <description> + </description> + <methods> + <method name="get_collider" qualifiers="const"> + <return type="Object"> + </return> + <description> + </description> + </method> + <method name="get_collider_id" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_collider_metadata" qualifiers="const"> + <return type="Variant"> + </return> + <description> + </description> + </method> + <method name="get_collider_shape" qualifiers="const"> + <return type="Object"> + </return> + <description> + </description> + </method> + <method name="get_collider_shape_index" qualifiers="const"> + <return type="int"> + </return> + <description> + </description> + </method> + <method name="get_collider_velocity" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + <method name="get_local_shape" qualifiers="const"> + <return type="Object"> + </return> + <description> + </description> + </method> + <method name="get_normal" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + <method name="get_position" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + <method name="get_remainder" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + <method name="get_travel" qualifiers="const"> + <return type="Vector3"> + </return> + <description> + </description> + </method> + </methods> + <members> + <member name="collider" type="Object" setter="" getter="get_collider" brief=""> + </member> + <member name="collider_id" type="int" setter="" getter="get_collider_id" brief=""> + </member> + <member name="collider_metadata" type="Variant" setter="" getter="get_collider_metadata" brief=""> + </member> + <member name="collider_shape" type="Object" setter="" getter="get_collider_shape" brief=""> + </member> + <member name="collider_shape_index" type="int" setter="" getter="get_collider_shape_index" brief=""> + </member> + <member name="collider_velocity" type="Vector3" setter="" getter="get_collider_velocity" brief=""> + </member> + <member name="local_shape" type="Object" setter="" getter="get_local_shape" brief=""> + </member> + <member name="normal" type="Vector3" setter="" getter="get_normal" brief=""> + </member> + <member name="position" type="Vector3" setter="" getter="get_position" brief=""> + </member> + <member name="remainder" type="Vector3" setter="" getter="get_remainder" brief=""> + </member> + <member name="travel" type="Vector3" setter="" getter="get_travel" brief=""> + </member> + </members> + <constants> + </constants> +</class> <class name="Label" inherits="Control" category="Core"> <brief_description> Control that displays formatted text. @@ -25233,7 +25915,7 @@ </description> <methods> <method name="get_align" qualifiers="const"> - <return type="int"> + <return type="int" enum="Label.Align"> </return> <description> Return the alignment mode (any of the ALIGN_* enumeration values). @@ -25289,7 +25971,7 @@ </description> </method> <method name="get_valign" qualifiers="const"> - <return type="int"> + <return type="int" enum="Label.VAlign"> </return> <description> Return the vertical alignment mode (any of the VALIGN_* enumeration values). @@ -25814,7 +26496,7 @@ </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Light2D.Mode"> </return> <description> Return the current mode set to the Light2D. @@ -25835,7 +26517,7 @@ </description> </method> <method name="get_shadow_filter" qualifiers="const"> - <return type="int"> + <return type="int" enum="Light2D.ShadowFilter"> </return> <description> </description> @@ -26154,10 +26836,10 @@ </class> <class name="LightOccluder2D" inherits="Node2D" category="Core"> <brief_description> - Occludes light cast by a Light2D, thus casting shadows. + Occludes light cast by a Light2D, casting shadows. </brief_description> <description> - Occludes light cast by a Light2D, thus casting shadows. The LightOccluder2D must be provided with a shape (see OccluderPolygon2D) that allows the shadow to be computed. This shape affects the resulting shadow, while the shape of the representating asset shadowed does not actually affect shadows. + Occludes light cast by a Light2D, casting shadows. The LightOccluder2D must be provided with an [OccluderPolygon2D] in order for the shadow to be computed. </description> <methods> <method name="get_occluder_light_mask" qualifiers="const"> @@ -26195,8 +26877,10 @@ </methods> <members> <member name="light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" brief=""> + The LightOccluder2D's light mask. The LightOccluder2D will cast shadows only from Light2D(s) that have the same light mask(s). </member> <member name="occluder" type="OccluderPolygon2D" setter="set_occluder_polygon" getter="get_occluder_polygon" brief=""> + The [OccluderPolygon2D] used to compute the shadow. </member> </members> <constants> @@ -26204,8 +26888,10 @@ </class> <class name="Line2D" inherits="Node2D" category="Core"> <brief_description> + A 2D line. </brief_description> <description> + A line through several points in 2D space. </description> <methods> <method name="add_point"> @@ -26214,10 +26900,11 @@ <argument index="0" name="pos" type="Vector2"> </argument> <description> + Add a point at the x/y position in the supplied [Vector2] </description> </method> <method name="get_begin_cap_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="LineCapMode"> </return> <description> </description> @@ -26229,7 +26916,7 @@ </description> </method> <method name="get_end_cap_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="LineCapMode"> </return> <description> </description> @@ -26241,7 +26928,7 @@ </description> </method> <method name="get_joint_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="LineJointMode"> </return> <description> </description> @@ -26285,7 +26972,7 @@ </description> </method> <method name="get_texture_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="LineTextureMode"> </return> <description> </description> @@ -26302,6 +26989,7 @@ <argument index="0" name="i" type="int"> </argument> <description> + Remove the point at index 'i' from the line. </description> </method> <method name="set_begin_cap_mode"> @@ -26503,9 +27191,10 @@ </description> </method> <method name="get_align" qualifiers="const"> - <return type="int"> + <return type="int" enum="LineEdit.Align"> </return> <description> + Return the align mode of the [LineEdit]. </description> </method> <method name="get_cursor_pos" qualifiers="const"> @@ -26532,18 +27221,21 @@ <return type="PopupMenu"> </return> <description> + Return the [PopupMenu] of this [LineEdit]. </description> </method> <method name="get_placeholder" qualifiers="const"> <return type="String"> </return> <description> + Return the placeholder text. </description> </method> <method name="get_placeholder_alpha" qualifiers="const"> <return type="float"> </return> <description> + Return transparency of the placeholder text. </description> </method> <method name="get_text" qualifiers="const"> @@ -26573,16 +27265,23 @@ <argument index="0" name="option" type="int"> </argument> <description> + Execute a given action as defined in the MENU_* enum. </description> </method> <method name="select"> <return type="void"> </return> - <argument index="0" name="from" type="int" default="-1"> + <argument index="0" name="from" type="int" default="0"> </argument> - <argument index="1" name="to" type="int" default="0"> + <argument index="1" name="to" type="int" default="-1"> </argument> <description> + Select the text inside [LineEdit] by the given character positions. [code]from[/code] is default to the beginning. [code]to[/code] is default to the end. + [codeblock] + select() # select all + select(5) # select from the fifth character to the end. + select(2, 5) # select from the second to the fifth character. + [/codeblock] </description> </method> <method name="select_all"> @@ -26598,6 +27297,7 @@ <argument index="0" name="align" type="int" enum="LineEdit.Align"> </argument> <description> + Set text alignment of the [LineEdit]. </description> </method> <method name="set_cursor_pos"> @@ -26641,6 +27341,7 @@ <argument index="0" name="text" type="String"> </argument> <description> + Set the placeholder text. </description> </method> <method name="set_placeholder_alpha"> @@ -26649,6 +27350,7 @@ <argument index="0" name="alpha" type="float"> </argument> <description> + Set transparency of the placeholder text. </description> </method> <method name="set_secret"> @@ -26712,24 +27414,34 @@ </signals> <constants> <constant name="ALIGN_LEFT" value="0"> + Align left. </constant> <constant name="ALIGN_CENTER" value="1"> + Align center. </constant> <constant name="ALIGN_RIGHT" value="2"> + Align right. </constant> <constant name="ALIGN_FILL" value="3"> + Align fill. </constant> <constant name="MENU_CUT" value="0"> + Cut (Copy and clear). </constant> <constant name="MENU_COPY" value="1"> + Copy the selected text. </constant> <constant name="MENU_PASTE" value="2"> + Paste the clipboard text over the selected text. </constant> <constant name="MENU_CLEAR" value="3"> + Clear the text. </constant> <constant name="MENU_SELECT_ALL" value="4"> + Select all text. </constant> <constant name="MENU_UNDO" value="5"> + Undo an action. </constant> <constant name="MENU_MAX" value="6"> </constant> @@ -26821,7 +27533,7 @@ </description> </method> <method name="get_underline_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="LinkButton.UnderlineMode"> </return> <description> Returns the underline mode for this button. @@ -26932,6 +27644,7 @@ <return type="void"> </return> <description> + Called before the program exits. </description> </method> <method name="_idle" qualifiers="virtual"> @@ -26940,12 +27653,14 @@ <argument index="0" name="delta" type="float"> </argument> <description> + Called each idle frame with time since last call as an only argument. </description> </method> <method name="_initialize" qualifiers="virtual"> <return type="void"> </return> <description> + Called once during initialization. </description> </method> <method name="_input_event" qualifiers="virtual"> @@ -27072,6 +27787,7 @@ <argument index="0" name="base64_str" type="String"> </argument> <description> + Return [PoolByteArray] of a given base64 encoded String. </description> </method> <method name="base64_to_utf8"> @@ -27080,6 +27796,7 @@ <argument index="0" name="base64_str" type="String"> </argument> <description> + Return utf8 String of a given base64 encoded String. </description> </method> <method name="base64_to_variant"> @@ -27088,6 +27805,7 @@ <argument index="0" name="base64_str" type="String"> </argument> <description> + Return [Variant] of a given base64 encoded String. </description> </method> <method name="raw_to_base64"> @@ -27096,6 +27814,7 @@ <argument index="0" name="array" type="PoolByteArray"> </argument> <description> + Return base64 encoded String of a given [PoolByteArray]. </description> </method> <method name="utf8_to_base64"> @@ -27104,6 +27823,7 @@ <argument index="0" name="utf8_str" type="String"> </argument> <description> + Return base64 encoded String of a given utf8 String. </description> </method> <method name="variant_to_base64"> @@ -27112,6 +27832,7 @@ <argument index="0" name="variant" type="Variant"> </argument> <description> + Return base64 encoded String of a given [Variant]. </description> </method> </methods> @@ -27191,6 +27912,7 @@ <signals> <signal name="about_to_show"> <description> + Emitted when [PopupMenu] of this MenuButton is about to show. </description> </signal> </signals> @@ -27233,6 +27955,7 @@ <return type="Shape"> </return> <description> + Calculate a [ConvexPolygonShape] from the mesh. </description> </method> <method name="create_outline" qualifiers="const"> @@ -27241,24 +27964,28 @@ <argument index="0" name="margin" type="float"> </argument> <description> + Calculate an outline mesh at a defined offset (margin) from the original mesh. Note: Typically returns the vertices in reverse order (e.g. clockwise to anti-clockwise). </description> </method> <method name="create_trimesh_shape" qualifiers="const"> <return type="Shape"> </return> <description> + Calculate a [ConcavePolygonShape] from the mesh. </description> </method> <method name="generate_triangle_mesh" qualifiers="const"> <return type="TriangleMesh"> </return> <description> + Generate a [TriangleMesh] from the mesh. </description> </method> <method name="get_faces" qualifiers="const"> <return type="PoolVector3Array"> </return> <description> + Returns all the vertices that make up the faces of the mesh. Each three vertices represent one triangle. </description> </method> </methods> @@ -27299,7 +28026,7 @@ </description> </method> <method name="commit_to_surface"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="mesh" type="ArrayMesh"> </argument> @@ -27307,7 +28034,7 @@ </description> </method> <method name="create_from_surface"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="mesh" type="ArrayMesh"> </argument> @@ -27630,6 +28357,7 @@ <return type="void"> </return> <description> + This helper creates a [StaticBody] child [Node] with a [ConvexPolygonShape] [CollisionShape] calculated from the mesh geometry. It's mainly used for testing. </description> </method> <method name="create_debug_tangents"> @@ -27642,14 +28370,14 @@ <return type="void"> </return> <description> - This helper creates a [StaticBody] child [Node] using the mesh geometry as collision. It's mainly used for testing. + This helper creates a [StaticBody] child [Node] with a [ConcavePolygonShape] [CollisionShape] calculated from the mesh geometry. It's mainly used for testing. </description> </method> <method name="get_mesh" qualifiers="const"> <return type="Mesh"> </return> <description> - Return the current [Mesh] resource for the instance. + Returns the current [Mesh] resource for the instance. </description> </method> <method name="get_skeleton_path"> @@ -27664,6 +28392,7 @@ <argument index="0" name="surface" type="int"> </argument> <description> + Returns the [Material] for a surface of the [Mesh] resource. </description> </method> <method name="set_mesh"> @@ -27672,7 +28401,6 @@ <argument index="0" name="mesh" type="Mesh"> </argument> <description> - Set the [Mesh] resource for the instance. </description> </method> <method name="set_skeleton_path"> @@ -27691,13 +28419,16 @@ <argument index="1" name="material" type="Material"> </argument> <description> + Sets the [Material] for a surface of the [Mesh] resource. </description> </method> </methods> <members> <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" brief=""> + The [Mesh] resource for the instance. </member> <member name="skeleton" type="NodePath" setter="set_skeleton_path" getter="get_skeleton_path" brief=""> + [NodePath] to the [Skeleton] associated with the instance. </member> </members> <constants> @@ -27727,6 +28458,14 @@ Create a new item in the library, supplied an id. </description> </method> + <method name="find_item_by_name" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="name" type="String"> + </argument> + <description> + </description> + </method> <method name="get_item_list" qualifiers="const"> <return type="PoolIntArray"> </return> @@ -27867,7 +28606,7 @@ </description> </method> <method name="get_color_format" qualifiers="const"> - <return type="int"> + <return type="int" enum="MultiMesh.ColorFormat"> </return> <description> </description> @@ -27905,7 +28644,7 @@ </description> </method> <method name="get_transform_format" qualifiers="const"> - <return type="int"> + <return type="int" enum="MultiMesh.TransformFormat"> </return> <description> </description> @@ -28042,7 +28781,7 @@ </description> </method> <method name="try_lock"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Try locking this [Mutex], does not block. Returns [OK] on success else [ERR_BUSY]. @@ -28146,7 +28885,7 @@ </argument> <argument index="1" name="end" type="Vector3"> </argument> - <argument index="2" name="use_collision" type="bool" default="null"> + <argument index="2" name="use_collision" type="bool" default="false"> </argument> <description> </description> @@ -28158,7 +28897,7 @@ </argument> <argument index="1" name="end" type="Vector3"> </argument> - <argument index="2" name="optimize" type="bool" default="null"> + <argument index="2" name="optimize" type="bool" default="true"> </argument> <description> </description> @@ -28244,7 +28983,7 @@ </argument> <argument index="1" name="end" type="Vector2"> </argument> - <argument index="2" name="optimize" type="bool" default="null"> + <argument index="2" name="optimize" type="bool" default="true"> </argument> <description> </description> @@ -28574,35 +29313,37 @@ </description> </method> <method name="create_client"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="ip" type="String"> </argument> <argument index="1" name="port" type="int"> </argument> - <argument index="2" name="in_bandwidth" type="int" default="null"> + <argument index="2" name="in_bandwidth" type="int" default="0"> </argument> - <argument index="3" name="out_bandwidth" type="int" default="null"> + <argument index="3" name="out_bandwidth" type="int" default="0"> </argument> <description> + Create client that connects to a server at address [code]ip[/code] using specified [code]port[/code]. </description> </method> <method name="create_server"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="port" type="int"> </argument> - <argument index="1" name="max_clients" type="int" default="0"> + <argument index="1" name="max_clients" type="int" default="32"> </argument> - <argument index="2" name="in_bandwidth" type="int" default="32"> + <argument index="2" name="in_bandwidth" type="int" default="0"> </argument> - <argument index="3" name="out_bandwidth" type="int" default="null"> + <argument index="3" name="out_bandwidth" type="int" default="0"> </argument> <description> + Create server that listens to connections via [code]port[/code]. </description> </method> <method name="get_compression_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="NetworkedMultiplayerENet.CompressionMode"> </return> <description> </description> @@ -28644,7 +29385,7 @@ </description> <methods> <method name="get_connection_status" qualifiers="const"> - <return type="int"> + <return type="int" enum="NetworkedMultiplayerPeer.ConnectionStatus"> </return> <description> </description> @@ -28665,6 +29406,7 @@ <return type="bool"> </return> <description> + Return whether this [NetworkedMultiplayerPeer] is refusing new connections. </description> </method> <method name="poll"> @@ -28679,6 +29421,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + If [code]endable[/code] is true, this [NetworkedMultiplayerPeer] will refuse new connections. </description> </method> <method name="set_target_peer"> @@ -28701,26 +29444,31 @@ <signals> <signal name="connection_failed"> <description> + Emitted when failed to connect to server. </description> </signal> <signal name="connection_succeeded"> <description> + Emitted when successfully connected to server. </description> </signal> <signal name="peer_connected"> <argument index="0" name="id" type="int"> </argument> <description> + Emitted by the server when a client is connected. </description> </signal> <signal name="peer_disconnected"> <argument index="0" name="id" type="int"> </argument> <description> + Emitted by the server when a client is disconnected. </description> </signal> <signal name="server_disconnected"> <description> + Emitted by clients when server is disconnected. </description> </signal> </signals> @@ -28916,7 +29664,7 @@ </description> <methods> <method name="get_h_axis_stretch_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="NinePatchRect.AxisStretchMode"> </return> <description> </description> @@ -28942,7 +29690,7 @@ </description> </method> <method name="get_v_axis_stretch_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="NinePatchRect.AxisStretchMode"> </return> <description> </description> @@ -29089,6 +29837,7 @@ <argument index="0" name="event" type="InputEvent"> </argument> <description> + Called when there is a change to input devices. Propagated through the node tree until a Node consumes it. </description> </method> <method name="_process" qualifiers="virtual"> @@ -29116,6 +29865,7 @@ <argument index="0" name="event" type="InputEvent"> </argument> <description> + Propagated to all nodes when the previous InputEvent is not consumed by any nodes. </description> </method> <method name="_unhandled_key_input" qualifiers="virtual"> @@ -29131,7 +29881,7 @@ </return> <argument index="0" name="node" type="Node"> </argument> - <argument index="1" name="legible_unique_name" type="bool" default="null"> + <argument index="1" name="legible_unique_name" type="bool" default="false"> </argument> <description> Add a child [Node]. Nodes can have as many children as they want, but every child must have a unique name. Children nodes are automatically deleted when the parent node is deleted, so deleting a whole scene is performed by deleting its topmost node. @@ -29143,7 +29893,7 @@ </return> <argument index="0" name="group" type="String"> </argument> - <argument index="1" name="persistent" type="bool" default="null"> + <argument index="1" name="persistent" type="bool" default="false"> </argument> <description> Add a node to a group. Groups are helpers to name and organize a subset of nodes, like for example "enemies" or "collectables". A [Node] can be in any number of groups. Nodes can be assigned a group at any time, but will not be added to it until they are inside the scene tree (see [method is_inside_tree]). @@ -29173,7 +29923,7 @@ </argument> <argument index="1" name="recursive" type="bool" default="true"> </argument> - <argument index="2" name="owned" type="bool" default="null"> + <argument index="2" name="owned" type="bool" default="true"> </argument> <description> Find a descendant of this node whose name matches [code]mask[/code] as in [method String.match] (i.e. case sensitive, but '*' matches zero or more characters and '?' matches any single character except '.'). Note that it does not match against the full path, just against individual node names. @@ -29310,15 +30060,17 @@ </description> </method> <method name="get_pause_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Node.PauseMode"> </return> <description> + Return the pause mode (PAUSE_MODE_*) of this Node. </description> </method> <method name="get_position_in_parent" qualifiers="const"> <return type="int"> </return> <description> + Return the order in the node tree branch, i.e. if called by the first child Node, return 0. </description> </method> <method name="get_process_delta_time" qualifiers="const"> @@ -29338,6 +30090,7 @@ <return type="SceneTree"> </return> <description> + Return a [SceneTree] that this node is inside. </description> </method> <method name="get_viewport" qualifiers="const"> @@ -29352,6 +30105,7 @@ <argument index="0" name="path" type="NodePath"> </argument> <description> + Return whether the node that a given [NodePath] points too exists. </description> </method> <method name="has_node_and_resource" qualifiers="const"> @@ -29405,12 +30159,14 @@ <argument index="0" name="group" type="String"> </argument> <description> + Return whether this Node is in the specified group. </description> </method> <method name="is_inside_tree" qualifiers="const"> <return type="bool"> </return> <description> + Return whether this Node is inside a [SceneTree]. </description> </method> <method name="is_network_master" qualifiers="const"> @@ -29483,7 +30239,7 @@ </argument> <argument index="1" name="args" type="Array" default="[ ]"> </argument> - <argument index="2" name="parent_first" type="bool" default="null"> + <argument index="2" name="parent_first" type="bool" default="false"> </argument> <description> Calls the method (if present) with the arguments given in "args" on this Node and recursively on all children. If the parent_first argument is true then the method will be called on the current [Node] first, then on all children. If it is false then the children will get called first. @@ -29502,6 +30258,7 @@ <return type="void"> </return> <description> + Queues a node for deletion at the end of the current frame. When deleted, all of its children nodes will be deleted as well. This method ensures it's safe to delete the node, contrary to [method Object.free]. Use [method Object.is_queued_for_deletion] to know whether a node will be deleted at the end of the frame. </description> </method> <method name="raise"> @@ -29541,7 +30298,7 @@ </return> <argument index="0" name="node" type="Node"> </argument> - <argument index="1" name="keep_data" type="bool" default="null"> + <argument index="1" name="keep_data" type="bool" default="false"> </argument> <description> Replace a node in a scene by a given one. Subscriptions that pass through this node will be lost. @@ -29551,6 +30308,7 @@ <return type="void"> </return> <description> + Request that [code]_ready[/code] be called again. </description> </method> <method name="rpc" qualifiers="vararg"> @@ -29711,7 +30469,7 @@ </return> <argument index="0" name="id" type="int"> </argument> - <argument index="1" name="recursive" type="bool" default="null"> + <argument index="1" name="recursive" type="bool" default="true"> </argument> <description> </description> @@ -29731,6 +30489,7 @@ <argument index="0" name="mode" type="int" enum="Node.PauseMode"> </argument> <description> + Set pause mode (PAUSE_MODE_*) of this Node. </description> </method> <method name="set_process"> @@ -29801,10 +30560,12 @@ </signal> <signal name="tree_entered"> <description> + Emitted when Node enters the tree. </description> </signal> <signal name="tree_exited"> <description> + Emitted when Node exits the tree. </description> </signal> </signals> @@ -29849,18 +30610,25 @@ <constant name="RPC_MODE_DISABLED" value="0"> </constant> <constant name="RPC_MODE_REMOTE" value="1"> + Call a method remotely. </constant> <constant name="RPC_MODE_SYNC" value="2"> + Call a method both remotely and locally. </constant> <constant name="RPC_MODE_MASTER" value="3"> + Call a method if the Node is Master. </constant> <constant name="RPC_MODE_SLAVE" value="4"> + Call a method if the Node is Slave. </constant> <constant name="PAUSE_MODE_INHERIT" value="0"> + Inherits pause mode from parent. For root node, it is equivalent to PAUSE_MODE_STOP. </constant> <constant name="PAUSE_MODE_STOP" value="1"> + Stop processing when SceneTree is paused. </constant> <constant name="PAUSE_MODE_PROCESS" value="2"> + Continue to process regardless of SceneTree pause state. </constant> <constant name="DUPLICATE_SIGNALS" value="1"> </constant> @@ -29874,10 +30642,10 @@ </class> <class name="Node2D" inherits="CanvasItem" category="Core"> <brief_description> - Base node for 2D system. + A 2D game object, parent of all 2D related nodes. Has a position, rotation, scale and Z-index. </brief_description> <description> - Base node for 2D system. Node2D contains a position, rotation and scale, which is used to position and animate. It can alternatively be used with a custom 2D transform ([Transform2D]). A tree of Node2Ds allows complex hierarchies for animation and positioning. + A 2D game object, with a position, rotation and scale. All 2D physics nodes and sprites inherit from Node2D. Use Node2D as a parent node to move, scale and rotate children in a 2D project. Also gives control on the node's render order. </description> <methods> <method name="apply_scale"> @@ -29886,7 +30654,7 @@ <argument index="0" name="ratio" type="Vector2"> </argument> <description> - Apply the 'ratio' scale to the 2D node, according to its current scale value. + Multiplies the current scale by the 'ratio' vector. </description> </method> <method name="edit_set_pivot"> @@ -29895,7 +30663,7 @@ <argument index="0" name="pivot" type="Vector2"> </argument> <description> - Set the pivot position of the 2D node to 'pivot' value. This method is implemented only in some nodes that inherit Node2D. + Set the pivot position of the 2D node to 'pivot' value. Only some Node2Ds implement this method. </description> </method> <method name="get_angle_to" qualifiers="const"> @@ -29904,42 +30672,42 @@ <argument index="0" name="point" type="Vector2"> </argument> <description> - Return the rotation angle in radians needed for the 2d node to point at 'point' position. + Returns the angle between the node and the 'point' in radians. </description> </method> <method name="get_global_position" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the global position of the 2D node. + Returns the node's global position. </description> </method> <method name="get_global_rotation" qualifiers="const"> <return type="float"> </return> <description> - Return the global rotation in radians of the 2D node. + Returns the node's global rotation in radians. </description> </method> <method name="get_global_rotation_in_degrees" qualifiers="const"> <return type="float"> </return> <description> - Return the global rotation in degrees of the 2D node. + Return the node's global rotation in degrees. </description> </method> <method name="get_global_scale" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the global scale of the 2D node. + Returns the node's global scale. </description> </method> <method name="get_position" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the position of the 2D node. + Returns the node's position. </description> </method> <method name="get_relative_transform_to_parent" qualifiers="const"> @@ -29948,35 +30716,35 @@ <argument index="0" name="parent" type="Node"> </argument> <description> - Return the transform [Transform2D] calculated relatively to the parent of this 2D node. + Returns the [Transform2D] relative to this node's parent. </description> </method> <method name="get_rotation" qualifiers="const"> <return type="float"> </return> <description> - Return the rotation in radians of the 2D node. + Returns the node's rotation in radians. </description> </method> <method name="get_rotation_in_degrees" qualifiers="const"> <return type="float"> </return> <description> - Return the rotation in degrees of the 2D node. + Returns the node's rotation in degrees. </description> </method> <method name="get_scale" qualifiers="const"> <return type="Vector2"> </return> <description> - Return the scale of the 2D node. + Returns the node's scale. </description> </method> <method name="get_z" qualifiers="const"> <return type="int"> </return> <description> - Return the Z-index of the 2D node. + Returns the node's Z-index. </description> </method> <method name="global_translate"> @@ -29985,14 +30753,14 @@ <argument index="0" name="offset" type="Vector2"> </argument> <description> - Apply a global translation of 'offset' to the 2D node, starting from its current global position. + Adds the 'offset' vector to the node's global position. </description> </method> <method name="is_z_relative" qualifiers="const"> <return type="bool"> </return> <description> - Return true if the Z-index value of this 2D node is relative to its parent's. Else, return false. + Returns true if this node's Z-index is relative to its parent's. Else, returns false. </description> </method> <method name="look_at"> @@ -30001,7 +30769,7 @@ <argument index="0" name="point" type="Vector2"> </argument> <description> - Rotate the 2d node so it points at 'point' position. + Rotates the node so it points towards the 'point'. </description> </method> <method name="move_local_x"> @@ -30009,10 +30777,10 @@ </return> <argument index="0" name="delta" type="float"> </argument> - <argument index="1" name="scaled" type="bool" default="null"> + <argument index="1" name="scaled" type="bool" default="false"> </argument> <description> - Apply a local translation on X axis to the 2D node according to the 'delta' of the process. If 'scaled' is false, the movement is normalized. + Apply a local translation on the node's X axis based on the process's 'delta'. If 'scaled' is false, normalizes the movement. </description> </method> <method name="move_local_y"> @@ -30020,10 +30788,10 @@ </return> <argument index="0" name="delta" type="float"> </argument> - <argument index="1" name="scaled" type="bool" default="null"> + <argument index="1" name="scaled" type="bool" default="false"> </argument> <description> - Apply a local translation on Y axis to the 2D node according to the 'delta' of the process. If 'scaled' is false, the movement is normalized. + Apply a local translation on the node's Y axis based on the process's 'delta'. If 'scaled' is false, normalizes the movement. </description> </method> <method name="rotate"> @@ -30032,7 +30800,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> - Apply a rotation (in radians) to the 2D node, starting from its current rotation. + Apply a rotation to the node, in radians, starting from its current rotation. </description> </method> <method name="set_global_position"> @@ -30041,7 +30809,7 @@ <argument index="0" name="pos" type="Vector2"> </argument> <description> - Set the global position of the 2D node. + Set the node's global position. </description> </method> <method name="set_global_rotation"> @@ -30050,7 +30818,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> - Set the global rotation in radians of the 2D node + Set the node's global rotation in radians. </description> </method> <method name="set_global_rotation_in_degrees"> @@ -30059,7 +30827,7 @@ <argument index="0" name="degrees" type="float"> </argument> <description> - Set the global rotation in degrees of the 2D node + Set the node's global rotation in degrees. </description> </method> <method name="set_global_scale"> @@ -30068,7 +30836,7 @@ <argument index="0" name="scale" type="Vector2"> </argument> <description> - Set the global scale of the 2D node. + Set the node's global scale. </description> </method> <method name="set_global_transform"> @@ -30077,7 +30845,7 @@ <argument index="0" name="xform" type="Transform2D"> </argument> <description> - Set the global transform [Transform2D] of the 2D node. + Set the node's global [Transform2D]. </description> </method> <method name="set_position"> @@ -30086,7 +30854,7 @@ <argument index="0" name="pos" type="Vector2"> </argument> <description> - Set the position of the 2D node. + Set the node's position. </description> </method> <method name="set_rotation"> @@ -30095,7 +30863,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> - Set the rotation in radians of the 2D node. + Set the node's rotation in radians. </description> </method> <method name="set_rotation_in_degrees"> @@ -30104,7 +30872,7 @@ <argument index="0" name="degrees" type="float"> </argument> <description> - Set the rotation in degrees of the 2D node. + Set the node's rotation in degrees. </description> </method> <method name="set_scale"> @@ -30113,7 +30881,7 @@ <argument index="0" name="scale" type="Vector2"> </argument> <description> - Set the scale of the 2D node. + Set the node's scale. </description> </method> <method name="set_transform"> @@ -30122,7 +30890,7 @@ <argument index="0" name="xform" type="Transform2D"> </argument> <description> - Set the local transform [Transform2D] of the 2D node. + Set the node's local [Transform2D]. </description> </method> <method name="set_z"> @@ -30131,7 +30899,7 @@ <argument index="0" name="z" type="int"> </argument> <description> - Set the Z-index value of the 2D node. + Set the node's Z-index. </description> </method> <method name="set_z_as_relative"> @@ -30140,7 +30908,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> - Set the Z-index value as relative to the parent node of this 2D node. Thus, if this 2D node's Z-index value is 2 and its parent's effective Z-index is 3, then the effective Z-index value of this 2D node would be 3 + 2 = 5. + Make the node's Z-index relative to its parent's Z-index. If this node's Z-index is 2 and its parent's effective Z-index is 3, then this node's effective Z-index will be 2 + 3 = 5. </description> </method> <method name="to_global" qualifiers="const"> @@ -30165,34 +30933,46 @@ <argument index="0" name="offset" type="Vector2"> </argument> <description> - Apply a local translation of 'offset' to the 2D node, starting from its current local position. + Translate the node locally by the 'offset' vector, starting from its current local position. </description> </method> </methods> <members> <member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" brief=""> + Global position. </member> <member name="global_rotation" type="float" setter="set_global_rotation" getter="get_global_rotation" brief=""> + Global rotation in radians. </member> <member name="global_rotation_deg" type="float" setter="set_global_rotation_in_degrees" getter="get_global_rotation_in_degrees" brief=""> + Global rotation in degrees. </member> <member name="global_scale" type="Vector2" setter="set_global_scale" getter="get_global_scale" brief=""> + Global scale. </member> <member name="global_transform" type="Transform2D" setter="set_global_transform" getter="get_global_transform" brief=""> + Global [Transform2D]. </member> <member name="position" type="Vector2" setter="set_position" getter="get_position" brief=""> + Position, relative to the node's parent. </member> <member name="rotation" type="float" setter="set_rotation" getter="get_rotation" brief=""> + Rotation in radians. </member> <member name="rotation_deg" type="float" setter="set_rotation_in_degrees" getter="get_rotation_in_degrees" brief=""> + Rotation in degrees. </member> <member name="scale" type="Vector2" setter="set_scale" getter="get_scale" brief=""> + Rotation in degrees. </member> <member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" brief=""> + Local [Transform2D]. </member> <member name="z" type="int" setter="set_z" getter="get_z" brief=""> + Z-index. Controls the order in which the nodes render. A node with a higher Z-index will display in front of others. </member> <member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative" brief=""> + Make the node's Z-index relative to its parent's Z-index. If this node's Z-index is 2 and its parent's effective Z-index is 3, then this node's effective Z-index will be 2 + 3 = 5. </member> </members> <constants> @@ -30287,7 +31067,7 @@ </return> <argument index="0" name="text" type="String"> </argument> - <argument index="1" name="title" type="String" default="null"> + <argument index="1" name="title" type="String" default=""Alert!""> </argument> <description> Displays a modal dialog box utilizing the host OS. @@ -30355,7 +31135,7 @@ </argument> <argument index="2" name="blocking" type="bool"> </argument> - <argument index="3" name="output" type="Array" default="null"> + <argument index="3" name="output" type="Array" default="[ ]"> </argument> <description> Execute the binary file in given path, optionally blocking until it returns. A process ID is returned. @@ -30504,7 +31284,7 @@ </description> </method> <method name="get_power_state"> - <return type="int"> + <return type="int" enum="PowerState"> </return> <description> </description> @@ -30557,7 +31337,7 @@ </description> </method> <method name="get_screen_orientation" qualifiers="const"> - <return type="int"> + <return type="int" enum="_OS.ScreenOrientation"> </return> <description> Returns the current screen orientation, the return value will be one of the SCREEN_ORIENTATION constants in this class. @@ -30778,7 +31558,7 @@ </description> </method> <method name="kill"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="pid" type="int"> </argument> @@ -30799,7 +31579,7 @@ </description> </method> <method name="native_video_play"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -30938,7 +31718,7 @@ </description> </method> <method name="set_thread_name"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="name" type="String"> </argument> @@ -31025,7 +31805,7 @@ </description> </method> <method name="shell_open"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="uri" type="String"> </argument> @@ -31182,7 +31962,7 @@ </return> <argument index="0" name="signal" type="String"> </argument> - <argument index="1" name="arguments" type="Array" default="null"> + <argument index="1" name="arguments" type="Array" default="[ ]"> </argument> <description> Add a user signal (can be added anytime). Arguments are optional, but can be added as an array of dictionaries, each containing "name" and "type" (from [@Global Scope] TYPE_*). @@ -31222,7 +32002,7 @@ </description> </method> <method name="connect"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="signal" type="String"> </argument> @@ -31230,9 +32010,9 @@ </argument> <argument index="2" name="method" type="String"> </argument> - <argument index="3" name="binds" type="Array" default="null"> + <argument index="3" name="binds" type="Array" default="[ ]"> </argument> - <argument index="4" name="flags" type="int" default="null"> + <argument index="4" name="flags" type="int" default="0"> </argument> <description> Connect a signal to a method at a target (member function). Binds are optional and are passed as extra arguments to the call. Flags specify optional deferred or one shot connections, see enum CONNECT_*. A signal can only be connected once to a method, and it will throw an error if already connected. If you want to avoid this, use [method is_connected] to check. @@ -31415,7 +32195,7 @@ </return> <argument index="0" name="what" type="int"> </argument> - <argument index="1" name="reversed" type="bool" default="null"> + <argument index="1" name="reversed" type="bool" default="false"> </argument> <description> Notify the object of something. @@ -31517,7 +32297,7 @@ </description> <methods> <method name="get_cull_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="OccluderPolygon2D.CullMode"> </return> <description> </description> @@ -31585,13 +32365,13 @@ </description> <methods> <method name="get_shadow_detail" qualifiers="const"> - <return type="int"> + <return type="int" enum="OmniLight.ShadowDetail"> </return> <description> </description> </method> <method name="get_shadow_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="OmniLight.ShadowMode"> </return> <description> </description> @@ -31652,7 +32432,7 @@ </return> <argument index="0" name="label" type="String"> </argument> - <argument index="1" name="id" type="int" default="null"> + <argument index="1" name="id" type="int" default="-1"> </argument> <description> Add an item, with text "label" and (optionally) id. If no "id" is passed, "id" becomes the item index. New items are appended at the end. @@ -31865,7 +32645,7 @@ </description> <methods> <method name="add_file"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="pck_path" type="String"> </argument> @@ -31875,7 +32655,7 @@ </description> </method> <method name="flush"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="verbose" type="bool"> </argument> @@ -31883,7 +32663,7 @@ </description> </method> <method name="pck_start"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="pck_name" type="String"> </argument> @@ -31923,7 +32703,7 @@ </description> <methods> <method name="pack"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="value" type="Variant"> </argument> @@ -31988,7 +32768,7 @@ </description> </method> <method name="pack"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="Node"> </argument> @@ -32033,7 +32813,7 @@ </description> </method> <method name="get_packet_error" qualifiers="const"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Return the error state of the last packet received (via [method get_packet] and [method get_var]). @@ -32053,7 +32833,7 @@ </description> </method> <method name="put_packet"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="buffer" type="PoolByteArray"> </argument> @@ -32062,7 +32842,7 @@ </description> </method> <method name="put_var"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="var" type="Variant"> </argument> @@ -32168,13 +32948,13 @@ </description> </method> <method name="listen"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="port" type="int"> </argument> <argument index="1" name="bind_address" type="String" default=""*""> </argument> - <argument index="2" name="recv_buf_size" type="int" default="null"> + <argument index="2" name="recv_buf_size" type="int" default="65536"> </argument> <description> Make this [PacketPeerUDP] listen on the "port" binding to "bind_address" with a buffer size "recv_buf_size". @@ -32184,7 +32964,7 @@ </description> </method> <method name="set_dest_address"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="host" type="String"> </argument> @@ -32195,7 +32975,7 @@ </description> </method> <method name="wait"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Wait for a packet to arrive on the listening port, see [method listen]. @@ -32474,7 +33254,7 @@ </description> </method> <method name="get_draw_order" qualifiers="const"> - <return type="int"> + <return type="int" enum="Particles.DrawOrder"> </return> <description> </description> @@ -32775,7 +33555,7 @@ </description> </method> <method name="get_draw_order" qualifiers="const"> - <return type="int"> + <return type="int" enum="Particles2D.DrawOrder"> </return> <description> </description> @@ -33127,7 +33907,7 @@ </description> </method> <method name="get_emission_shape" qualifiers="const"> - <return type="int"> + <return type="int" enum="ParticlesMaterial.EmissionShape"> </return> <description> </description> @@ -33617,7 +34397,7 @@ </description> </method> <method name="get_rotation_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="PathFollow.RotationMode"> </return> <description> Returns the rotation mode. The constants below list which axes are allowed to rotate for each mode. @@ -34192,7 +34972,7 @@ </return> <argument index="0" name="shape" type="Physics2DShapeQueryParameters"> </argument> - <argument index="1" name="max_results" type="int" default="null"> + <argument index="1" name="max_results" type="int" default="32"> </argument> <description> Check the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. The resulting array contains a list of points where the shape intersects another. Like with [method intersect_shape], the number of returned results can be limited to save processing time. @@ -34221,13 +35001,13 @@ </return> <argument index="0" name="point" type="Vector2"> </argument> - <argument index="1" name="max_results" type="int" default="2147483647"> + <argument index="1" name="max_results" type="int" default="32"> </argument> <argument index="2" name="exclude" type="Array" default="[ ]"> </argument> - <argument index="3" name="collision_layer" type="int" default="32"> + <argument index="3" name="collision_layer" type="int" default="2147483647"> </argument> - <argument index="4" name="type_mask" type="int" default="null"> + <argument index="4" name="type_mask" type="int" default="15"> </argument> <description> Check whether a point is inside any shape. The shapes the point is inside of are returned in an array containing dictionaries with the following fields: @@ -34248,9 +35028,9 @@ </argument> <argument index="2" name="exclude" type="Array" default="[ ]"> </argument> - <argument index="3" name="collision_layer" type="int" default="null"> + <argument index="3" name="collision_layer" type="int" default="2147483647"> </argument> - <argument index="4" name="type_mask" type="int" default="null"> + <argument index="4" name="type_mask" type="int" default="15"> </argument> <description> Intersect a ray in a given space. The returned object is a dictionary with the following fields: @@ -34270,7 +35050,7 @@ </return> <argument index="0" name="shape" type="Physics2DShapeQueryParameters"> </argument> - <argument index="1" name="max_results" type="int" default="null"> + <argument index="1" name="max_results" type="int" default="32"> </argument> <description> Check the intersections of a shape, given through a [Physics2DShapeQueryParameters] object, against the space. The intersected shapes are returned in an array containing dictionaries with the following fields: @@ -34319,7 +35099,7 @@ </argument> <argument index="1" name="shape" type="RID"> </argument> - <argument index="2" name="transform" type="Transform2D" default="null"> + <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> </argument> <description> Add a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index. @@ -34413,7 +35193,7 @@ </description> </method> <method name="area_get_space_override_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Physics2DServer.AreaSpaceOverrideMode"> </return> <argument index="0" name="area" type="RID"> </argument> @@ -34596,7 +35376,7 @@ </argument> <argument index="1" name="shape" type="RID"> </argument> - <argument index="2" name="transform" type="Transform2D" default="null"> + <argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )"> </argument> <description> Add a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index. @@ -34638,9 +35418,9 @@ <method name="body_create"> <return type="RID"> </return> - <argument index="0" name="mode" type="int" enum="Physics2DServer.BodyMode" default="false"> + <argument index="0" name="mode" type="int" enum="Physics2DServer.BodyMode" default="2"> </argument> - <argument index="1" name="init_sleeping" type="bool" default="2"> + <argument index="1" name="init_sleeping" type="bool" default="false"> </argument> <description> Create a physics body. The first parameter can be any value from constants BODY_MODE*, for the type of body created. Additionally, the body can be created in sleeping state to save processing time. @@ -34665,7 +35445,7 @@ </description> </method> <method name="body_get_continuous_collision_detection_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Physics2DServer.CCDMode"> </return> <argument index="0" name="body" type="RID"> </argument> @@ -34683,7 +35463,7 @@ </description> </method> <method name="body_get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Physics2DServer.BodyMode"> </return> <argument index="0" name="body" type="RID"> </argument> @@ -35006,7 +35786,7 @@ </argument> <argument index="2" name="motion" type="Vector2"> </argument> - <argument index="3" name="margin" type="float" default="null"> + <argument index="3" name="margin" type="float" default="0.08"> </argument> <argument index="4" name="result" type="Physics2DTestMotionResult" default="null"> </argument> @@ -35023,7 +35803,7 @@ </argument> <argument index="2" name="body_a" type="RID"> </argument> - <argument index="3" name="body_b" type="RID" default="null"> + <argument index="3" name="body_b" type="RID"> </argument> <description> Create a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself. @@ -35080,9 +35860,9 @@ </argument> <argument index="2" name="anchor_b" type="Vector2"> </argument> - <argument index="3" name="body_a" type="RID" default="null"> + <argument index="3" name="body_a" type="RID"> </argument> - <argument index="4" name="body_b" type="RID" default="null"> + <argument index="4" name="body_b" type="RID"> </argument> <description> Create a groove joint between two bodies. If not specified, the bodyies are assumed to be the joint itself. @@ -35100,7 +35880,7 @@ </description> </method> <method name="joint_get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Physics2DServer.JointType"> </return> <argument index="0" name="joint" type="RID"> </argument> @@ -35128,7 +35908,7 @@ </argument> <argument index="1" name="body_a" type="RID"> </argument> - <argument index="2" name="body_b" type="RID" default="null"> + <argument index="2" name="body_b" type="RID"> </argument> <description> Create a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself. @@ -35162,7 +35942,7 @@ </description> </method> <method name="shape_get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Physics2DServer.ShapeType"> </return> <argument index="0" name="shape" type="RID"> </argument> @@ -36150,7 +36930,7 @@ </return> <argument index="0" name="shape" type="PhysicsShapeQueryParameters"> </argument> - <argument index="1" name="max_results" type="int" default="null"> + <argument index="1" name="max_results" type="int" default="32"> </argument> <description> </description> @@ -36172,9 +36952,9 @@ </argument> <argument index="2" name="exclude" type="Array" default="[ ]"> </argument> - <argument index="3" name="collision_layer" type="int" default="null"> + <argument index="3" name="collision_layer" type="int" default="2147483647"> </argument> - <argument index="4" name="type_mask" type="int" default="null"> + <argument index="4" name="type_mask" type="int" default="15"> </argument> <description> </description> @@ -36184,7 +36964,7 @@ </return> <argument index="0" name="shape" type="PhysicsShapeQueryParameters"> </argument> - <argument index="1" name="max_results" type="int" default="null"> + <argument index="1" name="max_results" type="int" default="32"> </argument> <description> </description> @@ -36218,7 +36998,7 @@ </argument> <argument index="1" name="shape" type="RID"> </argument> - <argument index="2" name="transform" type="Transform" default="null"> + <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </argument> <description> </description> @@ -36302,7 +37082,7 @@ </description> </method> <method name="area_get_space_override_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="PhysicsServer.AreaSpaceOverrideMode"> </return> <argument index="0" name="area" type="RID"> </argument> @@ -36460,7 +37240,7 @@ </argument> <argument index="1" name="shape" type="RID"> </argument> - <argument index="2" name="transform" type="Transform" default="null"> + <argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> </argument> <description> </description> @@ -36508,15 +37288,15 @@ <method name="body_create"> <return type="RID"> </return> - <argument index="0" name="mode" type="int" enum="PhysicsServer.BodyMode" default="false"> + <argument index="0" name="mode" type="int" enum="PhysicsServer.BodyMode" default="2"> </argument> - <argument index="1" name="init_sleeping" type="bool" default="2"> + <argument index="1" name="init_sleeping" type="bool" default="false"> </argument> <description> </description> </method> <method name="body_get_axis_lock" qualifiers="const"> - <return type="int"> + <return type="int" enum="PhysicsServer.BodyAxisLock"> </return> <argument index="0" name="body" type="RID"> </argument> @@ -36548,7 +37328,7 @@ </description> </method> <method name="body_get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="PhysicsServer.BodyMode"> </return> <argument index="0" name="body" type="RID"> </argument> @@ -37038,7 +37818,7 @@ </description> </method> <method name="joint_get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="PhysicsServer.JointType"> </return> <argument index="0" name="joint" type="RID"> </argument> @@ -37138,7 +37918,7 @@ </description> </method> <method name="shape_get_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="PhysicsServer.ShapeType"> </return> <argument index="0" name="shape" type="RID"> </argument> @@ -37842,8 +38622,10 @@ </class> <class name="PlaneMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Class representing a planar [PrimitiveMesh]. </brief_description> <description> + Class representing a planar [PrimitiveMesh]. This flat mesh does not have a thickness. </description> <methods> <method name="get_size" qualifiers="const"> @@ -37891,10 +38673,13 @@ </methods> <members> <member name="size" type="Vector2" setter="set_size" getter="get_size" brief=""> + Size of the generated plane. Defaults to (2.0, 2.0). </member> <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief=""> + Number of subdivision along the z-axis. Defaults to 0. </member> <member name="subdivide_width" type="int" setter="set_subdivide_width" getter="get_subdivide_width" brief=""> + Number of subdivision along the x-axis. Defaults to 0. </member> </members> <constants> @@ -38261,13 +39046,14 @@ <argument index="0" name="byte" type="int"> </argument> <description> + Append an element at the end of the array (alias of [method push_back]). </description> </method> <method name="append_array"> <argument index="0" name="array" type="PoolByteArray"> </argument> <description> - Append an [PoolByteArray] at the end of this array. + Append a [PoolByteArray] at the end of this array. </description> </method> <method name="compress"> @@ -38276,7 +39062,7 @@ <argument index="0" name="compression_mode" type="int" default="0"> </argument> <description> - Returns a new [PoolByteArray] with the data compressed. The compression mode can be set using one of the COMPRESS_* constants of [File]. + Returns a new [PoolByteArray] with the data compressed. Set the compression mode using one of [File]'s COMPRESS_* constants. </description> </method> <method name="decompress"> @@ -38287,21 +39073,21 @@ <argument index="1" name="compression_mode" type="int" default="0"> </argument> <description> - Returns a new [PoolByteArray] with the data decompressed. The buffer_size should be set as the size of the uncompressed data. The compression mode can be set using one of the COMPRESS_* constants of [File]. + Returns a new [PoolByteArray] with the data decompressed. Set buffer_size to the size of the uncompressed data. Set the compression mode using one of [File]'s COMPRESS_* constants. </description> </method> <method name="get_string_from_ascii"> <return type="String"> </return> <description> - Returns a copy of the array's contents formatted as String. Fast alternative to get_string_from_utf8(), assuming the content is ASCII-only (unlike the UTF-8 function, this function maps every byte to a character in the string, so any multibyte sequence will be torn apart). + Returns a copy of the array's contents as [String]. Fast alternative to [method PoolByteArray.get_string_from_utf8] if the content is ASCII-only. Unlike the UTF-8 function this function maps every byte to a character in the array. Multibyte sequences will not be interpreted correctly. For parsing user input always use [method PoolByteArray.get_string_from_utf8]. </description> </method> <method name="get_string_from_utf8"> <return type="String"> </return> <description> - Returns a copy of the array's contents formatted as String, assuming the array is formatted as UTF-8. Slower than get_string_from_ascii(), but works for UTF-8. Usually you should prefer this function over get_string_from_ascii() to support international input. + Returns a copy of the array's contents as [String]. Slower than [method PoolByteArray.get_string_from_ascii] but supports UTF-8 encoded data. Use this function if you are unsure about the source of the data. For user input this function should always be preferred. </description> </method> <method name="insert"> @@ -38338,7 +39124,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the [PoolByteArray]. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -38377,7 +39163,7 @@ Array of Colors </brief_description> <description> - Array of Color, can only contains colors. Optimized for memory usage, can't fragment the memory. + Array of Color, Contains colors. Optimized for memory usage, can't fragment the memory. </description> <methods> <method name="PoolColorArray"> @@ -38400,7 +39186,7 @@ <argument index="0" name="array" type="PoolColorArray"> </argument> <description> - Append an [PoolColorArray] at the end of this array. + Append a [PoolColorArray] at the end of this array. </description> </method> <method name="insert"> @@ -38437,7 +39223,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the [PoolColorArray]. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -38453,7 +39239,7 @@ <return type="int"> </return> <description> - Return the array size. + Return the size of the array. </description> </method> </methods> @@ -38465,7 +39251,7 @@ Integer Array. </brief_description> <description> - Integer Array. Array of integers. Can only contain integers. Optimized for memory usage, can't fragment the memory. + Integer Array. Contains integers. Optimized for memory usage, can't fragment the memory. </description> <methods> <method name="PoolIntArray"> @@ -38525,7 +39311,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the [PoolIntArray]. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -38613,7 +39399,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the [RealArray]. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -38680,15 +39466,16 @@ </method> <method name="invert"> <description> + Reverse the order of the elements in the array (so first element will now be the last). </description> </method> <method name="join"> <return type="String"> </return> - <argument index="0" name="string" type="String"> + <argument index="0" name="delimiter" type="String"> </argument> <description> - Reverse the order of the elements in the array (so first element will now be the last). + Returns a [String] with each element of the array joined with the delimiter. </description> </method> <method name="push_back"> @@ -38709,7 +39496,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the [StringArray]. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -38797,7 +39584,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the PoolVector2Array. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -38871,7 +39658,7 @@ <argument index="0" name="vector3" type="Vector3"> </argument> <description> - Insert a Vector3 at the end. + Insert a [Vector3] at the end. </description> </method> <method name="remove"> @@ -38885,7 +39672,7 @@ <argument index="0" name="idx" type="int"> </argument> <description> - Set the size of the PoolVector3Array. If larger than the current size it will reserve some space beforehand, and if it is smaller it will cut off the array. + Set the size of the array. If the array is grown reserve elements at the end of the array. If the array is shrunk truncate the array to the new size. </description> </method> <method name="set"> @@ -39021,7 +39808,7 @@ </argument> <argument index="1" name="id" type="int" default="-1"> </argument> - <argument index="2" name="accel" type="int" default="null"> + <argument index="2" name="accel" type="int" default="0"> </argument> <description> Add a new checkable item with text "label". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be created from the index. Note that checkable items just display a checkmark, but don't have any built-in checking behavior and must be checked/unchecked manually. @@ -39034,7 +39821,7 @@ </argument> <argument index="1" name="id" type="int" default="-1"> </argument> - <argument index="2" name="global" type="bool" default="null"> + <argument index="2" name="global" type="bool" default="false"> </argument> <description> </description> @@ -39046,9 +39833,9 @@ </argument> <argument index="1" name="label" type="String"> </argument> - <argument index="2" name="id" type="int" default="null"> + <argument index="2" name="id" type="int" default="-1"> </argument> - <argument index="3" name="accel" type="int" default="null"> + <argument index="3" name="accel" type="int" default="0"> </argument> <description> Add a new checkable item with text "label" and icon "texture". An id can optionally be provided, as well as an accelerator. If no id is provided, one will be @@ -39062,9 +39849,9 @@ </argument> <argument index="1" name="shortcut" type="ShortCut"> </argument> - <argument index="2" name="id" type="int" default="null"> + <argument index="2" name="id" type="int" default="-1"> </argument> - <argument index="3" name="global" type="bool" default="null"> + <argument index="3" name="global" type="bool" default="false"> </argument> <description> </description> @@ -39076,9 +39863,9 @@ </argument> <argument index="1" name="label" type="String"> </argument> - <argument index="2" name="id" type="int" default="null"> + <argument index="2" name="id" type="int" default="-1"> </argument> - <argument index="3" name="accel" type="int" default="null"> + <argument index="3" name="accel" type="int" default="0"> </argument> <description> Add a new item with text "label" and icon "texture". An id can optionally be provided, as well as an accelerator keybinding. If no id is provided, one will be created from the index. @@ -39091,9 +39878,9 @@ </argument> <argument index="1" name="shortcut" type="ShortCut"> </argument> - <argument index="2" name="id" type="int" default="null"> + <argument index="2" name="id" type="int" default="-1"> </argument> - <argument index="3" name="global" type="bool" default="null"> + <argument index="3" name="global" type="bool" default="false"> </argument> <description> </description> @@ -39105,7 +39892,7 @@ </argument> <argument index="1" name="id" type="int" default="-1"> </argument> - <argument index="2" name="accel" type="int" default="null"> + <argument index="2" name="accel" type="int" default="0"> </argument> <description> Add a new item with text "label". An id can optionally be provided, as well as an accelerator keybinding. If no id is provided, one will be created from the index. @@ -39125,7 +39912,7 @@ </argument> <argument index="1" name="id" type="int" default="-1"> </argument> - <argument index="2" name="global" type="bool" default="null"> + <argument index="2" name="global" type="bool" default="false"> </argument> <description> </description> @@ -39137,7 +39924,7 @@ </argument> <argument index="1" name="submenu" type="String"> </argument> - <argument index="2" name="id" type="int" default="null"> + <argument index="2" name="id" type="int" default="-1"> </argument> <description> Adds an item with a submenu. The submenu is the name of a child PopupMenu node that would be shown when the item is clicked. An id can optionally be provided, but if is isn't provided, one will be created from the index. @@ -39407,7 +40194,7 @@ </argument> <argument index="1" name="shortcut" type="ShortCut"> </argument> - <argument index="2" name="global" type="bool" default="null"> + <argument index="2" name="global" type="bool" default="false"> </argument> <description> </description> @@ -39552,8 +40339,10 @@ </class> <class name="PrimitiveMesh" inherits="Mesh" category="Core"> <brief_description> + Base class for all primitive meshes. Handles applying a [Material] to a primitive mesh. </brief_description> <description> + Base class for all primitive meshes. Handles applying a [Material] to a primitive mesh. </description> <methods> <method name="get_material" qualifiers="const"> @@ -39573,6 +40362,7 @@ </methods> <members> <member name="material" type="Material" setter="set_material" getter="get_material" brief=""> + The current [Material] of the primitive mesh. </member> </members> <constants> @@ -39580,8 +40370,10 @@ </class> <class name="PrismMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Class representing a prism-shaped [PrimitiveMesh]. </brief_description> <description> + Class representing a prism-shaped [PrimitiveMesh]. </description> <methods> <method name="get_left_to_right" qualifiers="const"> @@ -39657,14 +40449,19 @@ </methods> <members> <member name="left_to_right" type="float" setter="set_left_to_right" getter="get_left_to_right" brief=""> + Displacement of of the upper edge along the x-axis. 0.0 positions edge straight above the bottome left edge. Defaults to 0.5 (positioned on the midpoint). </member> <member name="size" type="Vector3" setter="set_size" getter="get_size" brief=""> + Size of the prism. Defaults to (2.0, 2.0, 2.0). </member> <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief=""> + Number of added edge loops along the z-axis. Defaults to 0. </member> <member name="subdivide_height" type="int" setter="set_subdivide_height" getter="get_subdivide_height" brief=""> + Number of added edge loops along the y-axis. Defaults to 0. </member> <member name="subdivide_width" type="int" setter="set_subdivide_width" getter="get_subdivide_width" brief=""> + Number of added edge loops along the x-axis. Defaults to 0. </member> </members> <constants> @@ -39767,7 +40564,7 @@ </description> </method> <method name="get_texture_size" qualifiers="const"> - <return type="int"> + <return type="int" enum="ProceduralSky.TextureSize"> </return> <description> </description> @@ -40108,13 +40905,13 @@ </description> </method> <method name="save"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> </description> </method> <method name="save_custom"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="file" type="String"> </argument> @@ -40214,8 +41011,10 @@ </class> <class name="QuadMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Class representing a square mesh. </brief_description> <description> + Class representing a square mesh with size (2,2,0). Consider using a [PlaneMesh] if you require a differently sized plane. </description> <methods> </methods> @@ -40575,11 +41374,11 @@ Query the closest object intersecting a ray. </brief_description> <description> - A RayCast represents a line from its origin to its destination position [code]cast_to[/code], it is used to query the 3D space in order to find the closest object intersecting with the ray. + A RayCast represents a line from its origin to its destination position, [code]cast_to[/code]. It is used to query the 3D space in order to find the closest object along the path of the ray. - RayCast can ignore some objects by adding them to the exception list via [code]add_exception[/code], setting proper filtering with layers, or by filtering object types with type masks. + RayCast can ignore some objects by adding them to the exception list via [code]add_exception[/code], by setting proper filtering with collision layers, or by filtering object types with type masks. - Only enabled raycasts will be able to query the space and report collisions! + Only enabled raycasts will be able to query the space and report collisions. RayCast calculates intersection every fixed frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between fixed frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast. </description> @@ -40590,7 +41389,7 @@ <argument index="0" name="node" type="Object"> </argument> <description> - Adds a collision exception so the ray does not report collisions with the specified [code]node[/code]. + Adds a collision exception so the ray does not report collisions with the specified node. </description> </method> <method name="add_exception_rid"> @@ -40599,20 +41398,22 @@ <argument index="0" name="rid" type="RID"> </argument> <description> + Adds a collision exception so the ray does not report collisions with the specified [RID]. </description> </method> <method name="clear_exceptions"> <return type="void"> </return> <description> - Removes all collision exception for this ray. + Removes all collision exceptions for this ray. </description> </method> <method name="force_raycast_update"> <return type="void"> </return> <description> - Updates the collision information in case if this object's properties changed during the current frame (for example position, rotation or the cast_point). Note, [code]set_enabled[/code] is not required for this to work. + Updates the collision information for the ray. + Use this method to update the collision information immediately instead of waiting for the next [code]_fixed_process[/code] call, for example if the ray or its parent has changed state. Note: [code]enabled == true[/code] is not required for this to work. </description> </method> <method name="get_cast_to" qualifiers="const"> @@ -40626,14 +41427,24 @@ <return type="Object"> </return> <description> - Return the closest object the ray is pointing to. Note that this does not consider the length of the vector, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray. + Return the closest object the ray is pointing to. Note that this does not consider the length of the ray, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray. + Example: + [codeblock] + if RayCast.is_colliding(): + var collider = RayCast.get_collider() + [/codeblock] </description> </method> <method name="get_collider_shape" qualifiers="const"> <return type="int"> </return> <description> - Returns the collision shape of the closest object the ray is pointing to. + Returns the collision shape of the closest object the ray is pointing to. Note that this does not consider the length of the ray, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray. + Example: + [codeblock] + if RayCast.is_colliding(): + var shape = RayCast.get_collider_shape() + [/codeblock] </description> </method> <method name="get_collision_layer" qualifiers="const"> @@ -40647,14 +41458,14 @@ <return type="Vector3"> </return> <description> - Returns the normal of the intersecting object shape face containing the collision point. + Returns the normal of the intersecting object's shape at the collision point. </description> </method> <method name="get_collision_point" qualifiers="const"> <return type="Vector3"> </return> <description> - Returns collision point. This point is in [b]global[/b] coordinate system. + Returns the collision point at which the ray intersects the closest object. Note: this point is in the [b]global[/b] coordinate system. </description> </method> <method name="get_type_mask" qualifiers="const"> @@ -40675,7 +41486,7 @@ <return type="bool"> </return> <description> - Returns whether this raycast is enabled or not. + Returns whether the ray is enabled or not. </description> </method> <method name="remove_exception"> @@ -40684,7 +41495,7 @@ <argument index="0" name="node" type="Object"> </argument> <description> - Removes a collision exception so the ray does report collisions with the specified [code]node[/code]. + Removes a collision exception so the ray does report collisions with the specified node. </description> </method> <method name="remove_exception_rid"> @@ -40693,6 +41504,7 @@ <argument index="0" name="rid" type="RID"> </argument> <description> + Removes a collision exception so the ray does report collisions with the specified [RID]. </description> </method> <method name="set_cast_to"> @@ -40701,7 +41513,7 @@ <argument index="0" name="local_point" type="Vector3"> </argument> <description> - Sets to which point ray should be casted. This point is in [b]local[/b] coordinate system. + Sets the ray destination point, so that the ray will test from the ray's origin to [code]local_point[/code]. </description> </method> <method name="set_collision_layer"> @@ -40734,12 +41546,20 @@ </methods> <members> <member name="cast_to" type="Vector3" setter="set_cast_to" getter="get_cast_to" brief=""> + The ray's destination point, relative to the RayCast's [code]position[/code]. </member> <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief=""> + The RayCast's collison layer(s). Only bodies in the same collision layer(s) will be detected. </member> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" brief=""> + If [code]true[/code], collisions will be reported. Default value: [code]false[/code]. </member> <member name="type_mask" type="int" setter="set_type_mask" getter="get_type_mask" brief=""> + Object types to detect using a logical sum (OR operation) of type constants defined in [Physics2DDirectSpaceState]. + Example: + [codeblock] + RayCast.type_mask = Physics2DDirectSpaceState.TYPE_MASK_STATIC_BODY | Physics2DDirectSpaceState.TYPE_MASK_KINEMATIC_BODY + [/codeblock] </member> </members> <constants> @@ -40750,12 +41570,9 @@ Query the closest object intersecting a ray. </brief_description> <description> - A RayCast2D represents a line from its origin to its destination position [code]cast_to[/code], it is used to query the 2D space in order to find the closest object intersecting with the ray. - - RayCast2D can ignore some objects by adding them to the exception list via [code]add_exception[/code], setting proper filtering with layers, or by filtering object types with type masks. - - Only enabled raycasts will be able to query the space and report collisions! - + A RayCast represents a line from its origin to its destination position, [code]cast_to[/code]. It is used to query the 2D space in order to find the closest object along the path of the ray. + RayCast2D can ignore some objects by adding them to the exception list via [code]add_exception[/code], by setting proper filtering with collision layers, or by filtering object types with type masks. + Only enabled raycasts will be able to query the space and report collisions. RayCast2D calculates intersection every fixed frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between fixed frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast. </description> <methods> @@ -40765,7 +41582,7 @@ <argument index="0" name="node" type="Object"> </argument> <description> - Adds a collision exception so the ray does not report collisions with the specified [code]node[/code]. + Adds a collision exception so the ray does not report collisions with the specified node. </description> </method> <method name="add_exception_rid"> @@ -40774,20 +41591,21 @@ <argument index="0" name="rid" type="RID"> </argument> <description> + Adds a collision exception so the ray does not report collisions with the specified [RID]. </description> </method> <method name="clear_exceptions"> <return type="void"> </return> <description> - Removes all collision exception for this ray. + Removes all collision exceptions for this ray. </description> </method> <method name="force_raycast_update"> <return type="void"> </return> <description> - Updates the collision information in case if this object's properties changed during the current frame (for example position, rotation or the cast_point). Note, [code]set_enabled[/code] is not required for this to work. + Updates the collision information for the ray. Use this method to update the collision information immediately instead of waiting for the next [code]_fixed_process[/code] call, for example if the ray or its parent has changed state. Note: [code]enabled == true[/code] is not required for this to work. </description> </method> <method name="get_cast_to" qualifiers="const"> @@ -40801,14 +41619,24 @@ <return type="Object"> </return> <description> - Return the closest object the ray is pointing to. Note that this does not consider the length of the vector, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray. + Returns the closest object the ray is pointing to. Note that this does not consider the length of the ray, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray. + Example: + [codeblock] + if RayCast2D.is_colliding(): + var collider = RayCast2D.get_collider() + [/codeblock] </description> </method> <method name="get_collider_shape" qualifiers="const"> <return type="int"> </return> <description> - Returns the collision shape of the closest object the ray is pointing to. + Returns the collision shape of the closest object the ray is pointing to. Note that this does not consider the length of the ray, so you must also use [method is_colliding] to check if the object returned is actually colliding with the ray. + Example: + [codeblock] + if RayCast2D.is_colliding(): + var shape = RayCast2D.get_collider_shape() + [/codeblock] </description> </method> <method name="get_collision_layer" qualifiers="const"> @@ -40822,14 +41650,14 @@ <return type="Vector2"> </return> <description> - Returns the normal of the intersecting object shape face containing the collision point. + Returns the normal of the intersecting object's shape at the collision point. </description> </method> <method name="get_collision_point" qualifiers="const"> <return type="Vector2"> </return> <description> - Returns the collision point in which the ray intersects the closest object. This point is in [b]global[/b] coordinate system. + Returns the collision point at which the ray intersects the closest object. Note: this point is in the [b]global[/b] coordinate system. </description> </method> <method name="get_exclude_parent_body" qualifiers="const"> @@ -40866,7 +41694,7 @@ <argument index="0" name="node" type="Object"> </argument> <description> - Removes a collision exception so the ray does report collisions with the specified [code]node[/code]. + Removes a collision exception so the ray does report collisions with the specified node. </description> </method> <method name="remove_exception_rid"> @@ -40875,6 +41703,7 @@ <argument index="0" name="rid" type="RID"> </argument> <description> + Removes a collision exception so the ray does report collisions with the specified [RID]. </description> </method> <method name="set_cast_to"> @@ -40925,14 +41754,23 @@ </methods> <members> <member name="cast_to" type="Vector2" setter="set_cast_to" getter="get_cast_to" brief=""> + The ray's destination point, relative to the RayCast's [code]position[/code]. </member> <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief=""> + The RayCast2D's collison layer(s). Only bodies in the same collision layer(s) will be detected. </member> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" brief=""> + If [code]true[/code], collisions will be reported. Default value: [code]false[/code]. </member> <member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" brief=""> + If [code]true[/code], the parent node will be excluded from collision detection. Default value: [code]true[/code]. </member> <member name="type_mask" type="int" setter="set_type_mask" getter="get_type_mask" brief=""> + Object types to detect using a logical sum (OR operation) of type constants defined in [Physics2DDirectSpaceState]. + Example: + [codeblock] + RayCast.type_mask = Physics2DDirectSpaceState.TYPE_MASK_STATIC_BODY | Physics2DDirectSpaceState.TYPE_MASK_KINEMATIC_BODY + [/codeblock] </member> </members> <constants> @@ -41486,7 +42324,7 @@ </description> </method> <method name="get_update_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="ReflectionProbe.UpdateMode"> </return> <description> </description> @@ -41672,7 +42510,7 @@ </description> </method> <method name="compile"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="pattern" type="String"> </argument> @@ -41715,7 +42553,7 @@ </argument> <argument index="1" name="offset" type="int" default="0"> </argument> - <argument index="2" name="end" type="int" default="null"> + <argument index="2" name="end" type="int" default="-1"> </argument> <description> Searches the text for the compiled pattern. Returns a [RegExMatch] container of the first matching reult if found, otherwise null. The region to search within can be specified without modifying where the start and end anchor would be. @@ -41730,9 +42568,9 @@ </argument> <argument index="2" name="all" type="bool" default="false"> </argument> - <argument index="3" name="offset" type="int" default="null"> + <argument index="3" name="offset" type="int" default="0"> </argument> - <argument index="4" name="end" type="int" default="null"> + <argument index="4" name="end" type="int" default="-1"> </argument> <description> Searches the text for the compiled pattern and replaces it with the specified string. Escapes and backreferences such as [code]\1[/code] and [code]\g<name>[/code] expanded and resolved. By default only the first instance is replaced but it can be changed for all instances (global replacement). The region to search within can be specified without modifying where the start and end anchor would be. @@ -42153,14 +42991,14 @@ </description> </method> <method name="poll"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Poll the load. If OK is returned, this means poll will have to be called again. If ERR_FILE_EOF is returned, them the load has finished and the resource can be obtained by calling [method get_resource]. </description> </method> <method name="wait"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> </description> @@ -42209,7 +43047,7 @@ </argument> <argument index="1" name="type_hint" type="String" default=""""> </argument> - <argument index="2" name="p_no_cache" type="bool" default="null"> + <argument index="2" name="p_no_cache" type="bool" default="false"> </argument> <description> </description> @@ -42219,7 +43057,7 @@ </return> <argument index="0" name="path" type="String"> </argument> - <argument index="1" name="type_hint" type="String" default="null"> + <argument index="1" name="type_hint" type="String" default=""""> </argument> <description> Load a resource interactively, the returned object allows to load with high granularity. @@ -42327,13 +43165,13 @@ </description> </method> <method name="save"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> <argument index="1" name="resource" type="Resource"> </argument> - <argument index="2" name="flags" type="int" default="null"> + <argument index="2" name="flags" type="int" default="0"> </argument> <description> Save a resource to disk, to a given path. @@ -42380,7 +43218,7 @@ </description> </method> <method name="append_bbcode"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="bbcode" type="String"> </argument> @@ -42474,7 +43312,7 @@ </description> </method> <method name="parse_bbcode"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="bbcode" type="String"> </argument> @@ -42738,6 +43576,8 @@ </theme_item> <theme_item name="mono_font" type="Font"> </theme_item> + <theme_item name="normal" type="StyleBox"> + </theme_item> <theme_item name="normal_font" type="Font"> </theme_item> <theme_item name="selection_color" type="Color"> @@ -42791,7 +43631,7 @@ </description> </method> <method name="get_axis_lock" qualifiers="const"> - <return type="int"> + <return type="int" enum="RigidBody.AxisLock"> </return> <description> Return the current axis lock of the body. One of AXIS_LOCK_* enum. @@ -42854,7 +43694,7 @@ </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="RigidBody.Mode"> </return> <description> Return the current body mode, see [method set_mode]. @@ -43069,38 +43909,55 @@ </methods> <members> <member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief=""> + Dampens rotational forces of the Rigid body by the 'angular_damp' rate. </member> <member name="angular_velocity" type="Vector3" setter="set_angular_velocity" getter="get_angular_velocity" brief=""> + The current rotational velocity of the Rigid body </member> <member name="axis_lock" type="int" setter="set_axis_lock" getter="get_axis_lock" brief="" enum="RigidBody.AxisLock"> + Locks the rotational forces to a particular axis, preventing rotations on other axes. </member> <member name="bounce" type="float" setter="set_bounce" getter="get_bounce" brief=""> + Bounciness of the Rigid body. </member> <member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep" brief=""> + If true, the Rigid body will no longer calculate forces when there is no movement and will act as a static body. It will wake up when other forces are applied through other collisions or when the 'apply_impulse' method is used. </member> <member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled" brief=""> + If true, the Rigid body will emit signals when it collides with another Rigid body. </member> <member name="contacts_reported" type="int" setter="set_max_contacts_reported" getter="get_max_contacts_reported" brief=""> + The maximum contacts to report. Bodies can keep a log of the contacts with other bodies, this is enabled by setting the maximum amount of contacts reported to a number greater than 0. </member> <member name="continuous_cd" type="bool" setter="set_use_continuous_collision_detection" getter="is_using_continuous_collision_detection" brief=""> + Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided. The first is more precise, and misses less impacts by small, fast-moving objects. The second is faster to compute, but can miss small, fast-moving objects. </member> <member name="custom_integrator" type="bool" setter="set_use_custom_integrator" getter="is_using_custom_integrator" brief=""> + If true, internal force integration will be disabled (like gravity or air friction) for this body. Other than collision response, the body will only move as determined by the [method _integrate_forces] function, if defined. </member> <member name="friction" type="float" setter="set_friction" getter="get_friction" brief=""> + The body friction, from 0 (frictionless) to 1 (max friction). </member> <member name="gravity_scale" type="float" setter="set_gravity_scale" getter="get_gravity_scale" brief=""> + The 'gravity_scale' for this Rigid body will be multiplied by the global 3d gravity setting found in "Project > Project Settings > Physics > 3d". A value of 1 will be normal gravity, 2 will apply double gravity, and 0.5 will apply half gravity to this object. </member> <member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp" brief=""> + The linear damp for this body. Default of -1, cannot be less than -1. If this value is different from -1, any linear damp derived from the world or areas will be overridden. </member> <member name="linear_velocity" type="Vector3" setter="set_linear_velocity" getter="get_linear_velocity" brief=""> + The body linear velocity. Can be used sporadically, but [b]DON'T SET THIS IN EVERY FRAME[/b], because physics may run in another thread and runs at a different granularity. Use [method _integrate_forces] as your process loop for precise control of the body state. </member> <member name="mass" type="float" setter="set_mass" getter="get_mass" brief=""> + The body mass. </member> <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="RigidBody.Mode"> + The body mode from the MODE_* enum. Modes include: MODE_STATIC, MODE_KINEMATIC, MODE_RIGID, and MODE_CHARACTER. </member> <member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping" brief=""> + The current 'sleeping' state of the Rigid body. </member> <member name="weight" type="float" setter="set_weight" getter="get_weight" brief=""> + The body weight given standard earth-weight (gravity 9.8). </member> </members> <signals> @@ -43251,7 +44108,7 @@ </description> </method> <method name="get_continuous_collision_detection_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="RigidBody2D.CCDMode"> </return> <description> Return whether this body is using continuous collision detection. @@ -43307,7 +44164,7 @@ </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="RigidBody2D.Mode"> </return> <description> Return the current body mode, see [method set_mode]. @@ -43762,7 +44619,7 @@ </return> <argument index="0" name="idx" type="int"> </argument> - <argument index="1" name="for_parent" type="bool" default="null"> + <argument index="1" name="for_parent" type="bool" default="false"> </argument> <description> </description> @@ -43850,7 +44707,7 @@ </description> </method> <method name="change_scene"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -43858,7 +44715,7 @@ </description> </method> <method name="change_scene_to"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="packed_scene" type="PackedScene"> </argument> @@ -43870,7 +44727,7 @@ </return> <argument index="0" name="time_sec" type="float"> </argument> - <argument index="1" name="pause_mode_process" type="bool" default="null"> + <argument index="1" name="pause_mode_process" type="bool" default="true"> </argument> <description> </description> @@ -44020,7 +44877,7 @@ </description> </method> <method name="reload_current_scene"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> </description> @@ -44131,7 +44988,7 @@ </argument> <argument index="2" name="minsize" type="Vector2"> </argument> - <argument index="3" name="shrink" type="int" default="null"> + <argument index="3" name="shrink" type="int" default="1"> </argument> <description> </description> @@ -44256,17 +45113,18 @@ </class> <class name="Script" inherits="Resource" category="Core"> <brief_description> - Base class for scripts. + A class stored as a resource. </brief_description> <description> - Base class for scripts. Any script that is loaded becomes one of these resources, which can then create instances. + A class stored as a resource. The script exends the functionality of all objects that instance it. + The 'new' method of a script subclass creates a new instance. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes. </description> <methods> <method name="can_instance" qualifiers="const"> <return type="bool"> </return> <description> - Return true if this script can be instance (ie not a library). + Returns true if the script can be instanced. </description> </method> <method name="get_node_type" qualifiers="const"> @@ -44279,7 +45137,7 @@ <return type="String"> </return> <description> - Return the script source code (if available). + Returns the script source code, or an empty string if source code is not available. </description> </method> <method name="has_script_signal" qualifiers="const"> @@ -44288,13 +45146,14 @@ <argument index="0" name="signal_name" type="String"> </argument> <description> + Returns true if the script, or a base class, defines a signal with the given name. </description> </method> <method name="has_source_code" qualifiers="const"> <return type="bool"> </return> <description> - Return true if the script contains source code. + Returns true if the script contains non-empty source code. </description> </method> <method name="instance_has" qualifiers="const"> @@ -44303,21 +45162,24 @@ <argument index="0" name="base_object" type="Object"> </argument> <description> - Return true if a given object uses an instance of this script. + Returns true if 'base_object' is an instance of this script. </description> </method> <method name="is_tool" qualifiers="const"> <return type="bool"> </return> <description> + Returns true if the script is a tool script. A tool script can run in the editor. </description> </method> <method name="reload"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="keep_state" type="bool" default="false"> + If true, preserve existing script instances and subclasses. </argument> <description> + Reloads the script's class implementation. Returns an error code. </description> </method> <method name="set_source_code"> @@ -44326,7 +45188,7 @@ <argument index="0" name="source" type="String"> </argument> <description> - Set the script source code. + Sets the script source code. Does not reload the class implementation. </description> </method> </methods> @@ -44550,14 +45412,14 @@ </description> <methods> <method name="post"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Lowers the [Semaphore], allowing one more thread in. </description> </method> <method name="wait"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Tries to wait for the [Semaphore], if its value is zero, blocks until non-zero. @@ -44602,7 +45464,7 @@ </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Shader.Mode"> </return> <description> </description> @@ -45067,7 +45929,7 @@ </description> <methods> <method name="get_radiance_size" qualifiers="const"> - <return type="int"> + <return type="int" enum="Sky.RadianceSize"> </return> <description> </description> @@ -45294,16 +46156,17 @@ </class> <class name="Spatial" inherits="Node" category="Core"> <brief_description> - Base class for all 3D nodes. + Most basic 3D game object, parent of all 3D related nodes. </brief_description> <description> - Spatial is the base for every type of 3D [Node]. It contains a 3D [Transform] which can be set or get as local or global. If a Spatial [Node] has Spatial children, their transforms will be relative to the parent. + Most basic 3D game object, with a 3D [Transform] and visibility settings. All 3D physics nodes and sprites inherit from Spatial. Use Spatial as a parent node to move, scale, rotate and show/hide children in a 3D project. </description> <methods> <method name="get_gizmo" qualifiers="const"> <return type="SpatialGizmo"> </return> <description> + Return the SpatialGizmo for this node. Used for example in [EditorSpatialGizmo] as custom visualization and editing handles in Editor. </description> </method> <method name="get_global_transform" qualifiers="const"> @@ -45357,6 +46220,7 @@ <return type="World"> </return> <description> + Return current [World] resource this Spatial node is registered to. </description> </method> <method name="global_rotate"> @@ -45367,6 +46231,7 @@ <argument index="1" name="radians" type="float"> </argument> <description> + Rotate current node along normal [Vector3] by angle in radians in Global space. </description> </method> <method name="global_translate"> @@ -45375,42 +46240,49 @@ <argument index="0" name="offset" type="Vector3"> </argument> <description> + Move current node by [Vector3] offset in Global space. </description> </method> <method name="hide"> <return type="void"> </return> <description> + Disable rendering of this node. Change Spatial Visible property to false. </description> </method> <method name="is_local_transform_notification_enabled" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether node sends notification that its local transformation changed. Spatial will not propagate this by default. </description> </method> <method name="is_set_as_toplevel" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether this node is set as Toplevel, ignoring its parent node transformations. </description> </method> <method name="is_transform_notification_enabled" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether node sends notification that its transformation changed. Spatial will not propagate this by default. </description> </method> <method name="is_visible" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether this node is set to be visible. </description> </method> <method name="is_visible_in_tree" qualifiers="const"> <return type="bool"> </return> <description> + Returns whether this node is visible, taking into consideration that its parents visibility. </description> </method> <method name="look_at"> @@ -45421,6 +46293,7 @@ <argument index="1" name="up" type="Vector3"> </argument> <description> + Rotates itself to point into direction of target position. Operations take place in global space. </description> </method> <method name="look_at_from_pos"> @@ -45433,12 +46306,14 @@ <argument index="2" name="up" type="Vector3"> </argument> <description> + Moves itself to specified position and then rotates itself to point into direction of target position. Operations take place in global space. </description> </method> <method name="orthonormalize"> <return type="void"> </return> <description> + Reset this node transformations (like scale, skew and taper) preserving its rotation and translation. Performs orthonormalization on this node [Transform3D]. </description> </method> <method name="rotate"> @@ -45449,6 +46324,7 @@ <argument index="1" name="radians" type="float"> </argument> <description> + Rotates node in local space on given normal [Vector3] by angle in radians. </description> </method> <method name="rotate_x"> @@ -45457,6 +46333,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> + Rotates node in local space on X axis by angle in radians. </description> </method> <method name="rotate_y"> @@ -45465,6 +46342,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> + Rotates node in local space on Y axis by angle in radians. </description> </method> <method name="rotate_z"> @@ -45473,6 +46351,7 @@ <argument index="0" name="radians" type="float"> </argument> <description> + Rotates node in local space on Z axis by angle in radians. </description> </method> <method name="set_as_toplevel"> @@ -45481,6 +46360,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + Makes this node ignore its parents tranformations. Node tranformations are only in global space. </description> </method> <method name="set_gizmo"> @@ -45489,6 +46369,7 @@ <argument index="0" name="gizmo" type="SpatialGizmo"> </argument> <description> + Set [SpatialGizmo] for this node. Used for example in [EditorSpatialGizmo] as custom visualization and editing handles in Editor. </description> </method> <method name="set_global_transform"> @@ -45497,13 +46378,14 @@ <argument index="0" name="global" type="Transform"> </argument> <description> - Set the transform globally, relative to worldspace. + Set the transform globally, relative to world space. </description> </method> <method name="set_identity"> <return type="void"> </return> <description> + Reset all tranformations for this node. Set its [Transform3D] to identity matrix. </description> </method> <method name="set_ignore_transform_notification"> @@ -45512,6 +46394,7 @@ <argument index="0" name="enabled" type="bool"> </argument> <description> + Set whether this node ignores notification that its transformation changed. </description> </method> <method name="set_notify_local_transform"> @@ -45520,6 +46403,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + Set whether this node sends notification that its local transformation changed. Spatial will not propagate this by default. </description> </method> <method name="set_notify_transform"> @@ -45528,6 +46412,7 @@ <argument index="0" name="enable" type="bool"> </argument> <description> + Set whether this node sends notification that its transformation changed. Spatial will not propagate this by default. </description> </method> <method name="set_rotation"> @@ -45554,6 +46439,7 @@ <argument index="0" name="scale" type="Vector3"> </argument> <description> + Set the scale. </description> </method> <method name="set_transform"> @@ -45585,6 +46471,7 @@ <return type="void"> </return> <description> + Enable rendering of this node. Change Spatial Visible property to false. </description> </method> <method name="to_global" qualifiers="const"> @@ -45593,6 +46480,7 @@ <argument index="0" name="local_point" type="Vector3"> </argument> <description> + Tranform [Vector3] from this node local space to world space. </description> </method> <method name="to_local" qualifiers="const"> @@ -45601,6 +46489,7 @@ <argument index="0" name="global_point" type="Vector3"> </argument> <description> + Tranform [Vector3] from world space to this node local space. </description> </method> <method name="translate"> @@ -45609,46 +46498,60 @@ <argument index="0" name="offset" type="Vector3"> </argument> <description> + Change node position by given offset [Vector3]. </description> </method> <method name="update_gizmo"> <return type="void"> </return> <description> + Update [SpatialGizmo] of this node. </description> </method> </methods> <members> <member name="global_transform" type="Transform" setter="set_global_transform" getter="get_global_transform" brief=""> + World space (global) [Transform] of this node. </member> <member name="rotation" type="Vector3" setter="set_rotation" getter="get_rotation" brief=""> + Local euler rotation in radians of this node. </member> <member name="rotation_deg" type="Vector3" setter="set_rotation_deg" getter="get_rotation_deg" brief=""> + Local euler rotation in degrees of this node. </member> <member name="scale" type="Vector3" setter="set_scale" getter="get_scale" brief=""> + Local scale of this node. </member> <member name="transform" type="Transform" setter="set_transform" getter="get_transform" brief=""> + Local space [Transform] of this node. </member> <member name="translation" type="Vector3" setter="set_translation" getter="get_translation" brief=""> + Local translation of this node. </member> <member name="visible" type="bool" setter="set_visible" getter="is_visible" brief=""> + Visibility of this node. Toggles if this node is rendered. </member> </members> <signals> <signal name="visibility_changed"> <description> + Emitted when node visibility changed. </description> </signal> </signals> <constants> <constant name="NOTIFICATION_TRANSFORM_CHANGED" value="29" enum=""> - Spatial nodes receive this notification with their global transform changes. This means that either the current or a parent node changed its transform. + Spatial nodes receive this notification when their global transform changes. This means that either the current or a parent node changed its transform. + In order for NOTIFICATION_TRANSFORM_CHANGED to work user first needs to ask for it, with set_notify_transform(true). </constant> <constant name="NOTIFICATION_ENTER_WORLD" value="41" enum=""> + Spatial nodes receive this notification when they are registered to new [World] resource. </constant> <constant name="NOTIFICATION_EXIT_WORLD" value="42" enum=""> + Spatial nodes receive this notification when they are unregistered from current [World] resource. </constant> <constant name="NOTIFICATION_VISIBILITY_CHANGED" value="43" enum=""> + Spatial nodes receive this notification when their visibility changes. </constant> </constants> </class> @@ -45687,19 +46590,19 @@ </description> </method> <method name="get_ao_texture_channel" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.TextureChannel"> </return> <description> </description> </method> <method name="get_billboard_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.BillboardMode"> </return> <description> </description> </method> <method name="get_blend_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.BlendMode"> </return> <description> </description> @@ -45717,7 +46620,7 @@ </description> </method> <method name="get_cull_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.CullMode"> </return> <description> </description> @@ -45735,7 +46638,7 @@ </description> </method> <method name="get_depth_draw_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.DepthDrawMode"> </return> <description> </description> @@ -45747,19 +46650,19 @@ </description> </method> <method name="get_detail_blend_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.BlendMode"> </return> <description> </description> </method> <method name="get_detail_uv" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.DetailUV"> </return> <description> </description> </method> <method name="get_diffuse_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.DiffuseMode"> </return> <description> </description> @@ -45811,7 +46714,7 @@ </description> </method> <method name="get_metallic_texture_channel" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.TextureChannel"> </return> <description> </description> @@ -45853,7 +46756,7 @@ </description> </method> <method name="get_refraction_texture_channel" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.TextureChannel"> </return> <description> </description> @@ -45877,7 +46780,7 @@ </description> </method> <method name="get_roughness_texture_channel" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.TextureChannel"> </return> <description> </description> @@ -45889,7 +46792,7 @@ </description> </method> <method name="get_specular_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpatialMaterial.SpecularMode"> </return> <description> </description> @@ -45908,6 +46811,12 @@ <description> </description> </method> + <method name="get_transmission" qualifiers="const"> + <return type="Color"> + </return> + <description> + </description> + </method> <method name="get_uv1_offset" qualifiers="const"> <return type="Vector3"> </return> @@ -46290,6 +47199,14 @@ <description> </description> </method> + <method name="set_transmission"> + <return type="void"> + </return> + <argument index="0" name="transmission" type="Color"> + </argument> + <description> + </description> + </method> <method name="set_uv1_offset"> <return type="void"> </return> @@ -46410,6 +47327,8 @@ </member> <member name="flags_vertex_lighting" type="bool" setter="set_flag" getter="get_flag" brief=""> </member> + <member name="flags_world_triplanar" type="bool" setter="set_flag" getter="get_flag" brief=""> + </member> <member name="metallic" type="float" setter="set_metallic" getter="get_metallic" brief=""> </member> <member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" brief=""> @@ -46482,6 +47401,12 @@ </member> <member name="subsurf_scatter_texture" type="Texture" setter="set_texture" getter="get_texture" brief=""> </member> + <member name="transmission" type="Color" setter="set_transmission" getter="get_transmission" brief=""> + </member> + <member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature" brief=""> + </member> + <member name="transmission_texture" type="Texture" setter="set_texture" getter="get_texture" brief=""> + </member> <member name="uv1_offset" type="Vector3" setter="set_uv1_offset" getter="get_uv1_offset" brief=""> </member> <member name="uv1_scale" type="Vector3" setter="set_uv1_scale" getter="get_uv1_scale" brief=""> @@ -46526,15 +47451,17 @@ </constant> <constant name="TEXTURE_SUBSURFACE_SCATTERING" value="10"> </constant> - <constant name="TEXTURE_REFRACTION" value="11"> + <constant name="TEXTURE_TRANSMISSION" value="11"> + </constant> + <constant name="TEXTURE_REFRACTION" value="12"> </constant> - <constant name="TEXTURE_DETAIL_MASK" value="12"> + <constant name="TEXTURE_DETAIL_MASK" value="13"> </constant> - <constant name="TEXTURE_DETAIL_ALBEDO" value="13"> + <constant name="TEXTURE_DETAIL_ALBEDO" value="14"> </constant> - <constant name="TEXTURE_DETAIL_NORMAL" value="14"> + <constant name="TEXTURE_DETAIL_NORMAL" value="15"> </constant> - <constant name="TEXTURE_MAX" value="15"> + <constant name="TEXTURE_MAX" value="16"> </constant> <constant name="DETAIL_UV_1" value="0"> </constant> @@ -46558,11 +47485,13 @@ </constant> <constant name="FEATURE_SUBSURACE_SCATTERING" value="8"> </constant> - <constant name="FEATURE_REFRACTION" value="9"> + <constant name="FEATURE_TRANSMISSION" value="9"> + </constant> + <constant name="FEATURE_REFRACTION" value="10"> </constant> - <constant name="FEATURE_DETAIL" value="10"> + <constant name="FEATURE_DETAIL" value="11"> </constant> - <constant name="FEATURE_MAX" value="11"> + <constant name="FEATURE_MAX" value="12"> </constant> <constant name="BLEND_MODE_MIX" value="0"> </constant> @@ -46604,15 +47533,17 @@ </constant> <constant name="FLAG_UV2_USE_TRIPLANAR" value="8"> </constant> - <constant name="FLAG_AO_ON_UV2" value="9"> + <constant name="FLAG_AO_ON_UV2" value="10"> </constant> - <constant name="FLAG_USE_ALPHA_SCISSOR" value="10"> + <constant name="FLAG_USE_ALPHA_SCISSOR" value="11"> </constant> - <constant name="FLAG_MAX" value="11"> + <constant name="FLAG_TRIPLANAR_USE_WORLD" value="9"> + </constant> + <constant name="FLAG_MAX" value="12"> </constant> <constant name="DIFFUSE_LAMBERT" value="0"> </constant> - <constant name="DIFFUSE_HALF_LAMBERT" value="1"> + <constant name="DIFFUSE_LAMBERT_WRAP" value="1"> </constant> <constant name="DIFFUSE_OREN_NAYAR" value="2"> </constant> @@ -46698,8 +47629,10 @@ </class> <class name="SphereMesh" inherits="PrimitiveMesh" category="Core"> <brief_description> + Class representing a spherical [PrimitiveMesh]. </brief_description> <description> + Class representing a spherical [PrimitiveMesh]. </description> <methods> <method name="get_height" qualifiers="const"> @@ -46775,14 +47708,19 @@ </methods> <members> <member name="height" type="float" setter="set_height" getter="get_height" brief=""> + Full height of the sphere. Defaults to 2.0. </member> <member name="is_hemisphere" type="bool" setter="set_is_hemisphere" getter="get_is_hemisphere" brief=""> + Determines whether a full sphere or a hemisphere is created. Attention: To get a regular hemisphere the height and radius of the sphere have to equal. Defaults to false. </member> <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" brief=""> + Number of radial segments on the sphere. Defaults to 64. </member> <member name="radius" type="float" setter="set_radius" getter="get_radius" brief=""> + Radius of sphere. Defaults to 1.0. </member> <member name="rings" type="int" setter="set_rings" getter="get_rings" brief=""> + Number of segments along the height of the sphere. Defaults to 32. </member> </members> <constants> @@ -46902,7 +47840,7 @@ </description> <methods> <method name="get_dragger_visibility" qualifiers="const"> - <return type="int"> + <return type="int" enum="SplitContainer.DraggerVisibility"> </return> <description> Return visibility of the split dragger (one of [DRAGGER_VISIBLE], [DRAGGER_HIDDEN] or [DRAGGER_HIDDEN_COLLAPSED]). @@ -47358,13 +48296,13 @@ </description> <methods> <method name="get_alpha_cut_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="SpriteBase3D.AlphaCutMode"> </return> <description> </description> </method> <method name="get_axis" qualifiers="const"> - <return type="int"> + <return type="int" enum="Vector3.Axis"> </return> <description> </description> @@ -47574,7 +48512,7 @@ </argument> <argument index="1" name="frame" type="Texture"> </argument> - <argument index="2" name="atpos" type="int" default="null"> + <argument index="2" name="atpos" type="int" default="-1"> </argument> <description> </description> @@ -47782,12 +48720,16 @@ </methods> <members> <member name="bounce" type="float" setter="set_bounce" getter="get_bounce" brief=""> + The body bounciness. </member> <member name="constant_angular_velocity" type="Vector3" setter="set_constant_angular_velocity" getter="get_constant_angular_velocity" brief=""> + The constant angular velocity for the body. This does not rotate the body, but affects other bodies that touch it, as if it was in a state of rotation. </member> <member name="constant_linear_velocity" type="Vector3" setter="set_constant_linear_velocity" getter="get_constant_linear_velocity" brief=""> + The constant linear velocity for the body. This does not move the body, but affects other bodies that touch it, as if it was in a state of movement. </member> <member name="friction" type="float" setter="set_friction" getter="get_friction" brief=""> + The body friction, from 0 (frictionless) to 1 (full friction). </member> </members> <constants> @@ -48053,7 +48995,7 @@ </description> </method> <method name="put_data"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="data" type="PoolByteArray"> </argument> @@ -48228,7 +49170,7 @@ </description> <methods> <method name="accept_stream"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="stream" type="StreamPeer"> </argument> @@ -48236,13 +49178,13 @@ </description> </method> <method name="connect_to_stream"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="stream" type="StreamPeer"> </argument> <argument index="1" name="validate_certs" type="bool" default="false"> </argument> - <argument index="2" name="for_hostname" type="String" default="null"> + <argument index="2" name="for_hostname" type="String" default=""""> </argument> <description> Connect to a peer using an underlying [StreamPeer] "stream", when "validate_certs" is true, [StreamPeerSSL] will validate that the certificate presented by the peer matches the "for_hostname". @@ -48256,7 +49198,7 @@ </description> </method> <method name="get_status" qualifiers="const"> - <return type="int"> + <return type="int" enum="StreamPeerSSL.Status"> </return> <description> Return the status of the connection, one of STATUS_* enum. @@ -48287,7 +49229,7 @@ </description> <methods> <method name="connect_to_host"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="host" type="String"> </argument> @@ -48319,7 +49261,7 @@ </description> </method> <method name="get_status" qualifiers="const"> - <return type="int"> + <return type="int" enum="StreamPeerTCP.Status"> </return> <description> Return the status of the connection, one of STATUS_* enum. @@ -48360,7 +49302,7 @@ </description> </method> <method name="load"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="path" type="String"> </argument> @@ -49206,10 +50148,26 @@ </class> <class name="StyleBoxFlat" inherits="StyleBox" category="Core"> <brief_description> - Stylebox of a single color. + Customizable Stylebox with a given set of parameters. (no texture required) </brief_description> <description> - Stylebox of a single color. Displays the stylebox of a single color, alternatively a border with light/dark colors can be assigned. + This stylebox can be used to achieve all kinds of looks without the need of a texture. Those properties are customizable: + - Color + - Border width (individual width for each border) + - Rounded corners (individual radius for each corner) + - Shadow + About corner radius: + Setting corner radius to high values is allowed. As soon as corners would overlap the stylebox will switch to a relative system. Example: + [codeblock] + height = 30 + corner_radius_top_left = 50 + corner_raidus_bottom_left = 100 + [/codeblock] + The relative system now would take the 1:2 ratio of the two left corners to calculate the actual corner width. Both corners added will [b]never[/b] be more than the height. Result: + [codeblock] + corner_radius_top_left: 10 + corner_raidus_bottom_left: 20 + [/codeblock] </description> <methods> <method name="get_aa_size" qualifiers="const"> @@ -49453,46 +50411,69 @@ </methods> <members> <member name="anti_aliasing" type="bool" setter="set_anti_aliased" getter="is_anti_aliased" brief=""> + Anti Aliasing draws a small ring around edges. This ring fades to transparent. As a result edges look much smoother. This is only noticable when using rounded corners. </member> <member name="anti_aliasing_size" type="int" setter="set_aa_size" getter="get_aa_size" brief=""> + This changes the size of the faded ring. Higher values can be used to achieve a "blurry" effect. </member> <member name="bg_color" type="Color" setter="set_bg_color" getter="get_bg_color" brief=""> + The background color of the stylebox. </member> <member name="border_blend" type="bool" setter="set_border_blend" getter="get_border_blend" brief=""> + When set to true, the border will fade into the background color. </member> <member name="border_color" type="Color" setter="set_border_color" getter="get_border_color" brief=""> + Sets the color of the border. </member> <member name="border_width_bottom" type="int" setter="set_border_width" getter="get_border_width" brief=""> + Border width for the bottom border. </member> <member name="border_width_left" type="int" setter="set_border_width" getter="get_border_width" brief=""> + Border width for the left border. </member> <member name="border_width_right" type="int" setter="set_border_width" getter="get_border_width" brief=""> + Border width for the right border. </member> <member name="border_width_top" type="int" setter="set_border_width" getter="get_border_width" brief=""> + Border width for the top border. </member> <member name="corner_detail" type="int" setter="set_corner_detail" getter="get_corner_detail" brief=""> + This sets the amount of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value you should take the corner radius ([method set_corner_radius]) into account. + For corner radius smaller than 10: 4-5 should be enough + For corner radius smaller than 30: 8-12 should be enough ... </member> <member name="corner_radius_bottom_left" type="int" setter="set_corner_radius" getter="get_corner_radius" brief=""> + The corner radius of the bottom left corner. When set to 0 the corner is not rounded. </member> <member name="corner_radius_bottom_right" type="int" setter="set_corner_radius" getter="get_corner_radius" brief=""> + The corner radius of the bottom right corner. When set to 0 the corner is not rounded. </member> <member name="corner_radius_top_left" type="int" setter="set_corner_radius" getter="get_corner_radius" brief=""> + The corner radius of the top left corner. When set to 0 the corner is not rounded. </member> <member name="corner_radius_top_right" type="int" setter="set_corner_radius" getter="get_corner_radius" brief=""> + The corner radius of the top right corner. When set to 0 the corner is not rounded. </member> <member name="draw_center" type="bool" setter="set_draw_center" getter="is_draw_center_enabled" brief=""> + Toggels drawing of the inner part of the stylebox. </member> <member name="expand_margin_bottom" type="float" setter="set_expand_margin" getter="get_expand_margin" brief=""> + Expands the stylebox outside of the control rect on the bottom edge. Useful in combination with border_width_bottom. To draw a border outside the control rect. </member> <member name="expand_margin_left" type="float" setter="set_expand_margin" getter="get_expand_margin" brief=""> + Expands the stylebox outside of the control rect on the left edge. Useful in combination with border_width_left. To draw a border outside the control rect. </member> <member name="expand_margin_right" type="float" setter="set_expand_margin" getter="get_expand_margin" brief=""> + Expands the stylebox outside of the control rect on the right edge. Useful in combination with border_width_right. To draw a border outside the control rect. </member> <member name="expand_margin_top" type="float" setter="set_expand_margin" getter="get_expand_margin" brief=""> + Expands the stylebox outside of the control rect on the top edge. Useful in combination with border_width_top. To draw a border outside the control rect. </member> <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" brief=""> + The color of the shadow. (This has no effect when shadow_size < 1) </member> <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" brief=""> + The shadow size in pixels. </member> </members> <constants> @@ -49515,7 +50496,7 @@ </description> </method> <method name="get_h_axis_stretch_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="StyleBoxTexture.AxisStretchMode"> </return> <description> </description> @@ -49553,7 +50534,7 @@ </description> </method> <method name="get_v_axis_stretch_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="StyleBoxTexture.AxisStretchMode"> </return> <description> </description> @@ -49794,15 +50775,15 @@ </return> <argument index="0" name="vertexes" type="PoolVector3Array"> </argument> - <argument index="1" name="uvs" type="PoolVector2Array" default="PoolVector3Array( )"> + <argument index="1" name="uvs" type="PoolVector2Array" default="PoolVector2Array( )"> </argument> - <argument index="2" name="colors" type="PoolColorArray" default="PoolVector2Array( )"> + <argument index="2" name="colors" type="PoolColorArray" default="PoolColorArray( )"> </argument> - <argument index="3" name="uv2s" type="PoolVector2Array" default="PoolColorArray( )"> + <argument index="3" name="uv2s" type="PoolVector2Array" default="PoolVector2Array( )"> </argument> - <argument index="4" name="normals" type="PoolVector3Array" default="PoolVector2Array( )"> + <argument index="4" name="normals" type="PoolVector3Array" default="PoolVector3Array( )"> </argument> - <argument index="5" name="tangents" type="Array" default="null"> + <argument index="5" name="tangents" type="Array" default="[ ]"> </argument> <description> Insert a triangle fan made of array data into [Mesh] being constructed. @@ -49947,11 +50928,11 @@ </description> </method> <method name="listen"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="port" type="int"> </argument> - <argument index="1" name="bind_address" type="String" default="null"> + <argument index="1" name="bind_address" type="String" default=""*""> </argument> <description> Listen on the "port" binding to "bind_address". @@ -50021,7 +51002,7 @@ </description> </method> <method name="get_tab_align" qualifiers="const"> - <return type="int"> + <return type="int" enum="TabContainer.TabAlign"> </return> <description> Return tab alignment, from the ALIGN_* enum. @@ -50216,9 +51197,9 @@ <method name="add_tab"> <return type="void"> </return> - <argument index="0" name="title" type="String" default="null"> + <argument index="0" name="title" type="String" default=""""> </argument> - <argument index="1" name="icon" type="Texture" default=""""> + <argument index="1" name="icon" type="Texture" default="null"> </argument> <description> </description> @@ -50238,13 +51219,13 @@ </description> </method> <method name="get_tab_align" qualifiers="const"> - <return type="int"> + <return type="int" enum="Tabs.TabAlign"> </return> <description> </description> </method> <method name="get_tab_close_display_policy" qualifiers="const"> - <return type="int"> + <return type="int" enum="Tabs.CloseButtonDisplayPolicy"> </return> <description> </description> @@ -50480,7 +51461,7 @@ </argument> <argument index="2" name="color" type="Color"> </argument> - <argument index="3" name="line_only" type="bool" default="null"> + <argument index="3" name="line_only" type="bool" default="false"> </argument> <description> Add color region (given the delimiters) and its colors. @@ -50585,7 +51566,7 @@ </return> <argument index="0" name="column" type="int"> </argument> - <argument index="1" name="adjust_viewport" type="bool" default="null"> + <argument index="1" name="adjust_viewport" type="bool" default="true"> </argument> <description> </description> @@ -50595,7 +51576,7 @@ </return> <argument index="0" name="line" type="int"> </argument> - <argument index="1" name="adjust_viewport" type="bool" default="null"> + <argument index="1" name="adjust_viewport" type="bool" default="true"> </argument> <description> </description> @@ -51028,7 +52009,7 @@ </argument> <argument index="2" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="3" name="transpose" type="bool" default="null"> + <argument index="3" name="transpose" type="bool" default="false"> </argument> <argument index="4" name="normal_map" type="Texture" default="null"> </argument> @@ -51044,9 +52025,9 @@ </argument> <argument index="2" name="tile" type="bool"> </argument> - <argument index="3" name="modulate" type="Color" default="null"> + <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="4" name="transpose" type="bool" default="null"> + <argument index="4" name="transpose" type="bool" default="false"> </argument> <argument index="5" name="normal_map" type="Texture" default="null"> </argument> @@ -51064,11 +52045,11 @@ </argument> <argument index="3" name="modulate" type="Color" default="Color( 1, 1, 1, 1 )"> </argument> - <argument index="4" name="transpose" type="bool" default="null"> + <argument index="4" name="transpose" type="bool" default="false"> </argument> <argument index="5" name="normal_map" type="Texture" default="null"> </argument> - <argument index="6" name="clip_uv" type="bool" default="null"> + <argument index="6" name="clip_uv" type="bool" default="true"> </argument> <description> </description> @@ -51199,7 +52180,7 @@ </description> </method> <method name="get_stretch_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="TextureButton.StretchMode"> </return> <description> </description> @@ -51490,14 +52471,14 @@ </class> <class name="TextureRect" inherits="Control" category="Core"> <brief_description> - Control Frame that draws a texture. + Control that draws a texture. </brief_description> <description> - Control frame that simply draws an assigned texture. It can stretch or not. It's a simple way to just show an image in a UI. + Control that draws a texture. </description> <methods> <method name="get_stretch_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="TextureRect.StretchMode"> </return> <description> </description> @@ -51541,10 +52522,13 @@ </methods> <members> <member name="expand" type="bool" setter="set_expand" getter="has_expand" brief=""> + If [code]true[/code] texture will expand to fit. Default value: [code]false[/code]. </member> <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" brief="" enum="TextureRect.StretchMode"> + Stretch mode of the texture. Use STRETCH_* constants as value. </member> <member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief=""> + The [Texture] resource for the node. </member> </members> <constants> @@ -51879,18 +52863,18 @@ <return type="String"> </return> <description> - Return the id of the thread, uniquely identifying it among all threads. + Returns the current [Thread]\ s id, uniquely identifying it among all threads. </description> </method> <method name="is_active" qualifiers="const"> <return type="bool"> </return> <description> - Whether this thread is currently active, an active Thread cannot start work on a new method but can be joined with [method wait_to_finish]. + Returns true if this [Thread] is currently active. An active [Thread] cannot start work on a new method but can be joined with [method wait_to_finish]. </description> </method> <method name="start"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="instance" type="Object"> </argument> @@ -51898,10 +52882,10 @@ </argument> <argument index="2" name="userdata" type="Variant" default="null"> </argument> - <argument index="3" name="priority" type="int" default="null"> + <argument index="3" name="priority" type="int" default="1"> </argument> <description> - Start a new [Thread], it will run "method" on object "instance" using "userdata" as an argument and running with "priority", one of PRIORITY_* enum. + Starts a new [Thread] that runs "method" on object "instance" with "userdata" passed as an argument. The "priority" of the [Thread] can be changed by passing a PRIORITY_* enum. Returns OK on success, or ERR_CANT_CREATE on failure. </description> </method> @@ -51924,11 +52908,10 @@ </class> <class name="TileMap" inherits="Node2D" category="Core"> <brief_description> - Node for 2D tile-based games. + Node for 2D tile-based maps. </brief_description> <description> - Node for 2D tile-based games. Tilemaps use a [TileSet] which contain a list of tiles (textures, their rect and a collision) and are used to create complex grid-based maps. - To optimize drawing and culling (sort of like [GridMap]), you can specify a quadrant size, so chunks of the map will be batched together at drawing time. + Node for 2D tile-based maps. Tilemaps use a [TileSet] which contain a list of tiles (textures plus optional collision, navigation, and/or occluder shapes) which are used to create grid-based maps. </description> <methods> <method name="clear"> @@ -52038,14 +53021,14 @@ </description> </method> <method name="get_half_offset" qualifiers="const"> - <return type="int"> + <return type="int" enum="TileMap.HalfOffset"> </return> <description> Return the current half offset configuration. </description> </method> <method name="get_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="TileMap.Mode"> </return> <description> Return the orientation mode. @@ -52065,7 +53048,7 @@ </description> </method> <method name="get_tile_origin" qualifiers="const"> - <return type="int"> + <return type="int" enum="TileMap.TileOrigin"> </return> <description> Return the tile origin configuration. @@ -52144,7 +53127,7 @@ </return> <argument index="0" name="mappos" type="Vector2"> </argument> - <argument index="1" name="ignore_half_ofs" type="bool" default="null"> + <argument index="1" name="ignore_half_ofs" type="bool" default="false"> </argument> <description> Return the absolute world position corresponding to the tilemap (grid-based) coordinates given as an argument. @@ -52160,11 +53143,11 @@ </argument> <argument index="2" name="tile" type="int"> </argument> - <argument index="3" name="flip_x" type="bool" default="null"> + <argument index="3" name="flip_x" type="bool" default="false"> </argument> - <argument index="4" name="flip_y" type="bool" default="null"> + <argument index="4" name="flip_y" type="bool" default="false"> </argument> - <argument index="5" name="transpose" type="bool" default="null"> + <argument index="5" name="transpose" type="bool" default="false"> </argument> <description> Set the tile index for the cell referenced by its grid-based X and Y coordinates. @@ -52190,9 +53173,9 @@ </argument> <argument index="2" name="flip_x" type="bool" default="false"> </argument> - <argument index="3" name="flip_y" type="bool" default="null"> + <argument index="3" name="flip_y" type="bool" default="false"> </argument> - <argument index="4" name="transpose" type="bool" default="null"> + <argument index="4" name="transpose" type="bool" default="false"> </argument> <description> Set the tile index for the cell referenced by a Vector2 of grid-based coordinates. @@ -52371,40 +53354,55 @@ </methods> <members> <member name="cell_custom_transform" type="Transform2D" setter="set_custom_transform" getter="get_custom_transform" brief=""> + The custom [Transform2D] to be applied to the TileMap's cells. </member> <member name="cell_half_offset" type="int" setter="set_half_offset" getter="get_half_offset" brief="" enum="TileMap.HalfOffset"> + Amount to offset alternating tiles. Uses HALF_OFFSET_* constants. Default value: HALF_OFFSET_DISABLED. </member> <member name="cell_quadrant_size" type="int" setter="set_quadrant_size" getter="get_quadrant_size" brief=""> + The TileMap's quadrant size. Optimizes drawing by batching, using chunks of this size. Default value: 16. </member> <member name="cell_size" type="Vector2" setter="set_cell_size" getter="get_cell_size" brief=""> + The TileMap's cell size. </member> <member name="cell_tile_origin" type="int" setter="set_tile_origin" getter="get_tile_origin" brief="" enum="TileMap.TileOrigin"> + Position for tile origin. Uses TILE_ORIGIN_* constants. Default value: TILE_ORIGIN_TOP_LEFT. </member> <member name="cell_y_sort" type="bool" setter="set_y_sort_mode" getter="is_y_sort_mode_enabled" brief=""> + If [code]true[/code] the TileMap's children will be drawn in order of their Y coordinate. Default value: [code]false[/code]. </member> <member name="collision_bounce" type="float" setter="set_collision_bounce" getter="get_collision_bounce" brief=""> + Bounce value for static body collisions (see [code]collision_use_kinematic[/code]). Default value: 0. </member> <member name="collision_friction" type="float" setter="set_collision_friction" getter="get_collision_friction" brief=""> + Friction value for static body collisions (see [code]collision_use_kinematic[/code]). Default value: 1. </member> <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief=""> + The collision layer(s) for all colliders in the TileMap. </member> <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief=""> + The collision mask(s) for all colliders in the TileMap. </member> <member name="collision_use_kinematic" type="bool" setter="set_collision_use_kinematic" getter="get_collision_use_kinematic" brief=""> + If [code]true[/code] TileMap collisions will be handled as a kinematic body. If [code]false[/code] collisions will be handled as static body. Default value: [code]false[/code]. </member> <member name="mode" type="int" setter="set_mode" getter="get_mode" brief="" enum="TileMap.Mode"> + The TileMap orientation mode. Uses MODE_* constants. Default value: MODE_SQUARE. </member> <member name="occluder_light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" brief=""> + The light mask assigned to all light occluders in the TileMap. The TileSet's light occluders will cast shadows only from Light2D(s) that have the same light mask(s). </member> <member name="tile_data" type="PoolIntArray" setter="_set_tile_data" getter="_get_tile_data" brief=""> + A [PoolIntArray] containing </member> <member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset" brief=""> + The assigned [TileSet]. </member> </members> <signals> <signal name="settings_changed"> <description> - Signal indicating that a tilemap setting has changed. + Emitted when a tilemap setting has changed. </description> </signal> </signals> @@ -52506,7 +53504,7 @@ </argument> <argument index="2" name="shape_transform" type="Transform2D"> </argument> - <argument index="3" name="one_way" type="bool" default="null"> + <argument index="3" name="one_way" type="bool" default="false"> </argument> <description> </description> @@ -52809,10 +53807,10 @@ </class> <class name="Timer" inherits="Node" category="Core"> <brief_description> - A simple Timer node. + A countdown timer. </brief_description> <description> - Timer node. This is a simple node that will emit a timeout callback when the timer runs out. It can optionally be set to loop. + Counts down a specified interval and emits a signal on reaching 0. Can be set to repeat or "one shot" mode. </description> <methods> <method name="get_time_left" qualifiers="const"> @@ -52823,7 +53821,7 @@ </description> </method> <method name="get_timer_process_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Timer.TimerProcessMode"> </return> <description> Return the timer's processing mode. @@ -52912,47 +53910,58 @@ <return type="void"> </return> <description> - Start the timer. + Start the Timer. </description> </method> <method name="stop"> <return type="void"> </return> <description> - Stop (cancel) the timer. + Stop (cancel) the Timer. </description> </method> </methods> <members> <member name="autostart" type="bool" setter="set_autostart" getter="has_autostart" brief=""> + If [code]true[/code], Timer will automatically start when entering the scene tree. Default value: [code]false[/code]. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="is_one_shot" brief=""> + If [code]true[/code], Timer will stop when reaching 0. If [code]false[/code], it will restart. Default value: [code]false[/code]. </member> <member name="process_mode" type="int" setter="set_timer_process_mode" getter="get_timer_process_mode" brief="" enum="Timer.TimerProcessMode"> + Processing mode. Uses TIMER_PROCESS_* constants as value. </member> <member name="wait_time" type="float" setter="set_wait_time" getter="get_wait_time" brief=""> + Wait time in seconds. </member> </members> <signals> <signal name="timeout"> <description> - Emitted when the time runs out. + Emitted when the Timer reaches 0. </description> </signal> </signals> <constants> <constant name="TIMER_PROCESS_FIXED" value="0"> - Update the timer at fixed intervals (framerate processing). + Update the Timer at fixed intervals (framerate processing). </constant> <constant name="TIMER_PROCESS_IDLE" value="1"> - Update the timer during the idle time at each frame. + Update the Timer during the idle time at each frame. </constant> </constants> </class> <class name="ToolButton" inherits="Button" category="Core"> <brief_description> + Flat button helper class. </brief_description> <description> + This is a helper class to generate a flat [Button] (see [method Button.set_flat]), creating a ToolButton is equivalent to: + + [codeblock] + var btn = Button.new() + btn.set_flat(true) + [/codeblock] </description> <methods> </methods> @@ -53020,7 +54029,7 @@ </description> </method> <method name="get_visibility_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="TouchScreenButton.VisibilityMode"> </return> <description> </description> @@ -53157,10 +54166,10 @@ </class> <class name="Transform" category="Built-In Types"> <brief_description> - 3D Transformation. + 3D Transformation. 3x4 matrix. </brief_description> <description> - Transform is used to store translation, rotation and scaling transformations. It consists of a Basis "basis" and Vector3 "origin". Transform is used to represent transformations of objects in space, and as such, determine their position, orientation and scale. It is similar to a 3x4 matrix. + Represents one or many transformations in 3D space such as translation, rotation, or scaling. It consists of a [Basis] "basis" and an [Vector3] "origin". It is similar to a 3x4 matrix. </description> <methods> <method name="Transform"> @@ -53175,7 +54184,7 @@ <argument index="3" name="origin" type="Vector3"> </argument> <description> - Construct the Transform from four Vector3. Each axis corresponds to local basis vectors (some of which may be scaled). + Construct the Transform from four [Vector3]. Each axis corresponds to local basis vectors (some of which may be scaled). </description> </method> <method name="Transform"> @@ -53186,7 +54195,7 @@ <argument index="1" name="origin" type="Vector3"> </argument> <description> - Construct the Transform from a Basis and Vector3. + Construct the Transform from a [Basis] and [Vector3]. </description> </method> <method name="Transform"> @@ -53195,7 +54204,7 @@ <argument index="0" name="from" type="Transform2D"> </argument> <description> - Construct the Transform from a Transform2D. + Construct the Transform from a [Transform2D]. </description> </method> <method name="Transform"> @@ -53204,7 +54213,7 @@ <argument index="0" name="from" type="Quat"> </argument> <description> - Construct the Transform from a Quat. The origin will be Vector3(0, 0, 0). + Construct the Transform from a [Quat]. The origin will be Vector3(0, 0, 0). </description> </method> <method name="Transform"> @@ -53213,7 +54222,7 @@ <argument index="0" name="from" type="Basis"> </argument> <description> - Construct the Transform from a Basis. The origin will be Vector3(0, 0, 0). + Construct the Transform from a [Basis]. The origin will be Vector3(0, 0, 0). </description> </method> <method name="affine_inverse"> @@ -53231,13 +54240,14 @@ <argument index="1" name="weight" type="float"> </argument> <description> + Interpolate to other Transform by weight amount (0-1). </description> </method> <method name="inverse"> <return type="Transform"> </return> <description> - Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling). + Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling). </description> </method> <method name="looking_at"> @@ -53284,7 +54294,7 @@ <argument index="0" name="ofs" type="Vector3"> </argument> <description> - Translate the transform by the specified displacement. + Translate the transform by the specified offset. </description> </method> <method name="xform"> @@ -53308,10 +54318,10 @@ </methods> <members> <member name="basis" type="Basis" setter="" getter="" brief=""> - The basis is a matrix containing 3 [Vector3] as its columns: X axis, Y axis, and Z axis. These vectors can be interpreted as the basis vectors of local coordinate system travelling with the object. + The basis is a matrix containing 3 [Vector3] as its columns: X axis, Y axis, and Z axis. These vectors can be interpreted as the basis vectors of local coordinate system traveling with the object. </member> <member name="origin" type="Vector3" setter="" getter="" brief=""> - The origin of the transform. Which is the translation offset. + The translation offset of the transform. </member> </members> <constants> @@ -53319,10 +54329,10 @@ </class> <class name="Transform2D" category="Built-In Types"> <brief_description> - 3x2 Matrix for 2D transforms. + 2D Transformation. 3x2 matrix. </brief_description> <description> - 3x2 Matrix for 2D transforms. + Represents one or many transformations in 3D space such as translation, rotation, or scaling. It consists of a two [Vector2] x, y and [Vector2] "origin". It is similar to a 3x2 matrix. </description> <methods> <method name="Transform2D"> @@ -53331,6 +54341,7 @@ <argument index="0" name="from" type="Transform"> </argument> <description> + Constructs the [Transform2D] from a 3D [Transform]. </description> </method> <method name="Transform2D"> @@ -53343,6 +54354,7 @@ <argument index="2" name="origin" type="Vector2"> </argument> <description> + Constructs the [Transform2D] from 3 [Vector2] consisting of rows x, y and origin. </description> </method> <method name="Transform2D"> @@ -53353,13 +54365,14 @@ <argument index="1" name="pos" type="Vector2"> </argument> <description> + Constructs the [Transform2D] from rotation angle in radians and position [Vector2]. </description> </method> <method name="affine_inverse"> <return type="Transform2D"> </return> <description> - Return the inverse of the matrix. + Returns the inverse of the matrix. </description> </method> <method name="basis_xform"> @@ -53368,6 +54381,7 @@ <argument index="0" name="v" type="var"> </argument> <description> + Transforms the given vector "v" by this transform basis (no translation). </description> </method> <method name="basis_xform_inv"> @@ -53376,12 +54390,14 @@ <argument index="0" name="v" type="var"> </argument> <description> + Inverse-transforms vector "v" by this transform basis (no translation). </description> </method> <method name="get_origin"> <return type="Vector2"> </return> <description> + Return the origin [Vector2] (translation). </description> </method> <method name="get_rotation"> @@ -53395,6 +54411,7 @@ <return type="Vector2"> </return> <description> + Return the scale. </description> </method> <method name="interpolate_with"> @@ -53405,18 +54422,21 @@ <argument index="1" name="weight" type="float"> </argument> <description> + Interpolate to other Transform2D by weight amount (0-1). </description> </method> <method name="inverse"> <return type="Transform2D"> </return> <description> + Returns the inverse of the transform, under the assumption that the transformation is composed of rotation and translation (no scaling, use affine_inverse for transforms with scaling). </description> </method> <method name="orthonormalized"> <return type="Transform2D"> </return> <description> + Returns a transfrom with the basis orthogonal (90 degrees), and normalized axis vectors. </description> </method> <method name="rotated"> @@ -53425,6 +54445,7 @@ <argument index="0" name="phi" type="float"> </argument> <description> + Rotate the transform by phi. </description> </method> <method name="scaled"> @@ -53433,6 +54454,7 @@ <argument index="0" name="scale" type="Vector2"> </argument> <description> + Scale the transform by the specified 2D scaling factors. </description> </method> <method name="translated"> @@ -53441,6 +54463,7 @@ <argument index="0" name="offset" type="Vector2"> </argument> <description> + Translate the transform by the specified offset. </description> </method> <method name="xform"> @@ -53449,6 +54472,7 @@ <argument index="0" name="v" type="var"> </argument> <description> + Transforms the given vector "v" by this transform. </description> </method> <method name="xform_inv"> @@ -53457,15 +54481,19 @@ <argument index="0" name="v" type="var"> </argument> <description> + Inverse-transforms the given vector "v" by this transform. </description> </method> </methods> <members> <member name="origin" type="Vector2" setter="" getter="" brief=""> + The translation offset of the transform. </member> <member name="x" type="Vector2" setter="" getter="" brief=""> + The X axis of 2x2 basis matrix containing 2 [Vector2] as its columns: X axis and Y axis. These vectors can be interpreted as the basis vectors of local coordinate system traveling with the object. </member> <member name="y" type="Vector2" setter="" getter="" brief=""> + The Y axis of 2x2 basis matrix containing 2 [Vector2] as its columns: X axis and Y axis. These vectors can be interpreted as the basis vectors of local coordinate system traveling with the object. </member> </members> <constants> @@ -53731,7 +54759,7 @@ </return> <argument index="0" name="item" type="Object"> </argument> - <argument index="1" name="column" type="int" default="null"> + <argument index="1" name="column" type="int" default="-1"> </argument> <description> Get the rectangle area of the the specified item. If column is specified, only get the position and size of that column, otherwise get the rectangle containing all columns. @@ -54099,9 +55127,9 @@ </argument> <argument index="2" name="button_idx" type="int" default="-1"> </argument> - <argument index="3" name="disabled" type="bool" default="null"> + <argument index="3" name="disabled" type="bool" default="false"> </argument> - <argument index="4" name="tooltip" type="String" default="null"> + <argument index="4" name="tooltip" type="String" default=""""> </argument> <description> </description> @@ -54159,7 +55187,7 @@ </description> </method> <method name="get_cell_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="TreeItem.TreeCellMode"> </return> <argument index="0" name="column" type="int"> </argument> @@ -54275,7 +55303,7 @@ </description> </method> <method name="get_text_align" qualifiers="const"> - <return type="int"> + <return type="int" enum="TreeItem.TextAlign"> </return> <argument index="0" name="column" type="int"> </argument> @@ -54437,7 +55465,7 @@ </argument> <argument index="1" name="color" type="Color"> </argument> - <argument index="2" name="just_outline" type="bool" default="null"> + <argument index="2" name="just_outline" type="bool" default="false"> </argument> <description> </description> @@ -54553,7 +55581,7 @@ </argument> <argument index="3" name="step" type="float"> </argument> - <argument index="4" name="expr" type="bool" default="null"> + <argument index="4" name="expr" type="bool" default="false"> </argument> <description> </description> @@ -54659,7 +55687,7 @@ </argument> <argument index="7" name="ease_type" type="int" enum="Tween.EaseType"> </argument> - <argument index="8" name="delay" type="float" default="null"> + <argument index="8" name="delay" type="float" default="0"> </argument> <description> Follow [code]method[/code] of [code]object[/code] and apply the returned value on [code]target_method[/code] of [code]target[/code], beginning from [code]initial_val[/code] for [code]duration[/code] seconds, [code]delay[/code] later. Methods are animated by calling them with consequitive values. @@ -54685,7 +55713,7 @@ </argument> <argument index="7" name="ease_type" type="int" enum="Tween.EaseType"> </argument> - <argument index="8" name="delay" type="float" default="null"> + <argument index="8" name="delay" type="float" default="0"> </argument> <description> Follow [code]property[/code] of [code]object[/code] and apply it on [code]target_property[/code] of [code]target[/code], beginning from [code]initial_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Note that [code]target:target_property[/code] would equal [code]object:property[/code] at the end of the tween. @@ -54707,7 +55735,7 @@ </description> </method> <method name="get_tween_process_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Tween.TweenProcessMode"> </return> <description> Returns the process mode that has been set from editor GUI or [method set_tween_process_mode] @@ -54776,7 +55804,7 @@ </argument> <argument index="6" name="ease_type" type="int" enum="Tween.EaseType"> </argument> - <argument index="7" name="delay" type="float" default="null"> + <argument index="7" name="delay" type="float" default="0"> </argument> <description> Animate [code]method[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values. @@ -54800,7 +55828,7 @@ </argument> <argument index="6" name="ease_type" type="int" enum="Tween.EaseType"> </argument> - <argument index="7" name="delay" type="float" default="null"> + <argument index="7" name="delay" type="float" default="0"> </argument> <description> Animate [code]property[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. @@ -54826,7 +55854,7 @@ </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="key" type="String" default="null"> + <argument index="1" name="key" type="String" default=""""> </argument> <description> Stop animating and completely remove a tween, given its object and property/method pair. Passing empty String as key will remove all tweens for given object. @@ -54844,7 +55872,7 @@ </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="key" type="String" default="null"> + <argument index="1" name="key" type="String" default=""""> </argument> <description> Resets a tween to the initial value (the one given, not the one before the tween), given its object and property/method pair. Passing empty String as key will reset all tweens for given object. @@ -54862,7 +55890,7 @@ </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="key" type="String" default="null"> + <argument index="1" name="key" type="String" default=""""> </argument> <description> Continue animating a stopped tween, given its object and property/method pair. Passing empty String as key will resume all tweens for given object. @@ -54932,7 +55960,7 @@ </return> <argument index="0" name="object" type="Object"> </argument> - <argument index="1" name="key" type="String" default="null"> + <argument index="1" name="key" type="String" default=""""> </argument> <description> Stop animating a tween, given its object and property/method pair. Passing empty String as key will stop all tweens for given object. @@ -54964,7 +55992,7 @@ </argument> <argument index="7" name="ease_type" type="int" enum="Tween.EaseType"> </argument> - <argument index="8" name="delay" type="float" default="null"> + <argument index="8" name="delay" type="float" default="0"> </argument> <description> Animate [code]method[/code] of [code]object[/code] from the value returned by [code]initial.initial_method[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values. @@ -54990,7 +56018,7 @@ </argument> <argument index="7" name="ease_type" type="int" enum="Tween.EaseType"> </argument> - <argument index="8" name="delay" type="float" default="null"> + <argument index="8" name="delay" type="float" default="0"> </argument> <description> Animate [code]property[/code] of [code]object[/code] from the current value of the [code]initial_val[/code] property of [code]initial[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. @@ -55188,7 +56216,7 @@ </return> <argument index="0" name="name" type="String"> </argument> - <argument index="1" name="merge_mode" type="int" enum="UndoRedo.MergeMode" default="null"> + <argument index="1" name="merge_mode" type="int" enum="UndoRedo.MergeMode" default="0"> </argument> <description> Create a new action. After this is called, do all your calls to [method add_do_method], [method add_undo_method], [method add_do_property] and [method add_undo_property]. @@ -55338,8 +56366,10 @@ </class> <class name="Variant" category="Core"> <brief_description> + The most important data type in Godot. </brief_description> <description> + A Variant takes up only 20 bytes and can store almost any engine datatype inside of it. Variants are rarely used to hold information for long periods of time, instead they are used mainly for communication, editing, serialization and moving data around. </description> <methods> </methods> @@ -56361,13 +57391,13 @@ </description> </method> <method name="get_clear_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Viewport.ClearMode"> </return> <description> </description> </method> <method name="get_debug_draw" qualifiers="const"> - <return type="int"> + <return type="int" enum="Viewport.DebugDraw"> </return> <description> </description> @@ -56401,7 +57431,7 @@ </description> </method> <method name="get_msaa" qualifiers="const"> - <return type="int"> + <return type="int" enum="Viewport.MSAA"> </return> <description> </description> @@ -56422,7 +57452,7 @@ </description> </method> <method name="get_shadow_atlas_quadrant_subdiv" qualifiers="const"> - <return type="int"> + <return type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv"> </return> <argument index="0" name="quadrant" type="int"> </argument> @@ -56457,14 +57487,14 @@ </description> </method> <method name="get_update_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="Viewport.UpdateMode"> </return> <description> Get when the viewport would be updated, will be one of the [code]UPDATE_*[/code] constants. </description> </method> <method name="get_usage" qualifiers="const"> - <return type="int"> + <return type="int" enum="Viewport.Usage"> </return> <description> </description> @@ -56717,7 +57747,7 @@ </argument> <argument index="1" name="size" type="Vector2" default="Vector2( -1, -1 )"> </argument> - <argument index="2" name="margin" type="Vector2" default="null"> + <argument index="2" name="margin" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> Set the size override of the viewport. If the enable parameter is true, it would use the override, otherwise it would use the default size. If the size parameter is equal to [code](-1, -1)[/code], it won't update the size. @@ -56764,6 +57794,10 @@ <argument index="0" name="use" type="bool"> </argument> <description> + If true this viewport will be bound to our ARVR Server. + If this is our main Godot viewport our AR/VR output will be displayed on screen. + If output is redirected to an HMD we'll see the output of just one of the eyes without any distortion applied else we'll see the stereo buffer with distortion applied if applicable + If this is an extra viewport output will only work if redirection to an HMD is supported by the interface. The render target will allow you to use the undistorted output for the right eye in the display. </description> </method> <method name="set_use_own_world"> @@ -56820,6 +57854,7 @@ <return type="bool"> </return> <description> + Returns whether this viewport is using our ARVR Server </description> </method> <method name="warp_mouse"> @@ -57323,7 +58358,7 @@ </argument> <argument index="2" name="node" type="VisualScriptNode"> </argument> - <argument index="3" name="pos" type="Vector2" default="null"> + <argument index="3" name="pos" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> </description> @@ -57335,7 +58370,7 @@ </argument> <argument index="1" name="default_value" type="Variant" default="null"> </argument> - <argument index="2" name="export" type="bool" default="null"> + <argument index="2" name="export" type="bool" default="false"> </argument> <description> </description> @@ -57349,7 +58384,7 @@ </argument> <argument index="2" name="argname" type="String"> </argument> - <argument index="3" name="index" type="int" default="null"> + <argument index="3" name="index" type="int" default="-1"> </argument> <description> </description> @@ -57373,7 +58408,7 @@ </description> </method> <method name="custom_signal_get_argument_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <argument index="0" name="name" type="String"> </argument> @@ -57761,7 +58796,7 @@ </description> <methods> <method name="get_basic_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -57805,7 +58840,7 @@ </description> <methods> <method name="get_func"> - <return type="int"> + <return type="int" enum="VisualScriptBuiltinFunc.BuiltinFunc"> </return> <description> </description> @@ -57947,7 +58982,7 @@ </description> <methods> <method name="get_constant_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -57997,7 +59032,7 @@ </description> </method> <method name="get_constructor_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -58163,7 +59198,7 @@ </description> <methods> <method name="get_deconstruct_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -58287,13 +59322,13 @@ </description> </method> <method name="get_basic_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> </method> <method name="get_call_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptFunctionCall.CallMode"> </return> <description> </description> @@ -58305,7 +59340,7 @@ </description> </method> <method name="get_rpc_call_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptFunctionCall.RPCCallMode"> </return> <description> </description> @@ -58535,7 +59570,7 @@ </description> <methods> <method name="get_action_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptInputAction.Mode"> </return> <description> </description> @@ -58595,7 +59630,7 @@ </description> </method> <method name="get_var_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -58639,7 +59674,7 @@ </description> </method> <method name="get_var_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -58677,7 +59712,7 @@ </description> <methods> <method name="get_math_constant"> - <return type="int"> + <return type="int" enum="VisualScriptMathConstant.MathConstant"> </return> <description> </description> @@ -58749,13 +59784,13 @@ </description> <methods> <method name="get_operator" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Operator"> </return> <description> </description> </method> <method name="get_typed" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -58839,13 +59874,13 @@ </description> </method> <method name="get_basic_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> </method> <method name="get_call_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptPropertyGet.CallMode"> </return> <description> </description> @@ -58953,7 +59988,7 @@ </description> <methods> <method name="get_assign_op" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptPropertySet.AssignOp"> </return> <description> </description> @@ -58977,13 +60012,13 @@ </description> </method> <method name="get_basic_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> </method> <method name="get_call_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptPropertySet.CallMode"> </return> <description> </description> @@ -59129,7 +60164,7 @@ </description> <methods> <method name="get_return_type" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -59211,7 +60246,7 @@ </description> <methods> <method name="get_typed" qualifiers="const"> - <return type="int"> + <return type="int" enum="Variant.Type"> </return> <description> </description> @@ -59421,7 +60456,7 @@ </description> </method> <method name="get_yield_mode"> - <return type="int"> + <return type="int" enum="VisualScriptYield.YieldMode"> </return> <description> </description> @@ -59477,7 +60512,7 @@ </description> </method> <method name="get_call_mode" qualifiers="const"> - <return type="int"> + <return type="int" enum="VisualScriptYieldSignal.CallMode"> </return> <description> </description> @@ -59566,7 +60601,7 @@ </return> <argument index="0" name="image" type="Image"> </argument> - <argument index="1" name="flags" type="int" default="null"> + <argument index="1" name="flags" type="int" default="7"> </argument> <description> </description> @@ -59920,7 +60955,7 @@ </description> </method> <method name="get_node_type"> - <return type="int"> + <return type="int" enum="XMLParser.NodeType"> </return> <description> Get the type of the current node. Compare with [code]NODE_*[/code] constants. @@ -59943,7 +60978,7 @@ </description> </method> <method name="open"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="file" type="String"> </argument> @@ -59952,7 +60987,7 @@ </description> </method> <method name="open_buffer"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="buffer" type="PoolByteArray"> </argument> @@ -59961,14 +60996,14 @@ </description> </method> <method name="read"> - <return type="int"> + <return type="int" enum="Error"> </return> <description> Read the next node of the file. This returns an error code. </description> </method> <method name="seek"> - <return type="int"> + <return type="int" enum="Error"> </return> <argument index="0" name="pos" type="int"> </argument> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 9cde74a8cf..5d62d2f5a0 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1134,6 +1134,10 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons _copy_texscreen(Rect2()); } + if (shader_ptr->canvas_item.uses_time) { + VisualServerRaster::redraw_request(); + } + state.canvas_shader.set_custom_shader(shader_ptr->custom_code_id); state.canvas_shader.bind(); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 6bef039dd1..146a2359b6 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -32,6 +32,7 @@ #include "os/os.h" #include "project_settings.h" #include "rasterizer_canvas_gles3.h" +#include "servers/visual/visual_server_raster.h" #ifndef GLES_OVER_GL #define glClearDepth glClearDepthf @@ -1939,6 +1940,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ bool prev_use_instancing = false; storage->info.render.draw_call_count += p_element_count; + bool prev_opaque_prepass = false; for (int i = 0; i < p_element_count; i++) { @@ -2072,6 +2074,13 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ } } + bool use_opaque_prepass = e->sort_key & RenderList::SORT_KEY_OPAQUE_PRE_PASS; + + if (use_opaque_prepass != prev_opaque_prepass) { + state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, use_opaque_prepass); + rebind = true; + } + bool use_instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH || e->instance->base_type == VS::INSTANCE_PARTICLES; if (use_instancing != prev_use_instancing) { @@ -2127,6 +2136,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ prev_shading = shading; prev_skeleton = skeleton; prev_use_instancing = use_instancing; + prev_opaque_prepass = use_opaque_prepass; first = false; } @@ -2148,9 +2158,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, false); } -void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow) { +void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass) { RasterizerStorageGLES3::Material *m = NULL; RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material); @@ -2182,22 +2193,21 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo ERR_FAIL_COND(!m); - _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass); while (m->next_pass.is_valid()) { m = storage->material_owner.getornull(m->next_pass); if (!m || !m->shader || !m->shader->valid) break; - _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass); } } -void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow) { +void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass) { bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture; bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX; bool has_alpha = has_base_alpha || has_blend_alpha; - bool shadow = false; bool mirror = p_instance->mirror; bool no_cull = false; @@ -2217,7 +2227,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G state.used_screen_texture = true; } - if (p_shadow) { + if (p_depth_pass) { if (has_blend_alpha || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) return; //bye @@ -2252,14 +2262,14 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G e->geometry->index = current_geometry_index++; } - if (!p_shadow && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) { + if (!p_depth_pass && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) { e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG; } e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT; e->sort_key |= uint64_t(e->instance->base_type) << RenderList::SORT_KEY_GEOMETRY_TYPE_SHIFT; - if (!p_shadow) { + if (!p_depth_pass) { if (e->material->last_pass != render_pass) { e->material->last_pass = render_pass; @@ -2269,17 +2279,6 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT; e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT; - if (!has_blend_alpha && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { - - //if nothing exists, add this element as opaque too - RenderList::Element *oe = render_list.add_element(); - - if (!oe) - return; - - copymem(oe, e, sizeof(RenderList::Element)); - } - if (e->instance->gi_probe_instances.size()) { e->sort_key |= SORT_KEY_GI_PROBES_FLAG; } @@ -2302,24 +2301,21 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G //e->light_type=0xFF; // no lights! - if (shadow || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - + if (p_depth_pass || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { e->sort_key |= SORT_KEY_UNSHADED_FLAG; } - if (!shadow && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { + if (p_depth_pass && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + e->sort_key |= RenderList::SORT_KEY_OPAQUE_PRE_PASS; + } + + if (!p_depth_pass && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG; } - if (!shadow && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { - //depth prepass for alpha - RenderList::Element *eo = render_list.add_element(); - - eo->instance = e->instance; - eo->geometry = e->geometry; - eo->material = e->material; - eo->sort_key = e->sort_key; + if (p_material->shader->spatial.uses_time) { + VisualServerRaster::redraw_request(); } } @@ -2603,7 +2599,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform } } - ubo_data.shadow_split_offsets[j] = 1.0 / li->shadow_transform[j].split; + ubo_data.shadow_split_offsets[j] = li->shadow_transform[j].split; Transform modelview = (p_camera_inverse_transform * li->shadow_transform[j].transform).inverse(); @@ -3032,7 +3028,7 @@ void RasterizerSceneGLES3::_copy_texture_to_front_buffer(GLuint p_texture) { storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); } -void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow) { +void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass) { current_geometry_index = 0; current_material_index = 0; @@ -3057,7 +3053,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p int mat_idx = inst->materials[i].is_valid() ? i : -1; RasterizerStorageGLES3::Surface *s = mesh->surfaces[i]; - _add_geometry(s, inst, NULL, mat_idx, p_shadow); + _add_geometry(s, inst, NULL, mat_idx, p_depth_pass); } //mesh->last_pass=frame; @@ -3080,7 +3076,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p for (int i = 0; i < ssize; i++) { RasterizerStorageGLES3::Surface *s = mesh->surfaces[i]; - _add_geometry(s, inst, multi_mesh, -1, p_shadow); + _add_geometry(s, inst, multi_mesh, -1, p_depth_pass); } } break; @@ -3089,7 +3085,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base); ERR_CONTINUE(!immediate); - _add_geometry(immediate, inst, NULL, -1, p_shadow); + _add_geometry(immediate, inst, NULL, -1, p_depth_pass); } break; case VS::INSTANCE_PARTICLES: { @@ -3111,7 +3107,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p for (int j = 0; j < ssize; j++) { RasterizerStorageGLES3::Surface *s = mesh->surfaces[j]; - _add_geometry(s, inst, particles, -1, p_shadow); + _add_geometry(s, inst, particles, -1, p_depth_pass); } } @@ -3178,6 +3174,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ for (int i = 0; i < storage->frame.current_rt->effects.ssao.depth_mipmap_fbos.size(); i++) { state.ssao_minify_shader.set_conditional(SsaoMinifyShaderGLES3::MINIFY_START, i == 0); + state.ssao_minify_shader.set_conditional(SsaoMinifyShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); state.ssao_minify_shader.bind(); state.ssao_minify_shader.set_uniform(SsaoMinifyShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far()); state.ssao_minify_shader.set_uniform(SsaoMinifyShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near()); @@ -3207,6 +3204,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glDepthFunc(GL_GREATER); // do SSAO! state.ssao_shader.set_conditional(SsaoShaderGLES3::ENABLE_RADIUS2, env->ssao_radius2 > 0.001); + state.ssao_shader.set_conditional(SsaoShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); state.ssao_shader.bind(); state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far()); state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near()); @@ -3316,6 +3314,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[0]); glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_11_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_LOW); state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_MEDIUM); state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_25_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_HIGH); @@ -3370,6 +3369,7 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_ //perform SSR state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS, env->ssr_roughness); + state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); state.ssr_shader.bind(); @@ -3523,6 +3523,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p int vp_h = storage->frame.current_rt->height; int vp_w = storage->frame.current_rt->width; + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_FAR_BLUR, true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, env->dof_blur_far_quality == VS::ENV_DOF_BLUR_QUALITY_LOW); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, env->dof_blur_far_quality == VS::ENV_DOF_BLUR_QUALITY_MEDIUM); @@ -3565,6 +3566,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH, false); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, false); composite_from = storage->frame.current_rt->effects.mip_maps[0].color; } @@ -3577,6 +3579,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p int vp_h = storage->frame.current_rt->height; int vp_w = storage->frame.current_rt->width; + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal()); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_BLUR, true); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_NEAR_FIRST_TAP, true); @@ -3652,6 +3655,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_LOW, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_MEDIUM, false); state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::DOF_QUALITY_HIGH, false); + state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::USE_ORTHOGONAL_PROJECTION, false); composite_from = storage->frame.current_rt->effects.mip_maps[0].color; } @@ -3743,6 +3747,8 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p SWAP(exposure_shrink[exposure_shrink.size() - 1].color, storage->frame.current_rt->exposure.color); glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height); + + VisualServerRaster::redraw_request(); //if using auto exposure, redraw must happen } int max_glow_level = -1; @@ -4159,7 +4165,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const clear_color = env->bg_color.to_linear(); storage->frame.clear_request = false; - } else if (env->bg_mode == VS::ENV_BG_SKY) { + } else if (env->bg_mode == VS::ENV_BG_SKY || env->bg_mode == VS::ENV_BG_COLOR_SKY) { sky = storage->sky_owner.getornull(env->sky); @@ -4167,6 +4173,9 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const env_radiance_tex = sky->radiance; } storage->frame.clear_request = false; + if (env->bg_mode == VS::ENV_BG_COLOR_SKY) { + clear_color = env->bg_color.to_linear(); + } } else { storage->frame.clear_request = false; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 5503dba5c4..b3fd6fa2a0 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -664,6 +664,7 @@ public: //bits 12-8 geometry type SORT_KEY_GEOMETRY_TYPE_SHIFT = 8, //bits 0-7 for flags + SORT_KEY_OPAQUE_PRE_PASS = 8, SORT_KEY_CULL_DISABLED_FLAG = 4, SORT_KEY_SKELETON_FLAG = 2, SORT_KEY_MIRROR_FLAG = 1 @@ -805,9 +806,9 @@ public: void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows); - _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow); + _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_passs); - _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow); + _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass); void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy); @@ -820,7 +821,7 @@ public: void _copy_to_front_buffer(Environment *env); void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug - void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow); + void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass); void _blur_effect_buffer(); void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 91ba3aa702..b99817fb12 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -165,7 +165,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ } break; case Image::FORMAT_RGB8: { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? GL_SRGB8 : GL_RGB8; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8 : GL_RGB8; r_gl_format = GL_RGB; r_gl_type = GL_UNSIGNED_BYTE; srgb = true; @@ -174,7 +174,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ case Image::FORMAT_RGBA8: { r_gl_format = GL_RGBA; - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? GL_SRGB8_ALPHA8 : GL_RGBA8; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8_ALPHA8 : GL_RGBA8; r_gl_type = GL_UNSIGNED_BYTE; srgb = true; @@ -254,7 +254,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.s3tc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -270,7 +270,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.s3tc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -286,7 +286,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.s3tc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -331,7 +331,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.bptc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : _EXT_COMPRESSED_RGBA_BPTC_UNORM; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : _EXT_COMPRESSED_RGBA_BPTC_UNORM; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -371,7 +371,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.pvrtc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -386,7 +386,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.pvrtc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -402,7 +402,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.pvrtc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -418,7 +418,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.pvrtc_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -503,7 +503,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.etc2_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB8_ETC2 : _EXT_COMPRESSED_RGB8_ETC2; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB8_ETC2 : _EXT_COMPRESSED_RGB8_ETC2; r_gl_format = GL_RGB; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -518,7 +518,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.etc2_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : _EXT_COMPRESSED_RGBA8_ETC2_EAC; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : _EXT_COMPRESSED_RGBA8_ETC2_EAC; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -533,7 +533,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ if (config.etc2_supported) { - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? _EXT_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; r_gl_format = GL_RGBA; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = true; @@ -560,7 +560,7 @@ Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_ } r_gl_format = GL_RGBA; - r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? GL_SRGB8_ALPHA8 : GL_RGBA8; + r_gl_internal_format = (config.srgb_decode_supported || (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) ? GL_SRGB8_ALPHA8 : GL_RGBA8; r_gl_type = GL_UNSIGNED_BYTE; r_compressed = false; srgb = true; @@ -595,7 +595,6 @@ RID RasterizerStorageGLES3::texture_create() { void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { - int components; GLenum format; GLenum internal_format; GLenum type; @@ -686,7 +685,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p texture->ignore_mipmaps = compressed && !img->has_mipmaps(); - if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) + if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps) glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR); else { if (texture->flags & VS::TEXTURE_FLAG_FILTER) { @@ -717,7 +716,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering } - if ((texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) { + if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) { if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); @@ -770,15 +769,13 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p } } - int mipmaps = (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1; + int mipmaps = ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && img->has_mipmaps()) ? img->get_mipmap_count() + 1 : 1; int w = img->get_width(); int h = img->get_height(); int tsize = 0; - int block = Image::get_format_block_size(img->get_format()); - for (int i = 0; i < mipmaps; i++) { int size, ofs; @@ -789,10 +786,6 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p if (texture->compressed) { glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - //this is not needed, as compressed takes the regular size, even if blocks extend it - //int bw = (w % block != 0) ? w + (block - w % block) : w; - //int bh = (h % block != 0) ? h + (block - h % block) : h; - int bw = w; int bh = h; @@ -820,7 +813,7 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p texture->stored_cube_sides |= (1 << p_cube_side); - if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) { + if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && mipmaps == 1 && !texture->ignore_mipmaps && (!(texture->flags & VS::TEXTURE_FLAG_CUBEMAP) || texture->stored_cube_sides == (1 << 6) - 1)) { //generate mipmaps if they were requested and the image does not contain them glGenerateMipmap(texture->target); } else if (mipmaps > 1) { @@ -912,7 +905,7 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture, uint32_t p_flags) uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; texture->flags = p_flags | cube; // can't remove a cube from being a cube - if ((texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) { + if (((texture->flags & VS::TEXTURE_FLAG_REPEAT) || (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) { if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); @@ -937,7 +930,7 @@ void RasterizerStorageGLES3::texture_set_flags(RID p_texture, uint32_t p_flags) } } - if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) { + if ((texture->flags & VS::TEXTURE_FLAG_MIPMAPS) && !texture->ignore_mipmaps) { if (!had_mipmaps && texture->mipmaps == 1) { glGenerateMipmap(texture->target); } @@ -1584,6 +1577,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv; shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv; shaders.actions_canvas.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->canvas_item.uses_screen_texture; + shaders.actions_canvas.usage_flag_pointers["TIME"] = &p_shader->canvas_item.uses_time; actions = &shaders.actions_canvas; actions->uniforms = &p_shader->uniforms; @@ -1632,6 +1626,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const { shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss; shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard; shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture; + shaders.actions_scene.usage_flag_pointers["TIME"] = &p_shader->spatial.uses_time; shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection; @@ -3358,7 +3353,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const { for (int i = 0; i < mesh->surfaces.size(); i++) { Rect3 laabb; - if (mesh->surfaces[i]->format & VS::ARRAY_FORMAT_BONES && mesh->surfaces[i]->skeleton_bone_aabb.size()) { + 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(); @@ -4471,6 +4466,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) { light->omni_shadow_mode = VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; light->omni_shadow_detail = VS::LIGHT_OMNI_SHADOW_DETAIL_VERTICAL; light->directional_blend_splits = false; + light->directional_range_mode = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE; light->reverse_cull = false; light->version = 0; @@ -4623,6 +4619,22 @@ VS::LightDirectionalShadowMode RasterizerStorageGLES3::light_directional_get_sha return light->directional_shadow_mode; } +void RasterizerStorageGLES3::light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode) { + + Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND(!light); + + light->directional_range_mode = p_range_mode; +} + +VS::LightDirectionalShadowDepthRangeMode RasterizerStorageGLES3::light_directional_get_shadow_depth_range_mode(RID p_light) const { + + const Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE); + + return light->directional_range_mode; +} + VS::LightType RasterizerStorageGLES3::light_get_type(RID p_light) const { const Light *light = light_owner.getornull(p_light); @@ -6845,42 +6857,28 @@ int RasterizerStorageGLES3::get_captured_render_info(VS::RenderInfo p_info) { int RasterizerStorageGLES3::get_render_info(VS::RenderInfo p_info) { switch (p_info) { - case VS::INFO_OBJECTS_IN_FRAME: { - + case VS::INFO_OBJECTS_IN_FRAME: return info.render_final.object_count; - } break; - case VS::INFO_VERTICES_IN_FRAME: { - + case VS::INFO_VERTICES_IN_FRAME: return info.render_final.vertices_count; - } break; - case VS::INFO_MATERIAL_CHANGES_IN_FRAME: { + case VS::INFO_MATERIAL_CHANGES_IN_FRAME: return info.render_final.material_switch_count; - } break; - case VS::INFO_SHADER_CHANGES_IN_FRAME: { + case VS::INFO_SHADER_CHANGES_IN_FRAME: return info.render_final.shader_rebind_count; - } break; - case VS::INFO_SURFACE_CHANGES_IN_FRAME: { + case VS::INFO_SURFACE_CHANGES_IN_FRAME: return info.render_final.surface_switch_count; - } break; - case VS::INFO_DRAW_CALLS_IN_FRAME: { + case VS::INFO_DRAW_CALLS_IN_FRAME: return info.render_final.draw_call_count; - } break; - case VS::INFO_USAGE_VIDEO_MEM_TOTAL: { - + case VS::INFO_USAGE_VIDEO_MEM_TOTAL: return 0; //no idea - } break; - case VS::INFO_VIDEO_MEM_USED: { - + case VS::INFO_VIDEO_MEM_USED: return info.vertex_mem + info.texture_mem; - } break; - case VS::INFO_TEXTURE_MEM_USED: { - + case VS::INFO_TEXTURE_MEM_USED: return info.texture_mem; - } break; - case VS::INFO_VERTEX_MEM_USED: { - + case VS::INFO_VERTEX_MEM_USED: return info.vertex_mem; - } break; + default: + return 0; //no idea either } } diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index f75b77aabe..6abc22b643 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -410,6 +410,7 @@ public: int light_mode; bool uses_screen_texture; bool uses_screen_uv; + bool uses_time; } canvas_item; @@ -449,6 +450,7 @@ public: bool uses_discard; bool uses_sss; bool uses_screen_texture; + bool uses_time; bool writes_modelview_or_projection; bool uses_vertex_lighting; @@ -877,6 +879,7 @@ public: VS::LightOmniShadowMode omni_shadow_mode; VS::LightOmniShadowDetail omni_shadow_detail; VS::LightDirectionalShadowMode directional_shadow_mode; + VS::LightDirectionalShadowDepthRangeMode directional_range_mode; bool directional_blend_splits; uint64_t version; }; @@ -904,6 +907,9 @@ public: virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light); virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light); + virtual void light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode); + virtual VS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const; + virtual bool light_has_shadow(RID p_light) const; virtual VS::LightType light_get_type(RID p_light) const; diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index c308e9eddb..419decce29 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -438,26 +438,44 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener SL::BlockNode *bnode = (SL::BlockNode *)p_node; //variables - code += _mktab(p_level - 1) + "{\n"; - for (Map<StringName, SL::BlockNode::Variable>::Element *E = bnode->variables.front(); E; E = E->next()) { - - code += _mktab(p_level) + _prestr(E->get().precision) + _typestr(E->get().type) + " " + _mkid(E->key()) + ";\n"; + if (!bnode->single_statement) { + code += _mktab(p_level - 1) + "{\n"; } - + for (int i = 0; i < bnode->statements.size(); i++) { String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions); - if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) { - // FIXME: if (A || A) ? I am hesitant to delete one of them, could be copy-paste error. + if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement ) { code += scode; //use directly } else { code += _mktab(p_level) + scode + ";\n"; } } - code += _mktab(p_level - 1) + "}\n"; + if (!bnode->single_statement) { + code += _mktab(p_level - 1) + "}\n"; + } } break; + case SL::Node::TYPE_VARIABLE_DECLARATION: { + SL::VariableDeclarationNode *vdnode = (SL::VariableDeclarationNode *)p_node; + + String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype); + for(int i=0;i<vdnode->declarations.size();i++) { + if (i>0) { + declaration+=","; + } else { + declaration+=" "; + } + declaration += _mkid(vdnode->declarations[i].name); + if (vdnode->declarations[i].initializer) { + declaration+="="; + declaration+=_dump_node_code(vdnode->declarations[i].initializer, p_level, r_gen_code, p_actions, p_default_actions); + } + } + + code+=declaration; + } break; case SL::Node::TYPE_VARIABLE: { SL::VariableNode *vnode = (SL::VariableNode *)p_node; @@ -600,6 +618,13 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ")\n"; code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions); + } else if (cfnode->flow_op == SL::FLOW_OP_FOR) { + + String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions); + String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions); + String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions); + code += _mktab(p_level) + "for (" +left+";"+middle+";"+right+")\n"; + code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions); } else if (cfnode->flow_op == SL::FLOW_OP_RETURN) { @@ -611,6 +636,12 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener } else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) { code = "discard;"; + } else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) { + + code = "continue;"; + } else if (cfnode->flow_op == SL::FLOW_OP_BREAK) { + + code = "break;"; } } break; @@ -751,8 +782,9 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; actions[VS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy"; actions[VS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; - actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread"; + //actions[VS::SHADER_SPATIAL].renames["SSS_SPREAD"] = "sss_spread"; actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; + actions[VS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission"; actions[VS::SHADER_SPATIAL].renames["AO"] = "ao"; actions[VS::SHADER_SPATIAL].renames["EMISSION"] = "emission"; //actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2; @@ -782,6 +814,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; + actions[VS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n"; 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"; @@ -792,7 +825,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; - actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 3bcfd24383..bf8eaf601d 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -116,7 +116,7 @@ void main() { #ifdef USE_TEXTURE_RECT - if (dst_rect.z < 0) { // Transpose is encoded as negative dst_rect.z + if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z uv_interp = src_rect.xy + abs(src_rect.zw) * vertex.yx; } else { uv_interp = src_rect.xy + abs(src_rect.zw) * vertex; @@ -139,7 +139,7 @@ void main() { float frame_w = 1.0/float(h_frames); float frame_h = 1.0/float(v_frames); uv_interp.x = uv_interp.x * frame_w + frame_w * float(frame % h_frames); - uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / v_frames); + uv_interp.y = uv_interp.y * frame_h + frame_h * float(frame / h_frames); #endif diff --git a/drivers/gles3/shaders/effect_blur.glsl b/drivers/gles3/shaders/effect_blur.glsl index 09e522866c..b5f98a1244 100644 --- a/drivers/gles3/shaders/effect_blur.glsl +++ b/drivers/gles3/shaders/effect_blur.glsl @@ -168,7 +168,11 @@ void main() { float depth = textureLod( dof_source_depth, uv_interp, 0.0).r; depth = depth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); +#endif float amount = smoothstep(dof_begin,dof_end,depth); float k_accum=0.0; @@ -182,8 +186,11 @@ void main() { float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; tap_depth = tap_depth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); - +#endif float tap_amount = mix(smoothstep(dof_begin,dof_end,tap_depth),1.0,int_ofs==0); tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect @@ -221,7 +228,11 @@ void main() { float tap_depth = texture( dof_source_depth, tap_uv, 0.0).r; tap_depth = tap_depth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + tap_depth = ((tap_depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else tap_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - tap_depth * (camera_z_far - camera_z_near)); +#endif float tap_amount = 1.0-smoothstep(dof_end,dof_begin,tap_depth); tap_amount*=tap_amount*tap_amount; //prevent undesired glow effect diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index ef4925895c..5f83033293 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -484,7 +484,7 @@ VERTEX_SHADER_CODE vec3 directional_diffuse = vec3(0.0); vec3 directional_specular = vec3(0.0); - light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),normal_interp,roughness,directional_diffuse,directional_specular); + light_compute(normal_interp,-light_direction_attenuation.xyz,-normalize( vertex_interp ),light_color_energy.rgb,roughness,directional_diffuse,directional_specular); float diff_avg = dot(diffuse_light_interp.rgb,vec3(0.33333)); float diff_dir_avg = dot(directional_diffuse,vec3(0.33333)); @@ -887,7 +887,7 @@ float GTR1(float NdotH, float a) -void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) { +void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse, inout vec3 specular) { #if defined(USE_LIGHT_SHADER_CODE) //light is written by the light shader @@ -900,10 +900,16 @@ LIGHT_SHADER_CODE float dotNL = max(dot(N,L), 0.0 ); -#if defined(DIFFUSE_HALF_LAMBERT) +#if defined(DIFFUSE_OREN_NAYAR) + vec3 light_amount; +#else + float light_amount; +#endif + - float hl = dot(N,L) * 0.5 + 0.5; - diffuse += hl * light_color * diffuse_color; +#if defined(DIFFUSE_LAMBERT_WRAP) + //energy conserving lambert wrap shader + light_amount = max(0.0,(dot(N,L) + roughness) / ((1.0 + roughness) * (1.0 + roughness))); #elif defined(DIFFUSE_OREN_NAYAR) @@ -919,31 +925,46 @@ LIGHT_SHADER_CODE vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33)); float B = 0.45 * sigma2 / (sigma2 + 0.09); - diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI; + light_amount = max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI; } #elif defined(DIFFUSE_TOON) - diffuse += smoothstep(-roughness,max(roughness,0.01),dot(N,L)) * light_color * diffuse_color; + light_amount = smoothstep(-roughness,max(roughness,0.01),dot(N,L)); #elif defined(DIFFUSE_BURLEY) { - float NdotL = dot(L, N); - float NdotV = dot(N, V); - float VdotH = dot(N, normalize(L+V)); + + + vec3 H = normalize(V + L); + float NoL = max(0.0,dot(N, L)); + float VoH = max(0.0,dot(L, H)); + float NoV = max(0.0,dot(N, V)); + + float FD90 = 0.5 + 2.0 * VoH * VoH * roughness; + float FdV = 1.0 + (FD90 - 1.0) * pow( 1.0 - NoV, 5.0 ); + float FdL = 1.0 + (FD90 - 1.0) * pow( 1.0 - NoL, 5.0 ); + light_amount = ( (1.0 / M_PI) * FdV * FdL ); +/* float energyBias = mix(roughness, 0.0, 0.5); float energyFactor = mix(roughness, 1.0, 1.0 / 1.51); - float fd90 = energyBias + 2.0 * VdotH * VdotH * roughness; + float fd90 = energyBias + 2.0 * VoH * VoH * roughness; float f0 = 1.0; - float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NdotL, 5.0); - float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NdotV, 5.0); + float lightScatter = f0 + (fd90 - f0) * pow(1.0 - NoL, 5.0); + float viewScatter = f0 + (fd90 - f0) * pow(1.0 - NoV, 5.0); - diffuse+= light_color * diffuse_color * lightScatter * viewScatter * energyFactor; + light_amount = lightScatter * viewScatter * energyFactor;*/ } #else //lambert - diffuse += dotNL * light_color * diffuse_color; + light_amount = dotNL; +#endif + +#if defined(TRANSMISSION_USED) + diffuse += light_color * diffuse_color * mix(vec3(light_amount),vec3(1.0),transmission); +#else + diffuse += light_color * diffuse_color * light_amount; #endif @@ -1116,7 +1137,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po } #endif -void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity,inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex; float light_length = length( light_rel_vec ); @@ -1170,11 +1191,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow); } - light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,omni_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,omni_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } -void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 transmission,float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex; float light_length = length( light_rel_vec ); @@ -1204,7 +1225,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow); } - light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_compute(normal,normalize(light_rel_vec),eye_vec,binormal,tangent,spot_lights[idx].light_color_energy.rgb*light_attenuation,albedo,transmission,spot_lights[idx].light_params.z*p_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); } @@ -1499,6 +1520,7 @@ void main() { //lay out everything, whathever is unused is optimized away anyway highp vec3 vertex = vertex_interp; vec3 albedo = vec3(0.8,0.8,0.8); + vec3 transmission = vec3(0.0); float metallic = 0.0; float specular = 0.5; vec3 emission = vec3(0.0,0.0,0.0); @@ -1577,6 +1599,12 @@ FRAGMENT_SHADER_CODE } #endif +#ifdef USE_OPAQUE_PREPASS + + if (alpha<0.99) { + discard; + } +#endif #if defined(ENABLE_NORMALMAP) @@ -1678,9 +1706,16 @@ FRAGMENT_SHADER_CODE vec3 light_attenuation=vec3(1.0); + float depth_z = -vertex.z; #ifdef LIGHT_DIRECTIONAL_SHADOW - if (gl_FragCoord.w > shadow_split_offsets.w) { +#ifdef LIGHT_USE_PSSM4 + if (depth_z < shadow_split_offsets.w) { +#elif defined(LIGHT_USE_PSSM2) + if (depth_z < shadow_split_offsets.y) { +#else + if (depth_z < shadow_split_offsets.x) { +#endif //LIGHT_USE_PSSM4 vec3 pssm_coord; float pssm_fade=0.0; @@ -1689,17 +1724,15 @@ FRAGMENT_SHADER_CODE float pssm_blend; vec3 pssm_coord2; bool use_blend=true; - vec3 light_pssm_split_inv = 1.0/shadow_split_offsets.xyz; - float w_inv = 1.0/gl_FragCoord.w; #endif #ifdef LIGHT_USE_PSSM4 - if (gl_FragCoord.w > shadow_split_offsets.y) { + if (depth_z < shadow_split_offsets.y) { - if (gl_FragCoord.w > shadow_split_offsets.x) { + if (depth_z < shadow_split_offsets.x) { highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); pssm_coord=splane.xyz/splane.w; @@ -1709,7 +1742,7 @@ FRAGMENT_SHADER_CODE splane=(shadow_matrix2 * vec4(vertex,1.0)); pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(0.0,light_pssm_split_inv.x,w_inv); + pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z); #endif } else { @@ -1720,14 +1753,14 @@ FRAGMENT_SHADER_CODE #if defined(LIGHT_USE_PSSM_BLEND) splane=(shadow_matrix3 * vec4(vertex,1.0)); pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(light_pssm_split_inv.x,light_pssm_split_inv.y,w_inv); + pssm_blend=smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z); #endif } } else { - if (gl_FragCoord.w > shadow_split_offsets.z) { + if (depth_z < shadow_split_offsets.z) { highp vec4 splane=(shadow_matrix3 * vec4(vertex,1.0)); pssm_coord=splane.xyz/splane.w; @@ -1735,13 +1768,14 @@ FRAGMENT_SHADER_CODE #if defined(LIGHT_USE_PSSM_BLEND) splane=(shadow_matrix4 * vec4(vertex,1.0)); pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(light_pssm_split_inv.y,light_pssm_split_inv.z,w_inv); + pssm_blend=smoothstep(shadow_split_offsets.y,shadow_split_offsets.z,depth_z); #endif } else { + highp vec4 splane=(shadow_matrix4 * vec4(vertex,1.0)); pssm_coord=splane.xyz/splane.w; - pssm_fade = smoothstep(shadow_split_offsets.z,shadow_split_offsets.w,gl_FragCoord.w); + pssm_fade = smoothstep(shadow_split_offsets.z,shadow_split_offsets.w,depth_z); #if defined(LIGHT_USE_PSSM_BLEND) use_blend=false; @@ -1757,7 +1791,7 @@ FRAGMENT_SHADER_CODE #ifdef LIGHT_USE_PSSM2 - if (gl_FragCoord.w > shadow_split_offsets.x) { + if (depth_z < shadow_split_offsets.x) { highp vec4 splane=(shadow_matrix1 * vec4(vertex,1.0)); pssm_coord=splane.xyz/splane.w; @@ -1767,13 +1801,13 @@ FRAGMENT_SHADER_CODE splane=(shadow_matrix2 * vec4(vertex,1.0)); pssm_coord2=splane.xyz/splane.w; - pssm_blend=smoothstep(0.0,light_pssm_split_inv.x,w_inv); + pssm_blend=smoothstep(0.0,shadow_split_offsets.x,depth_z); #endif } else { highp vec4 splane=(shadow_matrix2 * vec4(vertex,1.0)); pssm_coord=splane.xyz/splane.w; - pssm_fade = smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,gl_FragCoord.w); + pssm_fade = smoothstep(shadow_split_offsets.x,shadow_split_offsets.y,depth_z); #if defined(LIGHT_USE_PSSM_BLEND) use_blend=false; @@ -1815,6 +1849,7 @@ FRAGMENT_SHADER_CODE } + #endif //LIGHT_DIRECTIONAL_SHADOW #ifdef USE_VERTEX_LIGHTING @@ -1822,7 +1857,7 @@ FRAGMENT_SHADER_CODE specular_light*=mix(vec3(1.0),light_attenuation,specular_light_interp.a); #else - light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); + light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,transmission,light_params.z*specular_blob_intensity,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light); #endif @@ -1860,11 +1895,11 @@ FRAGMENT_SHADER_CODE #else for(int i=0;i<omni_light_count;i++) { - light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); + light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); } for(int i=0;i<spot_light_count;i++) { - light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); + light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,transmission,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light); } #endif //USE_VERTEX_LIGHTING diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl index cc41d36c37..b2e6f7a736 100644 --- a/drivers/gles3/shaders/screen_space_reflection.glsl +++ b/drivers/gles3/shaders/screen_space_reflection.glsl @@ -56,7 +56,6 @@ vec2 view_to_screen(vec3 view_pos,out float w) { #define M_PI 3.14159265359 - void main() { @@ -158,8 +157,13 @@ void main() { w+=w_advance; //convert to linear depth + depth = texture(source_depth, pos*pixel_size).r * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); +#endif depth=-depth; z_from = z_to; diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl index 0e8fc89d6c..c668e63745 100644 --- a/drivers/gles3/shaders/ssao.glsl +++ b/drivers/gles3/shaders/ssao.glsl @@ -65,7 +65,12 @@ layout(location = 0) out float visibility; uniform vec4 proj_info; vec3 reconstructCSPosition(vec2 S, float z) { - return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z); +#ifdef USE_ORTHOGONAL_PROJECTION + return vec3((S.xy * proj_info.xy + proj_info.zw), z); +#else + return vec3((S.xy * proj_info.xy + proj_info.zw) * z, z); + +#endif } vec3 getPosition(ivec2 ssP) { @@ -73,7 +78,11 @@ vec3 getPosition(ivec2 ssP) { P.z = texelFetch(source_depth, ssP, 0).r; P.z = P.z * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); +#endif P.z = -P.z; // Offset to pixel center @@ -118,7 +127,12 @@ vec3 getOffsetPosition(ivec2 ssC, vec2 unitOffset, float ssR) { //read from depth buffer P.z = texelFetch(source_depth, mipP, 0).r; P.z = P.z * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + P.z = ((P.z + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else P.z = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - P.z * (camera_z_far - camera_z_near)); + +#endif P.z = -P.z; } else { @@ -214,8 +228,11 @@ void main() { // Choose the screen-space sample radius // proportional to the projected area of the sphere +#ifdef USE_ORTHOGONAL_PROJECTION + float ssDiskRadius = -proj_scale * radius; +#else float ssDiskRadius = -proj_scale * radius / C.z; - +#endif float sum = 0.0; for (int i = 0; i < NUM_SAMPLES; ++i) { sum += sampleAO(ssC, C, n_C, ssDiskRadius, radius,i, randomPatternRotationAngle); diff --git a/drivers/gles3/shaders/ssao_minify.glsl b/drivers/gles3/shaders/ssao_minify.glsl index 6e46a1842c..647c762438 100644 --- a/drivers/gles3/shaders/ssao_minify.glsl +++ b/drivers/gles3/shaders/ssao_minify.glsl @@ -41,7 +41,11 @@ void main() { #ifdef MINIFY_START float fdepth = texelFetch(source_depth, clamp(ssP * 2 + ivec2(ssP.y & 1, ssP.x & 1), ivec2(0), from_size - ivec2(1)), source_mipmap).r; fdepth = fdepth * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + fdepth = ((fdepth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else fdepth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - fdepth * (camera_z_far - camera_z_near)); +#endif fdepth /= camera_z_far; depth = uint(clamp(fdepth*65535.0,0.0,65535.0)); diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl index 8873443727..20c3b7473f 100644 --- a/drivers/gles3/shaders/subsurf_scattering.glsl +++ b/drivers/gles3/shaders/subsurf_scattering.glsl @@ -17,36 +17,36 @@ void main() { //#define QUALIFIER uniform // some guy on the interweb says it may be faster with this #define QUALIFIER const + #ifdef USE_25_SAMPLES const int kernel_size=25; - QUALIFIER vec2 kernel[25] = vec2[] ( -vec2(0.099654,0.0), -vec2(0.001133,-3.0), -vec2(0.002316,-2.52083), -vec2(0.00445,-2.08333), -vec2(0.008033,-1.6875), -vec2(0.013627,-1.33333), -vec2(0.021724,-1.02083), -vec2(0.032542,-0.75), -vec2(0.04581,-0.520833), -vec2(0.0606,-0.333333), -vec2(0.075333,-0.1875), -vec2(0.088001,-0.0833333), -vec2(0.096603,-0.0208333), -vec2(0.096603,0.0208333), -vec2(0.088001,0.0833333), -vec2(0.075333,0.1875), -vec2(0.0606,0.333333), -vec2(0.04581,0.520833), -vec2(0.032542,0.75), -vec2(0.021724,1.02083), -vec2(0.013627,1.33333), -vec2(0.008033,1.6875), -vec2(0.00445,2.08333), -vec2(0.002316,2.52), -vec2(0.001133,3.0) + vec2(0.530605, 0.0), + vec2(0.000973794, -3.0), + vec2(0.00333804, -2.52083), + vec2(0.00500364, -2.08333), + vec2(0.00700976, -1.6875), + vec2(0.0094389, -1.33333), + vec2(0.0128496, -1.02083), + vec2(0.017924, -0.75), + vec2(0.0263642, -0.520833), + vec2(0.0410172, -0.333333), + vec2(0.0493588, -0.1875), + vec2(0.0402784, -0.0833333), + vec2(0.0211412, -0.0208333), + vec2(0.0211412, 0.0208333), + vec2(0.0402784, 0.0833333), + vec2(0.0493588, 0.1875), + vec2(0.0410172, 0.333333), + vec2(0.0263642, 0.520833), + vec2(0.017924, 0.75), + vec2(0.0128496, 1.02083), + vec2(0.0094389, 1.33333), + vec2(0.00700976, 1.6875), + vec2(0.00500364, 2.08333), + vec2(0.00333804, 2.52083), + vec2(0.000973794, 3.0) ); #endif //USE_25_SAMPLES @@ -56,23 +56,23 @@ vec2(0.001133,3.0) const int kernel_size=17; QUALIFIER vec2 kernel[17] = vec2[]( -vec2(0.197417,0.0), -vec2(0.000078,-2.0), -vec2(0.000489,-1.53125), -vec2(0.002403,-1.125), -vec2(0.009245,-0.78125), -vec2(0.027835,-0.5), -vec2(0.065592,-0.28125), -vec2(0.12098,-0.125), -vec2(0.17467,-0.03125), -vec2(0.17467,0.03125), -vec2(0.12098,0.125), -vec2(0.065592,0.28125), -vec2(0.027835,0.5), -vec2(0.009245,0.78125), -vec2(0.002403,1.125), -vec2(0.000489,1.53125), -vec2(0.000078,2.0) + vec2(0.536343, 0.0), + vec2(0.00317394, -2.0), + vec2(0.0100386, -1.53125), + vec2(0.0144609, -1.125), + vec2(0.0216301, -0.78125), + vec2(0.0347317, -0.5), + vec2(0.0571056, -0.28125), + vec2(0.0582416, -0.125), + vec2(0.0324462, -0.03125), + vec2(0.0324462, 0.03125), + vec2(0.0582416, 0.125), + vec2(0.0571056, 0.28125), + vec2(0.0347317, 0.5), + vec2(0.0216301, 0.78125), + vec2(0.0144609, 1.125), + vec2(0.0100386, 1.53125), + vec2(0.00317394,2.0) ); #endif //USE_17_SAMPLES @@ -82,23 +82,24 @@ vec2(0.000078,2.0) const int kernel_size=11; -QUALIFIER vec2 kernel[kernel_size] = vec2[]( -vec2(0.198596,0.0), -vec2(0.0093,-2.0), -vec2(0.028002,-1.28), -vec2(0.065984,-0.72), -vec2(0.121703,-0.32), -vec2(0.175713,-0.08), -vec2(0.175713,0.08), -vec2(0.121703,0.32), -vec2(0.065984,0.72), -vec2(0.028002,1.28), -vec2(0.0093,2.0) +QUALIFIER vec4 kernel[11] = vec4[]( + vec4(0.560479, 0.0), + vec4(0.00471691, -2.0), + vec4(0.0192831, -1.28), + vec4(0.03639, -0.72), + vec4(0.0821904, -0.32), + vec4(0.0771802, -0.08), + vec4(0.0771802, 0.08), + vec4(0.0821904, 0.32), + vec4(0.03639, 0.72), + vec4(0.0192831, 1.28), + vec4(0.00471691,2.0) ); #endif //USE_11_SAMPLES + uniform float max_radius; uniform float camera_z_far; uniform float camera_z_near; @@ -126,12 +127,16 @@ void main() { // Fetch linear depth of current pixel: float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0; +#ifdef USE_ORTHOGONAL_PROJECTION + depth = ((depth + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; + float scale = unit_size; //remember depth is negative by default in OpenGL +#else depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near)); + float scale = unit_size / depth; //remember depth is negative by default in OpenGL +#endif - float scale = unit_size / depth; //remember depth is negative by default in OpenGL - // Calculate the final step to fetch the surrounding pixels: vec2 step = max_radius * scale * dir; step *= strength; // Modulate it using the alpha channel. @@ -153,9 +158,14 @@ void main() { #ifdef ENABLE_FOLLOW_SURFACE // If the difference in depth is huge, we lerp color back to "colorM": float depth_cmp = texture(source_depth, offset).r *2.0 - 1.0; + +#ifdef USE_ORTHOGONAL_PROJECTION + depth_cmp = ((depth_cmp + (camera_z_far + camera_z_near)/(camera_z_far - camera_z_near)) * (camera_z_far - camera_z_near))/2.0; +#else depth_cmp = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth_cmp * (camera_z_far - camera_z_near)); +#endif - float s = clamp(300.0f * distance * + float s = clamp(300.0f * scale * max_radius * abs(depth - depth_cmp),0.0,1.0); color = mix(color, base_color.rgb, s); #endif diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index ddc3b2ed33..6b8038c3ef 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -211,36 +211,35 @@ Error DirAccessUnix::make_dir(String p_dir) { Error DirAccessUnix::change_dir(String p_dir) { GLOBAL_LOCK_FUNCTION + p_dir = fix_path(p_dir); + // prev_dir is the directory we are changing out of + String prev_dir; char real_current_dir_name[2048]; getcwd(real_current_dir_name, 2048); - String prev_dir; if (prev_dir.parse_utf8(real_current_dir_name)) prev_dir = real_current_dir_name; //no utf8, maybe latin? - chdir(current_dir.utf8().get_data()); //ascii since this may be unicode or wathever the host os wants - bool worked = (chdir(p_dir.utf8().get_data()) == 0); // we can only give this utf8 - - String base = _get_root_path(); - if (base != "") { - - getcwd(real_current_dir_name, 2048); - String new_dir; - new_dir.parse_utf8(real_current_dir_name); - if (!new_dir.begins_with(base)) - worked = false; + // try_dir is the directory we are trying to change into + String try_dir = ""; + if (p_dir.is_rel_path()) { + String next_dir = current_dir + "/" + p_dir; + next_dir = next_dir.simplify_path(); + try_dir = next_dir; + } else { + try_dir = p_dir; } - if (worked) { - - getcwd(real_current_dir_name, 2048); - if (current_dir.parse_utf8(real_current_dir_name)) - current_dir = real_current_dir_name; //no utf8, maybe latin? + bool worked = (chdir(try_dir.utf8().get_data()) == 0); // we can only give this utf8 + if (!worked) { + return ERR_INVALID_PARAMETER; } + // the directory exists, so set current_dir to try_dir + current_dir = try_dir; chdir(prev_dir.utf8().get_data()); - return worked ? OK : ERR_INVALID_PARAMETER; + return OK; } String DirAccessUnix::get_current_dir() { @@ -307,11 +306,16 @@ size_t DirAccessUnix::get_space_left() { DirAccessUnix::DirAccessUnix() { dir_stream = 0; - current_dir = "."; _cisdir = false; /* determine drive count */ + // set current directory to an absolute path of the current directory + char real_current_dir_name[2048]; + getcwd(real_current_dir_name, 2048); + if (current_dir.parse_utf8(real_current_dir_name)) + current_dir = real_current_dir_name; + change_dir(current_dir); } diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index d5a66d9a1c..80565c5b02 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -36,12 +36,17 @@ #include <sys/stat.h> #include <sys/types.h> +#if defined(UNIX_ENABLED) +#include <unistd.h> +#endif + #ifndef ANDROID_ENABLED #include <sys/statvfs.h> #endif #ifdef MSVC #define S_ISREG(m) ((m)&_S_IFREG) +#include <io.h> #endif #ifndef S_ISREG #define S_ISREG(m) ((m)&S_IFREG) @@ -85,13 +90,18 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { //printf("opening %s as %s\n", p_path.utf8().get_data(), path.utf8().get_data()); struct stat st; - if (stat(path.utf8().get_data(), &st) == 0) { - - if (!S_ISREG(st.st_mode)) - return ERR_FILE_CANT_OPEN; - }; + int err = stat(path.utf8().get_data(), &st); + if (!err) { + switch (st.st_mode & S_IFMT) { + case S_IFLNK: + case S_IFREG: + break; + default: + return ERR_FILE_CANT_OPEN; + } + } - if (is_backup_save_enabled() && p_mode_flags & WRITE && !(p_mode_flags & READ)) { + if (is_backup_save_enabled() && (p_mode_flags & WRITE) && !(p_mode_flags & READ)) { save_path = path; path = path + ".tmp"; //print_line("saving instead to "+path); @@ -108,15 +118,19 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) { return OK; } } + void FileAccessUnix::close() { if (!f) return; + fclose(f); f = NULL; + if (close_notification_func) { close_notification_func(path, flags); } + if (save_path != "") { //unlink(save_path.utf8().get_data()); @@ -131,10 +145,12 @@ void FileAccessUnix::close() { ERR_FAIL_COND(rename_error != 0); } } + bool FileAccessUnix::is_open() const { return (f != NULL); } + void FileAccessUnix::seek(size_t p_position) { ERR_FAIL_COND(!f); @@ -143,29 +159,37 @@ void FileAccessUnix::seek(size_t p_position) { if (fseek(f, p_position, SEEK_SET)) check_errors(); } + void FileAccessUnix::seek_end(int64_t p_position) { ERR_FAIL_COND(!f); + if (fseek(f, p_position, SEEK_END)) check_errors(); } + size_t FileAccessUnix::get_pos() const { - size_t aux_position = 0; - if (!(aux_position = ftell(f))) { + ERR_FAIL_COND_V(!f, 0); + + int pos = ftell(f); + if (pos < 0) { check_errors(); - }; - return aux_position; + ERR_FAIL_V(0); + } + return pos; } + size_t FileAccessUnix::get_len() const { ERR_FAIL_COND_V(!f, 0); - FileAccessUnix *fau = const_cast<FileAccessUnix *>(this); - int pos = fau->get_pos(); - fau->seek_end(); - int size = fau->get_pos(); - fau->seek(pos); + int pos = ftell(f); + ERR_FAIL_COND_V(pos < 0, 0); + ERR_FAIL_COND_V(fseek(f, 0, SEEK_END), 0); + int size = ftell(f); + ERR_FAIL_COND_V(size < 0, 0); + ERR_FAIL_COND_V(fseek(f, pos, SEEK_SET), 0); return size; } @@ -181,8 +205,8 @@ uint8_t FileAccessUnix::get_8() const { uint8_t b; if (fread(&b, 1, 1, f) == 0) { check_errors(); - }; - + b = '\0'; + } return b; } @@ -202,22 +226,36 @@ Error FileAccessUnix::get_error() const { void FileAccessUnix::store_8(uint8_t p_dest) { ERR_FAIL_COND(!f); - fwrite(&p_dest, 1, 1, f); + ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1); } bool FileAccessUnix::file_exists(const String &p_path) { - FILE *g; - //printf("opening file %s\n", p_fname.c_str()); + int err; + struct stat st; String filename = fix_path(p_path); - g = fopen(filename.utf8().get_data(), "rb"); - if (g == NULL) { + // Does the name exist at all? + err = stat(filename.utf8().get_data(), &st); + if (err) return false; - } else { - fclose(g); - return true; +#ifdef UNIX_ENABLED + // See if we have access to the file + if (access(filename.utf8().get_data(), F_OK)) + return false; +#else + if (_access(filename.utf8().get_data(), 4) == -1) + return false; +#endif + + // See if this is a regular file + switch (st.st_mode & S_IFMT) { + case S_IFLNK: + case S_IFREG: + return true; + default: + return false; } } @@ -225,9 +263,9 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) { String file = fix_path(p_file); struct stat flags; - bool success = (stat(file.utf8().get_data(), &flags) == 0); + int err = stat(file.utf8().get_data(), &flags); - if (success) { + if (!err) { return flags.st_mtime; } else { print_line("ERROR IN: " + p_file); @@ -249,6 +287,7 @@ FileAccessUnix::FileAccessUnix() { flags = 0; last_error = OK; } + FileAccessUnix::~FileAccessUnix() { close(); diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h index 3fc0144294..0995e5236f 100644 --- a/drivers/unix/socket_helpers.h +++ b/drivers/unix/socket_helpers.h @@ -64,7 +64,6 @@ static size_t _set_sockaddr(struct sockaddr_storage *p_addr, const IP_Address &p // IPv4 socket with IPv6 address ERR_FAIL_COND_V(!p_ip.is_ipv4(), 0); - uint32_t ipv4 = *((uint32_t *)p_ip.get_ipv4()); struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr; addr4->sin_family = AF_INET; addr4->sin_port = htons(p_port); // short, network byte order diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 30c8332fa3..fe2069089c 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -159,7 +159,8 @@ void FileAccessWindows::seek_end(int64_t p_position) { size_t FileAccessWindows::get_pos() const { size_t aux_position = 0; - if (!(aux_position = ftell(f))) { + aux_position = ftell(f); + if (!aux_position) { check_errors(); }; return aux_position; diff --git a/editor/SCsub b/editor/SCsub index 172447147c..0e690cf465 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -155,31 +155,71 @@ def make_authors_header(target, source, env): g.write("#define _EDITOR_AUTHORS_H\n") current_section = "" - name_count = -1 + reading = False def close_section(): g.write("\t0\n") g.write("};\n") - g.write("#define " + current_section.upper() + "_COUNT " + str(name_count) + "\n") for line in f: - if name_count >= 0: + if reading: if line.startswith(" "): g.write("\t\"" + line.strip() + "\",\n") - name_count += 1 continue if line.startswith("## "): - if name_count >= 0: + if reading: close_section() - name_count = -1 + reading = False for i in range(len(sections)): if line.strip().endswith(sections[i]): current_section = sections_id[i] - name_count = 0 + reading = True g.write("static const char *" + current_section + "[] = {\n") break - if name_count >= 0: + if reading: + close_section() + + g.write("#endif\n") + +def make_donors_header(target, source, env): + + sections = ["Platinum sponsors", "Gold sponsors", "Mini sponsors", "Gold donors", "Silver donors", "Bronze donors"] + sections_id = ["donor_s_plat", "donor_s_gold", "donor_s_mini", "donor_gold", "donor_silver", "donor_bronze"] + + src = source[0].srcnode().abspath + dst = target[0].srcnode().abspath + f = open_utf8(src, "r") + g = open_utf8(dst, "w") + + g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") + g.write("#ifndef _EDITOR_DONORS_H\n") + g.write("#define _EDITOR_DONORS_H\n") + + current_section = "" + reading = False + + def close_section(): + g.write("\t0\n") + g.write("};\n") + + for line in f: + if reading >= 0: + if line.startswith(" "): + g.write("\t\"" + line.strip() + "\",\n") + continue + if line.startswith("## "): + if reading: + close_section() + reading = False + for i in range(len(sections)): + if line.strip().endswith(sections[i]): + current_section = sections_id[i] + reading = True + g.write("static const char *" + current_section + "[] = {\n") + break + + if reading: close_section() g.write("#endif\n") @@ -393,6 +433,10 @@ if (env["tools"] == "yes"): env.Depends('#editor/authors.gen.h', "../AUTHORS.md") env.Command('#editor/authors.gen.h', "../AUTHORS.md", make_authors_header) + # Donors + env.Depends('#editor/donors.gen.h', "../DONORS.md") + env.Command('#editor/donors.gen.h', "../DONORS.md", make_donors_header) + # License env.Depends('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"]) env.Command('#editor/license.gen.h', ["../COPYRIGHT.txt", "../LICENSE.txt"], make_license_header) diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp index 702adf0c68..f4e3bf4894 100644 --- a/editor/animation_editor.cpp +++ b/editor/animation_editor.cpp @@ -1092,10 +1092,14 @@ void AnimationKeyEditor::_track_editor_draw() { int sep = get_constant("vseparation", "Tree"); int hsep = get_constant("hseparation", "Tree"); Color color = get_color("font_color", "Tree"); - Color sepcolor = Color(1, 1, 1, 0.2); - Color timecolor = Color(1, 1, 1, 0.2); - Color hover_color = Color(1, 1, 1, 0.05); - Color select_color = Color(1, 1, 1, 0.1); + Color sepcolor = color; + sepcolor.a = 0.2; + Color timecolor = color; + timecolor.a = 0.2; + Color hover_color = color; + hover_color.a = 0.05; + Color select_color = color; + select_color.a = 0.1; Color invalid_path_color = get_color("error_color", "Editor"); Color track_select_color = get_color("highlight_color", "Editor"); @@ -1157,7 +1161,8 @@ void AnimationKeyEditor::_track_editor_draw() { int settings_limit = size.width - right_separator_ofs; int name_limit = settings_limit * name_column_ratio; - Color linecolor = Color(1, 1, 1, 0.2); + Color linecolor = color; + linecolor.a = 0.2; te->draw_line(ofs + Point2(name_limit, 0), ofs + Point2(name_limit, size.height), linecolor); te->draw_line(ofs + Point2(settings_limit, 0), ofs + Point2(settings_limit, size.height), linecolor); te->draw_texture(hsize_icon, ofs + Point2(name_limit - hsize_icon->get_width() - hsep, (h - hsize_icon->get_height()) / 2)); @@ -2890,11 +2895,9 @@ void AnimationKeyEditor::_notification(int p_what) { key_editor->edit(key_edit); - zoomicon->set_texture(get_icon("Zoom", "EditorIcons")); zoomicon->set_custom_minimum_size(Size2(24 * EDSCALE, 0)); zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED); - menu_add_track->set_icon(get_icon("Add", "EditorIcons")); menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue", "EditorIcons"), "Add Normal Track", ADD_TRACK_MENU_ADD_VALUE_TRACK); menu_add_track->get_popup()->add_icon_item(get_icon("KeyXform", "EditorIcons"), "Add Transform Track", ADD_TRACK_MENU_ADD_TRANSFORM_TRACK); menu_add_track->get_popup()->add_icon_item(get_icon("KeyCall", "EditorIcons"), "Add Call Func Track", ADD_TRACK_MENU_ADD_CALL_TRACK); @@ -2921,18 +2924,10 @@ void AnimationKeyEditor::_notification(int p_what) { optimize_dialog->connect("confirmed", this, "_animation_optimize"); menu_track->get_popup()->add_child(tpp); - //menu_track->get_popup()->add_submenu_item("Set Transitions..","Transitions"); - //menu_track->get_popup()->add_separator(); + menu_track->get_popup()->add_item(TTR("Optimize Animation"), TRACK_MENU_OPTIMIZE); menu_track->get_popup()->add_item(TTR("Clean-Up Animation"), TRACK_MENU_CLEAN_UP); - curve_linear->set_icon(get_icon("CurveLinear", "EditorIcons")); - curve_in->set_icon(get_icon("CurveIn", "EditorIcons")); - curve_out->set_icon(get_icon("CurveOut", "EditorIcons")); - curve_inout->set_icon(get_icon("CurveInOut", "EditorIcons")); - curve_outin->set_icon(get_icon("CurveOutIn", "EditorIcons")); - curve_constant->set_icon(get_icon("CurveConstant", "EditorIcons")); - curve_linear->connect("pressed", this, "_menu_track", varray(CURVE_SET_LINEAR)); curve_in->connect("pressed", this, "_menu_track", varray(CURVE_SET_IN)); curve_out->connect("pressed", this, "_menu_track", varray(CURVE_SET_OUT)); @@ -2940,17 +2935,39 @@ void AnimationKeyEditor::_notification(int p_what) { curve_outin->connect("pressed", this, "_menu_track", varray(CURVE_SET_OUTIN)); curve_constant->connect("pressed", this, "_menu_track", varray(CURVE_SET_CONSTANT)); + edit_button->connect("pressed", this, "_toggle_edit_curves"); + + curve_edit->connect("transition_changed", this, "_curve_transition_changed"); + call_select->connect("selected", this, "_add_call_track"); + + _update_menu(); + + } break; + + case NOTIFICATION_THEME_CHANGED: { + zoomicon->set_texture(get_icon("Zoom", "EditorIcons")); + + menu_add_track->set_icon(get_icon("Add", "EditorIcons")); + + menu_track->set_icon(get_icon("Tools", "EditorIcons")); + + menu_add_track->get_popup()->set_item_icon(ADD_TRACK_MENU_ADD_VALUE_TRACK, get_icon("KeyValue", "EditorIcons")); + menu_add_track->get_popup()->set_item_icon(ADD_TRACK_MENU_ADD_TRANSFORM_TRACK, get_icon("KeyXform", "EditorIcons")); + menu_add_track->get_popup()->set_item_icon(ADD_TRACK_MENU_ADD_CALL_TRACK, get_icon("KeyCall", "EditorIcons")); + + curve_linear->set_icon(get_icon("CurveLinear", "EditorIcons")); + curve_in->set_icon(get_icon("CurveIn", "EditorIcons")); + curve_out->set_icon(get_icon("CurveOut", "EditorIcons")); + curve_inout->set_icon(get_icon("CurveInOut", "EditorIcons")); + curve_outin->set_icon(get_icon("CurveOutIn", "EditorIcons")); + curve_constant->set_icon(get_icon("CurveConstant", "EditorIcons")); + move_up_button->set_icon(get_icon("MoveUp", "EditorIcons")); move_down_button->set_icon(get_icon("MoveDown", "EditorIcons")); remove_button->set_icon(get_icon("Remove", "EditorIcons")); edit_button->set_icon(get_icon("EditKey", "EditorIcons")); - edit_button->connect("pressed", this, "_toggle_edit_curves"); loop->set_icon(get_icon("Loop", "EditorIcons")); - curve_edit->connect("transition_changed", this, "_curve_transition_changed"); - - //edit_button->add_color_override("font_color",get_color("font_color","Tree")); - //edit_button->add_color_override("font_color_hover",get_color("font_color","Tree")); { @@ -2976,24 +2993,8 @@ void AnimationKeyEditor::_notification(int p_what) { get_icon("InterpWrapClamp", "EditorIcons"), get_icon("InterpWrapLoop", "EditorIcons"), }; - - //right_data_size_cache = remove_icon->get_width() + move_up_icon->get_width() + move_down_icon->get_width() + down_icon->get_width() *2 + interp_icon[0]->get_width() + cont_icon[0]->get_width() + add_key_icon->get_width() + hsep*11; right_data_size_cache = down_icon->get_width() * 3 + add_key_icon->get_width() + interp_icon[0]->get_width() + cont_icon[0]->get_width() + wrap_icon[0]->get_width() + hsep * 8; } - call_select->connect("selected", this, "_add_call_track"); - //rename_anim->set_icon( get_icon("Rename","EditorIcons") ); - /* - edit_anim->set_icon( get_icon("Edit","EditorIcons") ); - blend_anim->set_icon( get_icon("Blend","EditorIcons") ); - play->set_icon( get_icon("Play","EditorIcons") ); - stop->set_icon( get_icon("Stop","EditorIcons") ); - pause->set_icon( get_icon("Pause","EditorIcons") ); -*/ - //menu->set_icon(get_icon("Animation","EditorIcons")); - //play->set_icon(get_icon("AnimationPlay","EditorIcons")); - //menu->set_icon(get_icon("Animation","EditorIcons")); - _update_menu(); - } break; } } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 890c3d8091..54bf31cd62 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -489,6 +489,7 @@ DependencyErrorDialog::DependencyErrorDialog() { vb->add_margin_child(TTR("Scene failed to load due to missing dependencies:"), files, true); files->set_v_size_flags(SIZE_EXPAND_FILL); get_ok()->set_text(TTR("Open Anyway")); + get_cancel()->set_text(TTR("Done")); text = memnew(Label); vb->add_child(text); diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 5975e54356..6848c43b68 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -634,6 +634,9 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> & ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT); method.return_type = parser->get_attribute_value("type"); + if (parser->has_attribute("enum")) { + method.return_enum = parser->get_attribute_value("enum"); + } } else if (name == "argument") { DocData::ArgumentDoc argument; @@ -916,7 +919,11 @@ Error DocData::save(const String &p_path) { if (m.return_type != "") { - _write_string(f, 3, "<return type=\"" + m.return_type + "\">"); + String enum_text; + if (m.return_enum != String()) { + enum_text = " enum=\"" + m.return_enum + "\""; + } + _write_string(f, 3, "<return type=\"" + m.return_type + "\"" + enum_text + ">"); _write_string(f, 3, "</return>"); } diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 8bd7bfb4bd..a48e6c9057 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -30,6 +30,7 @@ #include "editor_about.h" #include "authors.gen.h" +#include "donors.gen.h" #include "license.gen.h" #include "version.h" #include "version_hash.gen.h" @@ -51,6 +52,47 @@ TextureRect *EditorAbout::get_logo() const { return _logo; } +ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]) { + + ScrollContainer *sc = memnew(ScrollContainer); + sc->set_name(p_name); + sc->set_v_size_flags(Control::SIZE_EXPAND); + + VBoxContainer *vbc = memnew(VBoxContainer); + vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sc->add_child(vbc); + + for (int i = 0; i < p_sections.size(); i++) { + + const char **names_ptr = p_src[i]; + if (*names_ptr) { + + Label *lbl = memnew(Label); + lbl->set_text(p_sections[i]); + vbc->add_child(lbl); + + ItemList *il = memnew(ItemList); + il->set_max_columns(16); + il->set_h_size_flags(Control::SIZE_EXPAND_FILL); + il->set_same_column_width(true); + il->set_auto_height(true); + while (*names_ptr) { + il->add_item(String::utf8(*names_ptr++), NULL, false); + } + vbc->add_child(il); + if (il->get_item_count() == 2) { + il->set_fixed_column_width(200 * EDSCALE); + } + + HSeparator *hs = memnew(HSeparator); + hs->set_modulate(Color(0, 0, 0, 0)); + vbc->add_child(hs); + } + } + + return sc; +} + EditorAbout::EditorAbout() { set_title(TTR("Thanks from the Godot community!")); @@ -84,43 +126,29 @@ EditorAbout::EditorAbout() { tc->set_v_size_flags(Control::SIZE_EXPAND_FILL); vbc->add_child(tc); - ScrollContainer *dev_base = memnew(ScrollContainer); - dev_base->set_name(TTR("Authors")); - dev_base->set_v_size_flags(Control::SIZE_EXPAND); - tc->add_child(dev_base); - - VBoxContainer *dev_vbc = memnew(VBoxContainer); - dev_vbc->set_h_size_flags(Control::SIZE_EXPAND_FILL); - dev_base->add_child(dev_vbc); + // Authors List<String> dev_sections; dev_sections.push_back(TTR("Project Founders")); dev_sections.push_back(TTR("Lead Developer")); dev_sections.push_back(TTR("Project Manager")); dev_sections.push_back(TTR("Developers")); - const char **dev_src[] = { dev_founders, dev_lead, dev_manager, dev_names }; + tc->add_child(_populate_list(TTR("Authors"), dev_sections, dev_src)); - for (int i = 0; i < dev_sections.size(); i++) { - - Label *lbl = memnew(Label); - lbl->set_text(dev_sections[i]); - dev_vbc->add_child(lbl); - - ItemList *il = memnew(ItemList); - il->set_max_columns(16); - il->set_h_size_flags(Control::SIZE_EXPAND_FILL); - il->set_fixed_column_width(230 * EDSCALE); - il->set_auto_height(true); - const char **dev_names_ptr = dev_src[i]; - while (*dev_names_ptr) - il->add_item(String::utf8(*dev_names_ptr++), NULL, false); - dev_vbc->add_child(il); - - HSeparator *hs = memnew(HSeparator); - hs->set_modulate(Color(0, 0, 0, 0)); - dev_vbc->add_child(hs); - } + // Donors + + List<String> donor_sections; + donor_sections.push_back(TTR("Platinum Sponsors")); + donor_sections.push_back(TTR("Gold Sponsors")); + donor_sections.push_back(TTR("Mini Sponsors")); + donor_sections.push_back(TTR("Gold Donors")); + donor_sections.push_back(TTR("Silver Donors")); + donor_sections.push_back(TTR("Bronze Donors")); + const char **donor_src[] = { donor_s_plat, donor_s_gold, donor_s_mini, donor_gold, donor_silver, donor_bronze }; + tc->add_child(_populate_list(TTR("Donors"), donor_sections, donor_src)); + + // License TextEdit *license = memnew(TextEdit); license->set_name(TTR("License")); @@ -131,6 +159,8 @@ EditorAbout::EditorAbout() { license->set_text(String::utf8(about_license)); tc->add_child(license); + // Thirdparty License + VBoxContainer *license_thirdparty = memnew(VBoxContainer); license_thirdparty->set_name(TTR("Thirdparty License")); license_thirdparty->set_h_size_flags(Control::SIZE_EXPAND_FILL); diff --git a/editor/editor_about.h b/editor/editor_about.h index d7047c03a3..d455b1f074 100644 --- a/editor/editor_about.h +++ b/editor/editor_about.h @@ -52,6 +52,7 @@ class EditorAbout : public AcceptDialog { private: void _license_tree_selected(); + ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[]); Tree *_tpl_tree; TextEdit *_tpl_text; diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 6937f74316..29159c7ad5 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -414,7 +414,10 @@ void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) { void EditorAudioBus::_bus_popup_pressed(int p_option) { - if (p_option == 1) { + if (p_option == 2) { + // Reset volume + emit_signal("vol_reset_request"); + } else if (p_option == 1) { emit_signal("delete_request"); } else if (p_option == 0) { //duplicate @@ -617,6 +620,7 @@ void EditorAudioBus::_bind_methods() { ADD_SIGNAL(MethodInfo("duplicate_request")); ADD_SIGNAL(MethodInfo("delete_request")); + ADD_SIGNAL(MethodInfo("vol_reset_request")); ADD_SIGNAL(MethodInfo("drop_end_request")); ADD_SIGNAL(MethodInfo("dropped")); } @@ -742,6 +746,7 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses) { bus_popup = bus_options->get_popup(); bus_popup->add_item(TTR("Duplicate")); bus_popup->add_item(TTR("Delete")); + bus_popup->add_item(TTR("Reset Volume")); bus_popup->connect("index_pressed", this, "_bus_popup_pressed"); delete_effect_popup = memnew(PopupMenu); @@ -790,6 +795,7 @@ void EditorAudioBuses::_update_buses() { bus_hb->add_child(audio_bus); audio_bus->connect("delete_request", this, "_delete_bus", varray(audio_bus), CONNECT_DEFERRED); audio_bus->connect("duplicate_request", this, "_duplicate_bus", varray(), CONNECT_DEFERRED); + audio_bus->connect("vol_reset_request", this, "_reset_bus_volume", varray(audio_bus), CONNECT_DEFERRED); audio_bus->connect("drop_end_request", this, "_request_drop_end"); audio_bus->connect("dropped", this, "_drop_at_index", varray(), CONNECT_DEFERRED); } @@ -919,6 +925,20 @@ void EditorAudioBuses::_duplicate_bus(int p_which) { ur->commit_action(); } +void EditorAudioBuses::_reset_bus_volume(Object *p_which) { + + EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which); + int index = bus->get_index(); + + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + ur->create_action(TTR("Reset Bus Volume")); + ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", index, 0.f); + ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", index, AudioServer::get_singleton()->get_bus_volume_db(index)); + ur->add_do_method(this, "_update_buses"); + ur->add_undo_method(this, "_update_buses"); + ur->commit_action(); +} + void EditorAudioBuses::_request_drop_end() { if (!drop_end && bus_hb->get_child_count()) { @@ -1063,6 +1083,7 @@ void EditorAudioBuses::_bind_methods() { ClassDB::bind_method("_load_default_layout", &EditorAudioBuses::_load_default_layout); ClassDB::bind_method("_new_layout", &EditorAudioBuses::_new_layout); ClassDB::bind_method("_duplicate_bus", &EditorAudioBuses::_duplicate_bus); + ClassDB::bind_method("_reset_bus_volume", &EditorAudioBuses::_reset_bus_volume); ClassDB::bind_method("_file_dialog_callback", &EditorAudioBuses::_file_dialog_callback); } diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index e04ba7b89d..2c61228bde 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -158,6 +158,7 @@ class EditorAudioBuses : public VBoxContainer { void _delete_bus(Object *p_which); void _duplicate_bus(int p_which); + void _reset_bus_volume(Object *p_which); void _request_drop_end(); void _drop_at_index(int p_bus, int p_index); diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp index 1b213501aa..cfb3abfd1d 100644 --- a/editor/editor_dir_dialog.cpp +++ b/editor/editor_dir_dialog.cpp @@ -31,50 +31,40 @@ #include "editor/editor_file_system.h" #include "editor/editor_settings.h" +#include "editor_scale.h" #include "os/keyboard.h" #include "os/os.h" - -void EditorDirDialog::_update_dir(TreeItem *p_item) { +void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) { updating = true; - p_item->clear_children(); - DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - String cdir = p_item->get_metadata(0); - - da->change_dir(cdir); - da->list_dir_begin(); - String p = da->get_next(); - List<String> dirs; - bool ishidden; - bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + String path = p_dir->get_path(); - while (p != "") { + p_item->set_metadata(0, p_dir->get_path()); + p_item->set_icon(0, get_icon("Folder", "EditorIcons")); - ishidden = da->current_is_hidden(); + if (!p_item->get_parent()) { + p_item->set_text(0, "res://"); + } else { - if (show_hidden || !ishidden) { - if (da->current_is_dir() && !p.begins_with(".")) { - dirs.push_back(p); - } + if (!opened_paths.has(path) && (p_select_path == String() || !p_select_path.begins_with(path))) { + p_item->set_collapsed(true); } - p = da->get_next(); + + p_item->set_text(0, p_dir->get_name()); } - dirs.sort(); + //this should be handled by EditorFileSystem already + //bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"); + updating = false; + for (int i = 0; i < p_dir->get_subdir_count(); i++) { - for (List<String>::Element *E = dirs.front(); E; E = E->next()) { TreeItem *ti = tree->create_item(p_item); - ti->set_text(0, E->get()); - ti->set_icon(0, get_icon("Folder", "EditorIcons")); - ti->set_collapsed(true); + _update_dir(ti, p_dir->get_subdir(i)); } - - memdelete(da); - updating = false; } -void EditorDirDialog::reload() { +void EditorDirDialog::reload(const String &p_with_path) { if (!is_visible_in_tree()) { must_reload = true; @@ -83,10 +73,7 @@ void EditorDirDialog::reload() { tree->clear(); TreeItem *root = tree->create_item(); - root->set_metadata(0, "res://"); - root->set_icon(0, get_icon("Folder", "EditorIcons")); - root->set_text(0, "/"); - _update_dir(root); + _update_dir(root, EditorFileSystem::get_singleton()->get_filesystem(), p_with_path); _item_collapsed(root); must_reload = false; } @@ -94,6 +81,7 @@ void EditorDirDialog::reload() { void EditorDirDialog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { + EditorFileSystem::get_singleton()->connect("filesystem_changed", this, "reload"); reload(); if (!tree->is_connected("item_collapsed", this, "_item_collapsed")) { @@ -105,6 +93,10 @@ void EditorDirDialog::_notification(int p_what) { } } + if (p_what == NOTIFICATION_EXIT_TREE) { + EditorFileSystem::get_singleton()->disconnect("filesystem_changed", this, "reload"); + } + if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { if (must_reload && is_visible_in_tree()) { reload(); @@ -116,57 +108,13 @@ void EditorDirDialog::_item_collapsed(Object *p_item) { TreeItem *item = Object::cast_to<TreeItem>(p_item); - if (updating || item->is_collapsed()) + if (updating) return; - TreeItem *ci = item->get_children(); - while (ci) { - - String p = ci->get_metadata(0); - if (p == "") { - String pp = item->get_metadata(0); - ci->set_metadata(0, pp.plus_file(ci->get_text(0))); - _update_dir(ci); - } - ci = ci->get_next(); - } -} - -void EditorDirDialog::set_current_path(const String &p_path) { - - reload(); - String p = p_path; - if (p.begins_with("res://")) - p = p.replace_first("res://", ""); - - Vector<String> dirs = p.split("/", false); - - TreeItem *r = tree->get_root(); - for (int i = 0; i < dirs.size(); i++) { - - String d = dirs[i]; - TreeItem *p = r->get_children(); - while (p) { - - if (p->get_text(0) == d) - break; - p = p->get_next(); - } - - ERR_FAIL_COND(!p); - String pp = p->get_metadata(0); - if (pp == "") { - p->set_metadata(0, String(r->get_metadata(0)).plus_file(d)); - _update_dir(p); - } - updating = true; - p->set_collapsed(false); - updating = false; - _item_collapsed(p); - r = p; - } - - r->select(0); + if (item->is_collapsed()) + opened_paths.erase(item->get_metadata(0)); + else + opened_paths.insert(item->get_metadata(0)); } void EditorDirDialog::ok_pressed() { @@ -201,14 +149,16 @@ void EditorDirDialog::_make_dir_confirm() { String dir = ti->get_metadata(0); - DirAccess *d = DirAccess::open(dir); + DirAccessRef d = DirAccess::open(dir); ERR_FAIL_COND(!d); Error err = d->make_dir(makedirname->get_text()); if (err != OK) { - mkdirerr->popup_centered_minsize(Size2(250, 80)); + mkdirerr->popup_centered_minsize(Size2(250, 80) * EDSCALE); } else { - set_current_path(dir.plus_file(makedirname->get_text())); + opened_paths.insert(dir); + //reload(dir.plus_file(makedirname->get_text())); + EditorFileSystem::get_singleton()->scan_changes(); //we created a dir, so rescan changes } makedirname->set_text(""); // reset label } @@ -218,7 +168,7 @@ void EditorDirDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("_item_collapsed"), &EditorDirDialog::_item_collapsed); ClassDB::bind_method(D_METHOD("_make_dir"), &EditorDirDialog::_make_dir); ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &EditorDirDialog::_make_dir_confirm); - ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload); + ClassDB::bind_method(D_METHOD("reload"), &EditorDirDialog::reload, DEFVAL("")); ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir"))); } diff --git a/editor/editor_dir_dialog.h b/editor/editor_dir_dialog.h index b8347f75fb..8aa685947b 100644 --- a/editor/editor_dir_dialog.h +++ b/editor/editor_dir_dialog.h @@ -30,6 +30,7 @@ #ifndef EDITOR_DIR_DIALOG_H #define EDITOR_DIR_DIALOG_H +#include "editor/editor_file_system.h" #include "os/dir_access.h" #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" @@ -42,12 +43,13 @@ class EditorDirDialog : public ConfirmationDialog { AcceptDialog *mkdirerr; Button *makedir; + Set<String> opened_paths; Tree *tree; bool updating; void _item_collapsed(Object *p_item); - void _update_dir(TreeItem *p_item); + void _update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path = String()); void _make_dir(); void _make_dir_confirm(); @@ -61,8 +63,7 @@ protected: static void _bind_methods(); public: - void set_current_path(const String &p_path); - void reload(); + void reload(const String &p_path = ""); EditorDirDialog(); }; diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index 915fb7e5db..8623b9acdb 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -697,6 +697,8 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co zd.zip = zip; Error err = export_project_files(p_preset, _save_zip_file, &zd); + if (err != OK) + ERR_PRINT("Failed to export project files"); zipClose(zip, NULL); diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 22a9c84d21..3ab3f05906 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -72,11 +72,14 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p m_name->add_fallback(FontJapanese); \ m_name->add_fallback(FontFallback); -#define MAKE_DEFAULT_FONT(m_name, m_size) \ - Ref<DynamicFont> m_name; \ - m_name.instance(); \ - m_name->set_size(m_size); \ - m_name->set_font_data(DefaultFont); \ +// the custom spacings might only work with Noto Sans +#define MAKE_DEFAULT_FONT(m_name, m_size) \ + Ref<DynamicFont> m_name; \ + m_name.instance(); \ + m_name->set_size(m_size); \ + m_name->set_font_data(DefaultFont); \ + m_name->set_spacing(DynamicFont::SPACING_TOP, -1); \ + m_name->set_spacing(DynamicFont::SPACING_BOTTOM, -1); \ MAKE_FALLBACKS(m_name); void editor_register_fonts(Ref<Theme> p_theme) { diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 0e22f0d386..7fa2c53275 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -1712,9 +1712,8 @@ void EditorHelp::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); - style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color")); - background_panel->add_style_override("panel", style); + + class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); } break; default: break; @@ -1786,14 +1785,12 @@ EditorHelp::EditorHelp() { { background_panel = memnew(Panel); - Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); - style->set_bg_color(EditorSettings::get_singleton()->get("text_editor/highlighting/background_color")); background_panel->set_v_size_flags(SIZE_EXPAND_FILL); - background_panel->add_style_override("panel", style); //get_stylebox("normal","TextEdit")); vbc->add_child(background_panel); class_desc = memnew(RichTextLabel); background_panel->add_child(class_desc); - class_desc->set_area_as_parent_rect(8); + class_desc->set_area_as_parent_rect(); + class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); class_desc->connect("meta_clicked", this, "_class_desc_select"); class_desc->connect("gui_input", this, "_class_desc_input"); } @@ -1882,8 +1879,13 @@ void EditorHelpBit::_bind_methods() { void EditorHelpBit::_notification(int p_what) { - if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - add_style_override("panel", get_stylebox("ScriptPanel", "EditorStyles")); + switch (p_what) { + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); + } break; + + default: break; } } @@ -1897,8 +1899,8 @@ EditorHelpBit::EditorHelpBit() { rich_text = memnew(RichTextLabel); add_child(rich_text); - rich_text->set_area_as_parent_rect(8 * EDSCALE); + rich_text->set_area_as_parent_rect(); rich_text->connect("meta_clicked", this, "_meta_clicked"); + rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1))); set_custom_minimum_size(Size2(0, 70 * EDSCALE)); - add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); } diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp index a1f416a17c..35291f8f9e 100644 --- a/editor/editor_log.cpp +++ b/editor/editor_log.cpp @@ -59,7 +59,6 @@ void EditorLog::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - log->add_color_override("default_color", get_color("font_color", "Tree")); //button->set_icon(get_icon("Console","EditorIcons")); } if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { @@ -91,7 +90,7 @@ void EditorLog::add_message(const String &p_msg, bool p_error) { log->add_newline(); if (p_error) { - log->push_color(get_color("fg_error", "Editor")); + log->push_color(get_color("error_color", "Editor")); Ref<Texture> icon = get_icon("Error", "EditorIcons"); log->add_image(icon); //button->set_icon(icon); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6b5db7572a..b4412014e7 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -283,13 +283,22 @@ void EditorNode::_notification(int p_what) { scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/capitalize_properties", true))); Ref<Theme> theme = create_editor_theme(theme_base->get_theme()); + theme_base->set_theme(theme); + gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles")); play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles")); scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles")); scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles")); + + file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + if (bool(EDITOR_DEF("interface/scene_tabs/resize_if_many_tabs", true))) { scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE); } else { @@ -403,7 +412,6 @@ void EditorNode::_fs_changed() { } if (changed.size()) { - int idx = 0; for (List<Ref<Resource> >::Element *E = changed.front(); E; E = E->next()) { E->get()->reload_from_file(); } @@ -1368,6 +1376,16 @@ void EditorNode::_set_editing_top_editors(Object *p_current_object) { editor_plugins_over->edit(p_current_object); } +static bool overrides_external_editor(Object *p_object) { + + Script *script = Object::cast_to<Script>(p_object); + + if (!script) + return false; + + return script->get_language()->overrides_external_editor(); +} + void EditorNode::_edit_current() { uint32_t current = editor_history.get_current(); @@ -1434,7 +1452,7 @@ void EditorNode::_edit_current() { if (main_plugin) { // special case if use of external editor is true - if (main_plugin->get_name() == "Script" && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { + if (main_plugin->get_name() == "Script" && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) { main_plugin->edit(current_obj); } @@ -1442,6 +1460,7 @@ void EditorNode::_edit_current() { // update screen main_plugin if (!changing_scene) { + if (editor_plugin_screen) editor_plugin_screen->make_visible(false); editor_plugin_screen = main_plugin; @@ -1977,6 +1996,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { int cur_idx = editor_data.get_edited_scene(); _remove_edited_scene(); Error err = load_scene(filename); + if (err != OK) + ERR_PRINT("Failed to load scene"); editor_data.move_edited_scene_to_index(cur_idx); get_undo_redo()->clear_history(); scene_tabs->set_current_tab(cur_idx); @@ -2721,6 +2742,14 @@ Dictionary EditorNode::_get_main_scene_state() { state["property_edit_offset"] = get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_value(); state["saved_version"] = saved_version; state["node_filter"] = scene_tree_dock->get_filter(); + int current = -1; + for (int i = 0; i < editor_table.size(); i++) { + if (editor_plugin_screen == editor_table[i]) { + current = i; + break; + } + } + state["editor_index"] = current; return state; } @@ -2731,8 +2760,9 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { changing_scene = false; - if (get_edited_scene()) { + if (p_state.has("editor_index")) { + int index = p_state["editor_index"]; int current = -1; for (int i = 0; i < editor_table.size(); i++) { if (editor_plugin_screen == editor_table[i]) { @@ -2741,15 +2771,18 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) { } } - if (current < 2) { - //use heuristic instead - - int n2d = 0, n3d = 0; - _find_node_types(get_edited_scene(), n2d, n3d); - if (n2d > n3d) { - _editor_select(EDITOR_2D); - } else if (n3d > n2d) { - _editor_select(EDITOR_3D); + if (current < 2) { //if currently in spatial/2d, only switch to spatial/2d. if curently in script, stay there + if (index < 2 || !get_edited_scene()) { + _editor_select(index); + } else { + //use heuristic instead + int n2d = 0, n3d = 0; + _find_node_types(get_edited_scene(), n2d, n3d); + if (n2d > n3d) { + _editor_select(EDITOR_2D); + } else if (n3d > n2d) { + _editor_select(EDITOR_3D); + } } } } @@ -3575,13 +3608,6 @@ void EditorNode::_update_dock_slots_visibility() { right_r_vsplit, }; - HSplitContainer *h_splits[4] = { - left_l_hsplit, - left_r_hsplit, - main_hsplit, - right_hsplit, - }; - if (!docks_visible) { for (int i = 0; i < DOCK_SLOT_MAX; i++) { @@ -4818,9 +4844,10 @@ EditorNode::EditorNode() { } file_menu = memnew(MenuButton); + file_menu->set_flat(false); file_menu->set_text(TTR("Scene")); - left_menu_hb->add_child(file_menu); file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(file_menu); prev_scene = memnew(ToolButton); prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons")); @@ -4908,6 +4935,7 @@ EditorNode::EditorNode() { p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q); project_menu = memnew(MenuButton); + project_menu->set_flat(false); project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools.")); project_menu->set_text(TTR("Project")); project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); @@ -4941,9 +4969,11 @@ EditorNode::EditorNode() { menu_hb->add_child(editor_region); debug_menu = memnew(MenuButton); + debug_menu->set_flat(false); debug_menu->set_text(TTR("Debug")); debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); left_menu_hb->add_child(debug_menu); + p = debug_menu->get_popup(); p->set_hide_on_item_selection(false); p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG); @@ -4965,9 +4995,10 @@ EditorNode::EditorNode() { menu_hb->add_spacer(); settings_menu = memnew(MenuButton); - left_menu_hb->add_child(settings_menu); + settings_menu->set_flat(false); settings_menu->set_text(TTR("Editor")); settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(settings_menu); p = settings_menu->get_popup(); p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES); @@ -4982,10 +5013,12 @@ EditorNode::EditorNode() { p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES); // Help Menu - MenuButton *help_menu = memnew(MenuButton); - left_menu_hb->add_child(help_menu); + help_menu = memnew(MenuButton); + help_menu->set_flat(false); help_menu->set_text(TTR("Help")); help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + left_menu_hb->add_child(help_menu); + p = help_menu->get_popup(); p->connect("id_pressed", this, "_menu_option"); p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES); diff --git a/editor/editor_node.h b/editor/editor_node.h index c3ceee350a..ea74bcbd9d 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -236,11 +236,12 @@ private: MenuButton *file_menu; MenuButton *project_menu; MenuButton *debug_menu; + MenuButton *settings_menu; + MenuButton *help_menu; PopupMenu *tool_menu; ToolButton *export_button; ToolButton *prev_scene; MenuButton *object_menu; - MenuButton *settings_menu; ToolButton *play_button; MenuButton *native_play_button; ToolButton *pause_button; diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 9c9eef848a..50cee6d892 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -603,7 +603,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["text_editor/theme/color_theme"] = PropertyInfo(Variant::STRING, "text_editor/theme/color_theme", PROPERTY_HINT_ENUM, "Default"); set("text_editor/theme/line_spacing", 4); - set("text_editor/theme/adapted_code_editor_background_color", true); _load_default_text_editor_theme(); @@ -677,9 +676,15 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { set("editors/3d/warped_mouse_panning", true); set("editors/3d/orbit_sensitivity", 0.4); - set("editors/3d/freelook_inertia", 3); - set("editors/3d/freelook_base_speed", 1); + set("editors/3d/orbit_inertia", 0.2); + hints["editors/3d/orbit_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/orbit_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + + set("editors/3d/freelook_inertia", 0.2); + hints["editors/3d/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01"); + + set("editors/3d/freelook_base_speed", 0.5); + hints["editors/3d/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.1"); set("editors/3d/freelook_activation_modifier", 0); hints["editors/3d/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl"); diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 8943d5f0dc..ff0e794a20 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -198,6 +198,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false); int border_size = EDITOR_DEF("interface/theme/border_size", 1); + Color script_bg_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)); + switch (preset) { case 0: { // Default highlight_color = Color::html("#699ce8"); @@ -235,8 +237,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5); Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2); - Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.3); - Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), 0.5); + Color contrast_color_1 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast, default_contrast)); + Color contrast_color_2 = base_color.linear_interpolate((dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)), MAX(contrast * 1.5, default_contrast * 1.5)); Color font_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0); Color font_color_disabled = dark_theme ? Color(0.6, 0.6, 0.6) : Color(0.45, 0.45, 0.45); @@ -279,8 +281,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { editor_register_fonts(theme); // Editor background - Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4); - theme->set_stylebox("Background", "EditorStyles", style_panel); + theme->set_stylebox("Background", "EditorStyles", make_flat_stylebox(dark_color_2, 4, 4, 4, 4)); // Focus Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(contrast_color_1, 4, 4, 4, 4); @@ -294,6 +295,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("panel", "PanelContainer", style_menu); theme->set_stylebox("MenuPanel", "EditorStyles", style_menu); + // Script Editor + theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(4, 0, 4, 4)); + theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); + // Play button group theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_empty_stylebox(8, 4, 8, 4)); //make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4)); @@ -302,12 +307,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4); style_menu_hover_border->set_draw_center(false); - style_menu_hover_border->set_border_width(MARGIN_BOTTOM, border_width); + style_menu_hover_border->set_border_width(MARGIN_BOTTOM, 2 * EDSCALE); style_menu_hover_border->set_border_color_all(highlight_color); - style_menu_hover_border->set_expand_margin_size(MARGIN_BOTTOM, border_width); theme->set_stylebox("normal", "MenuButton", style_menu); - theme->set_stylebox("hover", "MenuButton", style_menu_hover_border); + theme->set_stylebox("hover", "MenuButton", style_menu); theme->set_stylebox("pressed", "MenuButton", style_menu); theme->set_stylebox("focus", "MenuButton", style_menu); theme->set_stylebox("disabled", "MenuButton", style_menu); @@ -333,10 +337,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border); // Content of each tab - Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 5, 4, 4); + Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 4, 4, 4); style_content_panel->set_border_color_all(base_color); style_content_panel->set_border_width_all(border_width); - Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 5, border_width, border_width); + Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 4, border_width, border_width); style_content_panel_vp->set_border_color_all(base_color); style_content_panel_vp->set_border_width_all(border_width); theme->set_stylebox("panel", "TabContainer", style_content_panel); @@ -357,6 +361,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("disabled", "Button", style_button_type_disabled); + theme->set_color("font_color", "Button", button_font_color); theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "Button", highlight_color); @@ -366,13 +371,12 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a)); // OptionButton - Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4); - style_option_button->set_border_width_all(border_width); + theme->set_stylebox("normal", "OptionButton", style_button_type); theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, contrast_color_1)); theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_FONT)); theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color)); theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled); - theme->set_stylebox("normal", "OptionButton", style_button_type); + theme->set_color("font_color", "OptionButton", button_font_color); theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "OptionButton", highlight_color); @@ -385,6 +389,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // CheckButton theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons")); theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons")); + theme->set_color("font_color", "CheckButton", button_font_color); theme->set_color("font_color_hover", "CheckButton", HIGHLIGHT_COLOR_FONT); theme->set_color("font_color_pressed", "CheckButton", highlight_color); @@ -424,12 +429,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_tree_bg->set_border_color_all(dark_color_3); theme->set_stylebox("bg", "Tree", style_tree_bg); - // Script background - Ref<StyleBoxFlat> style_script_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0); - style_script_bg->set_border_width_all(border_width); - style_script_bg->set_border_color_all(dark_color_3); - theme->set_stylebox("ScriptPanel", "EditorStyles", style_script_bg); - // Tree theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons")); theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons")); @@ -441,7 +440,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("custom_button_pressed", "Tree", make_empty_stylebox()); theme->set_stylebox("custom_button_hover", "Tree", style_button_type); theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_FONT); - theme->set_color("font_color", "Tree", font_color_disabled); + theme->set_color("font_color", "Tree", font_color); theme->set_color("font_color_selected", "Tree", font_color); Ref<StyleBox> style_tree_btn = make_flat_stylebox(contrast_color_1, 2, 4, 2, 4); @@ -471,8 +470,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("prop_category", "Editor", prop_category_color); theme->set_color("prop_section", "Editor", prop_section_color); theme->set_color("prop_subsection", "Editor", prop_subsection_color); - theme->set_color("fg_selected", "Editor", HIGHLIGHT_COLOR_BG); - theme->set_color("fg_error", "Editor", error_color); theme->set_color("drop_position_color", "Tree", highlight_color); // ItemList @@ -531,6 +528,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // LineEdit Ref<StyleBoxFlat> style_line_edit = make_flat_stylebox(dark_color_1, 6, 4, 6, 4); + style_line_edit->set_border_width_all(border_width); style_line_edit = change_border_color(style_line_edit, contrast_color_1); Ref<StyleBoxFlat> style_line_edit_disabled = change_border_color(style_line_edit, dark_color_1); style_line_edit_disabled->set_bg_color(Color(0, 0, 0, .1)); @@ -614,11 +612,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons")); //RichTextLabel - theme->set_color("font_color", "RichTextLabel", font_color); + Color rtl_combined_bg_color = dark_color_1.linear_interpolate(script_bg_color, script_bg_color.a); + Color rtl_font_color = (rtl_combined_bg_color.r + rtl_combined_bg_color.g + rtl_combined_bg_color.b > 0.5 * 3) ? Color(0, 0, 0) : Color(1, 1, 1); + theme->set_color("default_color", "RichTextLabel", rtl_font_color); theme->set_stylebox("focus", "RichTextLabel", make_empty_stylebox()); + theme->set_stylebox("normal", "RichTextLabel", make_flat_stylebox(script_bg_color, 6, 6, 6, 6)); // Panel - theme->set_stylebox("panel", "Panel", style_panel); + theme->set_stylebox("panel", "Panel", make_flat_stylebox(dark_color_1, 6, 4, 6, 4)); // Label theme->set_color("font_color", "Label", font_color); diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp index ba90beee22..fccf7c323c 100644 --- a/editor/fileserver/editor_file_server.cpp +++ b/editor/fileserver/editor_file_server.cpp @@ -34,7 +34,7 @@ #include "io/marshalls.h" //#define DEBUG_PRINT(m_p) print_line(m_p) -#define DEBUG_TIME(m_what) printf("MS: %s - %lli\n", m_what, OS::get_singleton()->get_ticks_usec()); +#define DEBUG_TIME(m_what) printf("MS: %s - %lu\n", m_what, OS::get_singleton()->get_ticks_usec()); //#define DEBUG_TIME(m_what) diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 0ad7b25e4a..a66d1724a1 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -828,7 +828,12 @@ void FileSystemDock::_move_operation(const String &p_to_path) { //make list of remaps Map<String, String> renames; String repfrom = path == "res://" ? path : String(path + "/"); - String repto = p_to_path == "res://" ? p_to_path : String(p_to_path + "/"); + String repto = p_to_path; + if (!repto.ends_with("/")) { + repto += "/"; + } + + print_line("reprfrom: " + repfrom + " repto " + repto); for (int i = 0; i < move_files.size(); i++) { renames[move_files[i]] = move_files[i].replace_first(repfrom, repto); @@ -868,6 +873,13 @@ void FileSystemDock::_move_operation(const String &p_to_path) { if (err != OK) { EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + "\n"); } + if (FileAccess::exists(move_files[i] + ".import")) { //move imported files too + //@todo should remove the files in .import folder + err = da->rename(move_files[i] + ".import", to + ".import"); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + ".import\n"); + } + } } for (int i = 0; i < move_dirs.size(); i++) { @@ -1827,7 +1839,7 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { path = "res://"; - add_constant_override("separation", 3); + add_constant_override("separation", 4); } FileSystemDock::~FileSystemDock() { diff --git a/editor/icons/icon_class_list.svg b/editor/icons/icon_class_list.svg index 1f2b37bd25..87a20743c7 100644 --- a/editor/icons/icon_class_list.svg +++ b/editor/icons/icon_class_list.svg @@ -1,11 +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)" fill="#e0e0e0"> -<rect x="1" y="1038.4" width="5" height=".99998"/> -<rect x="6" y="1037.4" width="6" height="3"/> -<rect x="3" y="1038.4" width="1" height="11"/> -<rect x="4" y="1043.4" width="5" height="1"/> -<rect x="9" y="1042.4" width="6" height="3"/> -<rect x="4" y="1048.4" width="5" height="1"/> -<rect x="9" y="1047.4" width="6" height="3"/> +<g transform="translate(0 -1036.4)"> +<path transform="translate(0 1036.4)" d="m6 1v1h-5v1h2v10h1 5v1h6v-3h-6v1h-5v-4h5v1h6v-3h-6v1h-5v-4h2v1h6v-3h-6z" fill="#e0e0e0"/> </g> </svg> diff --git a/editor/icons/icon_file_dead.svg b/editor/icons/icon_file_dead.svg new file mode 100644 index 0000000000..e0aee6fd90 --- /dev/null +++ b/editor/icons/icon_file_dead.svg @@ -0,0 +1,7 @@ +<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)"> +<g transform="translate(0 -1.6949e-5)"> +<path transform="translate(0 1036.4)" d="m2 1v14h12v-9h-5v-5zm8 0v4h4zm-6.0078 6c0.1353-0.0020779 0.26567 0.050774 0.36133 0.14648l0.64648 0.64648 0.64648-0.64648c0.09183-0.091882 0.21582-0.14442 0.3457-0.14648 0.1353-0.00208 0.26567 0.050774 0.36133 0.14648 0.19521 0.19525 0.19521 0.51178 0 0.70703l-0.64648 0.64648 0.64648 0.64648c0.19521 0.19525 0.19521 0.51178 0 0.70703-0.19525 0.19521-0.51178 0.19521-0.70703 0l-0.64648-0.64648-0.64648 0.64648c-0.19525 0.19521-0.51178 0.19521-0.70703 0-0.19521-0.19525-0.19521-0.51178 0-0.70703l0.64648-0.64648-0.64648-0.64648c-0.19521-0.19525-0.19521-0.51178 0-0.70703 0.09183-0.091882 0.21582-0.14442 0.3457-0.14648zm6 0c0.1353-0.00208 0.26567 0.050774 0.36133 0.14648l0.64648 0.64648 0.64648-0.64648c0.09183-0.091883 0.21582-0.14442 0.3457-0.14648 0.1353-0.00208 0.26567 0.050774 0.36133 0.14648 0.19521 0.19525 0.19521 0.51178 0 0.70703l-0.64648 0.64648 0.64648 0.64648c0.19521 0.19525 0.19521 0.51178 0 0.70703-0.19525 0.19521-0.51178 0.19521-0.70703 0l-0.64648-0.64648-0.64648 0.64648c-0.19525 0.19521-0.51178 0.19521-0.70703 0-0.19521-0.19525-0.19521-0.51178 0-0.70703l0.64648-0.64648-0.64648-0.64648c-0.19521-0.19525-0.19521-0.51178 0-0.70703 0.09183-0.091882 0.21582-0.14442 0.3457-0.14648zm-6.4922 4h9c0.277 0 0.5 0.223 0.5 0.5s-0.223 0.5-0.5 0.5h-4.5c0 1.1046-0.89543 2-2 2s-2-0.8954-2-2h-0.5c-0.277 0-0.5-0.223-0.5-0.5s0.223-0.5 0.5-0.5zm1.5 1c-1.9e-5 0.5523 0.44771 1 1 1s1-0.4477 1-1z" fill="#ff8484"/> +</g> +</g> +</svg> diff --git a/editor/icons/icon_filesystem.svg b/editor/icons/icon_filesystem.svg new file mode 100644 index 0000000000..41e0348d68 --- /dev/null +++ b/editor/icons/icon_filesystem.svg @@ -0,0 +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 1v5h2v8h1 5v1h6v-3h-6v1h-5v-4h5v1h6v-3h-6v1h-5v-2h3v-4h-2l-1-1h-3z" fill="#e0e0e0"/> +</g> +</svg> diff --git a/editor/icons/icon_key_call.svg b/editor/icons/icon_key_call.svg new file mode 100644 index 0000000000..7fcc65801a --- /dev/null +++ b/editor/icons/icon_key_call.svg @@ -0,0 +1,5 @@ +<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)"> +<rect transform="rotate(-45)" x="-741.53" y="741.08" width="6.1027" height="6.1027" ry=".76286" fill="#adf18f"/> +</g> +</svg> diff --git a/editor/icons/icon_mini_checkerboard.svg b/editor/icons/icon_mini_checkerboard.svg new file mode 100644 index 0000000000..e740113b2d --- /dev/null +++ b/editor/icons/icon_mini_checkerboard.svg @@ -0,0 +1,4 @@ +<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> +<path d="m0 0v8h8v-8h-8zm8 8v8h8v-8h-8z" fill="#e0e0e0" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.9994"/> +<path d="m8 0v8h8v-8h-8zm0 8h-8v8h8v-8z" fill="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.9994"/> +</svg> diff --git a/editor/icons/icon_shader_material.svg b/editor/icons/icon_shader_material.svg new file mode 100644 index 0000000000..f77aa837c5 --- /dev/null +++ b/editor/icons/icon_shader_material.svg @@ -0,0 +1,11 @@ +<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="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v1h2 6 3l-2-2h-8z" fill="#ff7070"/> +<path transform="translate(0 1036.4)" d="m1 3v2h2v-2h-2zm8 0v2h5l-2-2h-3z" fill="#ffeb70"/> +<path transform="translate(0 1036.4)" d="m1 5v2h2v-2h-2zm8 0v1c0 0.554 0.44599 1 1 1h3 2v-1l-1-1h-5z" fill="#9dff70"/> +<path transform="translate(0 1036.4)" d="m1 7v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#70ffb9"/> +<path transform="translate(0 1036.4)" d="m1 9v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#70deff"/> +<path transform="translate(0 1036.4)" d="m1 13v1c5.52e-5 0.5523 0.44774 0.9999 1 1h12c0.55226-1e-4 0.99994-0.4477 1-1v-1h-2-10-2z" fill="#ff70ac"/> +<path transform="translate(0 1036.4)" d="m1 11v2h2v-2h-2zm12 0v2h2v-2h-2z" fill="#9f70ff"/> +</g> +</svg> diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 21cf08f524..831eb74b66 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -55,8 +55,8 @@ Error EditorSceneImporterGLTF::_parse_glb(const String &p_path, GLTFState &state uint32_t magic = f->get_32(); ERR_FAIL_COND_V(magic != 0x46546C67, ERR_FILE_UNRECOGNIZED); //glTF - uint32_t version = f->get_32(); - uint32_t length = f->get_32(); + f->get_32(); // version + f->get_32(); // length uint32_t chunk_length = f->get_32(); uint32_t chunk_type = f->get_32(); @@ -1945,7 +1945,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye bool last = false; while (true) { - float value = _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation); + _interpolate_track<float>(track.weight_tracks[i].times, track.weight_tracks[i].values, time, track.weight_tracks[i].interpolation); if (last) { break; } diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 594728d2e0..cc519c1c4b 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -40,6 +40,8 @@ #include "scene/3d/portal.h" #include "scene/3d/room_instance.h" #include "scene/3d/vehicle_body.h" +#include "scene/animation/animation_player.h" +#include "scene/resources/animation.h" #include "scene/resources/box_shape.h" #include "scene/resources/plane_shape.h" #include "scene/resources/ray_shape.h" @@ -118,9 +120,13 @@ String ResourceImporterScene::get_preset_name(int p_idx) const { switch (p_idx) { case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene"); + case PRESET_SEPERATE_ANIMATIONS: return TTR("Import with Seperate Animations"); case PRESET_SEPARATE_MATERIALS: return TTR("Import with Separate Materials"); case PRESET_SEPARATE_MESHES: return TTR("Import with Separate Objects"); case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import with Separate Objects+Materials"); + case PRESET_SEPARATE_MESHES_AND_ANIMATIONS: return TTR("Import with Seperate Objects+Animations"); + case PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS: return TTR("Import with Seperate Materials+Animations"); + case PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS: return TTR("Import with Seperate Objects+Materials+Animations"); case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes"); case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials"); } @@ -230,8 +236,8 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Array if (isroot) return p_node; - - if (MeshInstance *mi = Object::cast_to<MeshInstance>(p_node)) { + MeshInstance *mi = Object::cast_to<MeshInstance>(p_node); + if (mi) { Node *col = mi->create_trimesh_collision_node(); ERR_FAIL_COND_V(!col, NULL); @@ -810,12 +816,33 @@ static String _make_extname(const String &p_str) { return ext_name; } -void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { +void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animations, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) { List<PropertyInfo> pi; print_line("node: " + String(p_node->get_name())); + if (p_make_animations) { + if (Object::cast_to<AnimationPlayer>(p_node)) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node); + + List<StringName> anims; + ap->get_animation_list(&anims); + for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { + + Ref<Animation> anim = ap->get_animation(E->get()); + ERR_CONTINUE(anim.is_null()); + + if (!p_animations.has(anim)) { + + String ext_name = p_base_path.plus_file(_make_extname(E->get()) + ".anim"); + ResourceSaver::save(ext_name, anim, ResourceSaver::FLAG_CHANGE_PATH); + p_animations[anim] = anim; + } + } + } + } + p_node->get_property_list(&pi); for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) { @@ -907,7 +934,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String for (int i = 0; i < p_node->get_child_count(); i++) { - _make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_keep_materials, p_make_meshes, p_materials, p_meshes); + _make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_make_materials, p_keep_materials, p_make_meshes, p_animations, p_materials, p_meshes); } } @@ -927,9 +954,10 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in script_ext_hint += "*." + E->get(); } - bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; - bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS; + bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS || p_preset == PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS; + bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS; bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS; + bool animations_out = p_preset == PRESET_SEPERATE_ANIMATIONS || PRESET_SEPARATE_MESHES_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS || p_preset == PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS; r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), "")); r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0)); @@ -943,6 +971,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "animation/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), animations_out ? true : false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/optimizer/enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_linear_error"), 0.05)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/optimizer/max_angular_error"), 0.01)); @@ -1024,7 +1053,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p String root_type = p_options["nodes/root_type"]; if (scene->get_class() != root_type) { - Node *base_node = base_node = Object::cast_to<Node>(ClassDB::instance(root_type)); + Node *base_node = Object::cast_to<Node>(ClassDB::instance(root_type)); if (base_node) { @@ -1078,13 +1107,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p _filter_tracks(scene, animation_filter); } + bool external_animations = int(p_options["animation/storage"]) == 1; bool external_materials = p_options["materials/storage"]; bool external_meshes = p_options["meshes/storage"]; bool external_scenes = int(p_options["nodes/storage"]) == 1; String base_path = p_source_file.get_base_dir(); - if (external_materials || external_meshes || external_scenes) { + if (external_animations || external_materials || external_meshes || external_scenes) { if (bool(p_options["external_files/store_in_subdir"])) { String subdir_name = p_source_file.get_file().get_basename(); @@ -1097,13 +1127,14 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p } } - if (external_materials || external_meshes) { + if (external_animations || external_materials || external_meshes) { + Map<Ref<Animation>, Ref<Animation> > anim_map; Map<Ref<Material>, Ref<Material> > mat_map; Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map; bool keep_materials = bool(p_options["materials/keep_on_reimport"]); - _make_external_resources(scene, base_path, external_materials, keep_materials, external_meshes, mat_map, mesh_map); + _make_external_resources(scene, base_path, external_animations, external_materials, keep_materials, external_meshes, anim_map, mat_map, mesh_map); } progress.step(TTR("Running Custom Script.."), 2); diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 9c3d5e7876..a483c3776f 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -85,8 +85,15 @@ class ResourceImporterScene : public ResourceImporter { enum Presets { PRESET_SEPARATE_MATERIALS, PRESET_SEPARATE_MESHES, + PRESET_SEPERATE_ANIMATIONS, + PRESET_SINGLE_SCENE, + PRESET_SEPARATE_MESHES_AND_MATERIALS, + PRESET_SEPARATE_MESHES_AND_ANIMATIONS, + PRESET_SEPERATE_MATERIALS_AND_ANIMATIONS, + PRESET_SEPERATE_MESHES_MATERIALS_AND_ANIMATIONS, + PRESET_MULTIPLE_SCENES, PRESET_MULTIPLE_SCENES_AND_MATERIALS, }; @@ -112,7 +119,7 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); + void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Animation>, Ref<Animation> > &p_animation, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes); Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map); diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp index ade3550daa..f29bdde634 100644 --- a/editor/import/resource_importer_texture.cpp +++ b/editor/import/resource_importer_texture.cpp @@ -33,7 +33,7 @@ #include "io/config_file.h" #include "io/image_loader.h" #include "scene/resources/texture.h" - +#include "editor/editor_node.h" void ResourceImporterTexture::_texture_reimport_srgb(const Ref<StreamTexture> &p_tex) { singleton->mutex->lock(); @@ -411,10 +411,14 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String if (compress_mode == COMPRESS_VIDEO_RAM) { //must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc). //Android, GLES 2.x + + bool ok_on_pc=false; + if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) { _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); r_platform_variants->push_back("s3tc"); + ok_on_pc=true; } if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) { @@ -434,6 +438,9 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String r_platform_variants->push_back("pvrtc"); } + if (!ok_on_pc) { + EditorNode::add_io_error("Warning, no suitable PC VRAM compression enabled in Project Settings. This texture will not display correcly on PC."); + } } else { //import normally _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal); diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index e2bacd70e4..025dbbaacf 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -103,7 +103,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s } /* GET FILESIZE */ - uint32_t filesize = file->get_32(); + file->get_32(); // filesize /* CHECK WAVE */ diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index cc7fc57cde..d7762a66df 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -55,79 +55,87 @@ void AnimationPlayerEditor::_gui_input(Ref<InputEvent> p_event) { } void AnimationPlayerEditor::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_PROCESS: { - if (p_what == NOTIFICATION_PROCESS) { - - if (!player) - return; + if (!player) + return; - updating = true; + updating = true; - if (player->is_playing()) { + if (player->is_playing()) { - { - String animname = player->get_current_animation(); + { + String animname = player->get_current_animation(); - if (player->has_animation(animname)) { - Ref<Animation> anim = player->get_animation(animname); - if (!anim.is_null()) { + if (player->has_animation(animname)) { + Ref<Animation> anim = player->get_animation(animname); + if (!anim.is_null()) { - frame->set_max(anim->get_length()); + frame->set_max(anim->get_length()); + } } } + frame->set_value(player->get_current_animation_pos()); + key_editor->set_anim_pos(player->get_current_animation_pos()); + EditorNode::get_singleton()->get_property_editor()->refresh(); + + } else if (last_active) { + //need the last frame after it stopped + + frame->set_value(player->get_current_animation_pos()); } - frame->set_value(player->get_current_animation_pos()); - key_editor->set_anim_pos(player->get_current_animation_pos()); - EditorNode::get_singleton()->get_property_editor()->refresh(); - } else if (last_active) { - //need the last frame after it stopped + last_active = player->is_playing(); + //seek->set_val(player->get_position()); + updating = false; - frame->set_value(player->get_current_animation_pos()); - } + } break; - last_active = player->is_playing(); - //seek->set_val(player->get_position()); - updating = false; - } + case NOTIFICATION_ENTER_TREE: { + + save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu"); + + tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu"); + + blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); - if (p_what == NOTIFICATION_ENTER_TREE) { - - //editor->connect("hide_animation_player_editors",this,"_hide_anim_editors"); - add_anim->set_icon(get_icon("New", "EditorIcons")); - rename_anim->set_icon(get_icon("Rename", "EditorIcons")); - duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons")); - autoplay->set_icon(get_icon("AutoPlay", "EditorIcons")); - load_anim->set_icon(get_icon("Folder", "EditorIcons")); - save_anim->set_icon(get_icon("Save", "EditorIcons")); - save_anim->get_popup()->connect("id_pressed", this, "_animation_save_menu"); - remove_anim->set_icon(get_icon("Remove", "EditorIcons")); - - blend_anim->set_icon(get_icon("Blend", "EditorIcons")); - play->set_icon(get_icon("PlayStart", "EditorIcons")); - play_from->set_icon(get_icon("Play", "EditorIcons")); - play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons")); - play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons")); - - autoplay_icon = get_icon("AutoPlay", "EditorIcons"); - stop->set_icon(get_icon("Stop", "EditorIcons")); - resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons")); - pin->set_icon(get_icon("Pin", "EditorIcons")); - tool_anim->set_icon(get_icon("Tools", "EditorIcons")); - tool_anim->get_popup()->connect("id_pressed", this, "_animation_tool_menu"); - - blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed"); - - /* - anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons")); - anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons")); - anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons")); - anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons")); - anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons")); - anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons")); -*/ - - get_tree()->connect("node_removed", this, "_node_removed"); + get_tree()->connect("node_removed", this, "_node_removed"); + + add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); + add_constant_override("separation", get_constant("separation", "VBoxContainer")); + } break; + + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + + add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); + add_constant_override("separation", get_constant("separation", "VBoxContainer")); + } break; + + case NOTIFICATION_THEME_CHANGED: { + + add_anim->set_icon(get_icon("New", "EditorIcons")); + rename_anim->set_icon(get_icon("Rename", "EditorIcons")); + duplicate_anim->set_icon(get_icon("Duplicate", "EditorIcons")); + autoplay->set_icon(get_icon("AutoPlay", "EditorIcons")); + load_anim->set_icon(get_icon("Folder", "EditorIcons")); + save_anim->set_icon(get_icon("Save", "EditorIcons")); + + remove_anim->set_icon(get_icon("Remove", "EditorIcons")); + + blend_anim->set_icon(get_icon("Blend", "EditorIcons")); + play->set_icon(get_icon("PlayStart", "EditorIcons")); + play_from->set_icon(get_icon("Play", "EditorIcons")); + play_bw->set_icon(get_icon("PlayStartBackwards", "EditorIcons")); + play_bw_from->set_icon(get_icon("PlayBackwards", "EditorIcons")); + + autoplay_icon = get_icon("AutoPlay", "EditorIcons"); + stop->set_icon(get_icon("Stop", "EditorIcons")); + resource_edit_anim->set_icon(get_icon("EditResource", "EditorIcons")); + pin->set_icon(get_icon("Pin", "EditorIcons")); + tool_anim->set_icon(get_icon("Tools", "EditorIcons")); + + } break; } } @@ -1176,7 +1184,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { set_focus_mode(FOCUS_ALL); player = NULL; - add_style_override("panel", editor->get_gui_base()->get_stylebox("panel", "Panel")); Label *l; @@ -1376,7 +1383,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) { key_editor = memnew(AnimationKeyEditor); add_child(key_editor); - add_constant_override("separation", get_constant("separation", "VBoxContainer")); key_editor->set_v_size_flags(SIZE_EXPAND_FILL); key_editor->connect("timeline_changed", this, "_animation_key_editor_seek"); key_editor->connect("animation_len_changed", this, "_animation_key_editor_anim_len_changed"); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 3b74601e78..2b2358f3d0 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -580,7 +580,8 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE } else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT - if (Node2D *node_2d = Object::cast_to<Node2D>(canvas_item)) { + Node2D *node_2d = Object::cast_to<Node2D>(canvas_item); + if (node_2d) { if (p_move_mode == MOVE_LOCAL_WITH_ROT) { Transform2D m; @@ -589,9 +590,10 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE } node_2d->set_position(node_2d->get_position() + drag); - } else if (Control *control = Object::cast_to<Control>(canvas_item)) { - - control->set_position(control->get_position() + drag); + } else { + Control *control = Object::cast_to<Control>(canvas_item); + if (control) + control->set_position(control->get_position() + drag); } } } @@ -742,7 +744,8 @@ float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_op float radius = 0.05 / zoom; float basic_anchors[3] = { 0.0, 0.5, 1.0 }; for (int i = 0; i < 3; i++) { - if ((dist = fabs(p_anchor - basic_anchors[i])) < radius) { + dist = fabs(p_anchor - basic_anchors[i]); + if (dist < radius) { if (!snapped || dist <= dist_min) { p_anchor = basic_anchors[i]; dist_min = dist; @@ -750,7 +753,8 @@ float CanvasItemEditor::_anchor_snap(float p_anchor, bool *p_snapped, float p_op } } } - if (p_opposite_anchor >= 0 && (dist = fabs(p_anchor - p_opposite_anchor)) < radius) { + dist = fabs(p_anchor - p_opposite_anchor); + if (p_opposite_anchor >= 0 && dist < radius) { if (!snapped || dist <= dist_min) { p_anchor = p_opposite_anchor; dist_min = dist; @@ -1019,6 +1023,51 @@ void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) { } } +void CanvasItemEditor::_update_cursor() { + + CursorShape c = CURSOR_ARROW; + switch (drag) { + case DRAG_NONE: + if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + c = CURSOR_DRAG; + } else { + switch (tool) { + case TOOL_MOVE: + c = CURSOR_MOVE; + break; + case TOOL_EDIT_PIVOT: + c = CURSOR_CROSS; + break; + case TOOL_PAN: + c = CURSOR_DRAG; + break; + } + } + break; + case DRAG_LEFT: + case DRAG_RIGHT: + c = CURSOR_HSIZE; + break; + case DRAG_TOP: + case DRAG_BOTTOM: + c = CURSOR_VSIZE; + break; + case DRAG_TOP_LEFT: + case DRAG_BOTTOM_RIGHT: + c = CURSOR_FDIAGSIZE; + break; + case DRAG_TOP_RIGHT: + case DRAG_BOTTOM_LEFT: + c = CURSOR_BDIAGSIZE; + break; + case DRAG_ALL: + case DRAG_NODE_2D: + c = CURSOR_MOVE; + break; + } + viewport->set_default_cursor_shape(c); +} + void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { { @@ -1457,6 +1506,7 @@ void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseMotion> m = p_event; if (m.is_valid()) { // Mouse motion event + _update_cursor(); if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) viewport->call_deferred("grab_focus"); @@ -1469,7 +1519,7 @@ void CanvasItemEditor::_viewport_gui_input(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))) { + 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))) { // Pan the viewport Point2i relative; if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) { @@ -2223,6 +2273,8 @@ void CanvasItemEditor::_notification(int p_what) { if (p_what == NOTIFICATION_FIXED_PROCESS) { + EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels")); + List<Node *> &selection = editor_selection->get_selected_node_list(); bool all_control = true; @@ -3562,29 +3614,31 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons Sprite *sprite = memnew(Sprite); sprite->set_texture(texture); sprite->set_modulate(Color(1, 1, 1, 0.7f)); - preview->add_child(sprite); + preview_node->add_child(sprite); label->show(); label_desc->show(); } else { if (scene.is_valid()) { Node *instance = scene->instance(); if (instance) { - preview->add_child(instance); + preview_node->add_child(instance); } } } - editor->get_scene_root()->add_child(preview); + editor->get_scene_root()->add_child(preview_node); } } } void CanvasItemEditorViewport::_remove_preview() { - if (preview->get_parent()) { - editor->get_scene_root()->remove_child(preview); - for (int i = preview->get_child_count() - 1; i >= 0; i--) { - Node *node = preview->get_child(i); - memdelete(node); + if (preview_node->get_parent()) { + for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { + Node *node = preview_node->get_child(i); + node->queue_delete(); + preview_node->remove_child(node); } + editor->get_scene_root()->remove_child(preview_node); + label->hide(); label_desc->hide(); } @@ -3794,11 +3848,11 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian break; } if (can_instance) { - if (!preview->get_parent()) { // create preview only once + if (!preview_node->get_parent()) { // create preview only once _create_preview(files); } Transform2D trans = canvas->get_canvas_transform(); - preview->set_position((p_point - trans.get_origin()) / trans.get_scale().x); + preview_node->set_position((p_point - trans.get_origin()) / trans.get_scale().x); label->set_text(vformat(TTR("Adding %s..."), default_type)); } return can_instance; @@ -3820,11 +3874,16 @@ void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p List<Node *> list = editor->get_editor_selection()->get_selected_node_list(); if (list.size() == 0) { - accept->get_ok()->set_text(TTR("OK :(")); - accept->set_text(TTR("No parent to instance a child at.")); - accept->popup_centered_minsize(); - _remove_preview(); - return; + Node *root_node = editor->get_edited_scene(); + if (root_node) { + list.push_back(root_node); + } else { + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } } if (list.size() != 1) { accept->get_ok()->set_text(TTR("I see..")); @@ -3891,7 +3950,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte editor = p_node; editor_data = editor->get_scene_tree_dock()->get_editor_data(); canvas = p_canvas; - preview = memnew(Node2D); + preview_node = memnew(Node2D); accept = memnew(AcceptDialog); editor->get_gui_base()->add_child(accept); @@ -3945,5 +4004,5 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte } CanvasItemEditorViewport::~CanvasItemEditorViewport() { - memdelete(preview); + memdelete(preview_node); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index da217007ea..2e1a2eac5f 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/canvas_item.h" #include "scene/gui/box_container.h" -#include "scene/gui/button_group.h" #include "scene/gui/check_box.h" #include "scene/gui/label.h" #include "scene/gui/panel_container.h" @@ -324,6 +323,7 @@ class CanvasItemEditor : public VBoxContainer { bool updating_scroll; void _update_scroll(float); void _update_scrollbars(); + void _update_cursor(); void incbeg(float &beg, float &end, float inc, float minsize, bool p_symmetric); void incend(float &beg, float &end, float inc, float minsize, bool p_symmetric); @@ -459,7 +459,7 @@ class CanvasItemEditorViewport : public Control { EditorNode *editor; EditorData *editor_data; CanvasItemEditor *canvas; - Node2D *preview; + Node2D *preview_node; AcceptDialog *accept; WindowDialog *selector; Label *selector_label; diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h index bc3c5a1659..4715abd2e6 100644 --- a/editor/plugins/collision_polygon_2d_editor_plugin.h +++ b/editor/plugins/collision_polygon_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/collision_polygon_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h index 0150d8a9d7..0f63810443 100644 --- a/editor/plugins/collision_polygon_editor_plugin.h +++ b/editor/plugins/collision_polygon_editor_plugin.h @@ -35,7 +35,6 @@ #include "scene/3d/collision_polygon.h" #include "scene/3d/immediate_geometry.h" #include "scene/3d/mesh_instance.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/cube_grid_theme_editor_plugin.cpp b/editor/plugins/cube_grid_theme_editor_plugin.cpp index 08b38c2ca2..1c17daf425 100644 --- a/editor/plugins/cube_grid_theme_editor_plugin.cpp +++ b/editor/plugins/cube_grid_theme_editor_plugin.cpp @@ -88,7 +88,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, if (mesh.is_null()) continue; - int id = p_library->find_item_name(mi->get_name()); + int id = p_library->find_item_by_name(mi->get_name()); if (id < 0) { id = p_library->get_last_unused_item_id(); @@ -111,7 +111,8 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, sb->get_shape_owners(&shapes); for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) { - if (sb->is_shape_owner_disabled(E->get())) continue; + if (sb->is_shape_owner_disabled(E->get())) + continue; //Transform shape_transform = sb->shape_owner_get_transform(E->get()); @@ -120,7 +121,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) { Ref<Shape> collision = sb->shape_owner_get_shape(E->get(), k); - if (collision.is_valid()) + if (!collision.is_valid()) continue; MeshLibrary::ShapeData shape_data; shape_data.shape = collision; diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h index 7a4f18963d..b270dcb6e5 100644 --- a/editor/plugins/light_occluder_2d_editor_plugin.h +++ b/editor/plugins/light_occluder_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/light_occluder_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h index dea77ec248..dea0433084 100644 --- a/editor/plugins/line_2d_editor_plugin.h +++ b/editor/plugins/line_2d_editor_plugin.h @@ -34,7 +34,6 @@ #include "editor/editor_plugin.h" #include "scene/2d/line_2d.h" #include "scene/2d/path_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" class CanvasItemEditor; diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h index 33f9d5c785..7dd555e9c9 100644 --- a/editor/plugins/navigation_polygon_editor_plugin.h +++ b/editor/plugins/navigation_polygon_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/navigation_polygon.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index c195845244..f0f5d4d637 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/path_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index f7008298f0..3917c700f0 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -395,7 +395,7 @@ bool Polygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { if (mm.is_valid()) { - if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) { + if (edited_point != -1 && (wip_active || (mm->get_button_mask() & BUTTON_MASK_LEFT))) { Vector2 gpoint = mm->get_position(); Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint); @@ -554,7 +554,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) { if (mm.is_valid()) { - if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { + if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) { Vector2 drag(mm->get_relative().x, mm->get_relative().y); uv_hscroll->set_value(uv_hscroll->get_value() - drag.x); diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h index 38148ca7e3..f9d6a6b4b6 100644 --- a/editor/plugins/polygon_2d_editor_plugin.h +++ b/editor/plugins/polygon_2d_editor_plugin.h @@ -33,7 +33,6 @@ #include "editor/editor_node.h" #include "editor/editor_plugin.h" #include "scene/2d/polygon_2d.h" -#include "scene/gui/button_group.h" #include "scene/gui/tool_button.h" /** diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index a529f152dc..6f03d086ca 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -972,6 +972,14 @@ void ScriptEditor::_menu_option(int p_option) { EditorNode::get_singleton()->show_warning("Can't obtain the script for running"); break; } + + current->apply_code(); + Error err = scr->reload(false); //hard reload script before running always + + if (err != OK) { + EditorNode::get_singleton()->show_warning("Script failed reloading, check console for errors."); + return; + } if (!scr->is_tool()) { EditorNode::get_singleton()->show_warning("Script is not in tool mode, will not be able to run"); @@ -1149,8 +1157,6 @@ void ScriptEditor::_notification(int p_what) { case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); - help_search->set_icon(get_icon("HelpSearch", "EditorIcons")); site_search->set_icon(get_icon("Instance", "EditorIcons")); class_search->set_icon(get_icon("ClassList", "EditorIcons")); @@ -1417,7 +1423,7 @@ void ScriptEditor::_update_script_colors() { int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size; float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4); - script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v)); + script_list->set_item_custom_fg_color(i, hot_color.linear_interpolate(cold_color, v)); } } } @@ -1539,8 +1545,14 @@ bool ScriptEditor::edit(const Ref<Script> &p_script, int p_line, int p_col, bool bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change"); + if (p_script->get_language()->overrides_external_editor()) { + Error err = p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col); + if (err != OK) + ERR_PRINT("Couldn't open script in the overridden external text editor"); + return false; + } + if ((debugger->get_dump_stack_script() != p_script || debugger->get_debug_with_external_editor()) && - p_script->get_language()->open_in_external_editor(p_script, p_line >= 0 ? p_line : 0, p_col) == OK && p_script->get_path().is_resource_file() && bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) { @@ -2210,7 +2222,6 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { members_overview->set_v_size_flags(SIZE_EXPAND_FILL); tab_container = memnew(TabContainer); - tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles")); tab_container->set_tabs_visible(false); script_split->add_child(tab_container); @@ -2405,6 +2416,9 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) { use_space_indentation = false; ScriptServer::edit_request_func = _open_script_request; + + add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptEditorPanel", "EditorStyles")); + tab_container->add_style_override("panel", editor->get_gui_base()->get_stylebox("ScriptEditor", "EditorStyles")); } ScriptEditor::~ScriptEditor() { @@ -2506,9 +2520,9 @@ 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/script_temperature_hot_color", Color(1, 0, 0, 0.3)); - EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(0, 0, 1, 0.3)); - EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(0.81, 0.81, 0.14, 0.63)); + EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ed5e5e")); + EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(1, 1, 1, 0.3)); + EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(1, 1, 1, 0.5)); 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_text_editor.cpp b/editor/plugins/script_text_editor.cpp index 33890d890d..2192d3ac49 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -75,14 +75,9 @@ void ScriptTextEditor::_load_theme_settings() { text_edit->clear_colors(); - /* color from color_theme or from editor color */ - - Color background_color = EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0)); - if (EDITOR_DEF("text_editor/theme/adapted_code_editor_background_color", false)) - background_color = get_color("dark_color_1", "Editor"); - /* keyword color */ - text_edit->add_color_override("background_color", background_color); + + text_edit->add_color_override("background_color", EDITOR_DEF("text_editor/highlighting/background_color", Color(0, 0, 0, 0))); text_edit->add_color_override("completion_background_color", EDITOR_DEF("text_editor/highlighting/completion_background_color", Color(0, 0, 0, 0))); text_edit->add_color_override("completion_selected_color", EDITOR_DEF("text_editor/highlighting/completion_selected_color", Color::html("434244"))); text_edit->add_color_override("completion_existing_color", EDITOR_DEF("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf"))); @@ -629,7 +624,7 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> } String hint; Error err = script->get_language()->complete_code(p_code, script->get_path().get_base_dir(), base, r_options, r_force, hint); - if (hint != "") { + if (err == OK && hint != "") { code_editor->get_text_edit()->set_code_hint(hint); } } diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 13b0391a87..1b02f18d85 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -164,6 +164,8 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<String> String calltip; Error err = sl.complete(p_code, ShaderTypes::get_singleton()->get_functions(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_modes(VisualServer::ShaderMode(shader->get_mode())), ShaderTypes::get_singleton()->get_types(), r_options, calltip); + if (err != OK) + ERR_PRINT("Shaderlang complete failed"); if (calltip != "") { get_text_edit()->set_code_hint(calltip); @@ -289,6 +291,8 @@ void ShaderEditor::_editor_settings_changed() { shader_editor->get_text_edit()->cursor_set_blink_speed(EditorSettings::get_singleton()->get("text_editor/cursor/caret_blink_speed")); shader_editor->get_text_edit()->add_constant_override("line_spacing", EditorSettings::get_singleton()->get("text_editor/theme/line_spacing")); shader_editor->get_text_edit()->cursor_set_block_mode(EditorSettings::get_singleton()->get("text_editor/cursor/block_caret")); + shader_editor->get_text_edit()->set_smooth_scroll_enabled(EditorSettings::get_singleton()->get("text_editor/open_scripts/smooth_scrolling")); + shader_editor->get_text_edit()->set_v_scroll_speed(EditorSettings::get_singleton()->get("text_editor/open_scripts/v_scroll_speed")); } void ShaderEditor::_bind_methods() { @@ -401,13 +405,7 @@ void ShaderEditorPlugin::edit(Object *p_object) { bool ShaderEditorPlugin::handles(Object *p_object) const { - bool handles = true; Shader *shader = Object::cast_to<Shader>(p_object); - /* - if (Object::cast_to<ShaderGraph>(shader)) // Don't handle ShaderGraph's - handles = false; - */ - return shader != NULL; } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index d9fc2f32f7..93d12fd3d2 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -35,12 +35,15 @@ #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" +#include "editor/plugins/script_editor_plugin.h" +#include "editor/script_editor_debugger.h" #include "editor/spatial_editor_gizmos.h" #include "os/keyboard.h" #include "print_string.h" #include "project_settings.h" #include "scene/3d/camera.h" #include "scene/3d/visual_instance.h" +#include "scene/resources/packed_scene.h" #include "scene/resources/surface_tool.h" #include "sort.h" @@ -73,40 +76,35 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) { } else camera->set_perspective(get_fov(), get_znear(), get_zfar()); - Transform new_transform = to_camera_transform(cursor); - Transform old_transform = camera->get_global_transform(); - Transform transform; + float inertia = EDITOR_DEF("editors/3d/orbit_inertia", 0.5); + inertia = MAX(0, inertia); + + Cursor old_camera_cursor = camera_cursor; + camera_cursor = cursor; + + camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, p_interp_delta * (1 / inertia)); + camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, p_interp_delta * (1 / inertia)); bool disable_interp = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL); - if (p_interp_delta && !disable_interp) { - //interpolate - float interp_speed = 14; //maybe should be made configuration - transform = old_transform.interpolate_with(new_transform, MIN(1.0, p_interp_delta * interp_speed)); - } else { - transform = new_transform; + if (p_interp_delta == 0 || disable_interp || is_freelook_active()) { + camera_cursor = cursor; } float tolerance = 0.0001; bool equal = true; - for (int i = 0; i < 3; i++) { - if (transform.basis[i].distance_to(old_transform.basis[i]) > tolerance) { - equal = false; - break; - } - } + if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance) + equal = false; - if (equal && transform.origin.distance_to(old_transform.origin) > tolerance) { + if (equal && old_camera_cursor.pos.distance_squared_to(camera_cursor.pos) > tolerance * tolerance) equal = false; - } - if (equal) { - transform = new_transform; - } + if (equal && Math::abs(old_camera_cursor.distance - camera_cursor.distance) > tolerance) + equal = false; + + if (!equal || p_interp_delta == 0 || is_freelook_active()) { - if (!equal || p_interp_delta == 0) { - //print_line(transform); - camera->set_global_transform(transform); + camera->set_global_transform(to_camera_transform(camera_cursor)); update_transform_gizmo_view(); } } @@ -228,7 +226,7 @@ Vector3 SpatialEditorViewport::_get_camera_normal() const { return -_get_camera_transform().basis.get_axis(2); } -Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) { +Vector3 SpatialEditorViewport::_get_ray(const Vector2 &p_pos) const { return camera->project_ray_normal(p_pos); } @@ -700,6 +698,11 @@ void SpatialEditorViewport::_smouseenter() { surface->grab_focus(); } +void SpatialEditorViewport::_smouseexit() { + + _remove_preview(); +} + void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift()); @@ -1532,6 +1535,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { Vector3 pos = camera_transform.xform(Vector3(0, 0, 0)); Vector3 diff = camera->get_translation() - pos; cursor.pos += diff; + freelook_target_position += diff; name = ""; _update_name(); @@ -1653,7 +1657,7 @@ void SpatialEditorViewport::scale_cursor_distance(real_t scale) { Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const { Point2i relative; - if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) { + if (bool(EDITOR_DEF("editors/3d/warped_mouse_panning", false))) { relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect()); } else { relative = p_ev_mouse_motion->get_relative(); @@ -1664,7 +1668,7 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous void SpatialEditorViewport::_update_freelook(real_t delta) { if (!is_freelook_active()) { - freelook_velocity = Vector3(); + freelook_target_position = cursor.pos; return; } @@ -1681,60 +1685,47 @@ void SpatialEditorViewport::_update_freelook(real_t delta) { int key_speed_modifier = Object::cast_to<InputEventKey>(ED_GET_SHORTCUT("spatial_editor/freelook_speed_modifier")->get_shortcut().ptr())->get_scancode(); Vector3 direction; - bool pressed = false; bool speed_modifier = false; const Input &input = *Input::get_singleton(); if (input.is_key_pressed(key_left)) { direction -= right; - pressed = true; } if (input.is_key_pressed(key_right)) { direction += right; - pressed = true; } if (input.is_key_pressed(key_forward)) { direction += forward; - pressed = true; } if (input.is_key_pressed(key_backwards)) { direction -= forward; - pressed = true; } if (input.is_key_pressed(key_up)) { direction += up; - pressed = true; } if (input.is_key_pressed(key_down)) { direction -= up; - pressed = true; } if (input.is_key_pressed(key_speed_modifier)) { speed_modifier = true; } - const EditorSettings &s = *EditorSettings::get_singleton(); - real_t inertia = s.get("editors/3d/freelook_inertia"); - if (inertia < 0) - inertia = 0; - - const real_t base_speed = s.get("editors/3d/freelook_base_speed"); - const real_t modifier_speed_factor = s.get("editors/3d/freelook_modifier_speed_factor"); + real_t inertia = EDITOR_DEF("editors/3d/freelook_inertia", 0.2); + inertia = MAX(0, inertia); + const real_t base_speed = EDITOR_DEF("editors/3d/freelook_base_speed", 0.5); + const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook_modifier_speed_factor", 5); real_t speed = base_speed * cursor.distance; if (speed_modifier) speed *= modifier_speed_factor; - Vector3 instant_velocity = direction * speed; - // Higher inertia should increase "lag" (lerp with factor between 0 and 1) - // Inertia of zero should produce instant movement (lerp with factor of 1) - // Takes reference of 60fps for units, so that inertia of 1 gives approximate lerp factor of 0.5 - real_t factor = 1.0 / (1.0 + inertia * delta * 60.f); - freelook_velocity = freelook_velocity.linear_interpolate(instant_velocity, CLAMP(factor, 0, 1)); + // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1. - cursor.pos += freelook_velocity * delta; + freelook_target_position += direction * speed; + real_t factor = (1.0 / (inertia + 0.001)) * delta; + cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1)); } void SpatialEditorViewport::set_message(String p_message, float p_time) { @@ -1895,6 +1886,7 @@ void SpatialEditorViewport::_notification(int p_what) { surface->connect("draw", this, "_draw"); surface->connect("gui_input", this, "_sinput"); surface->connect("mouse_entered", this, "_smouseenter"); + surface->connect("mouse_exited", this, "_smouseexit"); info->add_style_override("panel", get_stylebox("panel", "Panel")); preview_camera->set_icon(get_icon("Camera", "EditorIcons")); _init_gizmo_instance(index); @@ -2425,6 +2417,7 @@ void SpatialEditorViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("_draw"), &SpatialEditorViewport::_draw); ClassDB::bind_method(D_METHOD("_smouseenter"), &SpatialEditorViewport::_smouseenter); + ClassDB::bind_method(D_METHOD("_smouseexit"), &SpatialEditorViewport::_smouseexit); ClassDB::bind_method(D_METHOD("_sinput"), &SpatialEditorViewport::_sinput); ClassDB::bind_method(D_METHOD("_menu_option"), &SpatialEditorViewport::_menu_option); ClassDB::bind_method(D_METHOD("_toggle_camera_preview"), &SpatialEditorViewport::_toggle_camera_preview); @@ -2432,6 +2425,8 @@ void SpatialEditorViewport::_bind_methods() { ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"), &SpatialEditorViewport::update_transform_gizmo_view); ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &SpatialEditorViewport::_selection_result_pressed); ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &SpatialEditorViewport::_selection_menu_hide); + ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpatialEditorViewport::can_drop_data_fw); + ClassDB::bind_method(D_METHOD("drop_data_fw"), &SpatialEditorViewport::drop_data_fw); ADD_SIGNAL(MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport"))); } @@ -2481,6 +2476,292 @@ void SpatialEditorViewport::focus_selection() { cursor.pos = center; } +void SpatialEditorViewport::assign_pending_data_pointers(Spatial *p_preview_node, Rect3 *p_preview_bounds, AcceptDialog *p_accept) { + preview_node = p_preview_node; + preview_bounds = p_preview_bounds; + accept = p_accept; +} + +Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const { + const float MAX_DISTANCE = 10; + + Vector3 world_ray = _get_ray(p_pos); + Vector3 world_pos = _get_ray_pos(p_pos); + + Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario()); + Set<Ref<SpatialEditorGizmo> > found_gizmos; + + float closest_dist = MAX_DISTANCE; + + Vector3 point = world_pos + world_ray * MAX_DISTANCE; + Vector3 normal = Vector3(0.0, 0.0, 0.0); + + for (int i = 0; i < instances.size(); i++) { + + MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(ObjectDB::get_instance(instances[i])); + + if (!mesh_instance) + continue; + + Ref<SpatialEditorGizmo> seg = mesh_instance->get_gizmo(); + + if ((!seg.is_valid()) || found_gizmos.has(seg)) { + continue; + } + + found_gizmos.insert(seg); + + Vector3 hit_point; + Vector3 hit_normal; + bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, NULL, false); + + if (!inters) + continue; + + float dist = world_pos.distance_to(hit_point); + + if (dist < 0) + continue; + + if (dist < closest_dist) { + closest_dist = dist; + point = hit_point; + normal = hit_normal; + } + } + Vector3 center = preview_bounds->get_size() * 0.5; + return point + (center * normal); +} + +Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) { + Rect3 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(); + mesh_instance_bounds.position += mesh_instance->get_global_transform().origin - p_parent->get_global_transform().origin; + bounds.merge_with(mesh_instance_bounds); + } + bounds = _calculate_spatial_bounds(child, bounds); + } + } + return bounds; +} + +void SpatialEditorViewport::_create_preview(const Vector<String> &files) const { + for (int i = 0; i < files.size(); i++) { + String path = files[i]; + RES res = ResourceLoader::load(path); + Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); + if (scene != NULL) { + if (scene.is_valid()) { + Node *instance = scene->instance(); + if (instance) { + preview_node->add_child(instance); + } + } + editor->get_scene_root()->add_child(preview_node); + } + } + *preview_bounds = _calculate_spatial_bounds(preview_node, Rect3()); +} + +void SpatialEditorViewport::_remove_preview() { + if (preview_node->get_parent()) { + for (int i = preview_node->get_child_count() - 1; i >= 0; i--) { + Node *node = preview_node->get_child(i); + node->queue_delete(); + preview_node->remove_child(node); + } + editor->get_scene_root()->remove_child(preview_node); + } +} + +bool SpatialEditorViewport::_cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node) { + if (p_desired_node->get_filename() == p_target_scene_path) { + return true; + } + + int childCount = p_desired_node->get_child_count(); + for (int i = 0; i < childCount; i++) { + Node *child = p_desired_node->get_child(i); + if (_cyclical_dependency_exists(p_target_scene_path, child)) { + return true; + } + } + return false; +} + +bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { + Ref<PackedScene> sdata = ResourceLoader::load(path); + if (!sdata.is_valid()) { // invalid scene + return false; + } + + Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { // error on instancing + return false; + } + + if (editor->get_edited_scene()->get_filename() != "") { // cyclical instancing + if (_cyclical_dependency_exists(editor->get_edited_scene()->get_filename(), instanced_scene)) { + memdelete(instanced_scene); + return false; + } + } + + instanced_scene->set_filename(ProjectSettings::get_singleton()->localize_path(path)); + + editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene); + editor_data->get_undo_redo().add_do_method(instanced_scene, "set_owner", editor->get_edited_scene()); + editor_data->get_undo_redo().add_do_reference(instanced_scene); + editor_data->get_undo_redo().add_undo_method(parent, "remove_child", instanced_scene); + + String new_name = parent->validate_child_name(instanced_scene); + ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger(); + editor_data->get_undo_redo().add_do_method(sed, "live_debug_instance_node", editor->get_edited_scene()->get_path_to(parent), path, new_name); + editor_data->get_undo_redo().add_undo_method(sed, "live_debug_remove_node", NodePath(String(editor->get_edited_scene()->get_path_to(parent)) + "/" + new_name)); + + Transform global_transform; + Spatial *parent_spatial = Object::cast_to<Spatial>(parent); + if (parent_spatial) + global_transform = parent_spatial->get_global_transform(); + + global_transform.origin = _get_instance_position(p_point); + + editor_data->get_undo_redo().add_do_method(instanced_scene, "set_global_transform", global_transform); + + return true; +} + +void SpatialEditorViewport::_perform_drop_data() { + _remove_preview(); + + Vector<String> error_files; + + editor_data->get_undo_redo().create_action(TTR("Create Node")); + + for (int i = 0; i < selected_files.size(); i++) { + String path = selected_files[i]; + RES res = ResourceLoader::load(path); + if (res.is_null()) { + continue; + } + Ref<PackedScene> scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*res)); + if (scene != NULL) { + bool success = _create_instance(target_node, path, drop_pos); + if (!success) { + error_files.push_back(path); + } + } + } + + editor_data->get_undo_redo().commit_action(); + + if (error_files.size() > 0) { + String files_str; + for (int i = 0; i < error_files.size(); i++) { + files_str += error_files[i].get_file().get_basename() + ","; + } + files_str = files_str.substr(0, files_str.length() - 1); + accept->get_ok()->set_text(TTR("Ugh")); + accept->set_text(vformat(TTR("Error instancing scene from %s"), files_str.c_str())); + accept->popup_centered_minsize(); + } +} + +bool SpatialEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const { + + bool can_instance = false; + + if (!preview_node->is_inside_tree()) { + Dictionary d = p_data; + if (d.has("type") && (String(d["type"]) == "files")) { + Vector<String> files = d["files"]; + + List<String> scene_extensions; + ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions); + + for (int i = 0; i < files.size(); i++) { + if (scene_extensions.find(files[i].get_extension())) { + RES res = ResourceLoader::load(files[i]); + if (res.is_null()) { + continue; + } + + String type = res->get_class(); + if (type == "PackedScene") { + Ref<PackedScene> sdata = ResourceLoader::load(files[i]); + Node *instanced_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE); + if (!instanced_scene) { + continue; + } + memdelete(instanced_scene); + } + can_instance = true; + break; + } + } + if (can_instance) { + _create_preview(files); + } + } + } else { + can_instance = true; + } + + if (can_instance) { + Transform global_transform = Transform(Basis(), _get_instance_position(p_point)); + preview_node->set_global_transform(global_transform); + } + + return can_instance; +} + +void SpatialEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) { + if (!can_drop_data_fw(p_point, p_data, p_from)) + return; + + bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT); + + selected_files.clear(); + Dictionary d = p_data; + if (d.has("type") && String(d["type"]) == "files") { + selected_files = d["files"]; + } + + List<Node *> list = editor->get_editor_selection()->get_selected_node_list(); + if (list.size() == 0) { + Node *root_node = editor->get_edited_scene(); + if (root_node) { + list.push_back(root_node); + } else { + accept->get_ok()->set_text(TTR("OK :(")); + accept->set_text(TTR("No parent to instance a child at.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + } + if (list.size() != 1) { + accept->get_ok()->set_text(TTR("I see..")); + accept->set_text(TTR("This operation requires a single selected node.")); + accept->popup_centered_minsize(); + _remove_preview(); + return; + } + + target_node = list[0]; + if (is_shift && target_node != editor->get_edited_scene()) { + target_node = target_node->get_parent(); + } + drop_pos = p_point; + + _perform_drop_data(); +} + SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) { _edit.mode = TRANSFORM_NONE; @@ -2491,6 +2772,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed index = p_index; editor = p_editor; + editor_data = editor->get_scene_tree_dock()->get_editor_data(); editor_selection = editor->get_editor_selection(); undo_redo = editor->get_undo_redo(); clicked = 0; @@ -2509,6 +2791,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed c->add_child(viewport); surface = memnew(Control); + surface->set_drag_forwarding(this); add_child(surface); surface->set_area_as_parent_rect(); surface->set_clip_contents(true); @@ -2573,9 +2856,10 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed preview_camera->hide(); preview_camera->connect("toggled", this, "_toggle_camera_preview"); previewing = NULL; - preview = NULL; gizmo_scale = 1.0; + preview_node = NULL; + info = memnew(PanelContainer); info->set_self_modulate(Color(1, 1, 1, 0.4)); surface->add_child(info); @@ -2583,6 +2867,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed info->add_child(info_label); info->hide(); + accept = NULL; + freelook_active = false; selection_menu = memnew(PopupMenu); @@ -3119,13 +3405,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) { settings_znear->set_value(float(d["znear"])); if (d.has("fov")) settings_fov->set_value(float(d["fov"])); - - if (d.has("default_srgb")) { - bool use = d["default_srgb"]; - - //viewport_environment->set_enable_fx(Environment::FX_SRGB,use); - //view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB), use ); - } if (d.has("show_grid")) { bool use = d["show_grid"]; @@ -4000,6 +4279,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { vs = memnew(VSeparator); hbc_menu->add_child(vs); + // Drag and drop support; + preview_node = memnew(Spatial); + preview_bounds = Rect3(); + 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); ED_SHORTCUT("spatial_editor/rear_view", TTR("Rear View"), KEY_MASK_ALT + KEY_KP_1); @@ -4044,6 +4327,9 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { p = view_menu->get_popup(); + accept = memnew(AcceptDialog); + editor->get_gui_base()->add_child(accept); + p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT); @@ -4078,6 +4364,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { viewports[i] = memnew(SpatialEditorViewport(this, editor, i)); viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view"); + viewports[i]->assign_pending_data_pointers(preview_node, &preview_bounds, accept); viewport_base->add_child(viewports[i]); } //vbc->add_child(viewport_base); @@ -4212,6 +4499,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) { } SpatialEditor::~SpatialEditor() { + memdelete(preview_node); } void SpatialEditorPlugin::make_visible(bool p_visible) { diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 374861b5e7..5f3ef2dbee 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -106,7 +106,16 @@ private: void _menu_option(int p_option); Size2 prev_size; + Spatial *preview_node; + Rect3 *preview_bounds; + Vector<String> selected_files; + AcceptDialog *accept; + + Node *target_node; + Point2 drop_pos; + EditorNode *editor; + EditorData *editor_data; EditorSelection *editor_selection; UndoRedo *undo_redo; @@ -122,7 +131,7 @@ private: float gizmo_scale; bool freelook_active; - Vector3 freelook_velocity; + Vector3 freelook_target_position; PanelContainer *info; Label *info_label; @@ -143,7 +152,7 @@ private: ObjectID _select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle = NULL, bool p_alt_select = false); void _find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select = false); Vector3 _get_ray_pos(const Vector2 &p_pos) const; - Vector3 _get_ray(const Vector2 &p_pos); + Vector3 _get_ray(const Vector2 &p_pos) const; Point2 _point_to_screen(const Vector3 &p_point); Transform _get_camera_transform() const; int get_selected_count() const; @@ -230,7 +239,7 @@ private: distance = 4; region_select = false; } - } cursor; + } cursor, camera_cursor; void scale_cursor_distance(real_t scale); @@ -250,6 +259,7 @@ private: void _draw(); void _smouseenter(); + void _smouseexit(); void _sinput(const Ref<InputEvent> &p_event); void _update_freelook(real_t delta); SpatialEditor *spatial_editor; @@ -266,6 +276,17 @@ private: void _list_select(Ref<InputEventMouseButton> b); 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); + 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); + bool _create_instance(Node *parent, String &path, const Point2 &p_point); + void _perform_drop_data(); + + bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const; + void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from); + protected: void _notification(int p_what); static void _bind_methods(); @@ -281,6 +302,11 @@ public: void focus_selection(); + void assign_pending_data_pointers( + Spatial *p_preview_node, + Rect3 *p_preview_bounds, + AcceptDialog *p_accept); + Viewport *get_viewport_node() { return viewport; } SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index); @@ -396,6 +422,10 @@ private: Ref<SpatialMaterial> indicator_mat; Ref<SpatialMaterial> cursor_material; + // Scene drag and drop support + Spatial *preview_node; + Rect3 preview_bounds; + /* struct Selected { AABB aabb; @@ -442,6 +472,8 @@ private: MenuButton *transform_menu; MenuButton *view_menu; + AcceptDialog *accept; + ConfirmationDialog *snap_dialog; ConfirmationDialog *xform_dialog; ConfirmationDialog *settings_dialog; @@ -559,6 +591,7 @@ public: Camera *get_camera() { return NULL; } void edit(Spatial *p_spatial); void clear(); + SpatialEditor(EditorNode *p_editor); ~SpatialEditor(); }; diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index c2c26bfe6c..7b40f69082 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -244,8 +244,22 @@ void SpriteFramesEditor::_down_pressed() { void SpriteFramesEditor::_delete_pressed() { + ERR_FAIL_COND(!frames->has_animation(edited_anim)); + if (tree->get_current() < 0) return; + + int to_delete = tree->get_current(); + if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) { + return; + } + + undo_redo->create_action(TTR("Delete Resource")); + undo_redo->add_do_method(frames, "remove_frame", edited_anim, to_delete); + undo_redo->add_undo_method(frames, "add_frame", edited_anim, frames->get_frame(edited_anim, to_delete), to_delete); + undo_redo->add_do_method(this, "_update_library"); + undo_redo->add_undo_method(this, "_update_library"); + undo_redo->commit_action(); } void SpriteFramesEditor::_animation_select() { diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h index cb6f086de6..16b2da94d1 100644 --- a/editor/plugins/theme_editor_plugin.h +++ b/editor/plugins/theme_editor_plugin.h @@ -30,7 +30,6 @@ #ifndef THEME_EDITOR_PLUGIN_H #define THEME_EDITOR_PLUGIN_H -#include "scene/gui/button_group.h" #include "scene/gui/check_box.h" #include "scene/gui/file_dialog.h" #include "scene/gui/option_button.h" diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index f943ee5f6d..43856116a6 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -550,7 +550,6 @@ void TileMapEditor::_draw_fill_preview(int p_cell, const Point2i &p_point, bool PoolVector<Vector2> points = _bucket_fill(p_point, false, true); PoolVector<Vector2>::Read pr = points.read(); int len = points.size(); - int time_after = OS::get_singleton()->get_ticks_msec(); for (int i = 0; i < len; ++i) { _draw_cell(p_cell, pr[i], p_flip_h, p_flip_v, p_transpose, p_xform); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index d649afc594..7e81513a8b 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -425,9 +425,10 @@ void ProjectExportDialog::_delete_preset_confirm() { int idx = presets->get_current(); parameters->edit(NULL); //to avoid crash + _edit_preset(-1); EditorExport::get_singleton()->remove_export_preset(idx); _update_presets(); - _edit_preset(-1); + _edit_preset(presets->get_current()); } Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) { @@ -732,6 +733,8 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) { ERR_FAIL_COND(platform.is_null()); Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0); + if (err != OK) + ERR_PRINT("Failed to export project"); } void ProjectExportDialog::_bind_methods() { diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 323a36154e..b36d4715c4 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -449,13 +449,15 @@ struct ProjectItem { String conf; uint64_t last_modified; bool favorite; + bool grayed; ProjectItem() {} - ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite = false) { + ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false) { project = p_project; path = p_path; conf = p_conf; last_modified = p_last_modified; favorite = p_favorite; + grayed = p_grayed; } _FORCE_INLINE_ bool operator<(const ProjectItem &l) const { return last_modified > l.last_modified; } _FORCE_INLINE_ bool operator==(const ProjectItem &l) const { return project == l.project; } @@ -465,7 +467,7 @@ void ProjectManager::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { - Engine::get_singleton()->set_editor_hint(true); + Engine::get_singleton()->set_editor_hint(false); } else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { @@ -737,6 +739,7 @@ void ProjectManager::_load_recent_projects() { String project = _name.get_slice("/", 1); String conf = path.plus_file("project.godot"); bool favorite = (_name.begins_with("favorite_projects/")) ? true : false; + bool grayed = false; uint64_t last_modified = 0; if (FileAccess::exists(conf)) { @@ -748,16 +751,15 @@ void ProjectManager::_load_recent_projects() { if (cache_modified > last_modified) last_modified = cache_modified; } - - ProjectItem item(project, path, conf, last_modified, favorite); - if (favorite) - favorite_projects.push_back(item); - else - projects.push_back(item); } else { - //project doesn't exist on disk but it's in the XML settings file - EditorSettings::get_singleton()->erase(_name); //remove it + grayed = true; } + + ProjectItem item(project, path, conf, last_modified, favorite, grayed); + if (favorite) + favorite_projects.push_back(item); + else + projects.push_back(item); } projects.sort(); @@ -782,14 +784,14 @@ void ProjectManager::_load_recent_projects() { String path = item.path; String conf = item.conf; bool is_favorite = item.favorite; + bool is_grayed = item.grayed; Ref<ConfigFile> cf = memnew(ConfigFile); - Error err = cf->load(conf); - ERR_CONTINUE(err != OK); + Error cf_err = cf->load(conf); String project_name = TTR("Unnamed Project"); - if (cf->has_section_key("application", "config/name")) { + if (cf_err == OK && cf->has_section_key("application", "config/name")) { project_name = static_cast<String>(cf->get_value("application", "config/name")).xml_unescape(); } @@ -797,7 +799,7 @@ void ProjectManager::_load_recent_projects() { continue; Ref<Texture> icon; - if (cf->has_section_key("application", "config/icon")) { + if (cf_err == OK && cf->has_section_key("application", "config/icon")) { String appicon = cf->get_value("application", "config/icon"); if (appicon != "") { Ref<Image> img; @@ -819,8 +821,10 @@ void ProjectManager::_load_recent_projects() { } String main_scene; - if (cf->has_section_key("application", "run/main_scene")) { + if (cf_err == OK && cf->has_section_key("application", "run/main_scene")) { main_scene = cf->get_value("application", "run/main_scene"); + } else { + main_scene = ""; } selected_list_copy.erase(project); @@ -848,6 +852,8 @@ void ProjectManager::_load_recent_projects() { hb->add_child(tf); VBoxContainer *vb = memnew(VBoxContainer); + if (is_grayed) + vb->set_modulate(Color(0.5, 0.5, 0.5)); vb->set_name("project"); vb->set_h_size_flags(SIZE_EXPAND_FILL); hb->add_child(vb); @@ -926,6 +932,13 @@ void ProjectManager::_open_project_confirm() { for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) { const String &selected = E->key(); String path = EditorSettings::get_singleton()->get("projects/" + selected); + String conf = path + "/project.godot"; + if (!FileAccess::exists(conf)) { + dialog_error->set_text(TTR("Can't open project")); + dialog_error->popup_centered_minsize(); + return; + } + print_line("OPENING: " + path + " (" + selected + ")"); List<String> args; @@ -1397,6 +1410,9 @@ ProjectManager::ProjectManager() { run_error_diag = memnew(AcceptDialog); gui_base->add_child(run_error_diag); run_error_diag->set_title(TTR("Can't run project")); + + dialog_error = memnew(AcceptDialog); + gui_base->add_child(dialog_error); } ProjectManager::~ProjectManager() { diff --git a/editor/project_manager.h b/editor/project_manager.h index ecc01955ba..9fcf10a0d9 100644 --- a/editor/project_manager.h +++ b/editor/project_manager.h @@ -58,6 +58,7 @@ class ProjectManager : public Control { ConfirmationDialog *multi_run_ask; ConfirmationDialog *multi_scan_ask; AcceptDialog *run_error_diag; + AcceptDialog *dialog_error; NewProjectDialog *npdialog; ScrollContainer *scroll; VBoxContainer *scroll_childs; diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp index 2cd0221ab6..1f65589643 100644 --- a/editor/project_settings_editor.cpp +++ b/editor/project_settings_editor.cpp @@ -182,8 +182,8 @@ void ProjectSettingsEditor::_device_input_add() { Ref<InputEvent> ie; String name = add_at; int idx = edit_idx; - Variant old_val = ProjectSettings::get_singleton()->get(name); - Array arr = old_val; + Array old_val = ProjectSettings::get_singleton()->get(name); + Array arr = old_val.duplicate(); switch (add_type) { @@ -285,8 +285,8 @@ void ProjectSettingsEditor::_press_a_key_confirm() { String name = add_at; int idx = edit_idx; - Variant old_val = ProjectSettings::get_singleton()->get(name); - Array arr = old_val; + Array old_val = ProjectSettings::get_singleton()->get(name); + Array arr = old_val.duplicate(); for (int i = 0; i < arr.size(); i++) { @@ -700,6 +700,8 @@ void ProjectSettingsEditor::_update_actions() { action->set_meta("__input", ie); } } + + _action_check(action_name->get_text()); } void ProjectSettingsEditor::popup_project_settings() { @@ -809,28 +811,41 @@ void ProjectSettingsEditor::_item_del() { undo_redo->commit_action(); } -void ProjectSettingsEditor::_action_adds(String) { +void ProjectSettingsEditor::_action_check(String p_action) { - _action_add(); -} + if (p_action == "") { -void ProjectSettingsEditor::_action_add() { + action_add->set_disabled(true); + } else { - String action = action_name->get_text(); - if (action.find("/") != -1 || action.find(":") != -1 || action == "") { - message->set_text(TTR("Invalid action (anything goes but '/' or ':').")); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; + if (p_action.find("/") != -1 || p_action.find(":") != -1) { + action_add->set_text(TTR("Can't contain '/' or ':'")); + action_add->set_disabled(true); + return; + } + if (ProjectSettings::get_singleton()->has("input/" + p_action)) { + action_add->set_text(TTR("Already existing")); + action_add->set_disabled(true); + return; + } + + action_add->set_disabled(false); } - if (ProjectSettings::get_singleton()->has("input/" + action)) { - message->set_text(vformat(TTR("Action '%s' already exists!"), action)); - message->popup_centered(Size2(300, 100) * EDSCALE); - return; + action_add->set_text(TTR("Add")); +} + +void ProjectSettingsEditor::_action_adds(String) { + + if (!action_add->is_disabled()) { + _action_add(); } +} + +void ProjectSettingsEditor::_action_add() { Array va; - String name = "input/" + action; + String name = "input/" + action_name->get_text(); undo_redo->create_action(TTR("Add Input Action Event")); undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", name, va); undo_redo->add_undo_method(ProjectSettings::get_singleton(), "clear", name); @@ -854,6 +869,7 @@ void ProjectSettingsEditor::_action_add() { return; r->select(0); input_editor->ensure_cursor_is_visible(); + action_add->set_text(TTR("Add")); } void ProjectSettingsEditor::_item_checked(const String &p_item, bool p_check) { @@ -1321,6 +1337,11 @@ void ProjectSettingsEditor::set_plugins_page() { tab_container->set_current_tab(plugin_settings->get_index()); } +TabContainer *ProjectSettingsEditor::get_tabs() { + + return tab_container; +} + void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_item_selected"), &ProjectSettingsEditor::_item_selected); @@ -1331,6 +1352,7 @@ void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_save"), &ProjectSettingsEditor::_save); ClassDB::bind_method(D_METHOD("_action_add"), &ProjectSettingsEditor::_action_add); ClassDB::bind_method(D_METHOD("_action_adds"), &ProjectSettingsEditor::_action_adds); + ClassDB::bind_method(D_METHOD("_action_check"), &ProjectSettingsEditor::_action_check); ClassDB::bind_method(D_METHOD("_action_selected"), &ProjectSettingsEditor::_action_selected); ClassDB::bind_method(D_METHOD("_action_edited"), &ProjectSettingsEditor::_action_edited); ClassDB::bind_method(D_METHOD("_action_activated"), &ProjectSettingsEditor::_action_activated); @@ -1361,6 +1383,8 @@ void ProjectSettingsEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_toggle_search_bar"), &ProjectSettingsEditor::_toggle_search_bar); ClassDB::bind_method(D_METHOD("_copy_to_platform_about_to_show"), &ProjectSettingsEditor::_copy_to_platform_about_to_show); + + ClassDB::bind_method(D_METHOD("get_tabs"), &ProjectSettingsEditor::get_tabs); } ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { @@ -1475,9 +1499,8 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { get_ok()->set_text(TTR("Close")); set_hide_on_ok(true); - message = memnew(ConfirmationDialog); + message = memnew(AcceptDialog); add_child(message); - message->set_hide_on_ok(true); Control *input_base = memnew(Control); input_base->set_name(TTR("Input Map")); @@ -1493,7 +1516,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { l = memnew(Label); vbc->add_child(l); - l->set_position(Point2(6, 5) * EDSCALE); l->set_text(TTR("Action:")); hbc = memnew(HBoxContainer); @@ -1503,12 +1525,15 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) { action_name->set_h_size_flags(SIZE_EXPAND_FILL); hbc->add_child(action_name); action_name->connect("text_entered", this, "_action_adds"); + action_name->connect("text_changed", this, "_action_check"); add = memnew(Button); hbc->add_child(add); add->set_custom_minimum_size(Size2(150, 0) * EDSCALE); add->set_text(TTR("Add")); + add->set_disabled(true); add->connect("pressed", this, "_action_add"); + action_add = add; input_editor = memnew(Tree); vbc->add_child(input_editor); diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h index ceec089953..7f9b18a968 100644 --- a/editor/project_settings_editor.h +++ b/editor/project_settings_editor.h @@ -66,7 +66,7 @@ class ProjectSettingsEditor : public AcceptDialog { ToolButton *clear_button; HBoxContainer *add_prop_bar; - ConfirmationDialog *message; + AcceptDialog *message; LineEdit *category; LineEdit *property; OptionButton *type; @@ -80,6 +80,7 @@ class ProjectSettingsEditor : public AcceptDialog { MenuButton *popup_copy_to_feature; LineEdit *action_name; + Button *action_add; Tree *input_editor; bool setting; bool updating_translations; @@ -108,6 +109,7 @@ class ProjectSettingsEditor : public AcceptDialog { void _add_item(int p_item, Ref<InputEvent> p_exiting_event = NULL); void _edit_item(Ref<InputEvent> p_exiting_event); + void _action_check(String p_action); void _action_adds(String); void _action_add(); void _device_input_add(); @@ -159,6 +161,8 @@ public: void popup_project_settings(); void set_plugins_page(); + TabContainer *get_tabs(); + void queue_save(); ProjectSettingsEditor(EditorData *p_data); diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp index a42fb41ee2..c7a4e1fc3b 100644 --- a/editor/property_editor.cpp +++ b/editor/property_editor.cpp @@ -2275,19 +2275,6 @@ void PropertyEditor::_check_reload_status(const String &p_name, TreeItem *item) } } - if (_might_be_in_instance()) { - - Variant vorig; - Dictionary d = item->get_metadata(0); - int usage = d.has("usage") ? int(int(d["usage"]) & (PROPERTY_USAGE_STORE_IF_NONONE | PROPERTY_USAGE_STORE_IF_NONZERO)) : 0; - - if (_get_instanced_node_original_property(p_name, vorig) || usage) { - Variant v = obj->get(p_name); - - bool has_reload = _is_property_different(v, vorig, usage); - } - } - if (obj->call("property_can_revert", p_name).operator bool()) { has_reload = true; diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp index 6bbb35ceab..86de7c56e1 100644 --- a/editor/property_selector.cpp +++ b/editor/property_selector.cpp @@ -75,6 +75,8 @@ void PropertySelector::_update_search() { if (properties) set_title(TTR("Select Property")); + else if (virtuals_only) + set_title(TTR("Select Virtual Method")); else set_title(TTR("Select Method")); @@ -209,7 +211,7 @@ void PropertySelector::_update_search() { StringName base = base_type; while (base) { methods.push_back(MethodInfo("*" + String(base))); - ClassDB::get_method_list(base, &methods, true); + ClassDB::get_method_list(base, &methods, true, true); base = ClassDB::get_parent_class(base); } } @@ -230,11 +232,13 @@ void PropertySelector::_update_search() { Ref<Texture> icon; script_methods = false; + print_line("name: " + E->get().name); + String rep = E->get().name.replace("*", ""); if (E->get().name == "*Script Methods") { icon = get_icon("Script", "EditorIcons"); script_methods = true; - } else if (has_icon(E->get().name, "EditorIcons")) { - icon = get_icon(E->get().name, "EditorIcons"); + } else if (has_icon(rep, "EditorIcons")) { + icon = get_icon(rep, "EditorIcons"); } else { icon = get_icon("Object", "EditorIcons"); } @@ -247,6 +251,12 @@ void PropertySelector::_update_search() { if (!script_methods && name.begins_with("_") && !(E->get().flags & METHOD_FLAG_VIRTUAL)) continue; + if (virtuals_only && !(E->get().flags & METHOD_FLAG_VIRTUAL)) + continue; + + if (!virtuals_only && (E->get().flags & METHOD_FLAG_VIRTUAL)) + continue; + if (search_box->get_text() != String() && name.find(search_box->get_text()) == -1) continue; @@ -283,6 +293,12 @@ void PropertySelector::_update_search() { desc += " )"; + if (E->get().flags & METHOD_FLAG_CONST) + desc += " const"; + + if (E->get().flags & METHOD_FLAG_VIRTUAL) + desc += " virtual"; + item->set_text(0, desc); item->set_metadata(0, name); item->set_selectable(0, true); @@ -397,7 +413,7 @@ void PropertySelector::_notification(int p_what) { } } -void PropertySelector::select_method_from_base_type(const String &p_base, const String &p_current) { +void PropertySelector::select_method_from_base_type(const String &p_base, const String &p_current, bool p_virtuals_only) { base_type = p_base; selected = p_current; @@ -405,6 +421,7 @@ void PropertySelector::select_method_from_base_type(const String &p_base, const script = 0; properties = false; instance = NULL; + virtuals_only = p_virtuals_only; popup_centered_ratio(0.6); search_box->set_text(""); @@ -421,6 +438,7 @@ void PropertySelector::select_method_from_script(const Ref<Script> &p_script, co script = p_script->get_instance_id(); properties = false; instance = NULL; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -436,6 +454,7 @@ void PropertySelector::select_method_from_basic_type(Variant::Type p_type, const script = 0; properties = false; instance = NULL; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -456,6 +475,7 @@ void PropertySelector::select_method_from_instance(Object *p_instance, const Str } properties = false; instance = NULL; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -471,6 +491,7 @@ void PropertySelector::select_property_from_base_type(const String &p_base, cons script = 0; properties = true; instance = NULL; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -488,6 +509,7 @@ void PropertySelector::select_property_from_script(const Ref<Script> &p_script, script = p_script->get_instance_id(); properties = true; instance = NULL; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -503,6 +525,7 @@ void PropertySelector::select_property_from_basic_type(Variant::Type p_type, con script = 0; properties = true; instance = NULL; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -518,6 +541,7 @@ void PropertySelector::select_property_from_instance(Object *p_instance, const S script = 0; properties = true; instance = p_instance; + virtuals_only = false; popup_centered_ratio(0.6); search_box->set_text(""); @@ -554,6 +578,7 @@ PropertySelector::PropertySelector() { search_options->connect("cell_selected", this, "_item_selected"); search_options->set_hide_root(true); search_options->set_hide_folding(true); + virtuals_only = false; help_bit = memnew(EditorHelpBit); vbc->add_margin_child(TTR("Description:"), help_bit); diff --git a/editor/property_selector.h b/editor/property_selector.h index 3fa60771d7..eb745d776f 100644 --- a/editor/property_selector.h +++ b/editor/property_selector.h @@ -55,6 +55,7 @@ class PropertySelector : public ConfirmationDialog { String base_type; ObjectID script; Object *instance; + bool virtuals_only; void _item_selected(); @@ -63,7 +64,7 @@ protected: static void _bind_methods(); public: - void select_method_from_base_type(const String &p_base, const String &p_current = ""); + void select_method_from_base_type(const String &p_base, const String &p_current = "", bool p_virtuals_only = false); void select_method_from_script(const Ref<Script> &p_script, const String &p_current = ""); void select_method_from_basic_type(Variant::Type p_type, const String &p_current = ""); void select_method_from_instance(Object *p_instance, const String &p_current = ""); diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp index c71cc5af3f..b92ebed167 100644 --- a/editor/quick_open.cpp +++ b/editor/quick_open.cpp @@ -171,33 +171,50 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str Pair<String, Ref<Texture> > pair; pair.first = file; pair.second = get_icon((has_icon(efsd->get_file_type(i), ei) ? efsd->get_file_type(i) : ot), ei); + list.push_back(pair); + } + } + + if (add_directories) { + for (int i = 0; i < efsd->get_subdir_count(); i++) { - if (search_text != String() && list.size() > 0) { + _parse_fs(efsd->get_subdir(i), list); + } + } +} - float this_sim = _path_cmp(search_text, file); - float other_sim = _path_cmp(list[0].first, file); - int pos = 1; +Vector<Pair<String, Ref<Texture> > > EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture> > > &list) { - while (pos < list.size() && this_sim <= other_sim) { - other_sim = _path_cmp(list[pos++].first, file); - } + String search_text = search_box->get_text(); + Vector<Pair<String, Ref<Texture> > > sorted_list; - pos = this_sim >= other_sim ? pos - 1 : pos; - list.insert(pos, pair); + if (search_text == String() || list.size() == 0) + return sorted_list; - } else { + Vector<float> scores; + scores.resize(list.size()); + for (int i = 0; i < list.size(); i++) + scores[i] = _path_cmp(search_text, list[i].first); - list.push_back(pair); - } - } - } + while (list.size() > 0) { - if (add_directories) { - for (int i = 0; i < efsd->get_subdir_count(); i++) { + float best_score = 0.0f; + int best_idx = 0; - _parse_fs(efsd->get_subdir(i), list); + for (int i = 0; i < list.size(); i++) { + float current_score = scores[i]; + if (current_score > best_score) { + best_score = current_score; + best_idx = i; + } } + + sorted_list.push_back(list[best_idx]); + list.remove(best_idx); + scores.remove(best_idx); } + + return sorted_list; } void EditorQuickOpen::_update_search() { @@ -208,6 +225,7 @@ void EditorQuickOpen::_update_search() { Vector<Pair<String, Ref<Texture> > > list; _parse_fs(efsd, list); + list = _sort_fs(list); for (int i = 0; i < list.size(); i++) { TreeItem *ti = search_options->create_item(root); diff --git a/editor/quick_open.h b/editor/quick_open.h index 3f64dd8cf0..5b91965920 100644 --- a/editor/quick_open.h +++ b/editor/quick_open.h @@ -49,6 +49,7 @@ class EditorQuickOpen : public ConfirmationDialog { void _sbox_input(const Ref<InputEvent> &p_ie); void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture> > > &list); + Vector<Pair<String, Ref<Texture> > > _sort_fs(Vector<Pair<String, Ref<Texture> > > &list); float _path_cmp(String search, String path) const; void _confirmed(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index afdf48b314..5b783493cb 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -433,7 +433,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { dup->set_name(parent->validate_child_name(dup)); - editor_data->get_undo_redo().add_do_method(parent, "_add_child_below_node", node, dup); + editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", node, dup); for (List<Node *>::Element *F = owned.front(); F; F = F->next()) { if (!duplimap.has(F->get())) { @@ -582,13 +582,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { new_scene_from_dialog->popup_centered_ratio(); new_scene_from_dialog->set_title(TTR("Save New Scene As..")); - } break; case TOOL_COPY_NODE_PATH: { List<Node *> selection = editor_selection->get_selected_node_list(); - - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { Node *root = EditorNode::get_singleton()->get_edited_scene(); NodePath path = root->get_path().rel_path_to(node->get_path()); OS::get_singleton()->set_clipboard(path); @@ -597,8 +597,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_SCENE_EDITABLE_CHILDREN: { List<Node *> selection = editor_selection->get_selected_node_list(); - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node); int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children")); int placeholder_item_idx = menu->get_item_idx_from_text(TTR("Load As Placeholder")); @@ -617,8 +619,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_SCENE_USE_PLACEHOLDER: { List<Node *> selection = editor_selection->get_selected_node_list(); - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { bool placeholder = node->get_scene_instance_load_placeholder(); placeholder = !placeholder; int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children")); @@ -635,15 +639,16 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_SCENE_CLEAR_INSTANCING: { List<Node *> selection = editor_selection->get_selected_node_list(); - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { Node *root = EditorNode::get_singleton()->get_edited_scene(); UndoRedo *undo_redo = &editor_data->get_undo_redo(); if (!root) break; ERR_FAIL_COND(node->get_filename() == String()); - undo_redo->create_action(TTR("Discard Instancing")); undo_redo->add_do_method(node, "set_filename", ""); undo_redo->add_undo_method(node, "set_filename", node->get_filename()); @@ -656,8 +661,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_SCENE_OPEN: { List<Node *> selection = editor_selection->get_selected_node_list(); - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { scene_tree->emit_signal("open", node->get_filename()); } } @@ -667,8 +674,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_SCENE_CLEAR_INHERITANCE_CONFIRM: { List<Node *> selection = editor_selection->get_selected_node_list(); - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { node->set_scene_inherited_state(Ref<SceneState>()); scene_tree->update_tree(); EditorNode::get_singleton()->get_property_editor()->update_tree(); @@ -677,8 +686,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } break; case TOOL_SCENE_OPEN_INHERITED: { List<Node *> selection = editor_selection->get_selected_node_list(); - if (List<Node *>::Element *e = selection.front()) { - if (Node *node = e->get()) { + List<Node *>::Element *e = selection.front(); + if (e) { + Node *node = e->get(); + if (node) { if (node && node->get_scene_inherited_state().is_valid()) { scene_tree->emit_signal("open", node->get_scene_inherited_state()->get_path()); } @@ -823,7 +834,14 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node *, Node *> &duplimap) { if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) continue; String name = E->get().name; - node->set(name, p_node->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<Node::GroupInfo> group_info; diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp index 623e458aca..05e3feedb5 100644 --- a/editor/settings_config_dialog.cpp +++ b/editor/settings_config_dialog.cpp @@ -165,7 +165,7 @@ void EditorSettingsDialog::_update_shortcuts() { section->set_custom_bg_color(1, get_color("prop_subsection", "Editor")); } - if (shortcut_filter.is_subsequence_ofi(sc->get_name())) { + if (shortcut_filter.is_subsequence_ofi(sc->get_name()) || shortcut_filter.is_subsequence_ofi(sc->get_as_text())) { TreeItem *item = shortcuts->create_item(section); item->set_text(0, sc->get_name()); diff --git a/main/main.cpp b/main/main.cpp index 7b2a890a8e..1295cd73b5 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1333,6 +1333,9 @@ bool Main::start() { Viewport::Usage usage = Viewport::Usage(int(GLOBAL_GET("rendering/quality/intended_usage/framebuffer_allocation"))); sml->get_root()->set_usage(usage); + bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); + sml->get_root()->set_snap_controls_to_pixels(snap_controls); + } else { GLOBAL_DEF("display/window/stretch/mode", "disabled"); ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport")); @@ -1342,6 +1345,7 @@ bool Main::start() { ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/shrink", PropertyInfo(Variant::STRING, "display/window/stretch/shrink", PROPERTY_HINT_RANGE, "1,8,1")); sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true)); sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true)); + GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); } String local_game_path; @@ -1383,6 +1387,8 @@ bool Main::start() { if (editor) { Error serr = editor_node->load_scene(local_game_path); + if (serr != OK) + ERR_PRINT("Failed to load scene"); OS::get_singleton()->set_context(OS::CONTEXT_EDITOR); } #endif diff --git a/methods.py b/methods.py index ec7e658a3b..2ab76a5416 100644 --- a/methods.py +++ b/methods.py @@ -1026,9 +1026,6 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs): fd.write("\t\t\t{" + x["set_mask"] + "," + x["clear_mask"] + "},\n") fd.write("\t\t};\n\n") - else: - fd.write("\t\tstatic const Enum *_enums=NULL;\n") - fd.write("\t\tstatic const EnumValue *_enum_values=NULL;\n") conditionals_found = [] if (len(header_data.conditionals)): diff --git a/misc/dist/html/default.html b/misc/dist/html/default.html new file mode 100644 index 0000000000..9fae34f97e --- /dev/null +++ b/misc/dist/html/default.html @@ -0,0 +1,386 @@ +<!DOCTYPE html> +<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> +<head> + <meta charset="utf-8" /> + <title></title> + <style type="text/css"> + + body { + margin: 0; + border: 0 none; + padding: 0; + text-align: center; + background-color: #222226; + font-family: 'Noto Sans', Arial, sans-serif; + } + + + /* Godot Engine default theme style + * ================================ */ + + .godot { + color: #e0e0e0; + background-color: #3b3943; + background-image: linear-gradient(to bottom, #403e48, #35333c); + border: 1px solid #45434e; + box-shadow: 0 0 1px 1px #2f2d35; + } + + button.godot { + font-family: 'Droid Sans', Arial, sans-serif; /* override user agent style */ + padding: 1px 5px; + background-color: #37353f; + background-image: linear-gradient(to bottom, #413e49, #3a3842); + border: 1px solid #514f5d; + border-radius: 1px; + box-shadow: 0 0 1px 1px #2a2930; + } + + button.godot:hover { + color: #f0f0f0; + background-color: #44414e; + background-image: linear-gradient(to bottom, #494652, #423f4c); + border: 1px solid #5a5667; + box-shadow: 0 0 1px 1px #26252b; + } + + button.godot:active { + color: #fff; + background-color: #3e3b46; + background-image: linear-gradient(to bottom, #36343d, #413e49); + border: 1px solid #4f4c59; + box-shadow: 0 0 1px 1px #26252b; + } + + button.godot:disabled { + color: rgba(230, 230, 230, 0.2); + background-color: #3d3d3d; + background-image: linear-gradient(to bottom, #434343, #393939); + border: 1px solid #474747; + box-shadow: 0 0 1px 1px #2d2b33; + } + + + /* Canvas / wrapper + * ================ */ + + #container { + display: inline-block; /* scale with canvas */ + vertical-align: top; /* prevent extra height */ + position: relative; /* root for absolutely positioned overlay */ + margin: 0; + border: 0 none; + padding: 0; + background-color: #0c0c0c; + } + + #canvas { + display: block; + margin: 0 auto; + color: white; + } + + #canvas:focus { + outline: none; + } + + + /* Status display + * ============== */ + + #status { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; + /* don't consume click events - make children visible explicitly */ + visibility: hidden; + } + + #status-progress { + width: 244px; + height: 7px; + background-color: #38363A; + border: 1px solid #444246; + padding: 1px; + box-shadow: 0 0 2px 1px #1B1C22; + border-radius: 2px; + visibility: visible; + } + + #status-progress-inner { + height: 100%; + width: 0; + box-sizing: border-box; + transition: width 0.5s linear; + background-color: #202020; + border: 1px solid #222223; + box-shadow: 0 0 1px 1px #27282E; + border-radius: 3px; + } + + #status-indeterminate { + visibility: visible; + position: relative; + } + + #status-indeterminate > div { + width: 3px; + height: 0; + border-style: solid; + border-width: 6px 2px 0 2px; + border-color: #2b2b2b transparent transparent transparent; + transform-origin: center 14px; + position: absolute; + } + + #status-indeterminate > div:nth-child(1) { transform: rotate( 22.5deg); } + #status-indeterminate > div:nth-child(2) { transform: rotate( 67.5deg); } + #status-indeterminate > div:nth-child(3) { transform: rotate(112.5deg); } + #status-indeterminate > div:nth-child(4) { transform: rotate(157.5deg); } + #status-indeterminate > div:nth-child(5) { transform: rotate(202.5deg); } + #status-indeterminate > div:nth-child(6) { transform: rotate(247.5deg); } + #status-indeterminate > div:nth-child(7) { transform: rotate(292.5deg); } + #status-indeterminate > div:nth-child(8) { transform: rotate(337.5deg); } + + #status-notice { + margin: 0 100px; + line-height: 1.3; + visibility: visible; + padding: 4px 6px; + visibility: visible; + } + + + /* Debug output + * ============ */ + + #output-panel { + display: none; + max-width: 700px; + font-size: small; + margin: 6px auto 0; + padding: 0 4px 4px; + text-align: left; + line-height: 2.2; + } + + #output-header { + display: flex; + justify-content: space-between; + align-items: center; + } + + #output-container { + padding: 6px; + background-color: #2c2a32; + box-shadow: inset 0 0 1px 1px #232127; + color: #bbb; + } + + #output-scroll { + line-height: 1; + height: 12em; + overflow-y: scroll; + white-space: pre-wrap; + font-size: small; + font-family: "Lucida Console", Monaco, monospace; + } + </style> +$GODOT_HEAD_INCLUDE +</head> +<body> + <div id="container"> + <canvas id="canvas" oncontextmenu="event.preventDefault();" width="640" height="480"> + HTML5 canvas appears to be unsupported in the current browser.<br /> + Please try updating or use a different browser. + </canvas> + <div id="status"> + <div id='status-progress' style='display: none;' oncontextmenu="event.preventDefault();"><div id ='status-progress-inner'></div></div> + <div id='status-indeterminate' style='display: none;' oncontextmenu="event.preventDefault();"> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + <div></div> + </div> + <div id="status-notice" class="godot" style='display: none;'></div> + </div> + </div> + <div id="output-panel" class="godot"> + <div id="output-header"> + Output: + <button id='output-clear' class='godot' type='button' autocomplete='off'>Clear</button> + </div> + <div id="output-container"><div id="output-scroll"></div></div> + </div> + + <script type="text/javascript" src="$GODOT_BASENAME.js"></script> + <script type="text/javascript">//<![CDATA[ + + var game = 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; + + var container = document.getElementById('container'); + var canvas = document.getElementById('canvas'); + var statusProgress = document.getElementById('status-progress'); + var statusProgressInner = document.getElementById('status-progress-inner'); + var statusIndeterminate = document.getElementById('status-indeterminate'); + var statusNotice = document.getElementById('status-notice'); + + var initializing = true; + var statusMode = 'hidden'; + var indeterminiateStatusAnimationId = 0; + + setStatusMode('indeterminate'); + game.setCanvas(canvas); + game.setAsmjsMemorySize(MEMORY_SIZE); + + function setStatusMode(mode) { + + if (statusMode === mode || !initializing) + return; + [statusProgress, statusIndeterminate, statusNotice].forEach(elem => { + elem.style.display = 'none'; + }); + if (indeterminiateStatusAnimationId !== 0) { + cancelAnimationFrame(indeterminiateStatusAnimationId); + indeterminiateStatusAnimationId = 0; + } + switch (mode) { + case 'progress': + statusProgress.style.display = 'block'; + break; + case 'indeterminate': + statusIndeterminate.style.display = 'block'; + indeterminiateStatusAnimationId = requestAnimationFrame(animateStatusIndeterminate); + break; + case 'notice': + statusNotice.style.display = 'block'; + break; + case 'hidden': + break; + default: + throw new Error("Invalid status mode"); + } + statusMode = mode; + } + + function animateStatusIndeterminate(ms) { + var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8); + if (statusIndeterminate.children[i].style.borderTopColor == '') { + Array.prototype.slice.call(statusIndeterminate.children).forEach(child => { + child.style.borderTopColor = ''; + }); + statusIndeterminate.children[i].style.borderTopColor = '#dfdfdf'; + } + requestAnimationFrame(animateStatusIndeterminate); + } + + function setStatusNotice(text) { + + while (statusNotice.lastChild) { + statusNotice.removeChild(statusNotice.lastChild); + } + var lines = text.split('\n'); + lines.forEach((line, index) => { + statusNotice.appendChild(document.createTextNode(line)); + statusNotice.appendChild(document.createElement('br')); + }); + }; + + game.setProgressFunc((current, total) => { + + if (total > 0) { + statusProgressInner.style.width = current/total * 100 + '%'; + setStatusMode('progress'); + if (current === total) { + // wait for progress bar animation + setTimeout(() => { + setStatusMode('indeterminate'); + }, 500); + } + } else { + setStatusMode('indeterminate'); + } + }); + + if (DEBUG_ENABLED) { + var outputRoot = document.getElementById("output-panel"); + var outputScroll = document.getElementById("output-scroll"); + var OUTPUT_MSG_COUNT_MAX = 400; + + document.getElementById('output-clear').addEventListener('click', () => { + while (outputScroll.firstChild) { + outputScroll.firstChild.remove(); + } + }); + + 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(); + } + var msg = document.createElement("div"); + if (String.prototype.trim.call(text).startsWith("**ERROR**")) { + msg.style.color = "#d44"; + } else if (String.prototype.trim.call(text).startsWith("**WARNING**")) { + msg.style.color = "#ccc000"; + } else if (String.prototype.trim.call(text).startsWith("**SCRIPT ERROR**")) { + msg.style.color = "#c6d"; + } + msg.textContent = text; + var scrollToBottom = outputScroll.scrollHeight - (outputScroll.clientHeight + outputScroll.scrollTop) < 10; + outputScroll.appendChild(msg); + if (scrollToBottom) { + outputScroll.scrollTop = outputScroll.scrollHeight; + } + }; + + function printError(text) { + print('**ERROR**' + ":", text); + } + + game.setStdoutFunc(text => { + print(text); + console.log(text); + }); + + game.setStderrFunc(text => { + printError(text); + console.warn(text); + }); + } + + game.start(BASENAME + '.pck').then(() => { + setStatusMode('hidden'); + initializing = false; + }, err => { + if (DEBUG_ENABLED) + printError(err.message); + setStatusNotice(err.message); + setStatusMode('notice'); + initializing = false; + }); + })(); + //]]></script> +</body> +</html> diff --git a/misc/dist/html_fs/godotfs.js b/misc/dist/html_fs/godotfs.js deleted file mode 100644 index 676ee689fb..0000000000 --- a/misc/dist/html_fs/godotfs.js +++ /dev/null @@ -1,151 +0,0 @@ - -var Module; -if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()'); -if (!Module.expectedDataFileDownloads) { - Module.expectedDataFileDownloads = 0; - Module.finishedDataFileDownloads = 0; -} -Module.expectedDataFileDownloads++; -(function() { - - const PACK_FILE_NAME = '$GODOT_PACK_NAME'; - const PACK_FILE_SIZE = $GODOT_PACK_SIZE; - function fetchRemotePackage(packageName, callback, errback) { - var xhr = new XMLHttpRequest(); - xhr.open('GET', packageName, true); - xhr.responseType = 'arraybuffer'; - xhr.onprogress = function(event) { - var url = packageName; - if (event.loaded && event.total) { - if (!xhr.addedTotal) { - xhr.addedTotal = true; - if (!Module.dataFileDownloads) Module.dataFileDownloads = {}; - Module.dataFileDownloads[url] = { - loaded: event.loaded, - total: event.total - }; - } else { - Module.dataFileDownloads[url].loaded = event.loaded; - } - var total = 0; - var loaded = 0; - var num = 0; - for (var download in Module.dataFileDownloads) { - var data = Module.dataFileDownloads[download]; - total += data.total; - loaded += data.loaded; - num++; - } - total = Math.ceil(total * Module.expectedDataFileDownloads/num); - if (Module['setStatus']) Module['setStatus']('Downloading data... (' + loaded + '/' + total + ')'); - } else if (!Module.dataFileDownloads) { - if (Module['setStatus']) Module['setStatus']('Downloading data...'); - } - }; - xhr.onload = function(event) { - var packageData = xhr.response; - callback(packageData); - }; - xhr.send(null); - }; - - function handleError(error) { - console.error('package error:', error); - }; - - var fetched = null, fetchedCallback = null; - fetchRemotePackage(PACK_FILE_NAME, function(data) { - if (fetchedCallback) { - fetchedCallback(data); - fetchedCallback = null; - } else { - fetched = data; - } - }, handleError); - - function runWithFS() { - -function assert(check, msg) { - if (!check) throw msg + new Error().stack; -} - - function DataRequest(start, end, crunched, audio) { - this.start = start; - this.end = end; - this.crunched = crunched; - this.audio = audio; - } - DataRequest.prototype = { - requests: {}, - open: function(mode, name) { - this.name = name; - this.requests[name] = this; - Module['addRunDependency']('fp ' + this.name); - }, - send: function() {}, - onload: function() { - var byteArray = this.byteArray.subarray(this.start, this.end); - - this.finish(byteArray); - - }, - finish: function(byteArray) { - var that = this; - Module['FS_createPreloadedFile'](this.name, null, byteArray, true, true, function() { - Module['removeRunDependency']('fp ' + that.name); - }, function() { - if (that.audio) { - Module['removeRunDependency']('fp ' + that.name); // workaround for chromium bug 124926 (still no audio with this, but at least we don't hang) - } else { - Module.printErr('Preloading file ' + that.name + ' failed'); - } - }, false, true); // canOwn this data in the filesystem, it is a slide into the heap that will never change - this.requests[this.name] = null; - }, - }; - new DataRequest(0, PACK_FILE_SIZE, 0, 0).open('GET', '/' + PACK_FILE_NAME); - - var PACKAGE_PATH; - if (typeof window === 'object') { - PACKAGE_PATH = window['encodeURIComponent'](window.location.pathname.toString().substring(0, window.location.pathname.toString().lastIndexOf('/')) + '/'); - } else { - // worker - PACKAGE_PATH = encodeURIComponent(location.pathname.toString().substring(0, location.pathname.toString().lastIndexOf('/')) + '/'); - } - var PACKAGE_NAME = PACK_FILE_NAME; - var REMOTE_PACKAGE_NAME = PACK_FILE_NAME; - var PACKAGE_UUID = 'b39761ce-0348-4959-9b16-302ed8e1592e'; - - function processPackageData(arrayBuffer) { - Module.finishedDataFileDownloads++; - assert(arrayBuffer, 'Loading data file failed.'); - var byteArray = new Uint8Array(arrayBuffer); - var curr; - - // Reuse the bytearray from the XHR as the source for file reads. - DataRequest.prototype.byteArray = byteArray; - DataRequest.prototype.requests['/' + PACK_FILE_NAME].onload(); - Module['removeRunDependency']('datafile_datapack'); - - }; - Module['addRunDependency']('datafile_datapack'); - - if (!Module.preloadResults) Module.preloadResults = {}; - - Module.preloadResults[PACKAGE_NAME] = {fromCache: false}; - if (fetched) { - processPackageData(fetched); - fetched = null; - } else { - fetchedCallback = processPackageData; - } - - } - if (Module['calledRun']) { - runWithFS(); - } else { - if (!Module['preRun']) Module['preRun'] = []; - Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it - } - -})(); diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp index e86fd06d81..dc7d23bbd7 100644 --- a/modules/etc/image_etc.cpp +++ b/modules/etc/image_etc.cpp @@ -37,7 +37,6 @@ static Image::Format _get_etc2_mode(Image::DetectChannels format) { switch (format) { - case Image::DETECTED_L: case Image::DETECTED_R: return Image::FORMAT_ETC2_R11; @@ -47,7 +46,7 @@ static Image::Format _get_etc2_mode(Image::DetectChannels format) { case Image::DETECTED_RGB: return Image::FORMAT_ETC2_RGB8; - case Image::DETECTED_RGBA: + default: return Image::FORMAT_ETC2_RGBA8; // TODO: would be nice if we could use FORMAT_ETC2_RGB8A1 for FORMAT_RGBA5551 diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub index 65970d48c1..f386f2b542 100644 --- a/modules/gdnative/SCsub +++ b/modules/gdnative/SCsub @@ -2,12 +2,16 @@ Import('env') -env.add_source_files(env.modules_sources, "*.cpp") -env.add_source_files(env.modules_sources, "godot/*.cpp") +gdn_env = env.Clone() -env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN']) -env.Append(CPPPATH=['#modules/gdnative/']) +gdn_env.add_source_files(env.modules_sources, "*.cpp") +gdn_env.add_source_files(env.modules_sources, "gdnative/*.cpp") +gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp") + +gdn_env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN']) +gdn_env.Append(CPPPATH=['#modules/gdnative/include/']) if "platform" in env and env["platform"] == "x11": # there has to be a better solution? env.Append(LINKFLAGS=["-rdynamic"]) + env.use_ptrcall = True diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index ded987557c..6da538844a 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -100,6 +100,11 @@ GDNativeLibrary::~GDNativeLibrary() { void GDNativeLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_library_path", "platform", "path"), &GDNativeLibrary::set_library_path); ClassDB::bind_method(D_METHOD("get_library_path", "platform"), &GDNativeLibrary::get_library_path); + + ClassDB::bind_method(D_METHOD("is_singleton_gdnative"), &GDNativeLibrary::is_singleton_gdnative); + ClassDB::bind_method(D_METHOD("set_singleton_gdnative", "singleton"), &GDNativeLibrary::set_singleton_gdnative); + + ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "singleton_gdnative"), "set_singleton_gdnative", "is_singleton_gdnative"); } bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_value) { @@ -175,7 +180,6 @@ GDNative::GDNative() { } GDNative::~GDNative() { - // TODO(karroffel): implement ALL the things! } extern "C" void _api_anchor(); diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index dc1c3507ec..4753c7efe5 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -35,7 +35,7 @@ #include "os/thread_safe.h" #include "resource.h" -#include <godot/gdnative.h> +#include "gdnative/gdnative.h" class GDNativeLibrary : public Resource { GDCLASS(GDNativeLibrary, Resource) @@ -77,6 +77,8 @@ class GDNativeLibrary : public Resource { String library_paths[NUM_PLATFORMS]; + bool singleton_gdnative = false; + protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; @@ -92,6 +94,9 @@ public: String get_library_path(StringName p_platform) const; String get_active_library_path() const; + + _FORCE_INLINE_ bool is_singleton_gdnative() const { return singleton_gdnative; } + _FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; } }; typedef godot_variant (*native_call_cb)(void *, godot_string *, godot_array *); diff --git a/modules/gdnative/godot/array.cpp b/modules/gdnative/gdnative/array.cpp index c3fde0e954..51c023981f 100644 --- a/modules/gdnative/godot/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/array.h> +#include "gdnative/array.h" #include "core/array.h" #include "core/os/memory.h" diff --git a/modules/gdnative/godot/basis.cpp b/modules/gdnative/gdnative/basis.cpp index 1d7aa18a70..b1327cdaef 100644 --- a/modules/gdnative/godot/basis.cpp +++ b/modules/gdnative/gdnative/basis.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/basis.h> +#include "gdnative/basis.h" #include "core/math/matrix3.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/color.cpp b/modules/gdnative/gdnative/color.cpp index 3677fdc265..2a5c0887a1 100644 --- a/modules/gdnative/godot/color.cpp +++ b/modules/gdnative/gdnative/color.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/color.h> +#include "gdnative/color.h" #include "core/color.h" #include "core/variant.h" @@ -112,14 +112,14 @@ godot_string GDAPI godot_color_as_string(const godot_color *p_self) { return ret; } -godot_int GDAPI godot_color_to_32(const godot_color *p_self) { +godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self) { const Color *self = (const Color *)p_self; - return self->to_32(); + return self->to_rgba32(); } -godot_int GDAPI godot_color_to_ARGB32(const godot_color *p_self) { +godot_int GDAPI godot_color_to_argb32(const godot_color *p_self) { const Color *self = (const Color *)p_self; - return self->to_ARGB32(); + return self->to_argb32(); } godot_real GDAPI godot_color_gray(const godot_color *p_self) { diff --git a/modules/gdnative/godot/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp index 2996cc78a3..ed98cdbb00 100644 --- a/modules/gdnative/godot/dictionary.cpp +++ b/modules/gdnative/gdnative/dictionary.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/dictionary.h> +#include "gdnative/dictionary.h" #include "core/variant.h" // core/variant.h before to avoid compile errors with MSVC diff --git a/modules/gdnative/godot/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp index 7cd52da34d..cf1f6a4f16 100644 --- a/modules/gdnative/godot/gdnative.cpp +++ b/modules/gdnative/gdnative/gdnative.cpp @@ -27,11 +27,10 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/gdnative.h> +#include "gdnative/gdnative.h" #include "class_db.h" #include "error_macros.h" -#include "gdnative.h" #include "global_constants.h" #include "os/os.h" #include "project_settings.h" diff --git a/modules/gdnative/godot/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp index 2309588a81..50fade5b94 100644 --- a/modules/gdnative/godot/node_path.cpp +++ b/modules/gdnative/gdnative/node_path.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/node_path.h> +#include "gdnative/node_path.h" #include "core/node_path.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/plane.cpp b/modules/gdnative/gdnative/plane.cpp index f3d4b6971e..a5e05ffa6b 100644 --- a/modules/gdnative/godot/plane.cpp +++ b/modules/gdnative/gdnative/plane.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/plane.h> +#include "gdnative/plane.h" #include "core/math/plane.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp index 49bf851051..1393374da2 100644 --- a/modules/gdnative/godot/pool_arrays.cpp +++ b/modules/gdnative/gdnative/pool_arrays.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/pool_arrays.h> +#include "gdnative/pool_arrays.h" #include "array.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/quat.cpp b/modules/gdnative/gdnative/quat.cpp index e6bea78b60..7db7847da1 100644 --- a/modules/gdnative/godot/quat.cpp +++ b/modules/gdnative/gdnative/quat.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/quat.h> +#include "gdnative/quat.h" #include "core/math/quat.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp index 98e7855dc9..ecd8cce9ca 100644 --- a/modules/gdnative/godot/rect2.cpp +++ b/modules/gdnative/gdnative/rect2.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/rect2.h> +#include "gdnative/rect2.h" #include "core/math/math_2d.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/rect3.cpp b/modules/gdnative/gdnative/rect3.cpp index 88952ab49c..d34d964db9 100644 --- a/modules/gdnative/godot/rect3.cpp +++ b/modules/gdnative/gdnative/rect3.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/rect3.h> +#include "gdnative/rect3.h" #include "core/math/rect3.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/rid.cpp b/modules/gdnative/gdnative/rid.cpp index 51c8aaa1b3..f05c39906c 100644 --- a/modules/gdnative/godot/rid.cpp +++ b/modules/gdnative/gdnative/rid.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/rid.h> +#include "gdnative/rid.h" #include "core/resource.h" #include "core/rid.h" diff --git a/modules/gdnative/godot/string.cpp b/modules/gdnative/gdnative/string.cpp index 1282cf95e5..9b715ce36a 100644 --- a/modules/gdnative/godot/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/string.h> +#include "gdnative/string.h" #include "core/variant.h" #include "string_db.h" diff --git a/modules/gdnative/godot/transform.cpp b/modules/gdnative/gdnative/transform.cpp index a965067b77..d7a3e78d3f 100644 --- a/modules/gdnative/godot/transform.cpp +++ b/modules/gdnative/gdnative/transform.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/transform.h> +#include "gdnative/transform.h" #include "core/math/transform.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp index 9fc44ecdfa..dcb54f7a53 100644 --- a/modules/gdnative/godot/transform2d.cpp +++ b/modules/gdnative/gdnative/transform2d.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/transform2d.h> +#include "gdnative/transform2d.h" #include "core/math/math_2d.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/variant.cpp b/modules/gdnative/gdnative/variant.cpp index 582544b3a0..b61f80b1f9 100644 --- a/modules/gdnative/godot/variant.cpp +++ b/modules/gdnative/gdnative/variant.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/variant.h> +#include "gdnative/variant.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp index 78ed5f06a9..67f858997f 100644 --- a/modules/gdnative/godot/vector2.cpp +++ b/modules/gdnative/gdnative/vector2.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/vector2.h> +#include "gdnative/vector2.h" #include "core/math/math_2d.h" #include "core/variant.h" diff --git a/modules/gdnative/godot/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp index 5faeac2864..c85a3f1c08 100644 --- a/modules/gdnative/godot/vector3.cpp +++ b/modules/gdnative/gdnative/vector3.cpp @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include <godot/vector3.h> +#include "gdnative/vector3.h" #include "core/variant.h" #include "core/vector.h" diff --git a/modules/gdnative/godot/icon.png.import b/modules/gdnative/godot/icon.png.import deleted file mode 100644 index 27920124f9..0000000000 --- a/modules/gdnative/godot/icon.png.import +++ /dev/null @@ -1,23 +0,0 @@ -[remap] - -importer="texture" -type="StreamTexture" -path="res://.import/icon.png-aa47d037a37fb38b3b7e7828e4eec407.stex" - -[params] - -compress/mode=0 -compress/lossy_quality=0.7 -compress/hdr_mode=0 -compress/normal_map=0 -flags/repeat=0 -flags/filter=true -flags/mipmaps=false -flags/anisotropic=false -flags/srgb=2 -process/fix_alpha_border=true -process/premult_alpha=false -process/HDR_as_SRGB=false -stream=false -size_limit=0 -detect_3d=true diff --git a/modules/gdnative/godot/array.h b/modules/gdnative/include/gdnative/array.h index 08f73c8785..edab028cba 100644 --- a/modules/gdnative/godot/array.h +++ b/modules/gdnative/include/gdnative/array.h @@ -46,10 +46,10 @@ typedef struct { } godot_array; #endif -#include <godot/pool_arrays.h> -#include <godot/variant.h> +#include <gdnative/pool_arrays.h> +#include <gdnative/variant.h> -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> void GDAPI godot_array_new(godot_array *r_dest); void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src); diff --git a/modules/gdnative/godot/basis.h b/modules/gdnative/include/gdnative/basis.h index f36d2199de..8ff6a6f541 100644 --- a/modules/gdnative/godot/basis.h +++ b/modules/gdnative/include/gdnative/basis.h @@ -45,9 +45,9 @@ typedef struct { } godot_basis; #endif -#include <godot/gdnative.h> -#include <godot/quat.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/quat.h> +#include <gdnative/vector3.h> void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis); void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi); diff --git a/modules/gdnative/godot/color.h b/modules/gdnative/include/gdnative/color.h index 5d550e40b3..14265466b9 100644 --- a/modules/gdnative/godot/color.h +++ b/modules/gdnative/include/gdnative/color.h @@ -45,8 +45,8 @@ typedef struct { } godot_color; #endif -#include <godot/gdnative.h> -#include <godot/string.h> +#include <gdnative/gdnative.h> +#include <gdnative/string.h> void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a); void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b); @@ -69,9 +69,9 @@ godot_real godot_color_get_v(const godot_color *p_self); godot_string GDAPI godot_color_as_string(const godot_color *p_self); -godot_int GDAPI godot_color_to_32(const godot_color *p_self); +godot_int GDAPI godot_color_to_rgba32(const godot_color *p_self); -godot_int GDAPI godot_color_to_ARGB32(const godot_color *p_self); +godot_int GDAPI godot_color_to_argb32(const godot_color *p_self); godot_real GDAPI godot_color_gray(const godot_color *p_self); diff --git a/modules/gdnative/godot/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h index 10d580af08..c85c3f3830 100644 --- a/modules/gdnative/godot/dictionary.h +++ b/modules/gdnative/include/gdnative/dictionary.h @@ -45,9 +45,9 @@ typedef struct { } godot_dictionary; #endif -#include <godot/array.h> -#include <godot/gdnative.h> -#include <godot/variant.h> +#include <gdnative/array.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> void GDAPI godot_dictionary_new(godot_dictionary *r_dest); void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src); diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h index c71a7ae1ef..c574c56d5a 100644 --- a/modules/gdnative/godot/gdnative.h +++ b/modules/gdnative/include/gdnative/gdnative.h @@ -146,100 +146,74 @@ typedef float godot_real; /////// Object (forward declared) typedef void godot_object; -/////// Brute force forward declarations for the rest -/* -typedef struct godot_variant godot_variant; -typedef struct godot_string godot_string; -typedef struct godot_vector2 godot_vector2; -typedef struct godot_rect2 godot_rect2; -typedef struct godot_vector3 godot_vector3; -typedef struct godot_transform2d godot_transform2d; -typedef struct godot_plane godot_plane; -typedef struct godot_quat godot_quat; -typedef struct godot_rect3 godot_rect3; -typedef struct godot_basis godot_basis; -typedef struct godot_transform godot_transform; -typedef struct godot_color godot_color; -typedef struct godot_node_path godot_node_path; -typedef struct godot_rid godot_rid; -typedef struct godot_dictionary godot_dictionary; -typedef struct godot_array godot_array; -typedef struct godot_pool_byte_array godot_pool_byte_array; -typedef struct godot_pool_int_array godot_pool_int_array; -typedef struct godot_pool_real_array godot_pool_real_array; -typedef struct godot_pool_string_array godot_pool_string_array; -typedef struct godot_pool_vector2_array godot_pool_vector2_array; -typedef struct godot_pool_vector3_array godot_pool_vector3_array; -typedef struct godot_pool_color_array godot_pool_color_array; -*/ /////// String -#include <godot/string.h> +#include <gdnative/string.h> ////// Vector2 -#include <godot/vector2.h> +#include <gdnative/vector2.h> ////// Rect2 -#include <godot/rect2.h> +#include <gdnative/rect2.h> ////// Vector3 -#include <godot/vector3.h> +#include <gdnative/vector3.h> ////// Transform2D -#include <godot/transform2d.h> +#include <gdnative/transform2d.h> /////// Plane -#include <godot/plane.h> +#include <gdnative/plane.h> /////// Quat -#include <godot/quat.h> +#include <gdnative/quat.h> /////// Rect3 -#include <godot/rect3.h> +#include <gdnative/rect3.h> /////// Basis -#include <godot/basis.h> +#include <gdnative/basis.h> /////// Transform -#include <godot/transform.h> +#include <gdnative/transform.h> /////// Color -#include <godot/color.h> +#include <gdnative/color.h> /////// NodePath -#include <godot/node_path.h> +#include <gdnative/node_path.h> /////// RID -#include <godot/rid.h> +#include <gdnative/rid.h> /////// Dictionary -#include <godot/dictionary.h> +#include <gdnative/dictionary.h> /////// Array -#include <godot/array.h> +#include <gdnative/array.h> // single API file for Pool*Array -#include <godot/pool_arrays.h> +#include <gdnative/pool_arrays.h> void GDAPI godot_object_destroy(godot_object *p_o); ////// Variant -#include <godot/variant.h> +#include <gdnative/variant.h> ////// Singleton API diff --git a/modules/gdnative/godot/node_path.h b/modules/gdnative/include/gdnative/node_path.h index 2f71ddd59d..0cfdbc1127 100644 --- a/modules/gdnative/godot/node_path.h +++ b/modules/gdnative/include/gdnative/node_path.h @@ -45,8 +45,8 @@ typedef struct { } godot_node_path; #endif -#include <godot/gdnative.h> -#include <godot/string.h> +#include <gdnative/gdnative.h> +#include <gdnative/string.h> void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from); void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src); diff --git a/modules/gdnative/godot/plane.h b/modules/gdnative/include/gdnative/plane.h index 27548c8b0c..6a8915e08b 100644 --- a/modules/gdnative/godot/plane.h +++ b/modules/gdnative/include/gdnative/plane.h @@ -45,8 +45,8 @@ typedef struct { } godot_plane; #endif -#include <godot/gdnative.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/vector3.h> void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d); void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3); diff --git a/modules/gdnative/godot/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h index 1b51dca38c..cb1095ee8c 100644 --- a/modules/gdnative/godot/pool_arrays.h +++ b/modules/gdnative/include/gdnative/pool_arrays.h @@ -113,12 +113,12 @@ typedef struct { } godot_pool_color_array; #endif -#include <godot/array.h> -#include <godot/color.h> -#include <godot/vector2.h> -#include <godot/vector3.h> +#include <gdnative/array.h> +#include <gdnative/color.h> +#include <gdnative/vector2.h> +#include <gdnative/vector3.h> -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> // byte diff --git a/modules/gdnative/godot/quat.h b/modules/gdnative/include/gdnative/quat.h index 9a3238a337..4ffb96eb26 100644 --- a/modules/gdnative/godot/quat.h +++ b/modules/gdnative/include/gdnative/quat.h @@ -45,8 +45,8 @@ typedef struct { } godot_quat; #endif -#include <godot/gdnative.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/vector3.h> void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w); void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle); diff --git a/modules/gdnative/godot/rect2.h b/modules/gdnative/include/gdnative/rect2.h index 8ceeddf1b4..9e6cf60342 100644 --- a/modules/gdnative/godot/rect2.h +++ b/modules/gdnative/include/gdnative/rect2.h @@ -43,8 +43,8 @@ typedef struct godot_rect2 { } godot_rect2; #endif -#include <godot/gdnative.h> -#include <godot/vector2.h> +#include <gdnative/gdnative.h> +#include <gdnative/vector2.h> void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size); void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height); diff --git a/modules/gdnative/godot/rect3.h b/modules/gdnative/include/gdnative/rect3.h index ca96aadd5c..f94b6fea25 100644 --- a/modules/gdnative/godot/rect3.h +++ b/modules/gdnative/include/gdnative/rect3.h @@ -45,9 +45,9 @@ typedef struct { } godot_rect3; #endif -#include <godot/gdnative.h> -#include <godot/plane.h> -#include <godot/vector3.h> +#include <gdnative/gdnative.h> +#include <gdnative/plane.h> +#include <gdnative/vector3.h> void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size); diff --git a/modules/gdnative/godot/rid.h b/modules/gdnative/include/gdnative/rid.h index c56ff38735..d9b5336fc9 100644 --- a/modules/gdnative/godot/rid.h +++ b/modules/gdnative/include/gdnative/rid.h @@ -45,7 +45,7 @@ typedef struct { } godot_rid; #endif -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> void GDAPI godot_rid_new(godot_rid *r_dest); diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/include/gdnative/string.h index 128448e64e..aca23a81d8 100644 --- a/modules/gdnative/godot/string.h +++ b/modules/gdnative/include/gdnative/string.h @@ -46,8 +46,8 @@ typedef struct { } godot_string; #endif -#include <godot/gdnative.h> -#include <godot/variant.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> void GDAPI godot_string_new(godot_string *r_dest); void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src); diff --git a/modules/gdnative/godot/transform.h b/modules/gdnative/include/gdnative/transform.h index 60788e3d57..656afae129 100644 --- a/modules/gdnative/godot/transform.h +++ b/modules/gdnative/include/gdnative/transform.h @@ -45,10 +45,10 @@ typedef struct { } godot_transform; #endif -#include <godot/basis.h> -#include <godot/gdnative.h> -#include <godot/variant.h> -#include <godot/vector3.h> +#include <gdnative/basis.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> +#include <gdnative/vector3.h> void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin); void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin); diff --git a/modules/gdnative/godot/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h index c0f5725eed..a945868b17 100644 --- a/modules/gdnative/godot/transform2d.h +++ b/modules/gdnative/include/gdnative/transform2d.h @@ -45,9 +45,9 @@ typedef struct { } godot_transform2d; #endif -#include <godot/gdnative.h> -#include <godot/variant.h> -#include <godot/vector2.h> +#include <gdnative/gdnative.h> +#include <gdnative/variant.h> +#include <gdnative/vector2.h> void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos); void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin); diff --git a/modules/gdnative/godot/variant.h b/modules/gdnative/include/gdnative/variant.h index 849ba8bda6..969506585d 100644 --- a/modules/gdnative/godot/variant.h +++ b/modules/gdnative/include/gdnative/variant.h @@ -99,25 +99,25 @@ typedef struct godot_variant_call_error { godot_variant_type expected; } godot_variant_call_error; -#include <godot/array.h> -#include <godot/basis.h> -#include <godot/color.h> -#include <godot/dictionary.h> -#include <godot/node_path.h> -#include <godot/plane.h> -#include <godot/pool_arrays.h> -#include <godot/quat.h> -#include <godot/rect2.h> -#include <godot/rect3.h> -#include <godot/rid.h> -#include <godot/string.h> -#include <godot/transform.h> -#include <godot/transform2d.h> -#include <godot/variant.h> -#include <godot/vector2.h> -#include <godot/vector3.h> - -#include <godot/gdnative.h> +#include <gdnative/array.h> +#include <gdnative/basis.h> +#include <gdnative/color.h> +#include <gdnative/dictionary.h> +#include <gdnative/node_path.h> +#include <gdnative/plane.h> +#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> +#include <gdnative/transform2d.h> +#include <gdnative/variant.h> +#include <gdnative/vector2.h> +#include <gdnative/vector3.h> + +#include <gdnative/gdnative.h> godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v); diff --git a/modules/gdnative/godot/vector2.h b/modules/gdnative/include/gdnative/vector2.h index 98e9700e32..0af4abae27 100644 --- a/modules/gdnative/godot/vector2.h +++ b/modules/gdnative/include/gdnative/vector2.h @@ -45,7 +45,7 @@ typedef struct { } godot_vector2; #endif -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y); diff --git a/modules/gdnative/godot/vector3.h b/modules/gdnative/include/gdnative/vector3.h index b76ca11a9c..a27d516ec5 100644 --- a/modules/gdnative/godot/vector3.h +++ b/modules/gdnative/include/gdnative/vector3.h @@ -45,8 +45,8 @@ typedef struct { } godot_vector3; #endif -#include <godot/basis.h> -#include <godot/gdnative.h> +#include <gdnative/basis.h> +#include <gdnative/gdnative.h> typedef enum { GODOT_VECTOR3_AXIS_X, diff --git a/modules/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h index d1cbf221ec..96f213ead7 100644 --- a/modules/nativescript/godot_nativescript.h +++ b/modules/gdnative/include/nativescript/godot_nativescript.h @@ -30,7 +30,7 @@ #ifndef GODOT_NATIVESCRIPT_H #define GODOT_NATIVESCRIPT_H -#include <godot/gdnative.h> +#include <gdnative/gdnative.h> #ifdef __cplusplus extern "C" { diff --git a/modules/nativescript/SCsub b/modules/gdnative/nativescript/SCsub index e980e40e8e..e980e40e8e 100644 --- a/modules/nativescript/SCsub +++ b/modules/gdnative/nativescript/SCsub diff --git a/modules/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp index fdd5a2ea19..fdd5a2ea19 100644 --- a/modules/nativescript/api_generator.cpp +++ b/modules/gdnative/nativescript/api_generator.cpp diff --git a/modules/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h index 56c2d786e6..56c2d786e6 100644 --- a/modules/nativescript/api_generator.h +++ b/modules/gdnative/nativescript/api_generator.h diff --git a/modules/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp index 926b3261b2..61ac13b796 100644 --- a/modules/nativescript/godot_nativescript.cpp +++ b/modules/gdnative/nativescript/godot_nativescript.cpp @@ -27,17 +27,17 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "godot_nativescript.h" - -#include "nativescript.h" +#include "nativescript/godot_nativescript.h" #include "class_db.h" #include "error_macros.h" -#include "gdnative.h" +#include "gdnative/gdnative.h" #include "global_constants.h" #include "project_settings.h" #include "variant.h" +#include "nativescript.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/modules/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp index e141080687..b9bd65af53 100644 --- a/modules/nativescript/nativescript.cpp +++ b/modules/gdnative/nativescript/nativescript.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "nativescript.h" -#include "modules/gdnative/godot/gdnative.h" +#include "gdnative/gdnative.h" #include "global_constants.h" #include "io/file_access_encrypted.h" @@ -315,7 +315,7 @@ void NativeScript::get_script_signal_list(List<MethodInfo> *r_signals) const { bool NativeScript::get_property_default_value(const StringName &p_property, Variant &r_value) const { NativeScriptDesc *script_data = get_script_desc(); - Map<StringName, NativeScriptDesc::Property>::Element *P = NULL; + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P; while (!P && script_data) { P = script_data->properties.find(p_property); script_data = script_data->base_data; @@ -323,7 +323,7 @@ bool NativeScript::get_property_default_value(const StringName &p_property, Vari if (!P) return false; - r_value = P->get().default_value; + r_value = P.get().default_value; return true; } @@ -355,23 +355,20 @@ void NativeScript::get_script_method_list(List<MethodInfo> *p_list) const { void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const { NativeScriptDesc *script_data = get_script_desc(); - if (!script_data) - return; - - Set<PropertyInfo> properties; - + Set<StringName> existing_properties; while (script_data) { - - for (Map<StringName, NativeScriptDesc::Property>::Element *E = script_data->properties.front(); E; E = E->next()) { - properties.insert(E->get().info); + List<PropertyInfo>::Element *insert_position = p_list->front(); + bool insert_before = true; + + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) { + if (!existing_properties.has(E.key())) { + insert_position = insert_before ? p_list->insert_before(insert_position, E.get().info) : p_list->insert_after(insert_position, E.get().info); + insert_before = false; + existing_properties.insert(E.key()); + } } - script_data = script_data->base_data; } - - for (Set<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) { - p_list->push_back(E->get()); - } } Variant NativeScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { @@ -461,10 +458,10 @@ bool NativeScriptInstance::set(const StringName &p_name, const Variant &p_value) NativeScriptDesc *script_data = GET_SCRIPT_DESC(); while (script_data) { - Map<StringName, NativeScriptDesc::Property>::Element *P = script_data->properties.find(p_name); + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = script_data->properties.find(p_name); if (P) { - P->get().setter.set_func((godot_object *)owner, - P->get().setter.method_data, + P.get().setter.set_func((godot_object *)owner, + P.get().setter.method_data, userdata, (godot_variant *)&p_value); return true; @@ -491,11 +488,11 @@ bool NativeScriptInstance::get(const StringName &p_name, Variant &r_ret) const { NativeScriptDesc *script_data = GET_SCRIPT_DESC(); while (script_data) { - Map<StringName, NativeScriptDesc::Property>::Element *P = script_data->properties.find(p_name); + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = script_data->properties.find(p_name); if (P) { godot_variant value; - value = P->get().getter.get_func((godot_object *)owner, - P->get().getter.method_data, + value = P.get().getter.get_func((godot_object *)owner, + P.get().getter.method_data, userdata); r_ret = *(Variant *)&value; godot_variant_destroy(&value); @@ -592,10 +589,10 @@ Variant::Type NativeScriptInstance::get_property_type(const StringName &p_name, while (script_data) { - Map<StringName, NativeScriptDesc::Property>::Element *P = script_data->properties.find(p_name); + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = script_data->properties.find(p_name); if (P) { *r_is_valid = true; - return P->get().info.type; + return P.get().info.type; } script_data = script_data->base_data; @@ -706,9 +703,9 @@ NativeScriptInstance::RPCMode NativeScriptInstance::get_rset_mode(const StringNa while (script_data) { - Map<StringName, NativeScriptDesc::Property>::Element *E = script_data->properties.find(p_variable); + OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable); if (E) { - switch (E->get().rset_mode) { + switch (E.get().rset_mode) { case GODOT_METHOD_RPC_MODE_DISABLED: return RPC_MODE_DISABLED; case GODOT_METHOD_RPC_MODE_REMOTE: @@ -796,12 +793,12 @@ void NativeScriptLanguage::_unload_stuff() { for (Map<StringName, NativeScriptDesc>::Element *C = L->get().front(); C; C = C->next()) { // free property stuff first - for (Map<StringName, NativeScriptDesc::Property>::Element *P = C->get().properties.front(); P; P = P->next()) { - if (P->get().getter.free_func) - P->get().getter.free_func(P->get().getter.method_data); + for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C->get().properties.front(); P; P = P.next()) { + if (P.get().getter.free_func) + P.get().getter.free_func(P.get().getter.method_data); - if (P->get().setter.free_func) - P->get().setter.free_func(P->get().setter.method_data); + if (P.get().setter.free_func) + P.get().setter.free_func(P.get().setter.method_data); } // free method stuff diff --git a/modules/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h index 571a3c9cc7..bc7e850d3e 100644 --- a/modules/nativescript/nativescript.h +++ b/modules/gdnative/nativescript/nativescript.h @@ -32,14 +32,15 @@ #include "io/resource_loader.h" #include "io/resource_saver.h" +#include "ordered_hash_map.h" #include "os/thread_safe.h" #include "resource.h" #include "scene/main/node.h" #include "script_language.h" #include "self_list.h" -#include "godot_nativescript.h" #include "modules/gdnative/gdnative.h" +#include <nativescript/godot_nativescript.h> #ifndef NO_THREADS #include "os/mutex.h" @@ -65,7 +66,7 @@ struct NativeScriptDesc { }; Map<StringName, Method> methods; - Map<StringName, Property> properties; + OrderedHashMap<StringName, Property> properties; Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals StringName base; StringName base_native_type; diff --git a/modules/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp index b846710ab8..b846710ab8 100644 --- a/modules/nativescript/register_types.cpp +++ b/modules/gdnative/nativescript/register_types.cpp diff --git a/modules/nativescript/register_types.h b/modules/gdnative/nativescript/register_types.h index 7ac558f68f..7ac558f68f 100644 --- a/modules/nativescript/register_types.h +++ b/modules/gdnative/nativescript/register_types.h diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 9ad05b7194..559e9fa455 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -28,12 +28,99 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "register_types.h" +#include "gdnative/gdnative.h" + #include "gdnative.h" #include "io/resource_loader.h" #include "io/resource_saver.h" +#include "nativescript/register_types.h" + +#include "core/engine.h" #include "core/os/os.h" +#include "core/project_settings.h" + +#ifdef TOOLS_ENABLED +#include "editor/editor_node.h" + +// Class used to discover singleton gdnative files + +void actual_discoverer_handler(); + +class GDNativeSingletonDiscover : public Object { + // GDCLASS(GDNativeSingletonDiscover, Object) + + virtual String get_class() const { + // okay, this is a really dirty hack. + // We're overriding get_class so we can connect it to a signal + // This works because get_class is a virtual method, so we don't + // need to register a new class to ClassDB just for this one + // little signal. + + actual_discoverer_handler(); + + return "Object"; + } +}; + +Set<String> get_gdnative_singletons(EditorFileSystemDirectory *p_dir) { + + Set<String> file_paths; + + // check children + + for (int i = 0; i < p_dir->get_file_count(); i++) { + String file_name = p_dir->get_file(i); + String file_type = p_dir->get_file_type(i); + + if (file_type != "GDNativeLibrary") { + continue; + } + + Ref<GDNativeLibrary> lib = ResourceLoader::load(p_dir->get_file_path(i)); + if (lib.is_valid() && lib->is_singleton_gdnative()) { + file_paths.insert(p_dir->get_file_path(i)); + } + } + + // check subdirectories + for (int i = 0; i < p_dir->get_subdir_count(); i++) { + Set<String> paths = get_gdnative_singletons(p_dir->get_subdir(i)); + + for (Set<String>::Element *E = paths.front(); E; E = E->next()) { + file_paths.insert(E->get()); + } + } + + return file_paths; +} + +void actual_discoverer_handler() { + EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->get_filesystem(); + + Set<String> file_paths = get_gdnative_singletons(dir); + + Array files; + files.resize(file_paths.size()); + int i = 0; + for (Set<String>::Element *E = file_paths.front(); E; i++, E = E->next()) { + files.set(i, E->get()); + } + + ProjectSettings::get_singleton()->set("gdnative/singletons", files); + + ProjectSettings::get_singleton()->save(); +} + +GDNativeSingletonDiscover *discoverer = NULL; + +void discoverer_callback() { + discoverer = memnew(GDNativeSingletonDiscover); + EditorFileSystem::get_singleton()->connect("filesystem_changed", discoverer, "get_class"); +} + +#endif godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot_array *p_args) { if (handle == NULL) { @@ -62,21 +149,110 @@ godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot return proc(NULL, p_args); } +void cb_singleton_call( + void *p_handle, + godot_string *p_proc_name, + void *p_data, + int p_num_args, + void **p_args, + void *r_return) { + if (p_handle == NULL) { + ERR_PRINT("No valid library handle, can't call singleton procedure"); + return; + } + + void *singleton_proc; + Error err = OS::get_singleton()->get_dynamic_library_symbol_handle( + p_handle, + *(String *)p_proc_name, + singleton_proc); + + if (err != OK) { + return; + } + + void (*singleton_procedure_ptr)() = (void (*)())singleton_proc; + singleton_procedure_ptr(); +} + GDNativeCallRegistry *GDNativeCallRegistry::singleton; +Vector<Ref<GDNative> > singleton_gdnatives; + void register_gdnative_types() { +#ifdef TOOLS_ENABLED + + if (Engine::get_singleton()->is_editor_hint()) { + EditorNode::add_init_callback(discoverer_callback); + } +#endif + ClassDB::register_class<GDNativeLibrary>(); ClassDB::register_class<GDNative>(); GDNativeCallRegistry::singleton = memnew(GDNativeCallRegistry); GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall); + + GDNativeCallRegistry::singleton->register_native_raw_call_type("gdnative_singleton_call", cb_singleton_call); + + register_nativescript_types(); + + // run singletons + + Array singletons = ProjectSettings::get_singleton()->get("gdnative/singletons"); + + singleton_gdnatives.resize(singletons.size()); + + for (int i = 0; i < singletons.size(); i++) { + String path = singletons[i]; + + Ref<GDNativeLibrary> lib = ResourceLoader::load(path); + + singleton_gdnatives[i].instance(); + singleton_gdnatives[i]->set_library(lib); + + if (!singleton_gdnatives[i]->initialize()) { + // Can't initialize. Don't make a native_call then + continue; + } + + singleton_gdnatives[i]->call_native_raw( + "gdnative_singleton_call", + "godot_gdnative_singleton", + NULL, + 0, + NULL, + NULL); + } } void unregister_gdnative_types() { + + for (int i = 0; i < singleton_gdnatives.size(); i++) { + + if (singleton_gdnatives[i].is_null()) { + continue; + } + + if (!singleton_gdnatives[i]->is_initialized()) { + continue; + } + + singleton_gdnatives[i]->terminate(); + } + + unregister_nativescript_types(); + memdelete(GDNativeCallRegistry::singleton); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint() && discoverer != NULL) { + memdelete(discoverer); + } +#endif + // This is for printing out the sizes of the core types /* diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index 70e7da5748..bc51b84047 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -866,7 +866,7 @@ static bool _guess_expression_type(GDCompletionContext &context, const GDParser: MethodBind *mb = ClassDB::get_method(base_type, getter); if (mb) { PropertyInfo rt = mb->get_return_info(); - if (rt.usage & PROPERTY_USAGE_CLASS_IS_ENUM && t == Variant::INT) { + if ((rt.usage & PROPERTY_USAGE_CLASS_IS_ENUM) && t == Variant::INT) { r_type.enumeration = rt.class_name; } else if (t == Variant::OBJECT) { @@ -1903,11 +1903,11 @@ static void _find_call_arguments(GDCompletionContext &context, const GDParser::N arghint += ", "; else arghint += " "; - if (i == p_argidx || (mi.flags & METHOD_FLAG_VARARG && i > p_argidx)) { + if (i == p_argidx || ((mi.flags & METHOD_FLAG_VARARG) && i > p_argidx)) { arghint += String::chr(0xFFFF); } arghint += _get_visual_datatype(mi.arguments[i]) + " " + mi.arguments[i].name; - if (i == p_argidx || (mi.flags & METHOD_FLAG_VARARG && i > p_argidx)) { + if (i == p_argidx || ((mi.flags & METHOD_FLAG_VARARG) && i > p_argidx)) { arghint += String::chr(0xFFFF); } } diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index f0cfdd6258..34d01c6beb 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -1177,20 +1177,28 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, VALIDATE_ARG_COUNT(1); switch (p_args[0]->get_type()) { + case Variant::STRING: { + + String d = *p_args[0]; + r_ret = d.length(); + } break; case Variant::DICTIONARY: { + Dictionary d = *p_args[0]; r_ret = d.size(); } break; case Variant::ARRAY: { + Array d = *p_args[0]; r_ret = d.size(); } break; case Variant::POOL_BYTE_ARRAY: { + PoolVector<uint8_t> d = *p_args[0]; r_ret = d.size(); - } break; case Variant::POOL_INT_ARRAY: { + PoolVector<int> d = *p_args[0]; r_ret = d.size(); } break; @@ -1200,14 +1208,14 @@ void GDFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, r_ret = d.size(); } break; case Variant::POOL_STRING_ARRAY: { + PoolVector<String> d = *p_args[0]; r_ret = d.size(); - } break; case Variant::POOL_VECTOR2_ARRAY: { + PoolVector<Vector2> d = *p_args[0]; r_ret = d.size(); - } break; case Variant::POOL_VECTOR3_ARRAY: { @@ -1412,12 +1420,12 @@ MethodInfo GDFunctions::get_info(Function p_func) { } break; case MATH_ISNAN: { MethodInfo mi("is_nan", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_ISINF: { MethodInfo mi("is_inf", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_EASE: { diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h index 6f05a4770b..5e1a8b19ac 100644 --- a/modules/gdscript/gd_script.h +++ b/modules/gdscript/gd_script.h @@ -389,7 +389,6 @@ public: virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return OK; } virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint); #ifdef TOOLS_ENABLED virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_base_path, Object *p_owner, LookupResult &r_result); diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp index 1b932f040e..4f7545a11d 100644 --- a/modules/gridmap/grid_map.cpp +++ b/modules/gridmap/grid_map.cpp @@ -396,8 +396,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) { Map<int, List<Pair<Transform, IndexKey> > > multimesh_items; - print_line("updating octant " + itos(p_key.x) + ", " + itos(p_key.y) + ", " + itos(p_key.z) + " cells: " + itos(g.cells.size())); - for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) { ERR_CONTINUE(!cell_map.has(E->get())); @@ -464,7 +462,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) { //update multimeshes for (Map<int, List<Pair<Transform, IndexKey> > >::Element *E = multimesh_items.front(); E; E = E->next()) { - print_line("multimesh item " + itos(E->key()) + " transforms " + itos(E->get().size())); Octant::MultimeshInstance mmi; RID mm = VS::get_singleton()->multimesh_create(); @@ -655,6 +652,24 @@ void GridMap::_notification(int p_what) { //_update_area_instances(); } break; + case NOTIFICATION_VISIBILITY_CHANGED: { + _update_visibility(); + } break; + } +} + +void GridMap::_update_visibility() { + if (!is_inside_tree()) + return; + + _change_notify("visible"); + + for (Map<OctantKey, Octant *>::Element *e = octant_map.front(); e; e = e->next()) { + Octant *octant = e->value(); + for (int i = 0; i < octant->multimesh_instances.size(); i++) { + Octant::MultimeshInstance &mi = octant->multimesh_instances[i]; + VS::get_singleton()->instance_set_visible(mi.instance, is_visible()); + } } } @@ -720,6 +735,7 @@ void GridMap::_update_octants_callback() { to_delete.pop_back(); } + _update_visibility(); awaiting_update = false; } diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h index 9e1d250680..eb1b215696 100644 --- a/modules/gridmap/grid_map.h +++ b/modules/gridmap/grid_map.h @@ -190,6 +190,7 @@ protected: void _get_property_list(List<PropertyInfo> *p_list) const; void _notification(int p_what); + void _update_visibility(); static void _bind_methods(); public: diff --git a/modules/nativescript/config.py b/modules/nativescript/config.py deleted file mode 100644 index 9f57b9bb74..0000000000 --- a/modules/nativescript/config.py +++ /dev/null @@ -1,8 +0,0 @@ - - -def can_build(platform): - return True - - -def configure(env): - env.use_ptrcall = True diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 9989785c70..90ee164b6f 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -74,15 +74,11 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, uint32_t mipmaps = f->get_32(); uint32_t flags = f->get_32(); uint32_t surfsize = f->get_32(); - uint32_t bpp = f->get_32(); - uint32_t rmask = f->get_32(); - uint32_t gmask = f->get_32(); - uint32_t bmask = f->get_32(); - uint32_t amask = f->get_32(); + f->seek(f->get_pos() + 20); // bpp, rmask, gmask, bmask, amask uint8_t pvrid[5] = { 0, 0, 0, 0, 0 }; f->get_buffer(pvrid, 4); ERR_FAIL_COND_V(String((char *)pvrid) != "PVR!", RES()); - uint32_t surfcount = f->get_32(); + f->get_32(); // surfcount /* print_line("height: "+itos(height)); diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index df427907f8..9457fbfaf6 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -45,6 +45,12 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra while (todo && active) { int mixed = stb_vorbis_get_samples_float_interleaved(ogg_stream, 2, (float *)p_buffer, todo * 2); + if (vorbis_stream->channels == 1 && mixed > 0) { + //mix mono to stereo + for (int i = 0; i < mixed; i++) { + p_buffer[i].r = p_buffer[i].l; + } + } todo -= mixed; frames_mixed += mixed; diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index f5c379d32e..935a412ed1 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -75,8 +75,8 @@ void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image, const Dictionary p_ if (r_c.get_type() == Variant::COLOR && n_c.get_type() == Variant::COLOR) { Color replace_color = r_c; Color new_color = n_c; - replace_colors_i.push_back(replace_color.to_ABGR32()); - new_colors_i.push_back(new_color.to_ABGR32()); + replace_colors_i.push_back(replace_color.to_abgr32()); + new_colors_i.push_back(new_color.to_abgr32()); } } diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp index 2a24f8d4d1..02b994f8db 100644 --- a/modules/theora/video_stream_theora.cpp +++ b/modules/theora/video_stream_theora.cpp @@ -414,7 +414,8 @@ void VideoStreamPlaybackTheora::update(float p_delta) { bool buffer_full = false; /* if there's pending, decoded audio, grab it */ - if ((ret = vorbis_synthesis_pcmout(&vd, &pcm)) > 0) { + ret = vorbis_synthesis_pcmout(&vd, &pcm); + if (ret > 0) { const int AUXBUF_LEN = 4096; int to_read = ret; diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h index b2e7a6aa27..297e9e510f 100644 --- a/modules/visual_script/visual_script.h +++ b/modules/visual_script/visual_script.h @@ -571,7 +571,6 @@ public: virtual bool has_named_classes() const; virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const; virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 8386687c9f..dfec1eea60 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -506,7 +506,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) { gnode->set_show_close_button(true); } - if (Object::cast_to<VisualScriptExpression>(*node)) { + if (Object::cast_to<VisualScriptExpression>(node.ptr())) { LineEdit *line_edit = memnew(LineEdit); line_edit->set_text(node->get_text()); @@ -520,10 +520,10 @@ void VisualScriptEditor::_update_graph(int p_only_id) { gnode->add_child(text); } - if (Object::cast_to<VisualScriptExpression>(*node)) { + if (Object::cast_to<VisualScriptComment>(node.ptr())) { Ref<VisualScriptComment> vsc = node; gnode->set_comment(true); - gnode->set_resizeable(true); + gnode->set_resizable(true); gnode->set_custom_minimum_size(vsc->get_size() * EDSCALE); gnode->connect("resize_request", this, "_comment_node_resized", varray(E->get())); } @@ -926,48 +926,6 @@ void VisualScriptEditor::_member_edited() { } } -void VisualScriptEditor::_override_pressed(int p_id) { - - //override a virtual function or method from base type - - ERR_FAIL_COND(!virtuals_in_menu.has(p_id)); - - VirtualInMenu vim = virtuals_in_menu[p_id]; - - String name = _validate_name(vim.name); - selected = name; - edited_func = selected; - Ref<VisualScriptFunction> func_node; - func_node.instance(); - func_node->set_name(vim.name); - - undo_redo->create_action(TTR("Add Function")); - undo_redo->add_do_method(script.ptr(), "add_function", name); - for (int i = 0; i < vim.args.size(); i++) { - func_node->add_argument(vim.args[i].first, vim.args[i].second); - } - - undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node); - if (vim.ret != Variant::NIL || vim.ret_variant) { - Ref<VisualScriptReturn> ret_node; - ret_node.instance(); - ret_node->set_return_type(vim.ret); - ret_node->set_enable_return_value(true); - ret_node->set_name(vim.name); - undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id() + 1, ret_node, Vector2(500, 0)); - } - - undo_redo->add_undo_method(script.ptr(), "remove_function", name); - undo_redo->add_do_method(this, "_update_members"); - undo_redo->add_undo_method(this, "_update_members"); - undo_redo->add_do_method(this, "_update_graph"); - undo_redo->add_undo_method(this, "_update_graph"); - - undo_redo->commit_action(); - - _update_graph(); -} - void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_button) { TreeItem *ti = Object::cast_to<TreeItem>(p_item); @@ -980,64 +938,9 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt //add function, this one uses menu if (p_button == 1) { - new_function_menu->clear(); - new_function_menu->set_size(Size2(0, 0)); - int idx = 0; - - virtuals_in_menu.clear(); - - List<MethodInfo> mi; - ClassDB::get_method_list(script->get_instance_base_type(), &mi); - for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) { - MethodInfo mi = E->get(); - if (mi.flags & METHOD_FLAG_VIRTUAL) { - - VirtualInMenu vim; - vim.name = mi.name; - vim.ret = mi.return_val.type; - if (mi.return_val.name != String()) - vim.ret_variant = true; - else - vim.ret_variant = false; - - String desc; - - if (mi.return_val.type == Variant::NIL) - desc = "var"; - else - desc = Variant::get_type_name(mi.return_val.type); - desc += " " + mi.name + " ( "; - - for (int i = 0; i < mi.arguments.size(); i++) { - - if (i > 0) - desc += ", "; - - if (mi.arguments[i].type == Variant::NIL) - desc += "var "; - else - desc += Variant::get_type_name(mi.arguments[i].type) + " "; - - desc += mi.arguments[i].name; - - Pair<Variant::Type, String> p; - p.first = mi.arguments[i].type; - p.second = mi.arguments[i].name; - vim.args.push_back(p); - } - desc += " )"; + new_virtual_method_select->select_method_from_base_type(script->get_instance_base_type(), String(), true); - virtuals_in_menu[idx] = vim; - - new_function_menu->add_item(desc, idx); - idx++; - } - } - - Rect2 pos = members->get_item_rect(ti); - new_function_menu->set_position(members->get_global_position() + pos.position + Vector2(0, pos.size.y)); - new_function_menu->popup(); return; } else if (p_button == 0) { @@ -2686,21 +2589,21 @@ void VisualScriptEditor::_selected_connect_node_method_or_setget(const String &p Ref<VisualScriptNode> vsn = script->get_node(edited_func, port_action_new_node); - if (Object::cast_to<VisualScriptFunctionCall>(*vsn)) { + if (Object::cast_to<VisualScriptFunctionCall>(vsn.ptr())) { Ref<VisualScriptFunctionCall> vsfc = vsn; vsfc->set_function(p_text); script->data_connect(edited_func, port_action_node, port_action_output, port_action_new_node, 0); } - if (Object::cast_to<VisualScriptPropertySet>(*vsn)) { + if (Object::cast_to<VisualScriptPropertySet>(vsn.ptr())) { Ref<VisualScriptPropertySet> vsp = vsn; vsp->set_property(p_text); script->data_connect(edited_func, port_action_node, port_action_output, port_action_new_node, 0); } - if (Object::cast_to<VisualScriptPropertyGet>(*vsn)) { + if (Object::cast_to<VisualScriptPropertyGet>(vsn.ptr())) { Ref<VisualScriptPropertyGet> vsp = vsn; vsp->set_property(p_text); @@ -2711,6 +2614,63 @@ void VisualScriptEditor::_selected_connect_node_method_or_setget(const String &p _update_graph_connections(); } +void VisualScriptEditor::_selected_new_virtual_method(const String &p_text) { + + String name = p_text; + if (script->has_function(name)) { + EditorNode::get_singleton()->show_warning(vformat(TTR("Script already has function '%s'"), name)); + return; + } + + MethodInfo minfo; + { + List<MethodInfo> methods; + bool found = false; + ClassDB::get_virtual_methods(script->get_instance_base_type(), &methods); + for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + if (E->get().name == name) { + minfo = E->get(); + found = true; + } + } + + ERR_FAIL_COND(!found); + } + + selected = name; + edited_func = selected; + Ref<VisualScriptFunction> func_node; + func_node.instance(); + func_node->set_name(name); + + undo_redo->create_action(TTR("Add Function")); + undo_redo->add_do_method(script.ptr(), "add_function", name); + + for (int i = 0; i < minfo.arguments.size(); i++) { + func_node->add_argument(minfo.arguments[i].type, minfo.arguments[i].name); + } + + undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id(), func_node); + if (minfo.return_val.type != Variant::NIL || minfo.return_val.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { + Ref<VisualScriptReturn> ret_node; + ret_node.instance(); + ret_node->set_return_type(minfo.return_val.type); + ret_node->set_enable_return_value(true); + ret_node->set_name(name); + undo_redo->add_do_method(script.ptr(), "add_node", name, script->get_available_id() + 1, ret_node, Vector2(500, 0)); + } + + undo_redo->add_undo_method(script.ptr(), "remove_function", name); + undo_redo->add_do_method(this, "_update_members"); + undo_redo->add_undo_method(this, "_update_members"); + undo_redo->add_do_method(this, "_update_graph"); + undo_redo->add_undo_method(this, "_update_graph"); + + undo_redo->commit_action(); + + _update_graph(); +} + void VisualScriptEditor::_cancel_connect_node_method_or_setget() { script->remove_node(edited_func, port_action_new_node); @@ -3147,7 +3107,6 @@ void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members); ClassDB::bind_method("_change_base_type", &VisualScriptEditor::_change_base_type); ClassDB::bind_method("_change_base_type_callback", &VisualScriptEditor::_change_base_type_callback); - ClassDB::bind_method("_override_pressed", &VisualScriptEditor::_override_pressed); ClassDB::bind_method("_node_selected", &VisualScriptEditor::_node_selected); ClassDB::bind_method("_node_moved", &VisualScriptEditor::_node_moved); ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node); @@ -3166,6 +3125,8 @@ void VisualScriptEditor::_bind_methods() { ClassDB::bind_method("_button_resource_previewed", &VisualScriptEditor::_button_resource_previewed); ClassDB::bind_method("_port_action_menu", &VisualScriptEditor::_port_action_menu); ClassDB::bind_method("_selected_connect_node_method_or_setget", &VisualScriptEditor::_selected_connect_node_method_or_setget); + ClassDB::bind_method("_selected_new_virtual_method", &VisualScriptEditor::_selected_new_virtual_method); + ClassDB::bind_method("_cancel_connect_node_method_or_setget", &VisualScriptEditor::_cancel_connect_node_method_or_setget); ClassDB::bind_method("_expression_text_changed", &VisualScriptEditor::_expression_text_changed); @@ -3344,9 +3305,6 @@ VisualScriptEditor::VisualScriptEditor() { undo_redo = EditorNode::get_singleton()->get_undo_redo(); - new_function_menu = memnew(PopupMenu); - new_function_menu->connect("id_pressed", this, "_override_pressed"); - add_child(new_function_menu); updating_members = false; set_process_input(true); //for revert on drag @@ -3366,6 +3324,11 @@ VisualScriptEditor::VisualScriptEditor() { new_connect_node_select->connect("selected", this, "_selected_connect_node_method_or_setget"); new_connect_node_select->get_cancel()->connect("pressed", this, "_cancel_connect_node_method_or_setget"); + new_virtual_method_select = memnew(PropertySelector); + add_child(new_virtual_method_select); + new_virtual_method_select->connect("selected", this, "_selected_new_virtual_method"); + new_virtual_method_select->get_cancel()->connect("pressed", this, "_selected_new_virtual_method"); + port_action_popup = memnew(PopupMenu); add_child(port_action_popup); port_action_popup->connect("id_pressed", this, "_port_action_menu"); diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index dd051ef8e4..5b8c3ea74e 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -103,6 +103,7 @@ class VisualScriptEditor : public ScriptEditorBase { PropertySelector *method_select; PropertySelector *new_connect_node_select; + PropertySelector *new_virtual_method_select; VisualScriptEditorVariableEdit *variable_editor; @@ -135,10 +136,6 @@ class VisualScriptEditor : public ScriptEditorBase { Vector<Pair<Variant::Type, String> > args; }; - Map<int, VirtualInMenu> virtuals_in_menu; - - PopupMenu *new_function_menu; - StringName edited_func; void _update_graph_connections(); @@ -177,6 +174,7 @@ class VisualScriptEditor : public ScriptEditorBase { void _port_action_menu(int p_option); void _selected_connect_node_method_or_setget(const String &p_text); void _cancel_connect_node_method_or_setget(); + void _selected_new_virtual_method(const String &p_text); int error_line; @@ -188,7 +186,6 @@ class VisualScriptEditor : public ScriptEditorBase { void _change_base_type(); void _member_selected(); void _member_edited(); - void _override_pressed(int p_id); void _begin_node_move(); void _end_node_move(); diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp index d0e9b5bb86..eae866d167 100644 --- a/modules/visual_script/visual_script_expression.cpp +++ b/modules/visual_script/visual_script_expression.cpp @@ -831,7 +831,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() { case TK_BUILTIN_FUNC: { //builtin function - Variant::Type bt = Variant::Type(int(tk.value)); _get_token(tk); if (tk.type != TK_PARENTHESIS_OPEN) { _set_error("Expected '('"); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 1decc004ab..093f01c49f 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -1493,7 +1493,7 @@ void VisualScriptGlobalConstant::_bind_methods() { cc += ","; cc += GlobalConstants::get_global_constant_name(i); } - ADD_PROPERTY(PropertyInfo(Variant::INT, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant"); } VisualScriptGlobalConstant::VisualScriptGlobalConstant() { @@ -1622,7 +1622,7 @@ void VisualScriptClassConstant::_bind_methods() { ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptClassConstant::get_base_type); ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant"); } VisualScriptClassConstant::VisualScriptClassConstant() { @@ -1760,7 +1760,7 @@ void VisualScriptBasicTypeConstant::_bind_methods() { } ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, argt), "set_basic_type", "get_basic_type"); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant"); } VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() { @@ -1881,7 +1881,7 @@ void VisualScriptMathConstant::_bind_methods() { cc += ","; cc += const_name[i]; } - ADD_PROPERTY(PropertyInfo(Variant::INT, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant"); } VisualScriptMathConstant::VisualScriptMathConstant() { @@ -2002,7 +2002,7 @@ void VisualScriptEngineSingleton::_bind_methods() { cc += E->get().name; } - ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant/constant", PROPERTY_HINT_ENUM, cc), "set_singleton", "get_singleton"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "/constant", PROPERTY_HINT_ENUM, cc), "set_singleton", "get_singleton"); } VisualScriptEngineSingleton::VisualScriptEngineSingleton() { @@ -3727,11 +3727,11 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("data/preload", create_node_generic<VisualScriptPreload>); VisualScriptLanguage::singleton->add_register_func("data/action", create_node_generic<VisualScriptInputAction>); - VisualScriptLanguage::singleton->add_register_func("constant/constants/constant", create_node_generic<VisualScriptConstant>); - VisualScriptLanguage::singleton->add_register_func("constant/constants/math_constant", create_node_generic<VisualScriptMathConstant>); - VisualScriptLanguage::singleton->add_register_func("constant/constants/class_constant", create_node_generic<VisualScriptClassConstant>); - VisualScriptLanguage::singleton->add_register_func("constant/constants/global_constant", create_node_generic<VisualScriptGlobalConstant>); - VisualScriptLanguage::singleton->add_register_func("constant/constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>); + VisualScriptLanguage::singleton->add_register_func("constants/constant", create_node_generic<VisualScriptConstant>); + VisualScriptLanguage::singleton->add_register_func("constants/math_constant", create_node_generic<VisualScriptMathConstant>); + VisualScriptLanguage::singleton->add_register_func("constants/class_constant", create_node_generic<VisualScriptClassConstant>); + VisualScriptLanguage::singleton->add_register_func("constants/global_constant", create_node_generic<VisualScriptGlobalConstant>); + VisualScriptLanguage::singleton->add_register_func("constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>); VisualScriptLanguage::singleton->add_register_func("custom/custom_node", create_node_generic<VisualScriptCustomNode>); VisualScriptLanguage::singleton->add_register_func("custom/sub_call", create_node_generic<VisualScriptSubCall>); diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index d691bd7629..e3615e2298 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -520,25 +520,21 @@ class EditorExportAndroid : public EditorExportPlatform { void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet) { - const int CHUNK_AXML_FILE = 0x00080003; - const int CHUNK_RESOURCEIDS = 0x00080180; + // Leaving the unused types commented because looking these constants up + // again later would be annoying + // const int CHUNK_AXML_FILE = 0x00080003; + // const int CHUNK_RESOURCEIDS = 0x00080180; const int CHUNK_STRINGS = 0x001C0001; - const int CHUNK_XML_END_NAMESPACE = 0x00100101; - const int CHUNK_XML_END_TAG = 0x00100103; - const int CHUNK_XML_START_NAMESPACE = 0x00100100; + // const int CHUNK_XML_END_NAMESPACE = 0x00100101; + // const int CHUNK_XML_END_TAG = 0x00100103; + // const int CHUNK_XML_START_NAMESPACE = 0x00100100; const int CHUNK_XML_START_TAG = 0x00100102; - const int CHUNK_XML_TEXT = 0x00100104; + // const int CHUNK_XML_TEXT = 0x00100104; const int UTF8_FLAG = 0x00000100; Vector<String> string_table; - uint32_t ofs = 0; - - uint32_t header = decode_uint32(&p_manifest[ofs]); - uint32_t filesize = decode_uint32(&p_manifest[ofs + 4]); - ofs += 8; - - //print_line("FILESIZE: "+itos(filesize)+" ACTUAL: "+itos(p_manifest.size())); + uint32_t ofs = 8; uint32_t string_count = 0; uint32_t styles_count = 0; @@ -646,24 +642,16 @@ class EditorExportAndroid : public EditorExportPlatform { case CHUNK_XML_START_TAG: { int iofs = ofs + 8; - uint32_t line = decode_uint32(&p_manifest[iofs]); - uint32_t nspace = decode_uint32(&p_manifest[iofs + 8]); uint32_t name = decode_uint32(&p_manifest[iofs + 12]); - uint32_t check = decode_uint32(&p_manifest[iofs + 16]); String tname = string_table[name]; - - //printf("NSPACE: %i\n",nspace); - //printf("NAME: %i (%s)\n",name,tname.utf8().get_data()); - //printf("CHECK: %x\n",check); uint32_t attrcount = decode_uint32(&p_manifest[iofs + 20]); iofs += 28; - //printf("ATTRCOUNT: %x\n",attrcount); + for (uint32_t i = 0; i < attrcount; i++) { uint32_t attr_nspace = decode_uint32(&p_manifest[iofs]); uint32_t attr_name = decode_uint32(&p_manifest[iofs + 4]); uint32_t attr_value = decode_uint32(&p_manifest[iofs + 8]); - uint32_t attr_flags = decode_uint32(&p_manifest[iofs + 12]); uint32_t attr_resid = decode_uint32(&p_manifest[iofs + 16]); String value; @@ -678,12 +666,6 @@ class EditorExportAndroid : public EditorExportPlatform { else nspace = ""; - //printf("ATTR %i NSPACE: %i\n",i,attr_nspace); - //printf("ATTR %i NAME: %i (%s)\n",i,attr_name,attrname.utf8().get_data()); - //printf("ATTR %i VALUE: %i (%s)\n",i,attr_value,value.utf8().get_data()); - //printf("ATTR %i FLAGS: %x\n",i,attr_flags); - //printf("ATTR %i RESID: %x\n",i,attr_resid); - //replace project information if (tname == "manifest" && attrname == "package") { @@ -691,9 +673,6 @@ class EditorExportAndroid : public EditorExportPlatform { string_table[attr_value] = get_package_name(package_name); } - //print_line("tname: "+tname); - //print_line("nspace: "+nspace); - //print_line("attrname: "+attrname); if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionCode") { print_line("FOUND versionCode"); @@ -712,13 +691,6 @@ class EditorExportAndroid : public EditorExportPlatform { if (tname == "activity" && /*nspace=="android" &&*/ attrname == "screenOrientation") { encode_uint32(orientation == 0 ? 0 : 1, &p_manifest[iofs + 16]); - /* - print_line("FOUND screen orientation"); - if (attr_value==0xFFFFFFFF) { - WARN_PRINT("Version name in a resource, should be plaintext") - } else { - string_table[attr_value]=(orientation==0?"landscape":"portrait"); - }*/ } if (tname == "uses-feature" && /*nspace=="android" &&*/ attrname == "glEsVersion") { @@ -771,13 +743,10 @@ class EditorExportAndroid : public EditorExportPlatform { } break; } - //printf("chunk %x: size: %d\n",chunk,size); ofs += size; } - //printf("end\n"); - //create new andriodmanifest binary Vector<uint8_t> ret; @@ -876,8 +845,6 @@ class EditorExportAndroid : public EditorExportPlatform { const int UTF8_FLAG = 0x00000100; print_line("*******************GORRRGLE***********************"); - uint32_t header = decode_uint32(&p_manifest[0]); - uint32_t filesize = decode_uint32(&p_manifest[4]); uint32_t string_block_len = decode_uint32(&p_manifest[16]); uint32_t string_count = decode_uint32(&p_manifest[20]); uint32_t string_flags = decode_uint32(&p_manifest[28]); @@ -887,10 +854,6 @@ class EditorExportAndroid : public EditorExportPlatform { String package_name = p_preset->get("package/name"); - //printf("stirng block len: %i\n",string_block_len); - //printf("stirng count: %i\n",string_count); - //printf("flags: %x\n",string_flags); - for (uint32_t i = 0; i < string_count; i++) { uint32_t offset = decode_uint32(&p_manifest[string_table_begins + i * 4]); diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index b804863ee1..e282041745 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -20,33 +20,32 @@ for x in javascript_files: javascript_objects.append(env_javascript.Object(x)) env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync','_send_notification']\""]) -env.Append(LINKFLAGS=["--shell-file", '"platform/javascript/godot_shell.html"']) # output file name without file extension basename = "godot" + env["PROGSUFFIX"] target_dir = env.Dir("#bin") -js_file = target_dir.File(basename + ".js") -implicit_targets = [js_file] zip_dir = target_dir.Dir('.javascript_zip') -zip_files = env.InstallAs([zip_dir.File("godot.js"), zip_dir.File("godotfs.js")], [js_file, "#misc/dist/html_fs/godotfs.js"]) +zip_files = env.InstallAs(zip_dir.File('godot.html'), '#misc/dist/html/default.html') +implicit_targets = [] if env['wasm'] == 'yes': - wasm_file = target_dir.File(basename+'.wasm') - implicit_targets.append(wasm_file) - zip_files.append(InstallAs(zip_dir.File('godot.wasm'), wasm_file)) + 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+'.html.mem')] - zip_files.append(InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files)) + 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') -# HTML file must be the first target in the list -html_file = env.Program(["#bin/godot"] + implicit_targets, javascript_objects, PROGSUFFIX=env["PROGSUFFIX"]+".html")[0] -Depends(html_file, "godot_shell.html") +js = env.Program(['#bin/godot'] + implicit_targets, javascript_objects, PROGSUFFIX=env['PROGSUFFIX'] + '.js')[0]; +zip_files.append(InstallAs(zip_dir.File('godot.js'), js)) -# Emscripten hardcodes file names, so replace common base name with -# placeholder while leaving extension; also change `.html.mem` to just `.mem` -fixup_html = env.Substfile(html_file, SUBST_DICT=[(basename, '$$GODOT_BASE'), ('.html.mem', '.mem')], SUBSTFILESUFFIX='.fixup.html') +postjs = env.File('engine.js') +env.Depends(js, [prejs, postjs]) +env.Append(LINKFLAGS=['--pre-js', prejs.path]) +env.Append(LINKFLAGS=['--post-js', postjs.path]) -zip_files.append(InstallAs(zip_dir.File('godot.html'), fixup_html)) -Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX']+env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET") +Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX'] + env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET") diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 5f066f1b15..bea8f156af 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -100,6 +100,7 @@ def configure(env): ## Link flags + env.Append(LINKFLAGS=['-s', 'EXTRA_EXPORTED_RUNTIME_METHODS="[\'FS\']"']) env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) if (env['wasm'] == 'yes'): @@ -112,6 +113,7 @@ def configure(env): else: env.Append(LINKFLAGS=['-s', 'ASM_JS=1']) env.Append(LINKFLAGS=['--separate-asm']) + env.Append(LINKFLAGS=['--memory-init-file', '1']) # TODO: Move that to opus module's config if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"): diff --git a/platform/javascript/engine.js b/platform/javascript/engine.js new file mode 100644 index 0000000000..552f5a7e02 --- /dev/null +++ b/platform/javascript/engine.js @@ -0,0 +1,366 @@ + return Module; + }, +}; + +(function() { + var engine = Engine; + + var USING_WASM = engine.USING_WASM; + var DOWNLOAD_ATTEMPTS_MAX = 4; + + var basePath = null; + var engineLoadPromise = null; + + var loadingFiles = {}; + + function getBasePath(path) { + + if (path.endsWith('/')) + path = path.slice(0, -1); + if (path.lastIndexOf('.') > path.lastIndexOf('/')) + path = path.slice(0, path.lastIndexOf('.')); + return path; + } + + function getBaseName(path) { + + path = getBasePath(path); + return path.slice(path.lastIndexOf('/') + 1); + } + + Engine = function Engine() { + + this.rtenv = null; + + var gameInitPromise = null; + var unloadAfterInit = true; + var memorySize = 268435456; + + var progressFunc = null; + var pckProgressTracker = {}; + var lastProgress = { loaded: 0, total: 0 }; + + var canvas = null; + var stdout = null; + var stderr = null; + + this.initGame = function(mainPack) { + + if (!gameInitPromise) { + + 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( + 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); + } + return gameInitPromise; + }; + + function instantiate(initializer) { + + var rtenvOpts = { + noInitialRun: true, + thisProgram: getBaseName(basePath), + engine: this, + }; + if (typeof stdout === 'function') + rtenvOpts.print = stdout; + if (typeof stderr === 'function') + rtenvOpts.printErr = stderr; + if (typeof WebAssembly === 'object' && initializer instanceof WebAssembly.Module) { + rtenvOpts.instantiateWasm = function(imports, onSuccess) { + WebAssembly.instantiate(initializer, imports).then(function(result) { + onSuccess(result); + }); + 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"); + } + + return new Promise(function(resolve, reject) { + rtenvOpts.onRuntimeInitialized = resolve; + rtenvOpts.onAbort = reject; + rtenvOpts.engine.rtenv = Engine.RuntimeEnvironment(rtenvOpts); + }); + } + + this.start = function(mainPack) { + + return this.initGame(mainPack).then(synchronousStart.bind(this)); + }; + + function synchronousStart(pckView) { + // TODO don't expect canvas when runninng as cli tool + if (canvas instanceof HTMLCanvasElement) { + this.rtenv.canvas = canvas; + } else { + var firstCanvas = document.getElementsByTagName('canvas')[0]; + if (firstCanvas instanceof HTMLCanvasElement) { + this.rtenv.canvas = firstCanvas; + } else { + throw new Error("No canvas found"); + } + } + + var actualCanvas = this.rtenv.canvas; + var context = false; + try { + context = actualCanvas.getContext('webgl2') || actualCanvas.getContext('experimental-webgl2'); + } catch (e) {} + if (!context) { + throw new Error("WebGL 2 not available"); + } + + // canvas can grab focus on click + if (actualCanvas.tabIndex < 0) { + actualCanvas.tabIndex = 0; + } + // necessary to calculate cursor coordinates correctly + actualCanvas.style.padding = 0; + actualCanvas.style.borderWidth = 0; + actualCanvas.style.borderStyle = 'none'; + // until context restoration is implemented + actualCanvas.addEventListener('webglcontextlost', function(ev) { + alert("WebGL context lost, please reload the page"); + ev.preventDefault(); + }, false); + + this.rtenv.FS.createDataFile('/', this.rtenv.thisProgram + '.pck', pckView, true, true, true); + gameInitPromise = null; + this.rtenv.callMain(); + } + + this.setProgressFunc = function(func) { + progressFunc = func; + }; + + function animateProgress() { + + var loaded = 0; + var total = 0; + var totalIsValid = true; + var progressIsFinal = true; + + [loadingFiles, pckProgressTracker].forEach(function(tracker) { + Object.keys(tracker).forEach(function(file) { + if (!tracker[file].final) + progressIsFinal = false; + if (!totalIsValid || tracker[file].total === 0) { + totalIsValid = false; + total = 0; + } else { + total += tracker[file].total; + } + loaded += tracker[file].loaded; + }); + }); + if (loaded !== lastProgress.loaded || total !== lastProgress.total) { + lastProgress.loaded = loaded; + lastProgress.total = total; + if (typeof progressFunc === 'function') + progressFunc(loaded, total); + } + if (!progressIsFinal) + requestAnimationFrame(animateProgress); + } + + this.setCanvas = function(elem) { + canvas = elem; + }; + + this.setAsmjsMemorySize = function(size) { + memorySize = size; + }; + + this.setUnloadAfterInit = function(enabled) { + + if (enabled && !unloadAfterInit && gameInitPromise) { + gameInitPromise.then(Engine.unloadEngine); + } + unloadAfterInit = enabled; + }; + + this.setStdoutFunc = function(func) { + + var print = function(text) { + if (arguments.length > 1) { + text = Array.prototype.slice.call(arguments).join(" "); + } + func(text); + }; + if (this.rtenv) + this.rtenv.print = print; + stdout = print; + }; + + this.setStderrFunc = function(func) { + + var printErr = function(text) { + if (arguments.length > 1) + text = Array.prototype.slice.call(arguments).join(" "); + func(text); + }; + if (this.rtenv) + this.rtenv.printErr = printErr; + stderr = printErr; + }; + + + }; // Engine() + + Engine.RuntimeEnvironment = engine.RuntimeEnvironment; + + Engine.initEngine = 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 WebAssembly.compile(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] }; + }); + } + engineLoadPromise = engineLoadPromise.catch(function(err) { + engineLoadPromise = null; + throw err; + }); + } + 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() { + engineLoadPromise = null; + }; + + function loadPromise(file, tracker) { + if (tracker === undefined) + tracker = loadingFiles; + return new Promise(function(resolve, reject) { + loadXHR(resolve, reject, file, tracker); + }); + } + + function loadXHR(resolve, reject, file, tracker) { + + var xhr = new XMLHttpRequest; + xhr.open('GET', file); + if (!file.endsWith('.js')) { + xhr.responseType = 'arraybuffer'; + } + ['loadstart', 'progress', 'load', 'error', 'timeout', 'abort'].forEach(function(ev) { + xhr.addEventListener(ev, onXHREvent.bind(xhr, resolve, reject, file, tracker)); + }); + xhr.send(); + } + + function onXHREvent(resolve, reject, file, tracker, ev) { + + if (this.status >= 400) { + + if (this.status < 500 || ++tracker[file].attempts >= DOWNLOAD_ATTEMPTS_MAX) { + reject(new Error("Failed loading file '" + file + "': " + this.statusText)); + this.abort(); + return; + } else { + loadXHR(resolve, reject, file); + } + } + + switch (ev.type) { + case 'loadstart': + if (tracker[file] === undefined) { + tracker[file] = { + total: ev.total, + loaded: ev.loaded, + attempts: 0, + final: false, + }; + } + break; + + case 'progress': + tracker[file].loaded = ev.loaded; + tracker[file].total = ev.total; + break; + + case 'load': + tracker[file].final = true; + resolve(this); + 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); + } + break; + + case 'abort': + tracker[file].final = true; + reject(new Error("Loading file '" + file + "' was aborted.")); + break; + } + } +})(); diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 5a161dd0ab..4a97bf4c32 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -100,8 +100,8 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re for (int i = 0; i < lines.size(); i++) { String current_line = lines[i]; - current_line = current_line.replace("$GODOT_TMEM", itos(memory_mb * 1024 * 1024)); - current_line = current_line.replace("$GODOT_BASE", p_name); + 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"); str_export += current_line + "\n"; @@ -114,28 +114,6 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re } } -void EditorExportPlatformJavaScript::_fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size) { - - String str_template = String::utf8(reinterpret_cast<const char *>(p_js.ptr()), p_js.size()); - String str_export; - Vector<String> lines = str_template.split("\n"); - for (int i = 0; i < lines.size(); i++) { - if (lines[i].find("$GODOT_PACK_NAME") != -1) { - str_export += lines[i].replace("$GODOT_PACK_NAME", p_pack_name); - } else if (lines[i].find("$GODOT_PACK_SIZE") != -1) { - str_export += lines[i].replace("$GODOT_PACK_SIZE", itos(p_pack_size)); - } else { - str_export += lines[i] + "\n"; - } - } - - CharString cs = str_export.utf8(); - p_js.resize(cs.length()); - for (int i = 0; i < cs.length(); i++) { - p_js[i] = cs[i]; - } -} - void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { if (p_preset->get("texture_format/s3tc")) { @@ -286,10 +264,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug); file = p_path.get_file(); - } else if (file == "godotfs.js") { - - _fix_fsloader_js(data, pck_path.get_file(), pack_size); - file = p_path.get_file().get_basename() + "fs.js"; } else if (file == "godot.js") { file = p_path.get_file().get_basename() + ".js"; diff --git a/platform/javascript/godot_shell.html b/platform/javascript/godot_shell.html deleted file mode 100644 index ee7399a129..0000000000 --- a/platform/javascript/godot_shell.html +++ /dev/null @@ -1,347 +0,0 @@ -<!DOCTYPE html> -<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> -<head> - <meta charset="utf-8" /> - <title></title> - <style type="text/css"> - body { - margin: 0; - border: 0 none; - padding: 0; - text-align: center; - background-color: #222226; - font-family: 'Droid Sans', Arial, sans-serif; - } - - - /* Godot Engine default theme style - * ================================ */ - - .godot { - color: #e0e0e0; - background-color: #3b3943; - background-image: linear-gradient(to bottom, #403e48, #35333c); - border: 1px solid #45434e; - box-shadow: 0 0 1px 1px #2f2d35; - } - - button.godot { - font-family: 'Droid Sans', Arial, sans-serif; /* override user agent style */ - padding: 1px 5px; - background-color: #37353f; - background-image: linear-gradient(to bottom, #413e49, #3a3842); - border: 1px solid #514f5d; - border-radius: 1px; - box-shadow: 0 0 1px 1px #2a2930; - } - - button.godot:hover { - color: #f0f0f0; - background-color: #44414e; - background-image: linear-gradient(to bottom, #494652, #423f4c); - border: 1px solid #5a5667; - box-shadow: 0 0 1px 1px #26252b; - } - - button.godot:active { - color: #fff; - background-color: #3e3b46; - background-image: linear-gradient(to bottom, #36343d, #413e49); - border: 1px solid #4f4c59; - box-shadow: 0 0 1px 1px #26252b; - } - - button.godot:disabled { - color: rgba(230, 230, 230, 0.2); - background-color: #3d3d3d; - background-image: linear-gradient(to bottom, #434343, #393939); - border: 1px solid #474747; - box-shadow: 0 0 1px 1px #2d2b33; - } - - - /* Canvas / wrapper - * ================ */ - - #container { - display: inline-block; /* scale with canvas */ - vertical-align: top; /* prevent extra height */ - position: relative; /* root for absolutely positioned overlay */ - margin: 0; - border: 0 none; - padding: 0; - background-color: #0c0c0c; - } - - #canvas { - display: block; - margin: 0 auto; - /* canvas must have border and padding set to zero to - * calculate cursor coordinates correctly */ - border: 0 none; - padding: 0; - color: white; - } - - #canvas:focus { - outline: none; - } - - - /* Status display - * ============== */ - - #status-container { - position: absolute; - left: 0; - top: 0; - right: 0; - bottom: 0; - display: flex; - justify-content: center; - align-items: center; - /* don't consume click events - make children visible explicitly */ - visibility: hidden; - } - - #status { - line-height: 1.3; - cursor: pointer; - visibility: visible; - padding: 4px 6px; - } - - - /* Debug output - * ============ */ - - #output-panel { - display: none; - max-width: 700px; - font-size: small; - margin: 6px auto 0; - padding: 0 4px 4px; - text-align: left; - line-height: 2.2; - } - - #output-header { - display: flex; - justify-content: space-between; - align-items: center; - } - - #output-container { - padding: 6px; - background-color: #2c2a32; - box-shadow: inset 0 0 1px 1px #232127; - color: #bbb; - } - - #output-scroll { - line-height: 1; - height: 12em; - overflow-y: scroll; - white-space: pre-wrap; - font-size: small; - font-family: "Lucida Console", Monaco, monospace; - } - </style> -$GODOT_HEAD_INCLUDE -</head> -<body> - <div id="container"> - <canvas id="canvas" width="640" height="480" tabindex="0" oncontextmenu="event.preventDefault();"> - HTML5 canvas appears to be unsupported in the current browser.<br /> - Please try updating or use a different browser. - </canvas> - <div id="status-container"> - <span id="status" class="godot" onclick="this.style.visibility='hidden';">Downloading page...</span> - </div> - </div> - <div id="output-panel" class="godot"> - <div id="output-header"> - Output: - <button class="godot" type="button" autocomplete="off" onclick="Presentation.clearOutput();">Clear</button> - </div> - <div id="output-container"><div id="output-scroll"></div></div> - </div> - - <!-- Scripts --> - <script type="text/javascript">//<![CDATA[ - var Presentation = (function() { - var statusElement = document.getElementById("status"); - var canvasElement = document.getElementById("canvas"); - - var presentation = { - postRun: [], - setStatusVisible: function setStatusVisible(visible) { - statusElement.style.visibility = (visible ? "visible" : "hidden"); - }, - setStatus: function setStatus(text) { - if (text.length === 0) { - // emscripten sets empty string as status after "Running..." - // per timeout, but another status may have been set by then - if (Presentation.setStatus.lastText === "Running...") - Presentation.setStatusVisible(false); - return; - } - Presentation.setStatus.lastText = text; - while (statusElement.lastChild) { - statusElement.removeChild(statusElement.lastChild); - } - var lines = text.split("\n"); - lines.forEach(function(line, index) { - statusElement.appendChild(document.createTextNode(line)); - statusElement.appendChild(document.createElement("br")); - }); - var closeNote = document.createElement("span"); - closeNote.style.fontSize = "small"; - closeNote.textContent = "click to close"; - statusElement.appendChild(closeNote); - Presentation.setStatusVisible(true); - }, - isWebGL2Available: function isWebGL2Available() { - var context; - try { - context = canvasElement.getContext("webgl2") || canvasElement.getContext("experimental-webgl2"); - } catch (e) {} - return !!context; - }, - }; - - window.onerror = function(event) { presentation.setStatus("Failure during start-up\nSee JavaScript console") }; - - if ($GODOT_DEBUG_ENABLED) { // debugging enabled - var outputRoot = document.getElementById("output-panel"); - var outputElement = document.getElementById("output-scroll"); - const maxOutputMessages = 400; - - presentation.setOutputVisible = function setOutputVisible(visible) { - outputRoot.style.display = (visible ? "block" : "none"); - }; - presentation.clearOutput = function clearOutput() { - while (outputElement.firstChild) { - outputElement.firstChild.remove(); - } - }; - - presentation.setOutputVisible(true); - - presentation.print = function print(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - if (text.length <= 0) return; - while (outputElement.childElementCount >= maxOutputMessages) { - outputElement.firstChild.remove(); - } - var msg = document.createElement("div"); - if (String.prototype.trim.call(text).startsWith("**ERROR**") - || String.prototype.trim.call(text).startsWith("**EXCEPTION**")) { - msg.style.color = "#d44"; - } else if (String.prototype.trim.call(text).startsWith("**WARNING**")) { - msg.style.color = "#ccc000"; - } else if (String.prototype.trim.call(text).startsWith("**SCRIPT ERROR**")) { - msg.style.color = "#c6d"; - } - msg.textContent = text; - var scrollToBottom = outputElement.scrollHeight - (outputElement.clientHeight + outputElement.scrollTop) < 10; - outputElement.appendChild(msg); - if (scrollToBottom) { - outputElement.scrollTop = outputElement.scrollHeight; - } - }; - - presentation.postRun.push(function() { - window.onerror = function(event) { presentation.print("**EXCEPTION**:", event) }; - }); - - } else { - presentation.postRun.push(function() { window.onerror = null; }); - } - - return presentation; - })(); - - // Emscripten interface - var Module = (function() { - const BASE_NAME = '$GODOT_BASE'; - var module = { - thisProgram: BASE_NAME, - wasmBinaryFile: BASE_NAME + '.wasm', - TOTAL_MEMORY: $GODOT_TMEM, - print: function print(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - console.log(text); - if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") { - Presentation.print(text); - } - }, - printErr: function printErr(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - console.error(text); - if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") { - Presentation.print("**ERROR**:", text) - } - }, - canvas: document.getElementById("canvas"), - setStatus: function setStatus(text) { - var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); - var now = Date.now(); - if (m) { - if (now - Date.now() < 30) // if this is a progress update, skip it if too soon - return; - text = m[1]; - } - if (typeof Presentation !== "undefined" && typeof Presentation.setStatus == "function") { - Presentation.setStatus(text); - } - } - }; - - // As a default initial behavior, pop up an alert when WebGL context is lost. To make your - // application robust, you may want to override this behavior before shipping! - // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 - module.canvas.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false); - - if (typeof Presentation !== "undefined" && Presentation.postRun instanceof Array) { - module.postRun = Presentation.postRun; - } - - return module; - })(); - - if (!Presentation.isWebGL2Available()) { - Presentation.setStatus("WebGL 2 appears to be unsupported.\nPlease update browser and drivers."); - Presentation.preventLoading = true; - } else { - Presentation.setStatus("Downloading..."); - } - - if (Presentation.preventLoading) { - // prevent *fs.js and Emscripten's SCRIPT placeholder from loading any files - Presentation._XHR_send = XMLHttpRequest.prototype.send; - XMLHttpRequest.prototype.send = function() {}; - Presentation._Node_appendChild = Node.prototype.appendChild; - Node.prototype.appendChild = function(node) { - if (!(node instanceof HTMLScriptElement)) { - return Presentation._Node_appendChild.call(this, node); - } - } - } - //]]></script> - <script type="text/javascript" src="$GODOT_BASEfs.js"></script> -{{{ SCRIPT }}} - <script type="text/javascript"> - if (Presentation.preventLoading) { - XMLHttpRequest.prototype.send = Presentation._XHR_send; - Node.prototype.appendChild = Presentation._Node_appendChild; - } - </script> -</body> -</html> diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index a0e5610591..ac8d367366 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -521,21 +521,6 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i #undef SET_EM_CALLBACK #undef EM_CHECK - /* clang-format off */ - EM_ASM_ARGS({ - const send_notification = Module.cwrap('send_notification', null, ['number']); - const notifs = arguments; - (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) { - Module.canvas.addEventListener(event, send_notification.bind(this, notifs[i])); - }); - }, - MainLoop::NOTIFICATION_WM_MOUSE_ENTER, - MainLoop::NOTIFICATION_WM_MOUSE_EXIT, - MainLoop::NOTIFICATION_WM_FOCUS_IN, - MainLoop::NOTIFICATION_WM_FOCUS_OUT - ); -/* clang-format on */ - #ifdef JAVASCRIPT_EVAL_ENABLED javascript_eval = memnew(JavaScript); ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaScript", javascript_eval)); @@ -818,7 +803,23 @@ void OS_JavaScript::main_loop_begin() { if (main_loop) main_loop->init(); + + /* clang-format off */ + EM_ASM_ARGS({ + const send_notification = Module.cwrap('send_notification', null, ['number']); + const notifs = arguments; + (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) { + Module.canvas.addEventListener(event, send_notification.bind(null, notifs[i])); + }); + }, + MainLoop::NOTIFICATION_WM_MOUSE_ENTER, + MainLoop::NOTIFICATION_WM_MOUSE_EXIT, + MainLoop::NOTIFICATION_WM_FOCUS_IN, + MainLoop::NOTIFICATION_WM_FOCUS_OUT + ); + /* clang-format on */ } + bool OS_JavaScript::main_loop_iterate() { if (!main_loop) diff --git a/platform/javascript/pre_asmjs.js b/platform/javascript/pre_asmjs.js new file mode 100644 index 0000000000..3c497721b6 --- /dev/null +++ b/platform/javascript/pre_asmjs.js @@ -0,0 +1,3 @@ +var Engine = { + USING_WASM: false, + RuntimeEnvironment: function(Module) { diff --git a/platform/javascript/pre_wasm.js b/platform/javascript/pre_wasm.js new file mode 100644 index 0000000000..be4383c8c9 --- /dev/null +++ b/platform/javascript/pre_wasm.js @@ -0,0 +1,3 @@ +var Engine = { + USING_WASM: true, + RuntimeEnvironment: function(Module) { diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index a2be126c58..25d44c24b5 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -466,8 +466,6 @@ void AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t EditorNode::progress_task_step(progress_task, "File: " + p_file_name, (p_file_no * 100) / p_total_files); } - bool do_hash = p_file_name != "AppxSignature.p7x"; - FileMeta meta; meta.name = p_file_name; meta.uncompressed_size = p_len; diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index 328b987f1f..8640f27699 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -130,24 +130,28 @@ Error ContextGL_Win::initialize() { 0, 0, 0 // Layer Masks Ignored }; - if (!(hDC = GetDC(hWnd))) { + hDC = GetDC(hWnd); + if (!hDC) { MessageBox(NULL, "Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } - if (!(pixel_format = ChoosePixelFormat(hDC, &pfd))) // Did Windows Find A Matching Pixel Format? + pixel_format = ChoosePixelFormat(hDC, &pfd); + if (!pixel_format) // Did Windows Find A Matching Pixel Format? { MessageBox(NULL, "Can't Find A Suitable pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } - if (!SetPixelFormat(hDC, pixel_format, &pfd)) // Are We Able To Set The Pixel Format? + BOOL ret = SetPixelFormat(hDC, pixel_format, &pfd); + if (!ret) // Are We Able To Set The Pixel Format? { MessageBox(NULL, "Can't Set The pixel_format.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE } - if (!(hRC = wglCreateContext(hDC))) // Are We Able To Get A Rendering Context? + hRC = wglCreateContext(hDC); + if (!hRC) // Are We Able To Get A Rendering Context? { MessageBox(NULL, "Can't Create A Temporary GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return FALSE @@ -175,8 +179,8 @@ Error ContextGL_Win::initialize() { return ERR_CANT_CREATE; } - HGLRC new_hRC; - if (!(new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs))) { + HGLRC new_hRC = wglCreateContextAttribsARB(hDC, 0, attribs); + if (!new_hRC) { wglDeleteContext(hRC); MessageBox(NULL, "Can't Create An OpenGL 3.3 Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return ERR_CANT_CREATE; // Return false diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp index 00cfa812de..0c7358f499 100644 --- a/platform/windows/joypad.cpp +++ b/platform/windows/joypad.cpp @@ -379,7 +379,9 @@ void JoypadWindows::process_joypads() { IDirectInputDevice8_Acquire(joy->di_joy); joy->di_joy->Poll(); } - if (FAILED(hr = joy->di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js))) { + + hr = joy->di_joy->GetDeviceState(sizeof(DIJOYSTATE2), &js); + if (FAILED(hr)) { //printf("failed to read joy #%d\n", i); continue; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index deb9c25576..5814d883cd 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -996,7 +996,16 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int video_mode.fullscreen = false; } else { - if (!(hWnd = CreateWindowExW(dwExStyle, L"Engine", L"", dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, (GetSystemMetrics(SM_CXSCREEN) - WindowRect.right) / 2, (GetSystemMetrics(SM_CYSCREEN) - WindowRect.bottom) / 2, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, NULL, NULL, hInstance, NULL))) { + hWnd = CreateWindowExW( + dwExStyle, + L"Engine", L"", + dwStyle | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + (GetSystemMetrics(SM_CXSCREEN) - WindowRect.right) / 2, + (GetSystemMetrics(SM_CYSCREEN) - WindowRect.bottom) / 2, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + NULL, NULL, hInstance, NULL); + if (!hWnd) { MessageBoxW(NULL, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); return; // Return FALSE } diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index f96343c92c..4dd85a558f 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -246,6 +246,11 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au // 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; @@ -695,6 +700,12 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { xev.xclient.data.l[2] = 0; XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + + // set bypass compositor hint + Atom bypass_compositor = XInternAtom(x11_display, "_NET_WM_BYPASS_COMPOSITOR", False); + unsigned long compositing_disable_on = p_enabled ? 1 : 0; + XChangeProperty(x11_display, x11_window, bypass_compositor, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&compositing_disable_on, 1); + XFlush(x11_display); if (!p_enabled && !is_window_resizable()) { diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 1124904963..9fc6c8d23a 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -596,7 +596,7 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("_area_enter_tree", "id"), &Area2D::_area_enter_tree); ClassDB::bind_method(D_METHOD("_area_exit_tree", "id"), &Area2D::_area_exit_tree); - ClassDB::bind_method(D_METHOD("set_space_override_mode", "enable"), &Area2D::set_space_override_mode); + ClassDB::bind_method(D_METHOD("set_space_override_mode", "space_override_mode"), &Area2D::set_space_override_mode); ClassDB::bind_method(D_METHOD("get_space_override_mode"), &Area2D::get_space_override_mode); ClassDB::bind_method(D_METHOD("set_gravity_is_point", "enable"), &Area2D::set_gravity_is_point); @@ -680,6 +680,12 @@ void Area2D::_bind_methods() { ADD_GROUP("Audio Bus", "audio_bus_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus"); + + BIND_ENUM_CONSTANT(SPACE_OVERRIDE_DISABLED); + BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE); + BIND_ENUM_CONSTANT(SPACE_OVERRIDE_COMBINE_REPLACE); + BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE); + BIND_ENUM_CONSTANT(SPACE_OVERRIDE_REPLACE_COMBINE); } Area2D::Area2D() diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp index 39d3f2d6bf..d2a8e3315a 100644 --- a/scene/2d/audio_stream_player_2d.cpp +++ b/scene/2d/audio_stream_player_2d.cpp @@ -217,13 +217,15 @@ void AudioStreamPlayer2D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - _change_notify("playing"); //update property in editor + //do not update, this makes it easier to animate (will shut off otherise) + //_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_fixed_process_internal(false); - _change_notify("playing"); //update property in editor + //do not update, this makes it easier to animate (will shut off otherise) + //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -252,8 +254,6 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) { stream.unref(); ERR_FAIL_COND(stream_playback.is_null()); } - - } Ref<AudioStream> AudioStreamPlayer2D::get_stream() const { @@ -439,7 +439,7 @@ void AudioStreamPlayer2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "1,65536,1"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING), "set_attenuation", "get_attenuation"); @@ -447,7 +447,6 @@ void AudioStreamPlayer2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask"); ADD_SIGNAL(MethodInfo("finished")); - } AudioStreamPlayer2D::AudioStreamPlayer2D() { diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 4f00966e75..ec1ea7df38 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -37,6 +37,7 @@ #include "scene/resources/style_box.h" #include "scene/resources/texture.h" #include "scene/scene_string_names.h" +#include "servers/visual/visual_server_raster.h" #include "servers/visual_server.h" Mutex *CanvasItemMaterial::material_mutex = NULL; @@ -337,7 +338,6 @@ void CanvasItem::_update_callback() { notification(NOTIFICATION_DRAW); emit_signal(SceneStringNames::get_singleton()->draw); if (get_script_instance()) { - Variant::CallError err; get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_draw, NULL, 0); } drawing = false; diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp index 1235013af4..53db30e3ce 100644 --- a/scene/2d/line_builder.cpp +++ b/scene/2d/line_builder.cpp @@ -173,13 +173,15 @@ void LineBuilder::build() { strip_begin(pos_up0, pos_down0, color0, uvx0); - // pos_up0 ------------- pos_up1 -------------------- - // | | - // pos0 - - - - - - - - - pos1 - - - - - - - - - pos2 - // | | - // pos_down0 ------------ pos_down1 ------------------ - // - // i-1 i i+1 + /* + * pos_up0 ------------- pos_up1 -------------------- + * | | + * pos0 - - - - - - - - - pos1 - - - - - - - - - pos2 + * | | + * pos_down0 ------------ pos_down1 ------------------ + * + * i-1 i i+1 + */ // http://labs.hyperandroid.com/tag/opengl-lines // (not the same implementation but visuals help a lot) @@ -206,17 +208,19 @@ void LineBuilder::build() { inner_normal1 = -u1 * hw; } - // --------------------------- - // / - // 0 / 1 - // / / - // --------------------x------ / - // / / (here shown with orientation == DOWN) - // / / - // / / - // / / - // 2 / - // / + /* + * --------------------------- + * / + * 0 / 1 + * / / + * --------------------x------ / + * / / (here shown with orientation == DOWN) + * / / + * / / + * / / + * 2 / + * / + */ // Find inner intersection at the joint Vector2 corner_pos_in, corner_pos_out; @@ -315,13 +319,14 @@ void LineBuilder::build() { // Add joint geometry if (current_joint_mode != LINE_JOINT_SHARP) { - // ________________ cbegin - // / \ - // / \ - // ____________/_ _ _\ cend - // | | - // | | - // | | + /* ________________ cbegin + * / \ + * / \ + * ____________/_ _ _\ cend + * | | + * | | + * | | + */ Vector2 cbegin, cend; if (orientation == UP) { diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index 1d7bd8fc2a..9bd5576d91 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -137,7 +137,8 @@ void PathFollow2D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { - if ((path = Object::cast_to<Path2D>(get_parent()))) { + path = Object::cast_to<Path2D>(get_parent()); + if (path) { _update_transform(); } diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index caf313190b..966dd88a2c 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -31,7 +31,6 @@ #include "arvr_nodes.h" #include "core/os/input.h" #include "servers/arvr/arvr_interface.h" -#include "servers/arvr/arvr_positional_tracker.h" #include "servers/arvr_server.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -142,6 +141,7 @@ void ARVRController::_bind_methods() { ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis); ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active); + ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand); ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button"))); ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button"))); @@ -204,6 +204,19 @@ bool ARVRController::get_is_active() const { return is_active; }; +ARVRPositionalTracker::TrackerHand ARVRController::get_hand() const { + // get our ARVRServer + ARVRServer *arvr_server = ARVRServer::get_singleton(); + ERR_FAIL_NULL_V(arvr_server, ARVRPositionalTracker::TRACKER_HAND_UNKNOWN); + + ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id); + if (tracker == NULL) { + return ARVRPositionalTracker::TRACKER_HAND_UNKNOWN; + }; + + return tracker->get_hand(); +}; + String ARVRController::get_configuration_warning() const { if (!is_visible() || !is_inside_tree()) return String(); diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h index 4c14be71b5..5269ec0248 100644 --- a/scene/3d/arvr_nodes.h +++ b/scene/3d/arvr_nodes.h @@ -33,6 +33,7 @@ #include "scene/3d/camera.h" #include "scene/3d/spatial.h" +#include "servers/arvr/arvr_positional_tracker.h" /** @author Bastiaan Olij <mux213@gmail.com> @@ -84,6 +85,7 @@ public: float get_joystick_axis(int p_axis) const; bool get_is_active() const; + ARVRPositionalTracker::TrackerHand get_hand() const; String get_configuration_warning() const; diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index a69bec2fc8..2073ebf94e 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -530,13 +530,15 @@ void AudioStreamPlayer3D::_notification(int p_what) { setseek = setplay; active = true; setplay = -1; - _change_notify("playing"); //update property in editor + //do not update, this makes it easier to animate (will shut off otherise) + ///_change_notify("playing"); //update property in editor } //stop playing if no longer active if (!active) { set_fixed_process_internal(false); - _change_notify("playing"); //update property in editor + //do not update, this makes it easier to animate (will shut off otherise) + //_change_notify("playing"); //update property in editor emit_signal("finished"); } } @@ -877,7 +879,7 @@ void AudioStreamPlayer3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "0,65536,1"), "set_max_distance", "get_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode"); diff --git a/scene/3d/bone_attachment.cpp b/scene/3d/bone_attachment.cpp index e1a5329fb0..2580b645e2 100644 --- a/scene/3d/bone_attachment.cpp +++ b/scene/3d/bone_attachment.cpp @@ -71,7 +71,8 @@ void BoneAttachment::_get_property_list(List<PropertyInfo> *p_list) const { void BoneAttachment::_check_bind() { - if (Skeleton *sk = Object::cast_to<Skeleton>(get_parent())) { + Skeleton *sk = Object::cast_to<Skeleton>(get_parent()); + if (sk) { int idx = sk->find_bone(bone_name); if (idx != -1) { @@ -86,7 +87,8 @@ void BoneAttachment::_check_unbind() { if (bound) { - if (Skeleton *sk = Object::cast_to<Skeleton>(get_parent())) { + Skeleton *sk = Object::cast_to<Skeleton>(get_parent()); + if (sk) { int idx = sk->find_bone(bone_name); if (idx != -1) { diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index 5f1151f8e9..f49d89122d 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -50,7 +50,8 @@ void CollisionShape::make_convex_from_brothers() { for (int i = 0; i < p->get_child_count(); i++) { Node *n = p->get_child(i); - if (MeshInstance *mi = Object::cast_to<MeshInstance>(n)) { + MeshInstance *mi = Object::cast_to<MeshInstance>(n); + if (mi) { Ref<Mesh> m = mi->get_mesh(); if (m.is_valid()) { diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index bb54a43028..66364d40f9 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -696,22 +696,6 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons p_baker->bake_cells[p_idx].normal[2] += normal_accum.z; p_baker->bake_cells[p_idx].alpha += alpha; - static const Vector3 side_normals[6] = { - Vector3(-1, 0, 0), - Vector3(1, 0, 0), - Vector3(0, -1, 0), - Vector3(0, 1, 0), - Vector3(0, 0, -1), - Vector3(0, 0, 1), - }; - - /* - for(int i=0;i<6;i++) { - if (normal.dot(side_normals[i])>CMP_EPSILON) { - p_baker->bake_cells[p_idx].used_sides|=(1<<i); - } - }*/ - } else { //go down @@ -1092,7 +1076,7 @@ void GIProbe::_plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_b void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node); - if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT)) { + if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) { Ref<Mesh> mesh = mi->get_mesh(); if (mesh.is_valid()) { @@ -1113,25 +1097,29 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) { } } - if (Spatial *s = Object::cast_to<Spatial>(p_at_node)) { + Spatial *s = Object::cast_to<Spatial>(p_at_node); + if (s) { - Array meshes = p_at_node->call("get_meshes"); - for (int i = 0; i < meshes.size(); i += 2) { + if (s->is_visible_in_tree()) { - Transform mxf = meshes[i]; - Ref<Mesh> mesh = meshes[i + 1]; - if (!mesh.is_valid()) - continue; + Array meshes = p_at_node->call("get_meshes"); + for (int i = 0; i < meshes.size(); i += 2) { - Rect3 aabb = mesh->get_aabb(); + Transform mxf = meshes[i]; + Ref<Mesh> mesh = meshes[i + 1]; + if (!mesh.is_valid()) + continue; - Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + Rect3 aabb = mesh->get_aabb(); - if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) { - Baker::PlotMesh pm; - pm.local_xform = xf; - pm.mesh = mesh; - p_baker->mesh_list.push_back(pm); + Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf); + + if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) { + Baker::PlotMesh pm; + pm.local_xform = xf; + pm.mesh = mesh; + p_baker->mesh_list.push_back(pm); + } } } } diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp index 157ae42571..0f281b694d 100644 --- a/scene/3d/interpolated_camera.cpp +++ b/scene/3d/interpolated_camera.cpp @@ -55,8 +55,8 @@ void InterpolatedCamera::_notification(int p_what) { Transform local_transform = get_global_transform(); local_transform = local_transform.interpolate_with(target_xform, delta); set_global_transform(local_transform); - - if (Camera *cam = Object::cast_to<Camera>(node)) { + Camera *cam = Object::cast_to<Camera>(node); + if (cam) { if (cam->get_projection() == get_projection()) { diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 09b253b309..096f787873 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -230,7 +230,6 @@ void Light::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_max_distance", PROPERTY_HINT_RANGE, "0,65536,0.1"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); @@ -308,6 +307,16 @@ DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const { return shadow_mode; } +void DirectionalLight::set_shadow_depth_range(ShadowDepthRange p_range) { + shadow_depth_range = p_range; + VS::get_singleton()->light_directional_set_shadow_depth_range_mode(light, VS::LightDirectionalShadowDepthRangeMode(p_range)); +} + +DirectionalLight::ShadowDepthRange DirectionalLight::get_shadow_depth_range() const { + + return shadow_depth_range; +} + void DirectionalLight::set_blend_splits(bool p_enable) { blend_splits = p_enable; @@ -324,6 +333,9 @@ void DirectionalLight::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight::set_shadow_mode); ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight::get_shadow_mode); + ClassDB::bind_method(D_METHOD("set_shadow_depth_range", "mode"), &DirectionalLight::set_shadow_depth_range); + ClassDB::bind_method(D_METHOD("get_shadow_depth_range"), &DirectionalLight::get_shadow_depth_range); + ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight::set_blend_splits); ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight::is_blend_splits_enabled); @@ -335,10 +347,15 @@ void DirectionalLight::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE); + ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_max_distance", PROPERTY_HINT_RANGE, "0,65536,0.1"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS); + + BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_STABLE); + BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_OPTIMIZED); } DirectionalLight::DirectionalLight() @@ -349,6 +366,7 @@ DirectionalLight::DirectionalLight() set_param(PARAM_SHADOW_MAX_DISTANCE, 200); set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); + set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); blend_splits = false; } diff --git a/scene/3d/light.h b/scene/3d/light.h index 5d589d33e5..6aa0220265 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -133,9 +133,15 @@ public: SHADOW_PARALLEL_4_SPLITS }; + enum ShadowDepthRange { + SHADOW_DEPTH_RANGE_STABLE = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE, + SHADOW_DEPTH_RANGE_OPTIMIZED = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED, + }; + private: bool blend_splits; ShadowMode shadow_mode; + ShadowDepthRange shadow_depth_range; protected: static void _bind_methods(); @@ -144,6 +150,9 @@ public: void set_shadow_mode(ShadowMode p_mode); ShadowMode get_shadow_mode() const; + void set_shadow_depth_range(ShadowDepthRange p_mode); + ShadowDepthRange get_shadow_depth_range() const; + void set_blend_splits(bool p_enable); bool is_blend_splits_enabled() const; @@ -151,6 +160,7 @@ public: }; VARIANT_ENUM_CAST(DirectionalLight::ShadowMode) +VARIANT_ENUM_CAST(DirectionalLight::ShadowDepthRange) class OmniLight : public Light { diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index ed4d88417c..60245fe6ce 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -155,8 +155,8 @@ void PathFollow::_notification(int p_what) { Node *parent = get_parent(); if (parent) { - - if ((path = Object::cast_to<Path>(parent))) { + path = Object::cast_to<Path>(parent); + if (path) { _update_transform(); } } diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 9590394211..6a8226c0e1 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -912,35 +912,24 @@ RigidBody::~RigidBody() { ////////////////////////////////////////////////////// ////////////////////////// -Dictionary KinematicBody::_move(const Vector3 &p_motion) { +Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion) { Collision col; - if (move(p_motion, col)) { - Dictionary d; - d["position"] = col.collision; - d["normal"] = col.normal; - d["local_shape"] = col.local_shape; - d["travel"] = col.travel; - d["remainder"] = col.remainder; - d["collider_id"] = col.collider; - if (col.collider) { - d["collider"] = ObjectDB::get_instance(col.collider); - } else { - d["collider"] = Variant(); + if (move_and_collide(p_motion, col)) { + if (motion_cache.is_null()) { + motion_cache.instance(); + motion_cache->owner = this; } - d["collider_velocity"] = col.collider_vel; - d["collider_shape_index"] = col.collider_shape; - d["collider_metadata"] = col.collider_metadata; - - return d; + motion_cache->collision = col; - } else { - return Dictionary(); + return motion_cache; } + + return Ref<KinematicCollision>(); } -bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) { +bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_collision) { Transform gt = get_global_transform(); PhysicsServer::MotionResult result; @@ -964,7 +953,7 @@ bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) { return colliding; } -Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) { +Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) { Vector3 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time(); Vector3 lv = p_linear_velocity; @@ -975,11 +964,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve colliders.clear(); floor_velocity = Vector3(); - while (p_max_bounces) { + while (p_max_slides) { Collision collision; - bool collided = move(motion, collision); + bool collided = move_and_collide(motion, collision); if (collided) { @@ -1017,7 +1006,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve break; } - p_max_bounces--; + p_max_slides--; if (motion == Vector3()) break; } @@ -1059,79 +1048,36 @@ float KinematicBody::get_safe_margin() const { return margin; } - -int KinematicBody::get_collision_count() const { +int KinematicBody::get_slide_count() const { return colliders.size(); } -Vector3 KinematicBody::get_collision_position(int p_collision) const { - - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].collision; -} -Vector3 KinematicBody::get_collision_normal(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].normal; +KinematicBody::Collision KinematicBody::get_slide_collision(int p_bounce) const { + ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision()); + return colliders[p_bounce]; } -Vector3 KinematicBody::get_collision_travel(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].travel; -} -Vector3 KinematicBody::get_collision_remainder(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].remainder; -} -Object *KinematicBody::get_collision_local_shape(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); - uint32_t owner = shape_find_owner(colliders[p_collision].local_shape); - return shape_owner_get_owner(owner); -} -Object *KinematicBody::get_collision_collider(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); +Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) { - if (colliders[p_collision].collider) { - return ObjectDB::get_instance(colliders[p_collision].collider); + ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision>()); + if (p_bounce > slide_colliders.size()) { + slide_colliders.resize(p_bounce + 1); } - return NULL; -} -ObjectID KinematicBody::get_collision_collider_id(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0); - - return colliders[p_collision].collider; -} -Object *KinematicBody::get_collision_collider_shape(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL); - Object *collider = get_collision_collider(p_collision); - if (collider) { - CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider); - if (obj2d) { - uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape); - return obj2d->shape_owner_get_owner(owner); - } + if (slide_colliders[p_bounce].is_null()) { + slide_colliders[p_bounce].instance(); + slide_colliders[p_bounce]->owner = this; } - return NULL; -} -int KinematicBody::get_collision_collider_shape_index(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1); - return colliders[p_collision].collider_shape; -} -Vector3 KinematicBody::get_collision_collider_velocity(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3()); - return colliders[p_collision].collider_vel; -} -Variant KinematicBody::get_collision_collider_metadata(int p_collision) const { - ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant()); - return colliders[p_collision].collider_metadata; + slide_colliders[p_bounce]->collision = colliders[p_bounce]; + return slide_colliders[p_bounce]; } void KinematicBody::_bind_methods() { - ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody::_move); - ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); + ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody::_move); + ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_slides", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45))); ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody::test_move); @@ -1143,18 +1089,8 @@ void KinematicBody::_bind_methods() { ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin); - ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody::get_collision_count); - ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody::get_collision_position); - ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody::get_collision_normal); - ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody::get_collision_travel); - ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody::get_collision_remainder); - ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody::get_collision_local_shape); - ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody::get_collision_collider); - ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody::get_collision_collider_id); - ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody::get_collision_collider_shape); - ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody::get_collision_collider_shape_index); - ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody::get_collision_collider_velocity); - ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody::get_collision_collider_metadata); + ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count); + ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision); ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin"); } @@ -1169,4 +1105,106 @@ KinematicBody::KinematicBody() on_wall = false; } KinematicBody::~KinematicBody() { + + if (motion_cache.is_valid()) { + motion_cache->owner = NULL; + } + + for (int i = 0; i < slide_colliders.size(); i++) { + if (slide_colliders[i].is_valid()) { + slide_colliders[i]->owner = NULL; + } + } +} +/////////////////////////////////////// + +Vector3 KinematicCollision::get_position() const { + + return collision.collision; +} +Vector3 KinematicCollision::get_normal() const { + return collision.normal; +} +Vector3 KinematicCollision::get_travel() const { + return collision.travel; +} +Vector3 KinematicCollision::get_remainder() const { + return collision.remainder; +} +Object *KinematicCollision::get_local_shape() const { + ERR_FAIL_COND_V(!owner, NULL); + uint32_t ownerid = owner->shape_find_owner(collision.local_shape); + return owner->shape_owner_get_owner(ownerid); +} + +Object *KinematicCollision::get_collider() const { + + if (collision.collider) { + return ObjectDB::get_instance(collision.collider); + } + + return NULL; +} +ObjectID KinematicCollision::get_collider_id() const { + + return collision.collider; +} +Object *KinematicCollision::get_collider_shape() const { + + Object *collider = get_collider(); + if (collider) { + CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider); + if (obj2d) { + uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape); + return obj2d->shape_owner_get_owner(ownerid); + } + } + + return NULL; +} +int KinematicCollision::get_collider_shape_index() const { + + return collision.collider_shape; +} +Vector3 KinematicCollision::get_collider_velocity() const { + + return collision.collider_vel; +} +Variant KinematicCollision::get_collider_metadata() const { + + return Variant(); +} + +void KinematicCollision::_bind_methods() { + + ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision::get_position); + ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision::get_normal); + ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision::get_travel); + ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision::get_remainder); + ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision::get_local_shape); + ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision::get_collider); + ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision::get_collider_id); + ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision::get_collider_shape); + ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision::get_collider_shape_index); + ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision::get_collider_velocity); + ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision::get_collider_metadata); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "", "get_position"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "", "get_normal"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_collider_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata"); +} + +KinematicCollision::KinematicCollision() { + collision.collider = 0; + collision.collider_shape = 0; + collision.local_shape = 0; + owner = NULL; } diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 23d752ad76..f88b3860dc 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -261,6 +261,8 @@ public: VARIANT_ENUM_CAST(RigidBody::Mode); VARIANT_ENUM_CAST(RigidBody::AxisLock); +class KinematicCollision; + class KinematicBody : public PhysicsBody { GDCLASS(KinematicBody, PhysicsBody); @@ -286,42 +288,62 @@ private: bool on_ceiling; bool on_wall; Vector<Collision> colliders; + Vector<Ref<KinematicCollision> > slide_colliders; + Ref<KinematicCollision> motion_cache; _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const; - Dictionary _move(const Vector3 &p_motion); + Ref<KinematicCollision> _move(const Vector3 &p_motion); + Ref<KinematicCollision> _get_slide_collision(int p_bounce); protected: static void _bind_methods(); public: - bool move(const Vector3 &p_motion, Collision &r_collision); + bool move_and_collide(const Vector3 &p_motion, Collision &r_collision); bool test_move(const Transform &p_from, const Vector3 &p_motion); void set_safe_margin(float p_margin); float get_safe_margin() const; - Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45)); + Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45)); bool is_on_floor() const; bool is_on_wall() const; bool is_on_ceiling() const; Vector3 get_floor_velocity() const; - int get_collision_count() const; - Vector3 get_collision_position(int p_collision) const; - Vector3 get_collision_normal(int p_collision) const; - Vector3 get_collision_travel(int p_collision) const; - Vector3 get_collision_remainder(int p_collision) const; - Object *get_collision_local_shape(int p_collision) const; - Object *get_collision_collider(int p_collision) const; - ObjectID get_collision_collider_id(int p_collision) const; - Object *get_collision_collider_shape(int p_collision) const; - int get_collision_collider_shape_index(int p_collision) const; - Vector3 get_collision_collider_velocity(int p_collision) const; - Variant get_collision_collider_metadata(int p_collision) const; + int get_slide_count() const; + Collision get_slide_collision(int p_bounce) const; KinematicBody(); ~KinematicBody(); }; +class KinematicCollision : public Reference { + + GDCLASS(KinematicCollision, Reference); + + KinematicBody *owner; + friend class KinematicBody; + KinematicBody::Collision collision; + +protected: + static void _bind_methods(); + +public: + Vector3 get_position() const; + Vector3 get_normal() const; + Vector3 get_travel() const; + Vector3 get_remainder() const; + Object *get_local_shape() const; + Object *get_collider() const; + ObjectID get_collider_id() const; + Object *get_collider_shape() const; + int get_collider_shape_index() const; + Vector3 get_collider_velocity() const; + Variant get_collider_metadata() const; + + KinematicCollision(); +}; + #endif // PHYSICS_BODY__H diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp index 7db3bb18bd..91fe426b99 100644 --- a/scene/3d/spatial.cpp +++ b/scene/3d/spatial.cpp @@ -175,7 +175,6 @@ void Spatial::_notification(int p_what) { if (get_script_instance()) { - Variant::CallError err; get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, NULL, 0); } #ifdef TOOLS_ENABLED @@ -207,7 +206,6 @@ void Spatial::_notification(int p_what) { if (get_script_instance()) { - Variant::CallError err; get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, NULL, 0); } diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index d6b3206fbf..3518113130 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -102,6 +102,14 @@ void VehicleWheel::_notification(int p_what) { } } +String VehicleWheel::get_configuration_warning() const { + if (!Object::cast_to<VehicleBody>(get_parent())) { + return TTR("VehicleWheel serves to provide a wheel system to a VehicleBody. Please use it as a child of a VehicleBody."); + } + + return String(); +} + void VehicleWheel::_update(PhysicsDirectBodyState *s) { if (m_raycastInfo.m_isInContact) diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h index d67209c58f..eb661adb90 100644 --- a/scene/3d/vehicle_body.h +++ b/scene/3d/vehicle_body.h @@ -131,6 +131,8 @@ public: void set_roll_influence(float p_value); float get_roll_influence() const; + String get_configuration_warning() const; + VehicleWheel(); }; diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index e2330eb0d4..7a5c7e450b 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -1156,6 +1156,7 @@ void AnimationTreePlayer::transition_node_set_xfade_time(const StringName &p_nod } void AnimationTreePlayer::TransitionNode::set_current(int p_current) { + ERR_FAIL_INDEX(p_current, inputs.size()); if (current == p_current) diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp index 8bd924e7ce..341ae45ce8 100644 --- a/scene/audio/audio_player.cpp +++ b/scene/audio/audio_player.cpp @@ -304,7 +304,7 @@ void AudioStreamPlayer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "play", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mix_target", PROPERTY_HINT_ENUM, "Stereo,Surround,Center"), "set_mix_target", "get_mix_target"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus"); diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp index 8fd19e8655..5713a35b7a 100644 --- a/scene/gui/base_button.cpp +++ b/scene/gui/base_button.cpp @@ -87,14 +87,14 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { status.pressed = !status.pressed; pressed(); - if (get_script_instance()) { - Variant::CallError ce; - get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce); - } + emit_signal("pressed"); _unpress_group(); toggled(status.pressed); + if (get_script_instance()) { + get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, status.pressed); + } emit_signal("toggled", status.pressed); } @@ -143,10 +143,10 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) { emit_signal("pressed"); toggled(status.pressed); - emit_signal("toggled", status.pressed); if (get_script_instance()) { get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, status.pressed); } + emit_signal("toggled", status.pressed); } _unpress_group(); diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp deleted file mode 100644 index 336c88fe9d..0000000000 --- a/scene/gui/button_group.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/*************************************************************************/ -/* button_group.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 "button_group.h" - -#if 0 -#include "base_button.h" - -void ButtonGroup::_add_button(BaseButton *p_button) { - - buttons.insert(p_button); - p_button->set_toggle_mode(true); - p_button->set_click_on_press(true); - p_button->connect("pressed",this,"_pressed",make_binds(p_button)); - -} - -void ButtonGroup::_remove_button(BaseButton *p_button){ - - buttons.erase(p_button); - p_button->disconnect("pressed",this,"_pressed"); - -} - -void ButtonGroup::set_pressed_button(BaseButton *p_button) { - - _pressed(p_button); -} - -void ButtonGroup::_pressed(Object *p_button) { - - ERR_FAIL_NULL(p_button); - BaseButton *b=Object::cast_to<BaseButton>(p_button); - ERR_FAIL_COND(!b); - - for(Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) { - - BaseButton *bb=E->get(); - bb->set_pressed( b==bb ); - if (b==bb){ - emit_signal("button_selected", b); - } - } -} - -Array ButtonGroup::_get_button_list() const { - - List<BaseButton*> b; - get_button_list(&b); - - b.sort_custom<Node::Comparator>(); - - Array arr; - arr.resize(b.size()); - - int idx=0; - - for(List<BaseButton*>::Element *E=b.front();E;E=E->next(),idx++) { - - arr[idx]=E->get(); - } - - return arr; -} - -void ButtonGroup::get_button_list(List<BaseButton*> *p_buttons) const { - - for(Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) { - - p_buttons->push_back(E->get()); - } -} - -BaseButton *ButtonGroup::get_pressed_button() const { - - for(Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) { - - if (E->get()->is_pressed()) - return E->get(); - } - - return NULL; -} - -BaseButton *ButtonGroup::get_focused_button() const{ - - for(Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) { - - if (E->get()->has_focus()) - return E->get(); - } - - return NULL; - -} - -int ButtonGroup::get_pressed_button_index() const { - //in tree order, this is bizarre - - ERR_FAIL_COND_V(!is_inside_tree(),0); - - BaseButton *pressed = get_pressed_button(); - if (!pressed) - return -1; - - List<BaseButton*> blist; - for(Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) { - - blist.push_back(E->get()); - - } - - blist.sort_custom<Node::Comparator>(); - - int idx=0; - for(List<BaseButton*>::Element *E=blist.front();E;E=E->next()) { - - if (E->get()==pressed) - return idx; - - idx++; - } - - return -1; -} - -void ButtonGroup::_bind_methods() { - - ClassDB::bind_method(D_METHOD("get_pressed_button"),&ButtonGroup::get_pressed_button); - ClassDB::bind_method(D_METHOD("get_pressed_button_index"),&ButtonGroup::get_pressed_button_index); - ClassDB::bind_method(D_METHOD("get_focused_button"),&ButtonGroup::get_focused_button); - ClassDB::bind_method(D_METHOD("get_button_list"),&ButtonGroup::_get_button_list); - ClassDB::bind_method(D_METHOD("_pressed"),&ButtonGroup::_pressed); - ClassDB::bind_method(D_METHOD("set_pressed_button","button"),&ButtonGroup::_pressed); - - ADD_SIGNAL( MethodInfo("button_selected",PropertyInfo(Variant::OBJECT,"button",PROPERTY_HINT_RESOURCE_TYPE,"BaseButton"))); -} - -ButtonGroup::ButtonGroup() : BoxContainer(true) -{ -} -#endif diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp index 21e2269141..e2b10a948f 100644 --- a/scene/gui/check_box.cpp +++ b/scene/gui/check_box.cpp @@ -29,7 +29,6 @@ /*************************************************************************/ #include "check_box.h" -#include "button_group.h" #include "servers/visual_server.h" void CheckBox::_notification(int p_what) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 961fccc804..87dfd95724 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -1249,6 +1249,10 @@ void Control::_size_changed() { new_size_cache.height = MAX(minimum_size.height, new_size_cache.height); } + if (get_viewport()->is_snap_controls_to_pixels_enabled()) { + new_size_cache = new_size_cache.floor(); + new_pos_cache = new_pos_cache.floor(); + } bool pos_changed = new_pos_cache != data.pos_cache; bool size_changed = new_size_cache != data.size_cache; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 990c0f3d96..87a232e766 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -183,8 +183,8 @@ void FileDialog::_action_pressed() { String path = dir_access->get_current_dir(); path = path.replace("\\", "/"); - - if (TreeItem *item = tree->get_selected()) { + TreeItem *item = tree->get_selected(); + if (item) { Dictionary d = item->get_metadata(0); if (d["dir"]) { path = path.plus_file(d["name"]); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 8730be0c06..bef0808fd0 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -270,7 +270,7 @@ void GraphNode::_notification(int p_what) { } } - if (resizeable) { + if (resizable) { draw_texture(resizer, get_size() - resizer->get_size()); } } @@ -594,7 +594,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) { Ref<Texture> resizer = get_icon("resizer"); - if (resizeable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) { + if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) { resizing = true; resizing_from = mpos; @@ -645,15 +645,15 @@ bool GraphNode::is_comment() const { return comment; } -void GraphNode::set_resizeable(bool p_enable) { +void GraphNode::set_resizable(bool p_enable) { - resizeable = p_enable; + resizable = p_enable; update(); } -bool GraphNode::is_resizeable() const { +bool GraphNode::is_resizable() const { - return resizeable; + return resizable; } void GraphNode::_bind_methods() { @@ -678,8 +678,8 @@ void GraphNode::_bind_methods() { ClassDB::bind_method(D_METHOD("set_comment", "comment"), &GraphNode::set_comment); ClassDB::bind_method(D_METHOD("is_comment"), &GraphNode::is_comment); - ClassDB::bind_method(D_METHOD("set_resizeable", "resizeable"), &GraphNode::set_resizeable); - ClassDB::bind_method(D_METHOD("is_resizeable"), &GraphNode::is_resizeable); + ClassDB::bind_method(D_METHOD("set_resizable", "resizable"), &GraphNode::set_resizable); + ClassDB::bind_method(D_METHOD("is_resizable"), &GraphNode::is_resizable); ClassDB::bind_method(D_METHOD("set_selected", "selected"), &GraphNode::set_selected); ClassDB::bind_method(D_METHOD("is_selected"), &GraphNode::is_selected); @@ -702,7 +702,7 @@ void GraphNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_close"), "set_show_close_button", "is_close_button_visible"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizeable"), "set_resizeable", "is_resizeable"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resizable"), "set_resizable", "is_resizable"); ADD_SIGNAL(MethodInfo("offset_changed")); ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "from"), PropertyInfo(Variant::VECTOR2, "to"))); @@ -722,7 +722,7 @@ GraphNode::GraphNode() { connpos_dirty = true; set_mouse_filter(MOUSE_FILTER_STOP); comment = false; - resizeable = false; + resizable = false; resizing = false; selected = false; } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 416d711aab..a606e47acd 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -68,7 +68,7 @@ private: bool show_close; Vector2 offset; bool comment; - bool resizeable; + bool resizable; bool resizing; Vector2 resizing_from; @@ -151,8 +151,8 @@ public: void set_comment(bool p_enable); bool is_comment() const; - void set_resizeable(bool p_enable); - bool is_resizeable() const; + void set_resizable(bool p_enable); + bool is_resizable() const; virtual Size2 get_minimum_size() const; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index f8d82a339c..9a605c98f3 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -151,6 +151,20 @@ Color ItemList::get_item_custom_bg_color(int p_idx) const { return items[p_idx].custom_bg; } +void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color) { + + ERR_FAIL_INDEX(p_idx, items.size()); + + items[p_idx].custom_fg = p_custom_fg_color; +} + +Color ItemList::get_item_custom_fg_color(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx, items.size(), Color()); + + return items[p_idx].custom_fg; +} + void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) { ERR_FAIL_INDEX(p_idx, items.size()); @@ -1021,7 +1035,7 @@ void ItemList::_notification(int p_what) { else max_len = size.x; - Color modulate = items[i].selected ? font_color_selected : font_color; + Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color); if (items[i].disabled) modulate.a *= 0.5; diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h index 8166975408..673b7d8956 100644 --- a/scene/gui/item_list.h +++ b/scene/gui/item_list.h @@ -61,6 +61,7 @@ private: bool tooltip_enabled; Variant metadata; String tooltip; + Color custom_fg; Color custom_bg; Rect2 rect_cache; @@ -150,6 +151,9 @@ public: void set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_color); Color get_item_custom_bg_color(int p_idx) const; + void set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color); + Color get_item_custom_fg_color(int p_idx) const; + void select(int p_idx, bool p_single = true); void unselect(int p_idx); bool is_selected(int p_idx) const; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 66b4e6cec1..6a5f56c78c 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -631,7 +631,7 @@ void LineEdit::_notification(int p_what) { if (has_icon("right_icon")) { Ref<Texture> r_icon = Control::get_icon("right_icon"); ofs_max -= r_icon->get_width(); - r_icon->draw(ci, Point2(width - r_icon->get_width() - x_ofs, y_ofs), Color(1, 1, 1, disabled_alpha * .9)); + r_icon->draw(ci, Point2(width - r_icon->get_width() - x_ofs, height / 2 - r_icon->get_height() / 2), Color(1, 1, 1, disabled_alpha * .9)); } int caret_height = font->get_height() > y_area ? y_area : font->get_height(); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index a3f116c883..ab2c2f445f 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -80,6 +80,10 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) { return NULL; } +Rect2 RichTextLabel::_get_text_rect() { + Ref<StyleBox> style = get_stylebox("normal"); + return Rect2(style->get_offset(), get_size() - style->get_minimum_size()); +} void RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) { RID ci; @@ -583,7 +587,7 @@ void RichTextLabel::_update_scroll() { int total_height = 0; if (main->lines.size()) - total_height = main->lines[main->lines.size() - 1].height_accum_cache; + total_height = main->lines[main->lines.size() - 1].height_accum_cache + get_stylebox("normal")->get_minimum_size().height; bool exceeds = total_height > get_size().height && scroll_active; @@ -641,7 +645,11 @@ void RichTextLabel::_notification(int p_what) { _update_scroll(); RID ci = get_canvas_item(); + Size2 size = get_size(); + Rect2 text_rect = _get_text_rect(); + + draw_style_box(get_stylebox("normal"), Rect2(Point2(), size)); if (has_focus()) { VisualServer::get_singleton()->canvas_item_add_clip_ignore(ci, true); @@ -657,10 +665,10 @@ void RichTextLabel::_notification(int p_what) { int total_chars = 0; while (from_line < main->lines.size()) { - if (main->lines[from_line].height_accum_cache >= ofs) + if (main->lines[from_line].height_accum_cache + _get_text_rect().get_position().y >= ofs) break; - from_line++; total_chars += main->lines[from_line].char_count; + from_line++; } if (from_line >= main->lines.size()) @@ -672,7 +680,7 @@ void RichTextLabel::_notification(int p_what) { while (y < size.height && from_line < main->lines.size()) { - _process_line(main, Point2(), y, size.width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars); + _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, Point2i(), NULL, NULL, NULL, total_chars); total_chars += main->lines[from_line].char_count; from_line++; } @@ -686,7 +694,7 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item *r_click_item = NULL; Size2 size = get_size(); - + Rect2 text_rect = _get_text_rect(); int ofs = vscroll->get_value(); //todo, change to binary search @@ -706,9 +714,9 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item Ref<Font> base_font = get_font("normal_font"); Color base_color = get_color("default_color"); - while (y < size.height && from_line < p_frame->lines.size()) { + while (y < text_rect.get_size().height && from_line < p_frame->lines.size()) { - _process_line(p_frame, Point2(), y, size.width - scroll_w, from_line, PROCESS_POINTER, base_font, base_color, p_click, r_click_item, r_click_char, r_outside); + _process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_POINTER, base_font, base_color, p_click, r_click_item, r_click_char, r_outside); if (r_click_item && *r_click_item) return; from_line++; @@ -791,7 +799,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) { Ref<InputEventKey> k = p_event; if (k.is_valid()) { - if (k->is_pressed() && !k->get_alt() && !k->get_shift() && !k->get_metakey()) { + if (k->is_pressed() && !k->get_alt() && !k->get_shift()) { bool handled = true; switch (k->get_scancode()) { case KEY_PAGEUP: { @@ -1015,13 +1023,14 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { //validate invalid lines!s Size2 size = get_size(); + Rect2 text_rect = _get_text_rect(); Ref<Font> base_font = get_font("normal_font"); for (int i = p_frame->first_invalid_line; i < p_frame->lines.size(); i++) { int y = 0; - _process_line(p_frame, Point2(), y, size.width - scroll_w, i, PROCESS_CACHE, base_font, Color()); + _process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, i, PROCESS_CACHE, base_font, Color()); p_frame->lines[i].height_cache = y; p_frame->lines[i].height_accum_cache = y; @@ -1031,7 +1040,7 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) { int total_height = 0; if (p_frame->lines.size()) - total_height = p_frame->lines[p_frame->lines.size() - 1].height_accum_cache; + total_height = p_frame->lines[p_frame->lines.size() - 1].height_accum_cache + get_stylebox("normal")->get_minimum_size().height; main->first_invalid_line = p_frame->lines.size(); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index 74bf180b5d..4db2c3a8e9 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -276,6 +276,8 @@ private: void _gui_input(Ref<InputEvent> p_event); Item *_get_next_item(Item *p_item, bool p_free = false); + Rect2 _get_text_rect(); + bool use_bbcode; String bbcode; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index ade665b418..1738e303aa 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2136,15 +2136,25 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { break; } } - if (auto_indent) { - // indent once again if previous line will end with ':' - // (i.e. colon precedes current cursor position) - if (cursor.column > 0 && text[cursor.line][cursor.column - 1] == ':') { + + bool brace_indent = false; + + // no need to indent if we are going upwards. + if (auto_indent && !(k->get_command() && k->get_shift())) { + // indent once again if previous line will end with ':' or '{' + // (i.e. colon/brace precedes current cursor position) + if (cursor.column > 0 && (text[cursor.line][cursor.column - 1] == ':' || text[cursor.line][cursor.column - 1] == '{')) { if (indent_using_spaces) { ins += space_indent; } else { ins += "\t"; } + + // no need to move the brace below if we are not taking the text with us. + if (text[cursor.line][cursor.column] == '}' && !k->get_command()) { + brace_indent = true; + ins += "\n" + ins.substr(1, ins.length() - 2); + } } } @@ -2168,6 +2178,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { if (first_line) { cursor_set_line(0); + } else if (brace_indent) { + cursor_set_line(cursor.line - 1); + cursor_set_column(text[cursor.line].length()); } } break; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 5e15bceb7d..db282262ec 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1116,7 +1116,8 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 cache.selected->draw(ci, r); } if (text_editor->is_visible_in_tree()) { - text_editor->set_position(get_global_position() + r.position); + Vector2 ofs(0, (text_editor->get_size().height - r.size.height) / 2); + text_editor->set_position(get_global_position() + r.position - ofs); } } @@ -2303,7 +2304,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { int col, h, section; TreeItem *it = _find_item_at_pos(root, mpos, col, h, section); - if (drop_mode_flags && it != drop_mode_over || section != drop_mode_section) { + if ((drop_mode_flags && it != drop_mode_over) || section != drop_mode_section) { drop_mode_over = it; drop_mode_section = section; update(); @@ -2477,7 +2478,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) { pressing_for_editor = false; blocked++; - bool handled = propagate_mouse_event(pos + cache.offset, 0, 0, b->is_doubleclick(), root, b->get_button_index(), b); + propagate_mouse_event(pos + cache.offset, 0, 0, b->is_doubleclick(), root, b->get_button_index(), b); blocked--; if (pressing_for_editor) { @@ -2572,7 +2573,8 @@ bool Tree::edit_selected() { } else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE || c.mode == TreeItem::CELL_MODE_RANGE_EXPRESSION) { - Point2i textedpos = get_global_position() + rect.position; + Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2); + Point2i textedpos = get_global_position() + rect.position - ofs; text_editor->set_position(textedpos); text_editor->set_size(rect.size); text_editor->clear(); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index c3d9d97c5a..a30fc03aa9 100755 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -50,7 +50,6 @@ void Node::_notification(int p_notification) { Variant time = get_process_delta_time(); const Variant *ptr[1] = { &time }; - Variant::CallError err; get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_process, ptr, 1); } } break; @@ -60,7 +59,6 @@ void Node::_notification(int p_notification) { Variant time = get_fixed_process_delta_time(); const Variant *ptr[1] = { &time }; - Variant::CallError err; get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_fixed_process, ptr, 1); } @@ -134,7 +132,6 @@ void Node::_notification(int p_notification) { set_fixed_process(true); } - Variant::CallError err; get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_ready, NULL, 0); } //emit_signal(SceneStringNames::get_singleton()->enter_tree); @@ -209,7 +206,6 @@ void Node::_propagate_enter_tree() { if (get_script_instance()) { - Variant::CallError err; get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_enter_tree, NULL, 0); } @@ -273,7 +269,6 @@ void Node::_propagate_exit_tree() { if (get_script_instance()) { - Variant::CallError err; get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_tree, NULL, 0); } emit_signal(SceneStringNames::get_singleton()->tree_exited); @@ -2117,7 +2112,15 @@ Node *Node::_duplicate(int p_flags) const { if (!(p_flags & DUPLICATE_SCRIPTS) && name == "script/script") continue; - node->set(name, get(name)); + Variant value = 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); } node->set_name(get_name()); @@ -2199,7 +2202,16 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) continue; String name = E->get().name; - node->set(name, get(name)); + + Variant value = 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); } node->set_name(get_name()); @@ -2657,7 +2669,7 @@ void Node::_bind_methods() { GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE); ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case")); - ClassDB::bind_method(D_METHOD("_add_child_below_node", "node", "child_node", "legible_unique_name"), &Node::add_child_below_node, DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_child_below_node", "node", "child_node", "legible_unique_name"), &Node::add_child_below_node, DEFVAL(false)); ClassDB::bind_method(D_METHOD("set_name", "name"), &Node::set_name); ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index a71b491bae..4f62d88934 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -870,7 +870,6 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p if (!n->can_process()) continue; - Variant::CallError ce; n->call_multilevel(p_method, (const Variant **)v, 1); //ERR_FAIL_COND(node_count != g.nodes.size()); } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index c71a280755..567b1dd7a1 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2578,6 +2578,16 @@ int Viewport::get_render_info(RenderInfo p_info) { return VS::get_singleton()->viewport_get_render_info(viewport, VS::ViewportRenderInfo(p_info)); } +void Viewport::set_snap_controls_to_pixels(bool p_enable) { + + snap_controls_to_pixels = p_enable; +} + +bool Viewport::is_snap_controls_to_pixels_enabled() const { + + return snap_controls_to_pixels; +} + void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_use_arvr", "use"), &Viewport::set_use_arvr); @@ -2680,6 +2690,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size); ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size); + ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels); + ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled); + ClassDB::bind_method(D_METHOD("set_shadow_atlas_quadrant_subdiv", "quadrant", "subdiv"), &Viewport::set_shadow_atlas_quadrant_subdiv); ClassDB::bind_method(D_METHOD("get_shadow_atlas_quadrant_subdiv", "quadrant"), &Viewport::get_shadow_atlas_quadrant_subdiv); @@ -2707,6 +2720,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "physics_object_picking"), "set_physics_object_picking", "get_physics_object_picking"); ADD_GROUP("GUI", "gui_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled"); ADD_GROUP("Shadow Atlas", "shadow_atlas_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0); @@ -2822,6 +2836,8 @@ Viewport::Viewport() { usage = USAGE_3D; debug_draw = DEBUG_DRAW_DISABLED; clear_mode = CLEAR_MODE_ALWAYS; + + snap_controls_to_pixels = true; } Viewport::~Viewport() { diff --git a/scene/main/viewport.h b/scene/main/viewport.h index ce2bc991f5..6bbd4b26b5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -1,3 +1,4 @@ + /*************************************************************************/ /* viewport.h */ /*************************************************************************/ @@ -193,6 +194,8 @@ private: bool filter; bool gen_mipmaps; + bool snap_controls_to_pixels; + bool physics_object_picking; List<Ref<InputEvent> > physics_picking_events; ObjectID physics_object_capture; @@ -463,6 +466,9 @@ public: int get_render_info(RenderInfo p_info); + void set_snap_controls_to_pixels(bool p_enable); + bool is_snap_controls_to_pixels_enabled() const; + Viewport(); ~Viewport(); }; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index e01f5e3cdf..9ed3734a36 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -66,7 +66,6 @@ #include "scene/audio/audio_player.h" #include "scene/gui/box_container.h" #include "scene/gui/button.h" -#include "scene/gui/button_group.h" #include "scene/gui/center_container.h" #include "scene/gui/check_box.h" #include "scene/gui/check_button.h" @@ -378,6 +377,7 @@ void register_scene_types() { ClassDB::register_virtual_class<CollisionObject>(); ClassDB::register_class<StaticBody>(); ClassDB::register_class<RigidBody>(); + ClassDB::register_class<KinematicCollision>(); ClassDB::register_class<KinematicBody>(); ClassDB::register_class<VehicleBody>(); diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 7fbaa1f73c..2e89a739bd 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -84,15 +84,6 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T int i = get_index(p_pos.x); - int nearest_index = i; - if (i + 1 < _points.size()) { - real_t diff0 = p_pos.x - _points[i].pos.x; - real_t diff1 = _points[i + 1].pos.x - p_pos.x; - - if (diff1 < diff0) - nearest_index = i + 1; - } - if (i == 0 && p_pos.x < _points[0].pos.x) { // Insert before anything else _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); @@ -331,18 +322,19 @@ real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const { const Point a = _points[index]; const Point b = _points[index + 1]; - // Cubic bezier - - // ac-----bc - // / \ - // / \ Here with a.right_tangent > 0 - // / \ and b.left_tangent < 0 - // / \ - // a b - // - // |-d1--|-d2--|-d3--| - // - // d1 == d2 == d3 == d / 3 + /* Cubic bezier + * + * ac-----bc + * / \ + * / \ Here with a.right_tangent > 0 + * / \ and b.left_tangent < 0 + * / \ + * a b + * + * |-d1--|-d2--|-d3--| + * + * d1 == d2 == d3 == d / 3 + */ // Control points are chosen at equal distances real_t d = b.pos.x - a.pos.x; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 4ff635edeb..1272e5a946 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -794,6 +794,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // RichTextLabel theme->set_stylebox("focus", "RichTextLabel", focus); + theme->set_stylebox("normal", "RichTextLabel", make_empty_stylebox(0, 0, 0, 0)); theme->set_font("normal_font", "RichTextLabel", default_font); theme->set_font("bold_font", "RichTextLabel", default_font); diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 14225d945d..da3bc6a95b 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -269,13 +269,13 @@ Ref<Texture> Environment::get_adjustment_color_correction() const { void Environment::_validate_property(PropertyInfo &property) const { if (property.name == "background_sky" || property.name == "background_sky_scale" || property.name == "ambient_light/sky_contribution") { - if (bg_mode != BG_SKY) { + if (bg_mode != BG_SKY && bg_mode != BG_COLOR_SKY) { property.usage = PROPERTY_USAGE_NOEDITOR; } } if (property.name == "background_color") { - if (bg_mode != BG_COLOR) { + if (bg_mode != BG_COLOR && bg_mode != BG_COLOR_SKY) { property.usage = PROPERTY_USAGE_NOEDITOR; } } @@ -839,7 +839,7 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution); ADD_GROUP("Background", "background_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep"), "set_background", "get_background"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Color+Sky,Canvas,Keep"), "set_background", "get_background"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_scale", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_sky_scale", "get_sky_scale"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color"); @@ -1118,6 +1118,7 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(BG_CLEAR_COLOR); BIND_ENUM_CONSTANT(BG_COLOR); BIND_ENUM_CONSTANT(BG_SKY); + BIND_ENUM_CONSTANT(BG_COLOR_SKY); BIND_ENUM_CONSTANT(BG_CANVAS); BIND_ENUM_CONSTANT(BG_MAX); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 6337981b95..9046ec1e49 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -45,6 +45,7 @@ public: BG_CLEAR_COLOR, BG_COLOR, BG_SKY, + BG_COLOR_SKY, BG_CANVAS, BG_KEEP, BG_MAX diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index f3d790eef5..abe9a00c3f 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -65,6 +65,12 @@ RID Material::get_rid() const { return material; } +void Material::_validate_property(PropertyInfo &property) const { + + if (!_can_do_next_pass() && property.name == "next_pass") { + property.usage = 0; + } +} void Material::_bind_methods() { @@ -74,7 +80,7 @@ void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_render_priority", "priority"), &Material::set_render_priority); ClassDB::bind_method(D_METHOD("get_render_priority"), &Material::get_render_priority); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass"); BIND_CONSTANT(RENDER_PRIORITY_MAX); @@ -204,6 +210,11 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id Resource::get_argument_options(p_function, p_idx, r_options); } +bool ShaderMaterial::_can_do_next_pass() const { + + return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL; +} + ShaderMaterial::ShaderMaterial() { } @@ -239,6 +250,7 @@ void SpatialMaterial::init_shaders() { shader_names->anisotropy = "anisotropy_ratio"; shader_names->depth_scale = "depth_scale"; shader_names->subsurface_scattering_strength = "subsurface_scattering_strength"; + shader_names->transmission = "transmission"; shader_names->refraction = "refraction"; shader_names->point_size = "point_size"; shader_names->uv1_scale = "uv1_scale"; @@ -276,6 +288,7 @@ void SpatialMaterial::init_shaders() { shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion"; shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth"; shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering"; + shader_names->texture_names[TEXTURE_TRANSMISSION] = "texture_transmission"; shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction"; shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask"; shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo"; @@ -352,7 +365,7 @@ void SpatialMaterial::_update_shader() { } switch (diffuse_mode) { case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break; - case DIFFUSE_HALF_LAMBERT: code += ",diffuse_half_lambert"; break; + case DIFFUSE_LAMBERT_WRAP: code += ",diffuse_lambert_wrap"; break; case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break; case DIFFUSE_BURLEY: code += ",diffuse_burley"; break; case DIFFUSE_TOON: code += ",diffuse_toon"; break; @@ -451,6 +464,12 @@ void SpatialMaterial::_update_shader() { code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n"; } + if (features[FEATURE_TRANSMISSION]) { + + code += "uniform vec4 transmission : hint_color;\n"; + code += "uniform sampler2D texture_transmission : hint_black;\n"; + } + if (features[FEATURE_DEPTH_MAPPING]) { code += "uniform sampler2D texture_depth : hint_black;\n"; code += "uniform float depth_scale;\n"; @@ -766,6 +785,15 @@ void SpatialMaterial::_update_shader() { code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n"; } + if (features[FEATURE_TRANSMISSION]) { + if (flags[FLAG_UV1_USE_TRIPLANAR]) { + code += "\tvec3 transmission_tex = triplanar_texture(texture_transmission,uv1_power_normal,uv1_triplanar_pos).rgb;\n"; + } else { + code += "\tvec3 transmission_tex = texture(texture_transmission,base_uv).rgb;\n"; + } + code += "\tTRANSMISSION = (transmission.rgb+transmission_tex);\n"; + } + if (features[FEATURE_DETAIL]) { bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2); @@ -1015,6 +1043,17 @@ float SpatialMaterial::get_subsurface_scattering_strength() const { return subsurface_scattering_strength; } +void SpatialMaterial::set_transmission(const Color &p_transmission) { + + transmission = p_transmission; + VS::get_singleton()->material_set_param(_get_material(), shader_names->transmission, transmission); +} + +Color SpatialMaterial::get_transmission() const { + + return transmission; +} + void SpatialMaterial::set_refraction(float p_refraction) { refraction = p_refraction; @@ -1180,6 +1219,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { _validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property); _validate_feature("depth", FEATURE_DEPTH_MAPPING, property); _validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property); + _validate_feature("transmission", FEATURE_TRANSMISSION, property); _validate_feature("refraction", FEATURE_REFRACTION, property); _validate_feature("detail", FEATURE_DETAIL, property); @@ -1530,6 +1570,9 @@ void SpatialMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength); ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength); + ClassDB::bind_method(D_METHOD("set_transmission", "transmission"), &SpatialMaterial::set_transmission); + ClassDB::bind_method(D_METHOD("get_transmission"), &SpatialMaterial::get_transmission); + ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction); ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction); @@ -1721,6 +1764,11 @@ void SpatialMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "subsurf_scatter_strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_subsurface_scattering_strength", "get_subsurface_scattering_strength"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_SCATTERING); + ADD_GROUP("Transmission", "transmission_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transmission_enabled"), "set_feature", "get_feature", FEATURE_TRANSMISSION); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "transmission", PROPERTY_HINT_COLOR_NO_ALPHA), "set_transmission", "get_transmission"); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "transmission_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_TRANSMISSION); + ADD_GROUP("Refraction", "refraction_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION); ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction"); @@ -1758,6 +1806,7 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(TEXTURE_AMBIENT_OCCLUSION); BIND_ENUM_CONSTANT(TEXTURE_DEPTH); BIND_ENUM_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING); + BIND_ENUM_CONSTANT(TEXTURE_TRANSMISSION); BIND_ENUM_CONSTANT(TEXTURE_REFRACTION); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_MASK); BIND_ENUM_CONSTANT(TEXTURE_DETAIL_ALBEDO); @@ -1776,6 +1825,7 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(FEATURE_AMBIENT_OCCLUSION); BIND_ENUM_CONSTANT(FEATURE_DEPTH_MAPPING); BIND_ENUM_CONSTANT(FEATURE_SUBSURACE_SCATTERING); + BIND_ENUM_CONSTANT(FEATURE_TRANSMISSION); BIND_ENUM_CONSTANT(FEATURE_REFRACTION); BIND_ENUM_CONSTANT(FEATURE_DETAIL); BIND_ENUM_CONSTANT(FEATURE_MAX); @@ -1809,7 +1859,7 @@ void SpatialMaterial::_bind_methods() { BIND_ENUM_CONSTANT(FLAG_MAX); BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT); - BIND_ENUM_CONSTANT(DIFFUSE_HALF_LAMBERT); + BIND_ENUM_CONSTANT(DIFFUSE_LAMBERT_WRAP); BIND_ENUM_CONSTANT(DIFFUSE_OREN_NAYAR); BIND_ENUM_CONSTANT(DIFFUSE_BURLEY); BIND_ENUM_CONSTANT(DIFFUSE_TOON); @@ -1850,6 +1900,7 @@ SpatialMaterial::SpatialMaterial() set_anisotropy(0); set_depth_scale(0.05); set_subsurface_scattering_strength(0); + set_transmission(Color(0, 0, 0)); set_refraction(0.05); set_line_width(1); set_point_size(1); diff --git a/scene/resources/material.h b/scene/resources/material.h index d560d7af55..fdb11982a8 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -53,6 +53,9 @@ class Material : public Resource { protected: _FORCE_INLINE_ RID _get_material() const { return material; } static void _bind_methods(); + virtual bool _can_do_next_pass() const { return false; } + + void _validate_property(PropertyInfo &property) const; public: enum { @@ -84,6 +87,8 @@ protected: void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const; + virtual bool _can_do_next_pass() const; + public: void set_shader(const Ref<Shader> &p_shader); Ref<Shader> get_shader() const; @@ -112,6 +117,7 @@ public: TEXTURE_AMBIENT_OCCLUSION, TEXTURE_DEPTH, TEXTURE_SUBSURFACE_SCATTERING, + TEXTURE_TRANSMISSION, TEXTURE_REFRACTION, TEXTURE_DETAIL_MASK, TEXTURE_DETAIL_ALBEDO, @@ -135,6 +141,7 @@ public: FEATURE_AMBIENT_OCCLUSION, FEATURE_DEPTH_MAPPING, FEATURE_SUBSURACE_SCATTERING, + FEATURE_TRANSMISSION, FEATURE_REFRACTION, FEATURE_DETAIL, FEATURE_MAX @@ -179,7 +186,7 @@ public: enum DiffuseMode { DIFFUSE_LAMBERT, - DIFFUSE_HALF_LAMBERT, + DIFFUSE_LAMBERT_WRAP, DIFFUSE_OREN_NAYAR, DIFFUSE_BURLEY, DIFFUSE_TOON, @@ -212,7 +219,7 @@ private: union MaterialKey { struct { - uint64_t feature_mask : 11; + uint64_t feature_mask : 12; uint64_t detail_uv : 1; uint64_t blend_mode : 2; uint64_t depth_draw_mode : 2; @@ -286,6 +293,7 @@ private: StringName anisotropy; StringName depth_scale; StringName subsurface_scattering_strength; + StringName transmission; StringName refraction; StringName point_size; StringName uv1_scale; @@ -337,6 +345,7 @@ private: float anisotropy; float depth_scale; float subsurface_scattering_strength; + Color transmission; float refraction; float line_width; float point_size; @@ -390,6 +399,7 @@ private: protected: static void _bind_methods(); void _validate_property(PropertyInfo &property) const; + virtual bool _can_do_next_pass() const { return true; } public: void set_albedo(const Color &p_albedo); @@ -443,6 +453,9 @@ public: void set_subsurface_scattering_strength(float p_subsurface_scattering_strength); float get_subsurface_scattering_strength() const; + void set_transmission(const Color &p_transmission); + Color get_transmission() const; + void set_refraction(float p_refraction); float get_refraction() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index aa7827a61a..04efe88102 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -761,7 +761,7 @@ Array ArrayMesh::surface_get_arrays(int p_surface) const { Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const { ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array()); - return Array(); + return VisualServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface); } int ArrayMesh::get_surface_count() const { @@ -1010,6 +1010,8 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &ArrayMesh::surface_get_material); ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name); ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name); + ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &ArrayMesh::surface_get_arrays); + ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &ArrayMesh::surface_get_blend_shape_arrays); ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape); ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape); ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 53c6eb2d89..f4edb258b6 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -120,6 +120,7 @@ public: virtual int surface_get_array_len(int p_idx) const = 0; virtual int surface_get_array_index_len(int p_idx) const = 0; virtual Array surface_get_arrays(int p_surface) const = 0; + virtual Array surface_get_blend_shape_arrays(int p_surface) const = 0; virtual uint32_t surface_get_format(int p_idx) const = 0; virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0; virtual Ref<Material> surface_get_material(int p_idx) const = 0; @@ -174,7 +175,7 @@ public: 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>()); Array surface_get_arrays(int p_surface) const; - virtual Array surface_get_blend_shape_arrays(int p_surface) const; + Array surface_get_blend_shape_arrays(int p_surface) const; void add_blend_shape(const StringName &p_name); int get_blend_shape_count() const; diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp index 4e1ffd2ab3..833a4c3d22 100644 --- a/scene/resources/mesh_library.cpp +++ b/scene/resources/mesh_library.cpp @@ -214,7 +214,7 @@ Vector<int> MeshLibrary::get_item_list() const { return ret; } -int MeshLibrary::find_item_name(const String &p_name) const { +int MeshLibrary::find_item_by_name(const String &p_name) const { for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) { @@ -275,6 +275,8 @@ void MeshLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_shapes", "id"), &MeshLibrary::_get_item_shapes); ClassDB::bind_method(D_METHOD("get_item_preview", "id"), &MeshLibrary::get_item_preview); ClassDB::bind_method(D_METHOD("remove_item", "id"), &MeshLibrary::remove_item); + ClassDB::bind_method(D_METHOD("find_item_by_name", "name"), &MeshLibrary::find_item_by_name); + ClassDB::bind_method(D_METHOD("clear"), &MeshLibrary::clear); ClassDB::bind_method(D_METHOD("get_item_list"), &MeshLibrary::get_item_list); ClassDB::bind_method(D_METHOD("get_last_unused_item_id"), &MeshLibrary::get_last_unused_item_id); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 99b6b48d61..c5d23ce50f 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -84,7 +84,7 @@ public: void clear(); - int find_item_name(const String &p_name) const; + int find_item_by_name(const String &p_name) const; Vector<int> get_item_list() const; int get_last_unused_item_id() const; diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index c525ca600a..5d6f44dfef 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -92,7 +92,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { NODE_FROM_ID(nparent, n.parent); #ifdef DEBUG_ENABLED - if (!nparent && n.parent & FLAG_ID_IS_PATH) { + if (!nparent && (n.parent & FLAG_ID_IS_PATH)) { WARN_PRINT(String("Parent path '" + String(node_paths[n.parent & FLAG_MASK]) + "' for node '" + String(snames[n.name]) + "' has vanished when instancing: '" + get_path() + "'.").ascii().get_data()); } @@ -489,7 +489,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map // only save what has been changed // only save changed properties in instance - if (E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE || E->get().name == "__meta__") { + if ((E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE) || E->get().name == "__meta__") { //property has requested that no instance state is saved, sorry //also, meta won't be overridden or saved continue; @@ -1288,7 +1288,7 @@ bool SceneState::is_node_instance_placeholder(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, nodes.size(), false); - return nodes[p_idx].instance >= 0 && nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER; + return nodes[p_idx].instance >= 0 && (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER); } Ref<PackedScene> SceneState::get_node_instance(int p_idx) const { @@ -1313,7 +1313,7 @@ String SceneState::get_node_instance_placeholder(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, nodes.size(), String()); - if (nodes[p_idx].instance >= 0 && nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER) { + if (nodes[p_idx].instance >= 0 && (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER)) { return variants[nodes[p_idx].instance & FLAG_MASK]; } diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index cfc1468533..ba356d89b1 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -105,6 +105,15 @@ Array PrimitiveMesh::surface_get_arrays(int p_surface) const { return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0); } +Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, 1, Array()); + if (pending_request) { + _update(); + } + + return Array(); +} + uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); if (pending_request) { @@ -119,6 +128,8 @@ Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { } Ref<Material> PrimitiveMesh::surface_get_material(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, 1, NULL); + return material; } @@ -151,6 +162,8 @@ void PrimitiveMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_material", "material"), &PrimitiveMesh::set_material); ClassDB::bind_method(D_METHOD("get_material"), &PrimitiveMesh::get_material); + ClassDB::bind_method(D_METHOD("get_mesh_arrays"), &PrimitiveMesh::get_mesh_arrays); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); } @@ -168,6 +181,10 @@ Ref<Material> PrimitiveMesh::get_material() const { return material; } +Array PrimitiveMesh::get_mesh_arrays() const { + return surface_get_arrays(0); +} + PrimitiveMesh::PrimitiveMesh() { // defaults mesh = VisualServer::get_singleton()->mesh_create(); @@ -213,7 +230,6 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { prevrow = 0; for (j = 0; j <= (rings + 1); j++) { v = j; - w; v /= (rings + 1); w = sin(0.5 * Math_PI * v); @@ -292,7 +308,6 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) const { prevrow = 0; for (j = 0; j <= (rings + 1); j++) { v = j; - w; v /= (rings + 1); v += 1.0; diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 34fb75a196..38a5695883 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -67,6 +67,7 @@ public: virtual int surface_get_array_len(int p_idx) const; virtual int surface_get_array_index_len(int p_idx) const; virtual Array surface_get_arrays(int p_surface) const; + virtual Array surface_get_blend_shape_arrays(int p_surface) const; virtual uint32_t surface_get_format(int p_idx) const; virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const; virtual Ref<Material> surface_get_material(int p_idx) const; @@ -78,6 +79,8 @@ public: void set_material(const Ref<Material> &p_material); Ref<Material> get_material() const; + Array get_mesh_arrays() const; + PrimitiveMesh(); ~PrimitiveMesh(); }; diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/arvr/arvr_positional_tracker.cpp index 539bac6703..4ecd7a3898 100644 --- a/servers/arvr/arvr_positional_tracker.cpp +++ b/servers/arvr/arvr_positional_tracker.cpp @@ -31,6 +31,10 @@ #include "core/os/input.h" void ARVRPositionalTracker::_bind_methods() { + BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN); + BIND_ENUM_CONSTANT(TRACKER_LEFT_HAND); + BIND_ENUM_CONSTANT(TRACKER_RIGHT_HAND); + // this class is read only from GDScript, so we only have access to getters.. ClassDB::bind_method(D_METHOD("get_type"), &ARVRPositionalTracker::get_type); ClassDB::bind_method(D_METHOD("get_name"), &ARVRPositionalTracker::get_name); @@ -39,6 +43,7 @@ void ARVRPositionalTracker::_bind_methods() { ClassDB::bind_method(D_METHOD("get_orientation"), &ARVRPositionalTracker::get_orientation); ClassDB::bind_method(D_METHOD("get_tracks_position"), &ARVRPositionalTracker::get_tracks_position); ClassDB::bind_method(D_METHOD("get_position"), &ARVRPositionalTracker::get_position); + ClassDB::bind_method(D_METHOD("get_hand"), &ARVRPositionalTracker::get_hand); ClassDB::bind_method(D_METHOD("get_transform", "adjust_by_reference_frame"), &ARVRPositionalTracker::get_transform); // these functions we don't want to expose to normal users but do need to be callable from GDNative @@ -141,6 +146,14 @@ Vector3 ARVRPositionalTracker::get_rw_position() const { return rw_position; }; +ARVRPositionalTracker::TrackerHand ARVRPositionalTracker::get_hand() const { + return hand; +}; + +void ARVRPositionalTracker::set_hand(const ARVRPositionalTracker::TrackerHand p_hand) { + hand = p_hand; +}; + Transform ARVRPositionalTracker::get_transform(bool p_adjust_by_reference_frame) const { Transform new_transform; @@ -164,6 +177,7 @@ ARVRPositionalTracker::ARVRPositionalTracker() { tracker_id = 0; tracks_orientation = false; tracks_position = false; + hand = TRACKER_HAND_UNKNOWN; }; ARVRPositionalTracker::~ARVRPositionalTracker(){ diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/arvr/arvr_positional_tracker.h index f91f862ba3..ff0c150f89 100644 --- a/servers/arvr/arvr_positional_tracker.h +++ b/servers/arvr/arvr_positional_tracker.h @@ -48,6 +48,13 @@ class ARVRPositionalTracker : public Object { GDCLASS(ARVRPositionalTracker, Object); _THREAD_SAFE_CLASS_ +public: + enum TrackerHand { + TRACKER_HAND_UNKNOWN, /* unknown or not applicable */ + TRACKER_LEFT_HAND, /* controller is the left hand controller */ + TRACKER_RIGHT_HAND /* controller is the right hand controller */ + }; + private: ARVRServer::TrackerType type; // type of tracker StringName name; // (unique) name of the tracker @@ -57,6 +64,7 @@ private: Basis orientation; // our orientation bool tracks_position; // do we track position? Vector3 rw_position; // our position "in the real world, so without world_scale applied" + TrackerHand hand; // if known, the hand this tracker is held in protected: static void _bind_methods(); @@ -77,6 +85,8 @@ public: Vector3 get_position() const; // get position with world_scale applied void set_rw_position(const Vector3 &p_rw_position); Vector3 get_rw_position() const; + ARVRPositionalTracker::TrackerHand get_hand() const; + void set_hand(const ARVRPositionalTracker::TrackerHand p_hand); Transform get_transform(bool p_adjust_by_reference_frame) const; @@ -84,4 +94,6 @@ public: ~ARVRPositionalTracker(); }; +VARIANT_ENUM_CAST(ARVRPositionalTracker::TrackerHand); + #endif diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp index bac24f6438..5d8cf20c92 100644 --- a/servers/arvr_server.cpp +++ b/servers/arvr_server.cpp @@ -68,8 +68,8 @@ void ARVRServer::_bind_methods() { ADD_SIGNAL(MethodInfo("interface_added", PropertyInfo(Variant::STRING, "name"))); ADD_SIGNAL(MethodInfo("interface_removed", PropertyInfo(Variant::STRING, "name"))); - ADD_SIGNAL(MethodInfo("tracker_added", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "type"))); - ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING, "name"))); + ADD_SIGNAL(MethodInfo("tracker_added", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id"))); + ADD_SIGNAL(MethodInfo("tracker_removed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::INT, "id"))); }; real_t ARVRServer::get_world_scale() const { @@ -130,7 +130,6 @@ void ARVRServer::request_reference_frame(bool p_ignore_tilt, bool p_keep_height) void ARVRServer::add_interface(const Ref<ARVRInterface> &p_interface) { ERR_FAIL_COND(p_interface.is_null()); - int idx = -1; for (int i = 0; i < interfaces.size(); i++) { if (interfaces[i] == p_interface) { @@ -232,7 +231,7 @@ void ARVRServer::add_tracker(ARVRPositionalTracker *p_tracker) { ERR_FAIL_NULL(p_tracker); trackers.push_back(p_tracker); - emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type()); + emit_signal("tracker_added", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id()); }; void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) { @@ -250,7 +249,7 @@ void ARVRServer::remove_tracker(ARVRPositionalTracker *p_tracker) { ERR_FAIL_COND(idx == -1); - emit_signal("tracker_removed", p_tracker->get_name()); + emit_signal("tracker_removed", p_tracker->get_name(), p_tracker->get_type(), p_tracker->get_tracker_id()); trackers.remove(idx); }; diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp index 391e5db639..9787ba8109 100644 --- a/servers/audio/effects/audio_effect_limiter.cpp +++ b/servers/audio/effects/audio_effect_limiter.cpp @@ -31,18 +31,13 @@ void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { - float thresh = Math::db2linear(base->threshold); float threshdb = base->threshold; float ceiling = Math::db2linear(base->ceiling); float ceildb = base->ceiling; float makeup = Math::db2linear(ceildb - threshdb); - float makeupdb = ceildb - threshdb; float sc = -base->soft_clip; float scv = Math::db2linear(sc); - float sccomp = Math::db2linear(-sc); float peakdb = ceildb + 25; - float peaklvl = Math::db2linear(peakdb); - float scratio = base->soft_clip_ratio; float scmult = Math::abs((ceildb - sc) / (peakdb - sc)); for (int i = 0; i < p_frame_count; i++) { diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index 3139c6bb7a..29014a7ced 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -203,8 +203,9 @@ void AudioServer::_mix_step() { if (!bus_map.has(bus->send)) { bus = buses[0]; //send to master } else { + int prev_index_cache = bus->index_cache; bus = bus_map[bus->send]; - if (bus->index_cache >= bus->index_cache) { //invalid, send to master + if (prev_index_cache >= bus->index_cache) { //invalid, send to master bus = buses[0]; } } diff --git a/servers/physics/broad_phase_basic.cpp b/servers/physics/broad_phase_basic.cpp index 959718a252..c6565ac2e9 100644 --- a/servers/physics/broad_phase_basic.cpp +++ b/servers/physics/broad_phase_basic.cpp @@ -30,9 +30,10 @@ #include "broad_phase_basic.h" #include "list.h" #include "print_string.h" + BroadPhaseSW::ID BroadPhaseBasic::create(CollisionObjectSW *p_object, int p_subindex) { - ERR_FAIL_COND_V(p_object == NULL, NULL); + ERR_FAIL_COND_V(p_object == NULL, 0); current++; diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index ab716a8f6e..3af8b542fa 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "collision_object_sw.h" +#include "servers/physics/physics_server_sw.h" #include "space_sw.h" void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform) { @@ -39,8 +40,12 @@ void CollisionObjectSW::add_shape(ShapeSW *p_shape, const Transform &p_transform s.bpid = 0; //needs update shapes.push_back(s); p_shape->add_owner(this); - _update_shapes(); - _shapes_changed(); + + if (!pending_shape_update_list.in_list()) { + PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + } + //_update_shapes(); + //_shapes_changed(); } void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) { @@ -50,8 +55,11 @@ void CollisionObjectSW::set_shape(int p_index, ShapeSW *p_shape) { shapes[p_index].shape = p_shape; p_shape->add_owner(this); - _update_shapes(); - _shapes_changed(); + if (!pending_shape_update_list.in_list()) { + PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + } + //_update_shapes(); + //_shapes_changed(); } void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_transform) { @@ -59,8 +67,11 @@ void CollisionObjectSW::set_shape_transform(int p_index, const Transform &p_tran shapes[p_index].xform = p_transform; shapes[p_index].xform_inv = p_transform.affine_inverse(); - _update_shapes(); - _shapes_changed(); + if (!pending_shape_update_list.in_list()) { + PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + } + //_update_shapes(); + //_shapes_changed(); } void CollisionObjectSW::remove_shape(ShapeSW *p_shape) { @@ -90,7 +101,11 @@ void CollisionObjectSW::remove_shape(int p_index) { shapes[p_index].shape->remove_owner(this); shapes.remove(p_index); - _shapes_changed(); + if (!pending_shape_update_list.in_list()) { + PhysicsServerSW::singleton->pending_shape_update_list.add(&pending_shape_update_list); + } + //_update_shapes(); + //_shapes_changed(); } void CollisionObjectSW::_set_static(bool p_static) { @@ -202,7 +217,8 @@ void CollisionObjectSW::_shape_changed() { _shapes_changed(); } -CollisionObjectSW::CollisionObjectSW(Type p_type) { +CollisionObjectSW::CollisionObjectSW(Type p_type) + : pending_shape_update_list(this) { _static = true; type = p_type; diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index dc988aae86..67a8a44944 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -75,6 +75,8 @@ private: Transform inv_transform; bool _static; + SelfList<CollisionObjectSW> pending_shape_update_list; + void _update_shapes(); protected: diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 8d6f7b3fd8..2d46770924 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -763,6 +763,8 @@ void PhysicsServerSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); + _update_shapes(); + body->apply_impulse(p_pos, p_impulse); body->wakeup(); }; @@ -772,6 +774,8 @@ void PhysicsServerSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_imp BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); + _update_shapes(); + body->apply_torque_impulse(p_impulse); body->wakeup(); }; @@ -781,6 +785,8 @@ void PhysicsServerSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_v BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); + _update_shapes(); + Vector3 v = body->get_linear_velocity(); Vector3 axis = p_axis_velocity.normalized(); v -= axis * axis.dot(v); @@ -793,6 +799,7 @@ void PhysicsServerSW::body_set_axis_lock(RID p_body, BodyAxisLock p_lock) { BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); + body->set_axis_lock(p_lock); body->wakeup(); } @@ -902,6 +909,8 @@ bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, cons ERR_FAIL_COND_V(!body->get_space(), false); ERR_FAIL_COND_V(body->get_space()->is_locked(), false); + _update_shapes(); + return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result); } @@ -1209,6 +1218,8 @@ bool PhysicsServerSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_a void PhysicsServerSW::free(RID p_rid) { + _update_shapes(); //just in case + if (shape_owner.owns(p_rid)) { ShapeSW *shape = shape_owner.get(p_rid); @@ -1312,6 +1323,8 @@ void PhysicsServerSW::step(real_t p_step) { if (!active) return; + _update_shapes(); + doing_sync = false; last_step = p_step; @@ -1409,6 +1422,14 @@ int PhysicsServerSW::get_process_info(ProcessInfo p_info) { return 0; } +void PhysicsServerSW::_update_shapes() { + + while (pending_shape_update_list.first()) { + pending_shape_update_list.first()->self()->_shape_changed(); + pending_shape_update_list.remove(pending_shape_update_list.first()); + } +} + void PhysicsServerSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) { CollCbkData *cbk = (CollCbkData *)p_userdata; diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 2e1fa7065a..99ba302acd 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -62,6 +62,10 @@ class PhysicsServerSW : public PhysicsServer { mutable RID_Owner<JointSW> joint_owner; //void _clear_query(QuerySW *p_query); + friend class CollisionObjectSW; + SelfList<CollisionObjectSW>::List pending_shape_update_list; + void _update_shapes(); + public: static PhysicsServerSW *singleton; diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp index 1845188089..80eeff93d0 100644 --- a/servers/physics/shape_sw.cpp +++ b/servers/physics/shape_sw.cpp @@ -954,6 +954,9 @@ Vector3 ConvexPolygonShapeSW::get_moment_of_inertia(real_t p_mass) const { void ConvexPolygonShapeSW::_setup(const Vector<Vector3> &p_vertices) { Error err = QuickHull::build(p_vertices, mesh); + if (err != OK) + ERR_PRINT("Failed to build QuickHull"); + Rect3 _aabb; for (int i = 0; i < mesh.vertices.size(); i++) { diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp index 79a55e0af1..76b097dda6 100644 --- a/servers/physics/step_sw.cpp +++ b/servers/physics/step_sw.cpp @@ -62,7 +62,7 @@ void StepSW::_setup_island(ConstraintSW *p_island, real_t p_delta) { ConstraintSW *ci = p_island; while (ci) { - bool process = ci->setup(p_delta); + ci->setup(p_delta); //todo remove from island if process fails ci = ci->get_island_next(); } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 187a0b180b..344c10089a 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -335,6 +335,8 @@ public: virtual void light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) = 0; virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; virtual bool light_directional_get_blend_splits(RID p_light) const = 0; + virtual void light_directional_set_shadow_depth_range_mode(RID p_light, VS::LightDirectionalShadowDepthRangeMode p_range_mode) = 0; + virtual VS::LightDirectionalShadowDepthRangeMode light_directional_get_shadow_depth_range_mode(RID p_light) const = 0; virtual VS::LightDirectionalShadowMode light_directional_get_shadow_mode(RID p_light) = 0; virtual VS::LightOmniShadowMode light_omni_get_shadow_mode(RID p_light) = 0; diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 0684cb1701..6ad433268f 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -79,7 +79,11 @@ String ShaderLanguage::get_operator_text(Operator p_op) { "|", "^", "~", - "++" + "++", + "--", + "?", + ":", + "++", "--", "()", "construct", @@ -2996,8 +3000,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha if (op->op == OP_CONSTRUCT) { ERR_FAIL_COND_V(op->arguments[0]->type != Node::TYPE_VARIABLE, p_node); - VariableNode *vn = static_cast<VariableNode *>(op->arguments[0]); - //StringName name=vn->name; DataType base = get_scalar_type(op->get_datatype()); @@ -3116,6 +3118,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat tk = _get_token(); + VariableDeclarationNode *vardecl = alloc_node<VariableDeclarationNode>(); + vardecl->datatype = type; + vardecl->precision = precision; + + p_block->statements.push_back(vardecl); + while (true) { if (tk.type != TK_IDENTIFIER) { @@ -3133,8 +3141,14 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat var.type = type; var.precision = precision; var.line = tk_line; + p_block->variables[name] = var; + VariableDeclarationNode::Declaration decl; + + decl.name = name; + decl.initializer = NULL; + tk = _get_token(); if (tk.type == TK_OP_ASSIGN) { @@ -3143,22 +3157,17 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat if (!n) return ERR_PARSE_ERROR; - OperatorNode *assign = alloc_node<OperatorNode>(); - VariableNode *vnode = alloc_node<VariableNode>(); - vnode->name = name; - vnode->datatype_cache = type; - assign->arguments.push_back(vnode); - assign->arguments.push_back(n); - assign->op = OP_ASSIGN; - p_block->statements.push_back(assign); - tk = _get_token(); + decl.initializer = n; - if (!_validate_operator(assign)) { - _set_error("Invalid assignment of '" + get_datatype_name(n->get_datatype()) + "' to '" + get_datatype_name(type) + "'"); + if (var.type != n->get_datatype()) { + _set_error("Invalid assignment of '" + get_datatype_name(n->get_datatype()) + "' to '" + get_datatype_name(var.type) + "'"); return ERR_PARSE_ERROR; } + tk = _get_token(); } + vardecl->declarations.push_back(decl); + if (tk.type == TK_COMMA) { tk = _get_token(); //another variable @@ -3221,7 +3230,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat //if () {} tk = _get_token(); if (tk.type != TK_PARENTHESIS_OPEN) { - _set_error("Expected '(' after if"); + _set_error("Expected '(' after while"); return ERR_PARSE_ERROR; } @@ -3243,7 +3252,63 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat cf->blocks.push_back(block); p_block->statements.push_back(cf); - Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue); + Error err = _parse_block(block, p_builtin_types, true, true, true); + if (err) + return err; + } else if (tk.type == TK_CF_FOR) { + //if () {} + tk = _get_token(); + if (tk.type != TK_PARENTHESIS_OPEN) { + _set_error("Expected '(' after for"); + return ERR_PARSE_ERROR; + } + + ControlFlowNode *cf = alloc_node<ControlFlowNode>(); + cf->flow_op = FLOW_OP_FOR; + + BlockNode *init_block = alloc_node<BlockNode>(); + init_block->parent_block = p_block; + init_block->single_statement = true; + cf->blocks.push_back(init_block); + if (_parse_block(init_block, p_builtin_types, true, false, false) != OK) { + return ERR_PARSE_ERROR; + } + + Node *n = _parse_and_reduce_expression(init_block, p_builtin_types); + if (!n) + return ERR_PARSE_ERROR; + + if (n->get_datatype() != TYPE_BOOL) { + _set_error("Middle expression is expected to be boolean."); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + if (tk.type != TK_SEMICOLON) { + _set_error("Expected ';' after middle expression"); + return ERR_PARSE_ERROR; + } + + cf->expressions.push_back(n); + + n = _parse_and_reduce_expression(init_block, p_builtin_types); + if (!n) + return ERR_PARSE_ERROR; + + cf->expressions.push_back(n); + + tk = _get_token(); + if (tk.type != TK_PARENTHESIS_CLOSE) { + _set_error("Expected ')' after third expression"); + return ERR_PARSE_ERROR; + } + + BlockNode *block = alloc_node<BlockNode>(); + block->parent_block = p_block; + cf->blocks.push_back(block); + p_block->statements.push_back(cf); + + Error err = _parse_block(block, p_builtin_types, true, true, true); if (err) return err; @@ -3320,6 +3385,42 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat } p_block->statements.push_back(flow); + } else if (tk.type == TK_CF_BREAK) { + + if (!p_can_break) { + //all is good + _set_error("Breaking is not allowed here"); + } + + ControlFlowNode *flow = alloc_node<ControlFlowNode>(); + flow->flow_op = FLOW_OP_BREAK; + + pos = _get_tkpos(); + tk = _get_token(); + if (tk.type != TK_SEMICOLON) { + //all is good + _set_error("Expected ';' after break"); + } + + p_block->statements.push_back(flow); + } else if (tk.type == TK_CF_CONTINUE) { + + if (!p_can_break) { + //all is good + _set_error("Contiuning is not allowed here"); + } + + ControlFlowNode *flow = alloc_node<ControlFlowNode>(); + flow->flow_op = FLOW_OP_CONTINUE; + + pos = _get_tkpos(); + tk = _get_token(); + if (tk.type != TK_SEMICOLON) { + //all is good + _set_error("Expected ';' after continue"); + } + + p_block->statements.push_back(flow); } else { @@ -3872,6 +3973,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct shader = alloc_node<ShaderNode>(); Error err = _parse_shader(p_functions, p_render_modes, p_shader_types); + if (err != OK) + ERR_PRINT("Failed to parse shader"); switch (completion_type) { diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index f00b4c5a97..50f5cebeaa 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -266,6 +266,7 @@ public: TYPE_FUNCTION, TYPE_BLOCK, TYPE_VARIABLE, + TYPE_VARIABLE_DECLARATION, TYPE_CONSTANT, TYPE_OPERATOR, TYPE_CONTROL_FLOW, @@ -315,6 +316,25 @@ public: } }; + struct VariableDeclarationNode : public Node { + + DataPrecision precision; + DataType datatype; + + struct Declaration { + + StringName name; + Node *initializer; + }; + + Vector<Declaration> declarations; + virtual DataType get_datatype() const { return datatype; } + + VariableDeclarationNode() { + type = TYPE_VARIABLE_DECLARATION; + } + }; + struct ConstantNode : public Node { DataType datatype; @@ -346,10 +366,12 @@ public: Map<StringName, Variable> variables; List<Node *> statements; + bool single_statement; BlockNode() { type = TYPE_BLOCK; parent_block = NULL; parent_function = NULL; + single_statement=false; } }; diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp index ef0d063f83..91c5d430f5 100644 --- a/servers/visual/shader_types.cpp +++ b/servers/visual/shader_types.cpp @@ -102,6 +102,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["TRANSMISSION"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["EMISSION"] = ShaderLanguage::TYPE_VEC3; shader_modes[VS::SHADER_SPATIAL].functions["fragment"].built_ins["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D; @@ -137,7 +138,7 @@ ShaderTypes::ShaderTypes() { shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded"); shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert"); - shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_half_lambert"); + shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert_wrap"); shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar"); shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley"); shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_toon"); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 3953bc5f48..7c7ce46268 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -795,6 +795,7 @@ public: BIND2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) BIND2(light_directional_set_blend_splits, RID, bool) + BIND2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) /* PROBE API */ diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 0d70b7fc0e..9fb4dc524d 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -101,7 +101,7 @@ void *VisualServerScene::_instance_pair(void *p_self, OctreeElementID, Instance SWAP(A, B); //lesser always first } - if (B->base_type == VS::INSTANCE_LIGHT && (1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK) { + if (B->base_type == VS::INSTANCE_LIGHT && ((1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK)) { InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -119,7 +119,7 @@ void *VisualServerScene::_instance_pair(void *p_self, OctreeElementID, Instance geom->lighting_dirty = true; return E; //this element should make freeing faster - } else if (B->base_type == VS::INSTANCE_REFLECTION_PROBE && (1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK) { + } else if (B->base_type == VS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK)) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -133,7 +133,7 @@ void *VisualServerScene::_instance_pair(void *p_self, OctreeElementID, Instance geom->reflection_dirty = true; return E; //this element should make freeing faster - } else if (B->base_type == VS::INSTANCE_GI_PROBE && (1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK) { + } else if (B->base_type == VS::INSTANCE_GI_PROBE && ((1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK)) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -151,8 +151,6 @@ void *VisualServerScene::_instance_pair(void *p_self, OctreeElementID, Instance } else if (B->base_type == VS::INSTANCE_GI_PROBE && A->base_type == VS::INSTANCE_LIGHT) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); - InstanceLightData *light = static_cast<InstanceLightData *>(A->base_data); - return gi_probe->lights.insert(A); } @@ -169,7 +167,7 @@ void VisualServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance SWAP(A, B); //lesser always first } - if (B->base_type == VS::INSTANCE_LIGHT && (1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK) { + if (B->base_type == VS::INSTANCE_LIGHT && ((1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK)) { InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -184,7 +182,7 @@ void VisualServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance } geom->lighting_dirty = true; - } else if (B->base_type == VS::INSTANCE_REFLECTION_PROBE && (1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK) { + } else if (B->base_type == VS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK)) { InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -196,7 +194,7 @@ void VisualServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance geom->reflection_dirty = true; - } else if (B->base_type == VS::INSTANCE_GI_PROBE && (1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK) { + } else if (B->base_type == VS::INSTANCE_GI_PROBE && ((1 << A->base_type) & VS::INSTANCE_GEOMETRY_MASK)) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data); @@ -211,8 +209,6 @@ void VisualServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance } else if (B->base_type == VS::INSTANCE_GI_PROBE && A->base_type == VS::INSTANCE_LIGHT) { InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data); - InstanceLightData *light = static_cast<InstanceLightData *>(A->base_data); - Set<Instance *>::Element *E = reinterpret_cast<Set<Instance *>::Element *>(udata); gi_probe->lights.erase(E); @@ -886,12 +882,53 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons float max_distance = p_cam_projection.get_z_far(); float shadow_max = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_SHADOW_MAX_DISTANCE); - if (shadow_max > 0) { + if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera max_distance = MIN(shadow_max, max_distance); } max_distance = MAX(max_distance, p_cam_projection.get_z_near() + 0.001); + float min_distance = MIN(p_cam_projection.get_z_near(), max_distance); + + VS::LightDirectionalShadowDepthRangeMode depth_range_mode = VSG::storage->light_directional_get_shadow_depth_range_mode(p_instance->base); + + if (depth_range_mode == VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED) { + //optimize min/max + Vector<Plane> planes = p_cam_projection.get_projection_planes(p_cam_transform); + int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK); + Plane base(p_cam_transform.origin, -p_cam_transform.basis.get_axis(2)); + //check distance max and min + + bool found_items = false; + float z_max = -1e20; + float z_min = 1e20; + + for (int i = 0; i < cull_count; i++) { + + Instance *instance = instance_shadow_cull_result[i]; + if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) { + continue; + } + + float max, min; + instance->transformed_aabb.project_range_in_plane(base, min, max); + + if (max > z_max) { + z_max = max; + } + + if (min < z_min) { + z_min = min; + } - float range = max_distance - p_cam_projection.get_z_near(); + found_items = true; + } + + if (found_items) { + min_distance = MAX(min_distance, z_min); + max_distance = MIN(max_distance, z_max); + } + } + + float range = max_distance - min_distance; int splits = 0; switch (VSG::storage->light_directional_get_shadow_mode(p_instance->base)) { @@ -902,9 +939,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons float distances[5]; - distances[0] = p_cam_projection.get_z_near(); + distances[0] = min_distance; for (int i = 0; i < splits; i++) { - distances[i + 1] = p_cam_projection.get_z_near() + VSG::storage->light_get_param(p_instance->base, VS::LightParam(VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range; + distances[i + 1] = min_distance + VSG::storage->light_get_param(p_instance->base, VS::LightParam(VS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET + i)) * range; }; distances[splits] = max_distance; @@ -984,8 +1021,6 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons { //camera viewport stuff - //this trick here is what stabilizes the shadow (make potential jaggies to not move) - //at the cost of some wasted resolution. Still the quality increase is very well worth it Vector3 center; @@ -1006,7 +1041,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons radius = d; } - radius *= texture_size / (texture_size - 2.0); //add a texel by each side, so stepified texture will always fit + radius *= texture_size / (texture_size - 2.0); //add a texel by each side if (i == 0) { first_radius = radius; @@ -1021,12 +1056,17 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons z_max_cam = z_vec.dot(center) + radius; z_min_cam = z_vec.dot(center) - radius; - float unit = radius * 2.0 / texture_size; + if (depth_range_mode == VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) { + //this trick here is what stabilizes the shadow (make potential jaggies to not move) + //at the cost of some wasted resolution. Still the quality increase is very well worth it + + float unit = radius * 2.0 / texture_size; - x_max_cam = Math::stepify(x_max_cam, unit); - x_min_cam = Math::stepify(x_min_cam, unit); - y_max_cam = Math::stepify(y_max_cam, unit); - y_min_cam = Math::stepify(y_min_cam, unit); + x_max_cam = Math::stepify(x_max_cam, unit); + x_min_cam = Math::stepify(x_min_cam, unit); + y_max_cam = Math::stepify(y_max_cam, unit); + y_min_cam = Math::stepify(y_min_cam, unit); + } } //now that we now all ranges, we can proceed to make the light frustum planes, for culling octree @@ -1069,6 +1109,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons } { + CameraMatrix ortho_camera; real_t half_x = (x_max_cam - x_min_cam) * 0.5; real_t half_y = (y_max_cam - y_min_cam) * 0.5; @@ -1375,7 +1416,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam gi_probe_update_list.add(&gi_probe->update_element); } - } else if ((1 << ins->base_type) & VS::INSTANCE_GEOMETRY_MASK && ins->visible && ins->cast_shadows != VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) { + } else if (((1 << ins->base_type) & VS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != VS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) { keep = true; @@ -2085,7 +2126,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co int success_count = 0; - uint64_t us = OS::get_singleton()->get_ticks_usec(); + // uint64_t us = OS::get_singleton()->get_ticks_usec(); for (int i = 0; i < p_leaf_count; i++) { @@ -2138,14 +2179,15 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co success_count++; } } - //print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); - //print_line("valid cells: " + itos(success_count)); + + // print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); + // print_line("valid cells: " + itos(success_count)); } break; case VS::LIGHT_OMNI: case VS::LIGHT_SPOT: { - uint64_t us = OS::get_singleton()->get_ticks_usec(); + // uint64_t us = OS::get_singleton()->get_ticks_usec(); Vector3 light_pos = light_cache.transform.origin; Vector3 spot_axis = -light_cache.transform.basis.get_axis(2).normalized(); @@ -2244,8 +2286,7 @@ void VisualServerScene::_bake_gi_probe_light(const GIProbeDataHeader *header, co light->energy[2] += int32_t(light_b * att * ((cell->albedo) & 0xFF) / 255.0); } } - //print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); - + // print_line("BAKE TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); } break; } } @@ -2657,18 +2698,17 @@ void VisualServerScene::render_probes() { } break; case GI_UPDATE_STAGE_UPLOADING: { - uint64_t us = OS::get_singleton()->get_ticks_usec(); + // uint64_t us = OS::get_singleton()->get_ticks_usec(); for (int i = 0; i < (int)probe->dynamic.mipmaps_3d.size(); i++) { - int mmsize = probe->dynamic.mipmaps_3d[i].size(); PoolVector<uint8_t>::Read r = probe->dynamic.mipmaps_3d[i].read(); VSG::storage->gi_probe_dynamic_data_update(probe->dynamic.probe_data, 0, probe->dynamic.grid_size[2] >> i, i, r.ptr()); } probe->dynamic.updating_stage = GI_UPDATE_STAGE_CHECK; - //print_line("UPLOAD TIME: "+rtos((OS::get_singleton()->get_ticks_usec()-us)/1000000.0)); + // print_line("UPLOAD TIME: " + rtos((OS::get_singleton()->get_ticks_usec() - us) / 1000000.0)); } break; } } diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index f24049be92..5cf941b93d 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -233,6 +233,7 @@ public: FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode) FUNC2(light_directional_set_blend_splits, RID, bool) + FUNC2(light_directional_set_shadow_depth_range_mode, RID, LightDirectionalShadowDepthRangeMode) /* PROBE API */ diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 67b847d127..47a5f4c7f3 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -1420,6 +1420,29 @@ Array VisualServer::mesh_surface_get_arrays(RID p_mesh, int p_surface) const { return _get_array_from_surface(format, vertex_data, vertex_len, index_data, index_len); } +Array VisualServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const { + + Vector<PoolVector<uint8_t> > blend_shape_data = mesh_surface_get_blend_shapes(p_mesh, p_surface); + if (blend_shape_data.size() > 0) { + int vertex_len = mesh_surface_get_array_len(p_mesh, p_surface); + + PoolVector<uint8_t> index_data = mesh_surface_get_index_array(p_mesh, p_surface); + int index_len = mesh_surface_get_array_index_len(p_mesh, p_surface); + + uint32_t format = mesh_surface_get_format(p_mesh, p_surface); + + Array blend_shape_array; + blend_shape_array.resize(blend_shape_data.size()); + for (int i = 0; i < blend_shape_data.size(); i++) { + blend_shape_array.set(i, _get_array_from_surface(format, blend_shape_data[i], vertex_len, index_data, index_len)); + } + + return blend_shape_array; + } else { + return Array(); + } +} + void VisualServer::_bind_methods() { ClassDB::bind_method(D_METHOD("force_draw"), &VisualServer::draw); diff --git a/servers/visual_server.h b/servers/visual_server.h index d516013ee2..72f36f6b65 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -267,6 +267,7 @@ public: virtual PoolVector<uint8_t> mesh_surface_get_index_array(RID p_mesh, int p_surface) const = 0; virtual Array mesh_surface_get_arrays(RID p_mesh, int p_surface) const; + virtual Array mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const; 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; @@ -406,6 +407,14 @@ public: virtual void light_directional_set_shadow_mode(RID p_light, LightDirectionalShadowMode p_mode) = 0; virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; + enum LightDirectionalShadowDepthRangeMode { + LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE, + LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED, + + }; + + virtual void light_directional_set_shadow_depth_range_mode(RID p_light, LightDirectionalShadowDepthRangeMode p_range_mode) = 0; + /* PROBE API */ virtual RID reflection_probe_create() = 0; @@ -620,6 +629,7 @@ public: ENV_BG_CLEAR_COLOR, ENV_BG_COLOR, ENV_BG_SKY, + ENV_BG_COLOR_SKY, ENV_BG_CANVAS, ENV_BG_KEEP, ENV_BG_MAX |