summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DONORS.md2
-rw-r--r--core/color.cpp12
-rw-r--r--core/color.h6
-rw-r--r--core/io/file_access_network.cpp2
-rw-r--r--core/io/file_access_pack.cpp4
-rw-r--r--core/io/resource_format_binary.cpp45
-rw-r--r--core/io/resource_format_binary.h2
-rw-r--r--core/io/stream_peer.cpp3
-rw-r--r--core/map.h3
-rw-r--r--core/math/a_star.cpp11
-rw-r--r--core/math/a_star.h1
-rw-r--r--core/math/camera_matrix.cpp29
-rw-r--r--core/math/camera_matrix.h1
-rw-r--r--core/math/triangle_mesh.cpp2
-rw-r--r--core/ordered_hash_map.h6
-rw-r--r--core/project_settings.cpp10
-rw-r--r--core/script_debugger_remote.cpp3
-rw-r--r--core/script_language.cpp1
-rw-r--r--core/set.h3
-rw-r--r--core/type_info.h75
-rw-r--r--core/variant_call.cpp10
-rw-r--r--doc/base/classes.xml1301
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp89
-rw-r--r--drivers/gles3/shaders/scene.glsl23
-rw-r--r--drivers/unix/dir_access_unix.cpp20
-rw-r--r--drivers/unix/socket_helpers.h1
-rw-r--r--drivers/windows/file_access_windows.cpp3
-rw-r--r--editor/animation_editor.cpp75
-rw-r--r--editor/dependency_editor.cpp1
-rw-r--r--editor/editor_audio_buses.cpp23
-rw-r--r--editor/editor_audio_buses.h1
-rw-r--r--editor/editor_export.cpp2
-rw-r--r--editor/editor_node.cpp10
-rw-r--r--editor/editor_settings.cpp10
-rw-r--r--editor/editor_themes.cpp4
-rw-r--r--editor/fileserver/editor_file_server.cpp2
-rw-r--r--editor/icons/icon_class_list.svg10
-rw-r--r--editor/icons/icon_file_dead.svg7
-rw-r--r--editor/icons/icon_filesystem.svg5
-rw-r--r--editor/icons/icon_key_call.svg5
-rw-r--r--editor/icons/icon_mini_checkerboard.svg4
-rw-r--r--editor/icons/icon_shader_material.svg11
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp6
-rw-r--r--editor/import/resource_importer_scene.cpp51
-rw-r--r--editor/import/resource_importer_scene.h9
-rw-r--r--editor/import/resource_importer_wav.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp130
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp19
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp3
-rw-r--r--editor/plugins/script_text_editor.cpp2
-rw-r--r--editor/plugins/shader_editor_plugin.cpp8
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp85
-rw-r--r--editor/plugins/spatial_editor_plugin.h4
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp1
-rw-r--r--editor/project_export.cpp5
-rw-r--r--editor/project_manager.cpp46
-rw-r--r--editor/project_manager.h1
-rw-r--r--editor/property_editor.cpp13
-rw-r--r--editor/property_selector.cpp33
-rw-r--r--editor/property_selector.h3
-rw-r--r--editor/scene_tree_dock.cpp56
-rw-r--r--main/main.cpp4
-rw-r--r--methods.py3
-rw-r--r--misc/dist/html/default.html386
-rw-r--r--misc/dist/html_fs/godotfs.js151
-rw-r--r--modules/gdnative/gdnative/color.cpp8
-rw-r--r--modules/gdnative/include/gdnative/color.h4
-rw-r--r--modules/gdnative/register_types.cpp2
-rw-r--r--modules/gdscript/gd_editor.cpp6
-rw-r--r--modules/gdscript/gd_functions.cpp18
-rw-r--r--modules/pvr/texture_loader_pvr.cpp8
-rw-r--r--modules/svg/image_loader_svg.cpp4
-rw-r--r--modules/theora/video_stream_theora.cpp3
-rw-r--r--modules/visual_script/visual_script_editor.cpp177
-rw-r--r--modules/visual_script/visual_script_editor.h7
-rw-r--r--modules/visual_script/visual_script_expression.cpp1
-rw-r--r--modules/visual_script/visual_script_nodes.cpp20
-rw-r--r--platform/android/export/export.cpp57
-rw-r--r--platform/javascript/SCsub33
-rw-r--r--platform/javascript/detect.py2
-rw-r--r--platform/javascript/engine.js366
-rw-r--r--platform/javascript/export/export.cpp30
-rw-r--r--platform/javascript/godot_shell.html347
-rw-r--r--platform/javascript/pre_asmjs.js3
-rw-r--r--platform/javascript/pre_wasm.js3
-rw-r--r--platform/uwp/export/export.cpp2
-rw-r--r--platform/windows/context_gl_win.cpp16
-rw-r--r--platform/windows/joypad.cpp4
-rw-r--r--platform/windows/os_windows.cpp11
-rw-r--r--scene/2d/area_2d.cpp8
-rw-r--r--scene/2d/audio_stream_player_2d.cpp3
-rw-r--r--scene/2d/canvas_item.cpp1
-rw-r--r--scene/2d/line_builder.cpp55
-rw-r--r--scene/2d/path_2d.cpp3
-rw-r--r--scene/3d/arvr_nodes.cpp15
-rw-r--r--scene/3d/arvr_nodes.h2
-rw-r--r--scene/3d/bone_attachment.cpp6
-rw-r--r--scene/3d/collision_shape.cpp3
-rw-r--r--scene/3d/gi_probe.cpp19
-rw-r--r--scene/3d/interpolated_camera.cpp4
-rw-r--r--scene/3d/light.cpp9
-rw-r--r--scene/3d/path.cpp4
-rw-r--r--scene/3d/spatial.cpp2
-rw-r--r--scene/3d/vehicle_body.cpp8
-rw-r--r--scene/3d/vehicle_body.h2
-rw-r--r--scene/animation/animation_tree_player.cpp1
-rw-r--r--scene/gui/control.cpp2
-rw-r--r--scene/gui/file_dialog.cpp4
-rw-r--r--scene/gui/tree.cpp4
-rwxr-xr-xscene/main/node.cpp28
-rw-r--r--scene/main/scene_tree.cpp1
-rw-r--r--scene/main/viewport.cpp3
-rw-r--r--scene/resources/curve.cpp34
-rw-r--r--scene/resources/default_theme/default_theme.cpp2
-rw-r--r--scene/resources/material.cpp8
-rw-r--r--scene/resources/mesh.cpp4
-rw-r--r--scene/resources/mesh.h3
-rw-r--r--scene/resources/packed_scene.cpp8
-rw-r--r--scene/resources/primitive_meshes.cpp19
-rw-r--r--scene/resources/primitive_meshes.h3
-rw-r--r--servers/arvr/arvr_positional_tracker.cpp14
-rw-r--r--servers/arvr/arvr_positional_tracker.h12
-rw-r--r--servers/arvr_server.cpp9
-rw-r--r--servers/audio/effects/audio_effect_limiter.cpp5
-rw-r--r--servers/audio_server.cpp3
-rw-r--r--servers/physics/broad_phase_basic.cpp3
-rw-r--r--servers/physics/shape_sw.cpp3
-rw-r--r--servers/physics/step_sw.cpp2
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/shader_language.cpp25
-rw-r--r--servers/visual/visual_server_scene.cpp72
-rw-r--r--servers/visual_server.cpp23
-rw-r--r--servers/visual_server.h1
134 files changed, 2792 insertions, 1644 deletions
diff --git a/DONORS.md b/DONORS.md
index 09049ede48..57902fb2fc 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -21,7 +21,7 @@ None so far, but your company could be the first! :)
## Mini sponsors
Arron Washington
- Chrisartguy
+ Chris Phyffer
Christian Uldall Pedersen
Hein-Pieter van Braam
Matthieu Huvé
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 084d8ffcab..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;
}
@@ -1123,16 +1113,14 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
}
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
@@ -1793,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
@@ -1814,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/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 572a6c5239..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;
@@ -266,27 +265,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 {
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},
+ 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 },
};
- for(int i=0;i<8;i++) {
+ for (int i = 0; i < 8; i++) {
Vector3 point;
- bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]],planes[intersections[i][2]], &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[i] = p_transform.xform(point);
}
return true;
-
}
Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform) const {
@@ -564,10 +562,9 @@ int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const {
bool CameraMatrix::is_orthogonal() const {
- return matrix[3][3]==1.0;
+ 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 87cc4b95b8..3145d73356 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -84,7 +84,6 @@ struct CameraMatrix {
Plane xform4(const Plane &p_vec4) const;
_FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const;
-
operator String() const;
void scale_translate_to_fit(const Rect3 &p_aabb);
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/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/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/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/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 dc1c24d234..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);
@@ -1524,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());
@@ -1623,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/doc/base/classes.xml b/doc/base/classes.xml
index a097470306..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,7 +38,10 @@
<argument index="1" name="alpha" type="float">
</argument>
<description>
- Make a color from color name (color_names.inc) and alpha ranging from 0 to 1.
+ 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">
@@ -40,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">
@@ -49,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">
@@ -58,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">
@@ -67,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 &amp;&amp; speed < 20)
+ [/codeblock]
</description>
</method>
<method name="atan">
@@ -76,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">
@@ -87,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">
@@ -105,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">
@@ -115,6 +162,12 @@
</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">
@@ -127,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">
@@ -139,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">
@@ -147,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">
@@ -156,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">
@@ -174,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">
@@ -187,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">
@@ -196,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">
@@ -205,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">
@@ -225,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">
@@ -234,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">
@@ -260,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">
@@ -271,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">
@@ -280,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">
@@ -289,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">
@@ -298,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">
@@ -323,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">
@@ -332,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">
@@ -341,7 +494,16 @@
<argument index="0" name="var" type="Variant">
</argument>
<description>
- Returns the length of the given Variant if applicable. It will return character count of a String, element count of an Array, etc.
+<<<<<<< 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">
@@ -372,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">
@@ -381,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">
@@ -392,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">
@@ -403,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">
@@ -412,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">
@@ -423,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">
@@ -433,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">
@@ -442,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">
@@ -2007,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">
@@ -2041,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>
@@ -2053,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>
@@ -2063,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">
@@ -2091,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">
@@ -2105,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">
@@ -2113,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>
@@ -2125,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>
@@ -2139,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">
@@ -2191,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>
@@ -2212,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">
@@ -2237,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>
@@ -2249,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">
@@ -2295,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" enum="ARVRServer.TrackerType">
</return>
<description>
+ Type of tracker.
</description>
</method>
</methods>
@@ -2309,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">
@@ -2327,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">
@@ -2343,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>
@@ -2399,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">
@@ -2409,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">
@@ -2417,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">
@@ -2425,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">
@@ -2445,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">
@@ -2465,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">
@@ -2483,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">
@@ -2491,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>
@@ -2503,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">
@@ -2517,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>
@@ -2558,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">
@@ -2568,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">
@@ -2580,7 +2905,12 @@
<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">
@@ -2591,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">
@@ -2611,7 +2941,16 @@
<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">
@@ -2622,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">
@@ -2637,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">
@@ -2646,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">
@@ -2657,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">
@@ -2668,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">
@@ -2677,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">
@@ -2686,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">
@@ -2695,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">
@@ -2704,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>
@@ -5083,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">
@@ -5115,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">
@@ -5131,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">
@@ -5166,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">
@@ -5395,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>
@@ -5507,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">
@@ -6073,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>
@@ -6083,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">
@@ -6099,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>
@@ -6131,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">
@@ -6153,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">
@@ -6161,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">
@@ -6169,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">
@@ -6177,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">
@@ -6185,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">
@@ -6193,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">
@@ -6207,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">
@@ -6215,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">
@@ -6225,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">
@@ -6235,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">
@@ -6245,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">
@@ -6255,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">
@@ -6265,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">
@@ -6275,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">
@@ -6283,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>
@@ -9025,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">
@@ -9035,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">
@@ -9043,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">
@@ -9051,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">
@@ -9073,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">
@@ -9083,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>
@@ -9261,6 +9714,7 @@
<return type="String">
</return>
<description>
+ Returns the name of the bone node attached to.
</description>
</method>
<method name="set_bone_name">
@@ -9269,6 +9723,7 @@
<argument index="0" name="bone_name" type="String">
</argument>
<description>
+ Changes the name of the bone node
</description>
</method>
</methods>
@@ -9370,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" 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">
@@ -9407,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">
@@ -9416,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">
@@ -9425,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">
@@ -9434,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">
@@ -9443,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>
@@ -9464,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.
@@ -11033,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">
@@ -11096,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>
@@ -12155,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">
@@ -12175,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">
@@ -12183,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">
@@ -12204,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>
@@ -12213,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">
@@ -12260,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>
@@ -12277,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 &gt; 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 &gt; 1.
</description>
<methods>
<method name="Color">
@@ -12295,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">
@@ -12308,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">
@@ -12317,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">
@@ -12326,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">
@@ -12335,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">
@@ -12367,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">
@@ -12390,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>
@@ -12572,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>
@@ -12619,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">
@@ -12635,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>
@@ -12934,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">
@@ -12965,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">
@@ -13820,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">
@@ -13836,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">
@@ -13845,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>
@@ -14171,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">
@@ -14234,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>
@@ -14929,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">
@@ -15006,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>
@@ -19249,20 +19803,31 @@
</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>
@@ -20461,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">
@@ -20490,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>
@@ -22105,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">
@@ -22114,6 +22683,7 @@
<argument index="0" name="hostname" type="String" default="&quot;&quot;">
</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">
@@ -22122,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">
@@ -22137,7 +22708,7 @@
<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">
@@ -22146,7 +22717,7 @@
<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">
@@ -22157,7 +22728,7 @@
<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">
@@ -22168,7 +22739,7 @@
<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>
@@ -23249,6 +23820,7 @@
</class>
<class name="InputEvent" inherits="Resource" category="Core">
<brief_description>
+ Generic input event
</brief_description>
<description>
</description>
@@ -23259,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">
@@ -23285,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">
@@ -23294,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">
@@ -23303,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">
@@ -23316,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">
@@ -26260,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">
@@ -26301,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>
@@ -26310,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">
@@ -26320,6 +26900,7 @@
<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">
@@ -26408,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">
@@ -27373,6 +27955,7 @@
<return type="Shape">
</return>
<description>
+ Calculate a [ConvexPolygonShape] from the mesh.
</description>
</method>
<method name="create_outline" qualifiers="const">
@@ -27381,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>
@@ -27770,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">
@@ -27782,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">
@@ -27804,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">
@@ -27812,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">
@@ -27831,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>
@@ -29667,7 +30258,7 @@
<return type="void">
</return>
<description>
- Destroy this Node and its children when they are not in use.
+ 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">
@@ -30051,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">
@@ -30063,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">
@@ -30072,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">
@@ -30081,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">
@@ -30125,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">
@@ -30162,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">
@@ -30178,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">
@@ -30189,7 +30780,7 @@
<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">
@@ -30200,7 +30791,7 @@
<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">
@@ -30209,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">
@@ -30218,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">
@@ -30227,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">
@@ -30236,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">
@@ -30245,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">
@@ -30254,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">
@@ -30263,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">
@@ -30272,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">
@@ -30281,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">
@@ -30290,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">
@@ -30299,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">
@@ -30308,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">
@@ -30317,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">
@@ -30342,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>
@@ -38019,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">
@@ -38068,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>
@@ -38438,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">
@@ -38453,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">
@@ -38464,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">
@@ -38515,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">
@@ -38554,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">
@@ -38577,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">
@@ -38614,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">
@@ -38630,7 +39239,7 @@
<return type="int">
</return>
<description>
- Return the array size.
+ Return the size of the array.
</description>
</method>
</methods>
@@ -38642,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">
@@ -38702,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">
@@ -38790,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">
@@ -38857,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">
@@ -38886,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">
@@ -38974,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">
@@ -39048,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">
@@ -39062,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">
@@ -39729,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">
@@ -39750,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>
@@ -39757,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">
@@ -39834,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>
@@ -40391,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>
@@ -40752,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>
@@ -40767,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">
@@ -40776,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">
@@ -40803,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">
@@ -40824,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">
@@ -40852,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">
@@ -40861,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">
@@ -40870,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">
@@ -40878,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">
@@ -40911,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>
@@ -40927,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>
@@ -40942,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">
@@ -40951,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">
@@ -40978,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">
@@ -40999,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">
@@ -41043,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">
@@ -41052,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">
@@ -41102,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>
@@ -43248,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>
@@ -44435,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">
@@ -44458,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">
@@ -44467,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">
@@ -44482,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" 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">
@@ -44505,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>
@@ -45473,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">
@@ -45536,6 +46220,7 @@
<return type="World">
</return>
<description>
+ Return current [World] resource this Spatial node is registered to.
</description>
</method>
<method name="global_rotate">
@@ -45546,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">
@@ -45554,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">
@@ -45600,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">
@@ -45612,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">
@@ -45628,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">
@@ -45636,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">
@@ -45644,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">
@@ -45652,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">
@@ -45660,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">
@@ -45668,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">
@@ -45676,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">
@@ -45691,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">
@@ -45699,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">
@@ -45707,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">
@@ -45733,6 +46439,7 @@
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
+ Set the scale.
</description>
</method>
<method name="set_transform">
@@ -45764,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">
@@ -45772,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">
@@ -45780,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">
@@ -45788,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>
@@ -46905,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">
@@ -46982,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>
@@ -47989,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>
@@ -49422,7 +50157,7 @@
- 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:
+ 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
@@ -51736,10 +52471,10 @@
</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">
@@ -51787,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>
@@ -52125,14 +52863,14 @@
<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">
@@ -52147,7 +52885,7 @@
<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>
@@ -52170,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">
@@ -52617,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>
@@ -53055,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">
@@ -53158,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>
@@ -53403,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">
@@ -53421,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">
@@ -53432,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">
@@ -53441,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">
@@ -53450,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">
@@ -53459,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">
@@ -53477,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">
@@ -53530,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">
@@ -53554,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>
@@ -53565,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">
@@ -53577,6 +54341,7 @@
<argument index="0" name="from" type="Transform">
</argument>
<description>
+ Constructs the [Transform2D] from a 3D [Transform].
</description>
</method>
<method name="Transform2D">
@@ -53589,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">
@@ -53599,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">
@@ -53614,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">
@@ -53622,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">
@@ -53641,6 +54411,7 @@
<return type="Vector2">
</return>
<description>
+ Return the scale.
</description>
</method>
<method name="interpolate_with">
@@ -53651,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">
@@ -53671,6 +54445,7 @@
<argument index="0" name="phi" type="float">
</argument>
<description>
+ Rotate the transform by phi.
</description>
</method>
<method name="scaled">
@@ -53679,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">
@@ -53687,6 +54463,7 @@
<argument index="0" name="offset" type="Vector2">
</argument>
<description>
+ Translate the transform by the specified offset.
</description>
</method>
<method name="xform">
@@ -53695,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">
@@ -53703,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>
@@ -55584,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>
@@ -57010,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">
@@ -57066,6 +57854,7 @@
<return type="bool">
</return>
<description>
+ Returns whether this viewport is using our ARVR Server
</description>
</method>
<method name="warp_mouse">
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 3cacfac578..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);
}
@@ -3360,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();
@@ -4631,7 +4624,7 @@ void RasterizerStorageGLES3::light_directional_set_shadow_depth_range_mode(RID p
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
- light->directional_range_mode=p_range_mode;
+ light->directional_range_mode = p_range_mode;
}
VS::LightDirectionalShadowDepthRangeMode RasterizerStorageGLES3::light_directional_get_shadow_depth_range_mode(RID p_light) const {
@@ -6864,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/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 73268c1914..5f83033293 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -935,17 +935,26 @@ LIGHT_SHADER_CODE
#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);
- light_amount = lightScatter * viewScatter * energyFactor;
+ light_amount = lightScatter * viewScatter * energyFactor;*/
}
#else
//lambert
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index b85a63a44a..6b8038c3ef 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -221,37 +221,24 @@ Error DirAccessUnix::change_dir(String p_dir) {
if (prev_dir.parse_utf8(real_current_dir_name))
prev_dir = real_current_dir_name; //no utf8, maybe latin?
- //print_line("directory we are changing out of (prev_dir): " + prev_dir);
-
// 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;
- //print_line("p_dir is relative: " + p_dir + " about to simplfy: " + next_dir);
next_dir = next_dir.simplify_path();
try_dir = next_dir;
} else {
try_dir = p_dir;
- //print_line("p_dir is absolute: " + p_dir);
- }
-
- // if try_dir is nothing, it is not changing directory so change it to a "." otherwise chdir will fail
- if (try_dir == "") {
- try_dir = ".";
}
- //print_line("directory we are changing in to (try_dir): " + try_dir);
-
bool worked = (chdir(try_dir.utf8().get_data()) == 0); // we can only give this utf8
if (!worked) {
- //print_line("directory does not exist");
return ERR_INVALID_PARAMETER;
}
// the directory exists, so set current_dir to try_dir
current_dir = try_dir;
chdir(prev_dir.utf8().get_data());
- //print_line("directory exists, setting current_dir to: " + current_dir);
return OK;
}
@@ -319,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/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/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/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_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_node.cpp b/editor/editor_node.cpp
index 91d2ddcd19..b4412014e7 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -412,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();
}
@@ -1997,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);
@@ -3607,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++) {
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index db76a27f5f..50cee6d892 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -676,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 19356aad3a..ff0e794a20 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -295,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));
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/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_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 3d5732c749..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;
@@ -1515,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"))) {
@@ -2269,7 +2273,6 @@ 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();
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/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 04be1ba4ab..6f03d086ca 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2416,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() {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index fae57eb5d2..2192d3ac49 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -624,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 b02016c273..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);
@@ -403,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 4e722be44b..93d12fd3d2 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -76,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);
- bool disable_interp = orthogonal || (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);
+ Cursor old_camera_cursor = camera_cursor;
+ camera_cursor = cursor;
- 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;
+ 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 == 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();
}
}
@@ -1540,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();
@@ -1661,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();
@@ -1672,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;
}
@@ -1689,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) {
@@ -2528,7 +2511,6 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const
found_gizmos.insert(seg);
- int handle = -1;
Vector3 hit_point;
Vector3 hit_normal;
bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, NULL, false);
@@ -3423,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"];
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index db5abe2b53..5f3ef2dbee 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -131,7 +131,7 @@ private:
float gizmo_scale;
bool freelook_active;
- Vector3 freelook_velocity;
+ Vector3 freelook_target_position;
PanelContainer *info;
Label *info_label;
@@ -239,7 +239,7 @@ private:
distance = 4;
region_select = false;
}
- } cursor;
+ } cursor, camera_cursor;
void scale_cursor_distance(real_t scale);
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/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/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/main/main.cpp b/main/main.cpp
index fe07ba484d..1295cd73b5 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1325,7 +1325,6 @@ bool Main::start() {
int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
-
sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q0_subdiv));
sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q1_subdiv));
@@ -1347,7 +1346,6 @@ bool Main::start() {
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;
@@ -1389,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/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp
index 3f8912d896..2a5c0887a1 100644
--- a/modules/gdnative/gdnative/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -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/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index 90dccf75aa..14265466b9 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -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/register_types.cpp b/modules/gdnative/register_types.cpp
index d809109987..559e9fa455 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -248,7 +248,7 @@ void unregister_gdnative_types() {
memdelete(GDNativeCallRegistry::singleton);
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint()) {
+ if (Engine::get_singleton()->is_editor_hint() && discoverer != NULL) {
memdelete(discoverer);
}
#endif
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/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/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_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 37bd730d08..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,7 +520,7 @@ 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_resizable(true);
@@ -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/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/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 ea2e77fc47..d2a8e3315a 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -254,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 {
@@ -449,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 a7c5d1adbb..ec1ea7df38 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -338,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/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 7792a86b4a..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
@@ -1113,7 +1097,8 @@ 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) {
if (s->is_visible_in_tree()) {
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 d410ba1e2a..096f787873 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -308,9 +308,8 @@ DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const {
}
void DirectionalLight::set_shadow_depth_range(ShadowDepthRange p_range) {
- shadow_depth_range=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 {
@@ -318,7 +317,6 @@ DirectionalLight::ShadowDepthRange DirectionalLight::get_shadow_depth_range() co
return shadow_depth_range;
}
-
void DirectionalLight::set_blend_splits(bool p_enable) {
blend_splits = p_enable;
@@ -356,8 +354,8 @@ void DirectionalLight::_bind_methods() {
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 );
+ BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_STABLE);
+ BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_OPTIMIZED);
}
DirectionalLight::DirectionalLight()
@@ -370,7 +368,6 @@ DirectionalLight::DirectionalLight()
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
-
blend_splits = false;
}
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/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/gui/control.cpp b/scene/gui/control.cpp
index 7bf11e6712..87dfd95724 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1250,7 +1250,7 @@ void Control::_size_changed() {
}
if (get_viewport()->is_snap_controls_to_pixels_enabled()) {
- new_size_cache =new_size_cache.floor();
+ new_size_cache = new_size_cache.floor();
new_pos_cache = new_pos_cache.floor();
}
bool pos_changed = new_pos_cache != data.pos_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/tree.cpp b/scene/gui/tree.cpp
index de17416d8e..db282262ec 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2304,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();
@@ -2478,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) {
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 434d594bbb..567b1dd7a1 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2580,7 +2580,7 @@ int Viewport::get_render_info(RenderInfo p_info) {
void Viewport::set_snap_controls_to_pixels(bool p_enable) {
- snap_controls_to_pixels=p_enable;
+ snap_controls_to_pixels = p_enable;
}
bool Viewport::is_snap_controls_to_pixels_enabled() const {
@@ -2588,7 +2588,6 @@ 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);
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 fdea5960e5..1272e5a946 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -794,7 +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_stylebox(tree_bg_png, 3, 3, 3, 3));
+ 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/material.cpp b/scene/resources/material.cpp
index a187692bcb..abe9a00c3f 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -67,8 +67,8 @@ RID Material::get_rid() const {
}
void Material::_validate_property(PropertyInfo &property) const {
- if (!_can_do_next_pass() && property.name=="next_pass") {
- property.usage=0;
+ if (!_can_do_next_pass() && property.name == "next_pass") {
+ property.usage = 0;
}
}
@@ -80,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);
@@ -212,7 +212,7 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
bool ShaderMaterial::_can_do_next_pass() const {
- return shader.is_valid() && shader->get_mode()==Shader::MODE_SPATIAL;
+ return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL;
}
ShaderMaterial::ShaderMaterial() {
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/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/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 0784fb1049..344c10089a 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -338,7 +338,6 @@ public:
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 c7b02c92f7..6ad433268f 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -3000,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());
@@ -3121,8 +3119,8 @@ 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;
+ vardecl->datatype = type;
+ vardecl->precision = precision;
p_block->statements.push_back(vardecl);
@@ -3148,8 +3146,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
VariableDeclarationNode::Declaration decl;
- decl.name=name;
- decl.initializer=NULL;
+ decl.name = name;
+ decl.initializer = NULL;
tk = _get_token();
@@ -3161,13 +3159,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
decl.initializer = n;
- if (var.type!=n->get_datatype()) {
+ 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);
@@ -3272,9 +3268,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
BlockNode *init_block = alloc_node<BlockNode>();
init_block->parent_block = p_block;
- init_block->single_statement=true;
+ init_block->single_statement = true;
cf->blocks.push_back(init_block);
- if (_parse_block(init_block,p_builtin_types,true,false,false)!=OK) {
+ if (_parse_block(init_block, p_builtin_types, true, false, false) != OK) {
return ERR_PARSE_ERROR;
}
@@ -3282,10 +3278,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
if (!n)
return ERR_PARSE_ERROR;
- if (n->get_datatype()!=TYPE_BOOL) {
+ if (n->get_datatype() != TYPE_BOOL) {
_set_error("Middle expression is expected to be boolean.");
return ERR_PARSE_ERROR;
-
}
tk = _get_token();
@@ -3392,7 +3387,6 @@ 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");
@@ -3411,7 +3405,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
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");
@@ -3980,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/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index e791f7b443..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);
@@ -890,50 +886,48 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
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);
+ 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) {
+ 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));
+ 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;
+ bool found_items = false;
+ float z_max = -1e20;
+ float z_min = 1e20;
- for(int i=0;i<cull_count;i++) {
+ 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;
+ float max, min;
instance->transformed_aabb.project_range_in_plane(base, min, max);
- if (max>z_max) {
- z_max=max;
+ if (max > z_max) {
+ z_max = max;
}
- if (min<z_min) {
- z_min=min;
+ if (min < z_min) {
+ z_min = min;
}
- found_items=true;
+ found_items = true;
}
if (found_items) {
- min_distance=MAX(min_distance,z_min);
- max_distance=MIN(max_distance,z_max);
+ min_distance = MAX(min_distance, z_min);
+ max_distance = MIN(max_distance, z_max);
}
-
}
-
float range = max_distance - min_distance;
int splits = 0;
@@ -1062,7 +1056,7 @@ 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;
- if (depth_range_mode==VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE) {
+ 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
@@ -1073,8 +1067,6 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
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
@@ -1118,7 +1110,6 @@ 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;
@@ -1425,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;
@@ -2135,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++) {
@@ -2188,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();
@@ -2294,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;
}
}
@@ -2707,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_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 7494820287..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;