summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/multiplayer_api.cpp146
-rw-r--r--core/io/multiplayer_api.h34
-rw-r--r--core/script_debugger_remote.cpp57
-rw-r--r--core/script_debugger_remote.h9
-rw-r--r--core/script_language.h1
-rw-r--r--core/ustring.cpp4
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp7
-rw-r--r--drivers/gles2/shaders/canvas.glsl26
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp7
-rw-r--r--drivers/gles3/shaders/canvas.glsl26
-rw-r--r--editor/animation_track_editor.cpp12
-rw-r--r--editor/animation_track_editor.h2
-rw-r--r--editor/editor_network_profiler.cpp192
-rw-r--r--editor/editor_network_profiler.h72
-rw-r--r--editor/editor_path.cpp3
-rw-r--r--editor/import_dock.cpp8
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp23
-rw-r--r--editor/plugins/animation_player_editor_plugin.h11
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp108
-rw-r--r--editor/plugins/tile_map_editor_plugin.h2
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp26
-rw-r--r--editor/plugins/tile_set_editor_plugin.h1
-rw-r--r--editor/script_editor_debugger.cpp75
-rw-r--r--editor/script_editor_debugger.h5
-rw-r--r--misc/dist/html/full-size.html2
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp106
-rw-r--r--modules/gdscript/gdscript_compiler.cpp8
-rw-r--r--modules/gdscript/gdscript_function.cpp13
-rw-r--r--modules/gdscript/gdscript_parser.cpp42
-rw-r--r--modules/gdscript/gdscript_parser.h7
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp19
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs2
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp1
-rw-r--r--modules/mono/glue/Managed/Files/Rect2.cs8
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp2
-rw-r--r--modules/mono/utils/string_utils.cpp10
-rw-r--r--scene/gui/line_edit.cpp89
-rw-r--r--scene/gui/line_edit.h12
-rw-r--r--scene/gui/rich_text_effect.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp2
-rw-r--r--scene/gui/text_edit.cpp90
-rw-r--r--scene/gui/text_edit.h11
-rw-r--r--scene/main/scene_tree.cpp1
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/style_box.cpp11
-rw-r--r--scene/resources/visual_shader_nodes.cpp119
-rw-r--r--servers/visual/shader_language.cpp40
-rw-r--r--servers/visual/shader_language.h4
-rw-r--r--servers/visual/shader_types.cpp1
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.cpp24
-rw-r--r--thirdparty/assimp/code/FBX/FBXConverter.h4
-rw-r--r--thirdparty/assimp/code/FBX/FBXImporter.cpp2
-rw-r--r--thirdparty/assimp/include/assimp/material.h46
54 files changed, 1327 insertions, 217 deletions
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index d20133642b..ed6905c9a6 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -33,6 +33,10 @@
#include "core/io/marshalls.h"
#include "scene/main/node.h"
+#ifdef DEBUG_ENABLED
+#include "core/os/os.h"
+#endif
+
_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) {
switch (mode) {
@@ -166,6 +170,14 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
ERR_FAIL_COND_MSG(root_node == NULL, "Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it.");
ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small.");
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ bandwidth_incoming_data.write[bandwidth_incoming_pointer].timestamp = OS::get_singleton()->get_ticks_msec();
+ bandwidth_incoming_data.write[bandwidth_incoming_pointer].packet_size = p_packet_len;
+ bandwidth_incoming_pointer = (bandwidth_incoming_pointer + 1) % bandwidth_incoming_data.size();
+ }
+#endif
+
uint8_t packet_type = p_packet[0];
switch (packet_type) {
@@ -284,6 +296,14 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const StringName &p_name, int p_
p_offset++;
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].incoming_rpc += 1;
+ }
+#endif
+
for (int i = 0; i < argc; i++) {
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
@@ -322,6 +342,14 @@ void MultiplayerAPI::_process_rset(Node *p_node, const StringName &p_name, int p
bool can_call = _can_call_mode(p_node, rset_mode, p_from);
ERR_FAIL_COND_MSG(!can_call, "RSET '" + String(p_name) + "' is not allowed on node " + p_node->get_path() + " from: " + itos(p_from) + ". Mode is " + itos((int)rset_mode) + ", master is " + itos(p_node->get_network_master()) + ".");
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].incoming_rset += 1;
+ }
+#endif
+
Variant value;
Error err = decode_variant(value, &p_packet[p_offset], p_packet_len - p_offset, NULL, allow_object_decoding || network_peer->is_object_decoding_allowed());
@@ -512,6 +540,14 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
}
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ bandwidth_outgoing_data.write[bandwidth_outgoing_pointer].timestamp = OS::get_singleton()->get_ticks_msec();
+ bandwidth_outgoing_data.write[bandwidth_outgoing_pointer].packet_size = ofs;
+ bandwidth_outgoing_pointer = (bandwidth_outgoing_pointer + 1) % bandwidth_outgoing_data.size();
+ }
+#endif
+
// See if all peers have cached path (is so, call can be fast).
bool has_all_peers = _send_confirm_path(from_path, psc, p_to);
@@ -615,6 +651,15 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
if (!skip_rpc) {
+
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].outgoing_rpc += 1;
+ }
+#endif
+
_send_rpc(p_node, p_peer_id, p_unreliable, false, p_method, p_arg, p_argcount);
}
@@ -709,6 +754,14 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
return;
}
+#ifdef DEBUG_ENABLED
+ if (profiling) {
+ ObjectID id = p_node->get_instance_id();
+ _init_node_profile(id);
+ profiler_frame_data[id].outgoing_rset += 1;
+ }
+#endif
+
const Variant *vptr = &p_value;
_send_rpc(p_node, p_peer_id, p_unreliable, true, p_property, &vptr, 1);
@@ -792,6 +845,96 @@ bool MultiplayerAPI::is_object_decoding_allowed() const {
return allow_object_decoding;
}
+void MultiplayerAPI::profiling_start() {
+#ifdef DEBUG_ENABLED
+ profiling = true;
+ profiler_frame_data.clear();
+
+ bandwidth_incoming_pointer = 0;
+ bandwidth_incoming_data.resize(16384); // ~128kB
+ for (int i = 0; i < bandwidth_incoming_data.size(); ++i) {
+ bandwidth_incoming_data.write[i].packet_size = -1;
+ }
+
+ bandwidth_outgoing_pointer = 0;
+ bandwidth_outgoing_data.resize(16384); // ~128kB
+ for (int i = 0; i < bandwidth_outgoing_data.size(); ++i) {
+ bandwidth_outgoing_data.write[i].packet_size = -1;
+ }
+#endif
+}
+
+void MultiplayerAPI::profiling_end() {
+#ifdef DEBUG_ENABLED
+ profiling = false;
+ bandwidth_incoming_data.clear();
+ bandwidth_outgoing_data.clear();
+#endif
+}
+
+int MultiplayerAPI::get_profiling_frame(ProfilingInfo *r_info) {
+ int i = 0;
+#ifdef DEBUG_ENABLED
+ for (Map<ObjectID, ProfilingInfo>::Element *E = profiler_frame_data.front(); E; E = E->next()) {
+ r_info[i] = E->get();
+ ++i;
+ }
+ profiler_frame_data.clear();
+#endif
+ return i;
+}
+
+int MultiplayerAPI::get_incoming_bandwidth_usage() {
+#ifdef DEBUG_ENABLED
+ return _get_bandwidth_usage(bandwidth_incoming_data, bandwidth_incoming_pointer);
+#else
+ return 0;
+#endif
+}
+
+int MultiplayerAPI::get_outgoing_bandwidth_usage() {
+#ifdef DEBUG_ENABLED
+ return _get_bandwidth_usage(bandwidth_outgoing_data, bandwidth_outgoing_pointer);
+#else
+ return 0;
+#endif
+}
+
+#ifdef DEBUG_ENABLED
+int MultiplayerAPI::_get_bandwidth_usage(const Vector<BandwidthFrame> &p_buffer, int p_pointer) {
+ int total_bandwidth = 0;
+
+ uint32_t timestamp = OS::get_singleton()->get_ticks_msec();
+ uint32_t final_timestamp = timestamp - 1000;
+
+ int i = (p_pointer + p_buffer.size() - 1) % p_buffer.size();
+
+ while (i != p_pointer && p_buffer[i].packet_size > 0) {
+ if (p_buffer[i].timestamp < final_timestamp) {
+ return total_bandwidth;
+ }
+ total_bandwidth += p_buffer[i].packet_size;
+ i = (i + p_buffer.size() - 1) % p_buffer.size();
+ }
+
+ ERR_EXPLAIN("Reached the end of the bandwidth profiler buffer, values might be inaccurate.");
+ ERR_FAIL_COND_V(i == p_pointer, total_bandwidth);
+ return total_bandwidth;
+}
+
+void MultiplayerAPI::_init_node_profile(ObjectID p_node) {
+ if (profiler_frame_data.has(p_node))
+ return;
+ profiler_frame_data.insert(p_node, ProfilingInfo());
+ profiler_frame_data[p_node].node = p_node;
+ profiler_frame_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path();
+ profiler_frame_data[p_node].incoming_rpc = 0;
+ profiler_frame_data[p_node].incoming_rset = 0;
+ profiler_frame_data[p_node].outgoing_rpc = 0;
+ profiler_frame_data[p_node].outgoing_rset = 0;
+}
+#endif
+
void MultiplayerAPI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_root_node", "node"), &MultiplayerAPI::set_root_node);
ClassDB::bind_method(D_METHOD("send_bytes", "bytes", "id", "mode"), &MultiplayerAPI::send_bytes, DEFVAL(NetworkedMultiplayerPeer::TARGET_PEER_BROADCAST), DEFVAL(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE));
@@ -842,6 +985,9 @@ MultiplayerAPI::MultiplayerAPI() :
allow_object_decoding(false) {
rpc_sender_id = 0;
root_node = NULL;
+#ifdef DEBUG_ENABLED
+ profiling = false;
+#endif
clear();
}
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index 5258dde5d7..b824456e0f 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -38,6 +38,16 @@ class MultiplayerAPI : public Reference {
GDCLASS(MultiplayerAPI, Reference);
+public:
+ struct ProfilingInfo {
+ ObjectID node;
+ String node_path;
+ int incoming_rpc;
+ int incoming_rset;
+ int outgoing_rpc;
+ int outgoing_rset;
+ };
+
private:
//path sent caches
struct PathSentCache {
@@ -55,6 +65,23 @@ private:
Map<int, NodeInfo> nodes;
};
+#ifdef DEBUG_ENABLED
+ struct BandwidthFrame {
+ uint32_t timestamp;
+ int packet_size;
+ };
+
+ int bandwidth_incoming_pointer;
+ Vector<BandwidthFrame> bandwidth_incoming_data;
+ int bandwidth_outgoing_pointer;
+ Vector<BandwidthFrame> bandwidth_outgoing_data;
+ Map<ObjectID, ProfilingInfo> profiler_frame_data;
+ bool profiling;
+
+ void _init_node_profile(ObjectID p_node);
+ int _get_bandwidth_usage(const Vector<BandwidthFrame> &p_buffer, int p_pointer);
+#endif
+
Ref<NetworkedMultiplayerPeer> network_peer;
int rpc_sender_id;
Set<int> connected_peers;
@@ -130,6 +157,13 @@ public:
void set_allow_object_decoding(bool p_enable);
bool is_object_decoding_allowed() const;
+ void profiling_start();
+ void profiling_end();
+
+ int get_profiling_frame(ProfilingInfo *r_info);
+ int get_incoming_bandwidth_usage();
+ int get_outgoing_bandwidth_usage();
+
MultiplayerAPI();
~MultiplayerAPI();
};
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 0b2b7368d2..65ef2a0978 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -769,6 +769,14 @@ void ScriptDebuggerRemote::_poll_events() {
profiling = false;
_send_profiling_data(false);
print_line("PROFILING END!");
+ } else if (command == "start_network_profiling") {
+
+ multiplayer->profiling_start();
+ profiling_network = true;
+ } else if (command == "stop_network_profiling") {
+
+ multiplayer->profiling_end();
+ profiling_network = false;
} else if (command == "reload_scripts") {
reload_all_scripts = true;
} else if (command == "breakpoint") {
@@ -918,6 +926,18 @@ void ScriptDebuggerRemote::idle_poll() {
}
}
+ if (profiling_network) {
+ uint64_t pt = OS::get_singleton()->get_ticks_msec();
+ if (pt - last_net_bandwidth_time > 200) {
+ last_net_bandwidth_time = pt;
+ _send_network_bandwidth_usage();
+ }
+ if (pt - last_net_prof_time > 100) {
+ last_net_prof_time = pt;
+ _send_network_profiling_data();
+ }
+ }
+
if (reload_all_scripts) {
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -929,6 +949,35 @@ void ScriptDebuggerRemote::idle_poll() {
_poll_events();
}
+void ScriptDebuggerRemote::_send_network_profiling_data() {
+ ERR_FAIL_COND(multiplayer.is_null());
+
+ int n_nodes = multiplayer->get_profiling_frame(&network_profile_info.write[0]);
+
+ packet_peer_stream->put_var("network_profile");
+ packet_peer_stream->put_var(n_nodes * 6);
+ for (int i = 0; i < n_nodes; ++i) {
+ packet_peer_stream->put_var(network_profile_info[i].node);
+ packet_peer_stream->put_var(network_profile_info[i].node_path);
+ packet_peer_stream->put_var(network_profile_info[i].incoming_rpc);
+ packet_peer_stream->put_var(network_profile_info[i].incoming_rset);
+ packet_peer_stream->put_var(network_profile_info[i].outgoing_rpc);
+ packet_peer_stream->put_var(network_profile_info[i].outgoing_rset);
+ }
+}
+
+void ScriptDebuggerRemote::_send_network_bandwidth_usage() {
+ ERR_FAIL_COND(multiplayer.is_null());
+
+ int incoming_bandwidth = multiplayer->get_incoming_bandwidth_usage();
+ int outgoing_bandwidth = multiplayer->get_outgoing_bandwidth_usage();
+
+ packet_peer_stream->put_var("network_bandwidth");
+ packet_peer_stream->put_var(2);
+ packet_peer_stream->put_var(incoming_bandwidth);
+ packet_peer_stream->put_var(outgoing_bandwidth);
+}
+
void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_args) {
mutex->lock();
@@ -1068,6 +1117,10 @@ void ScriptDebuggerRemote::set_live_edit_funcs(LiveEditFuncs *p_funcs) {
live_edit_funcs = p_funcs;
}
+void ScriptDebuggerRemote::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
+ multiplayer = p_multiplayer;
+}
+
bool ScriptDebuggerRemote::is_profiling() const {
return profiling;
@@ -1117,12 +1170,15 @@ ScriptDebuggerRemote::ResourceUsageFunc ScriptDebuggerRemote::resource_usage_fun
ScriptDebuggerRemote::ScriptDebuggerRemote() :
profiling(false),
+ profiling_network(false),
max_frame_functions(16),
skip_profile_frame(false),
reload_all_scripts(false),
tcp_client(Ref<StreamPeerTCP>(memnew(StreamPeerTCP))),
packet_peer_stream(Ref<PacketPeerStream>(memnew(PacketPeerStream))),
last_perf_time(0),
+ last_net_prof_time(0),
+ last_net_bandwidth_time(0),
performance(Engine::get_singleton()->get_singleton_object("Performance")),
requested_quit(false),
mutex(Mutex::create()),
@@ -1154,6 +1210,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() :
add_error_handler(&eh);
profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
+ network_profile_info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
profile_info_ptrs.resize(profile_info.size());
}
diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h
index 34585afc80..b6dd925181 100644
--- a/core/script_debugger_remote.h
+++ b/core/script_debugger_remote.h
@@ -54,11 +54,13 @@ class ScriptDebuggerRemote : public ScriptDebugger {
Vector<ScriptLanguage::ProfilingInfo> profile_info;
Vector<ScriptLanguage::ProfilingInfo *> profile_info_ptrs;
+ Vector<MultiplayerAPI::ProfilingInfo> network_profile_info;
Map<StringName, int> profiler_function_signature_map;
float frame_time, idle_time, physics_time, physics_frame_time;
bool profiling;
+ bool profiling_network;
int max_frame_functions;
bool skip_profile_frame;
bool reload_all_scripts;
@@ -67,6 +69,8 @@ class ScriptDebuggerRemote : public ScriptDebugger {
Ref<PacketPeerStream> packet_peer_stream;
uint64_t last_perf_time;
+ uint64_t last_net_prof_time;
+ uint64_t last_net_bandwidth_time;
Object *performance;
bool requested_quit;
Mutex *mutex;
@@ -123,10 +127,14 @@ class ScriptDebuggerRemote : public ScriptDebugger {
void _send_video_memory();
LiveEditFuncs *live_edit_funcs;
+ Ref<MultiplayerAPI> multiplayer;
+
ErrorHandlerList eh;
static void _err_handler(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
void _send_profiling_data(bool p_for_frame);
+ void _send_network_profiling_data();
+ void _send_network_bandwidth_usage();
struct FrameData {
@@ -170,6 +178,7 @@ public:
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata);
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs);
+ virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer);
virtual bool is_profiling() const;
virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data);
diff --git a/core/script_language.h b/core/script_language.h
index 5c7e8bb36c..116918fdc0 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -482,6 +482,7 @@ public:
virtual void set_request_scene_tree_message_func(RequestSceneTreeMessageFunc p_func, void *p_udata) {}
virtual void set_live_edit_funcs(LiveEditFuncs *p_funcs) {}
+ virtual void set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {}
virtual bool is_profiling() const = 0;
virtual void add_profiling_frame_data(const StringName &p_name, const Array &p_data) = 0;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index 3f5e198281..fb4bd6d802 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -3285,7 +3285,7 @@ static int _humanize_digits(int p_num) {
String String::humanize_size(size_t p_size) {
uint64_t _div = 1;
- static const char *prefix[] = { " Bytes", " KB", " MB", " GB", " TB", " PB", " EB", "" };
+ static const char *prefix[] = { " B", " KiB", " MiB", " GiB", " TiB", " PiB", " EiB", "" };
int prefix_idx = 0;
while (p_size > (_div * 1024) && prefix[prefix_idx][0]) {
@@ -3296,7 +3296,7 @@ String String::humanize_size(size_t p_size) {
int digits = prefix_idx > 0 ? _humanize_digits(p_size / _div) : 0;
double divisor = prefix_idx > 0 ? _div : 1;
- return String::num(p_size / divisor).pad_decimals(digits) + prefix[prefix_idx];
+ return String::num(p_size / divisor).pad_decimals(digits) + RTR(prefix[prefix_idx]);
}
bool String::is_abs_path() const {
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 640d45ae65..1db8a870a2 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -353,6 +353,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
varying_code += _typestr(E->get().type);
varying_code += " ";
varying_code += _mkid(E->key());
+ if (E->get().array_size > 0) {
+ varying_code += "[";
+ varying_code += itos(E->get().array_size);
+ varying_code += "]";
+ }
varying_code += ";\n";
String final_code = varying_code.as_string();
@@ -943,6 +948,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light";
actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color";
+ actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
@@ -952,6 +958,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n";
// Ported from GLES3
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index fa0b315e29..08548ded17 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -331,6 +331,7 @@ void light_compute(
inout vec4 light_color,
vec2 light_uv,
inout vec4 shadow_color,
+ inout vec2 shadow_vec,
vec3 normal,
vec2 uv,
#if defined(SCREEN_UV_USED)
@@ -407,6 +408,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTING
vec2 light_vec = transformed_light_uv;
+ vec2 shadow_vec = transformed_light_uv;
if (normal_used) {
normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
@@ -434,6 +436,7 @@ FRAGMENT_SHADER_CODE
real_light_color,
light_uv,
real_light_shadow_color,
+ shadow_vec,
normal,
uv,
#if defined(SCREEN_UV_USED)
@@ -452,11 +455,18 @@ FRAGMENT_SHADER_CODE
color *= light;
#ifdef USE_SHADOWS
- // Reset light_vec to compute shadows, the shadow map is created from the light origin, so it only
- // makes sense to compute shadows from there.
- light_vec = light_uv_interp.zw;
- float angle_to_light = -atan(light_vec.x, light_vec.y);
+#ifdef SHADOW_VEC_USED
+ mat3 inverse_light_matrix = mat3(light_matrix);
+ inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
+ inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
+ inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
+ shadow_vec = (inverse_light_matrix * vec3(shadow_vec, 0.0)).xy;
+#else
+ shadow_vec = light_uv_interp.zw;
+#endif
+
+ float angle_to_light = -atan(shadow_vec.x, shadow_vec.y);
float PI = 3.14159265358979323846264;
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
float ang*/
@@ -467,18 +477,18 @@ FRAGMENT_SHADER_CODE
vec2 point;
float sh;
if (abs_angle < 45.0 * PI / 180.0) {
- point = light_vec;
+ point = shadow_vec;
sh = 0.0 + (1.0 / 8.0);
} else if (abs_angle > 135.0 * PI / 180.0) {
- point = -light_vec;
+ point = -shadow_vec;
sh = 0.5 + (1.0 / 8.0);
} else if (angle_to_light > 0.0) {
- point = vec2(light_vec.y, -light_vec.x);
+ point = vec2(shadow_vec.y, -shadow_vec.x);
sh = 0.25 + (1.0 / 8.0);
} else {
- point = vec2(-light_vec.y, light_vec.x);
+ point = vec2(-shadow_vec.y, shadow_vec.x);
sh = 0.75 + (1.0 / 8.0);
}
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 0121d88f4d..7499962da3 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -467,6 +467,11 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
vcode += " " + _mkid(E->key());
+ if (E->get().array_size > 0) {
+ vcode += "[";
+ vcode += itos(E->get().array_size);
+ vcode += "]";
+ }
vcode += ";\n";
r_gen_code.vertex_global += interp_mode + "out " + vcode;
r_gen_code.fragment_global += interp_mode + "in " + vcode;
@@ -936,6 +941,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT_UV"] = "light_uv";
actions[VS::SHADER_CANVAS_ITEM].renames["LIGHT"] = "light";
actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_COLOR"] = "shadow_color";
+ actions[VS::SHADER_CANVAS_ITEM].renames["SHADOW_VEC"] = "shadow_vec";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["COLOR"] = "#define COLOR_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
@@ -944,6 +950,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMAL"] = "#define NORMAL_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["NORMALMAP"] = "#define NORMALMAP_USED\n";
actions[VS::SHADER_CANVAS_ITEM].usage_defines["LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ actions[VS::SHADER_CANVAS_ITEM].usage_defines["SHADOW_VEC"] = "#define SHADOW_VEC_USED\n";
actions[VS::SHADER_CANVAS_ITEM].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
/** SPATIAL SHADER **/
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index 10c8764b8e..e83f53d648 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -345,6 +345,7 @@ void light_compute(
inout vec4 light_color,
vec2 light_uv,
inout vec4 shadow_color,
+ inout vec2 shadow_vec,
vec3 normal,
vec2 uv,
#if defined(SCREEN_UV_USED)
@@ -512,6 +513,7 @@ FRAGMENT_SHADER_CODE
#ifdef USE_LIGHTING
vec2 light_vec = transformed_light_uv;
+ vec2 shadow_vec = transformed_light_uv;
if (normal_used) {
normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
@@ -539,6 +541,7 @@ FRAGMENT_SHADER_CODE
real_light_color,
light_uv,
real_light_shadow_color,
+ shadow_vec,
normal,
uv,
#if defined(SCREEN_UV_USED)
@@ -557,11 +560,16 @@ FRAGMENT_SHADER_CODE
color *= light;
#ifdef USE_SHADOWS
- // Reset light_vec to compute shadows, the shadow map is created from the light origin, so it only
- // makes sense to compute shadows from there.
- light_vec = light_uv_interp.zw;
-
- float angle_to_light = -atan(light_vec.x, light_vec.y);
+#ifdef SHADOW_VEC_USED
+ mat3 inverse_light_matrix = mat3(light_matrix);
+ inverse_light_matrix[0] = normalize(inverse_light_matrix[0]);
+ inverse_light_matrix[1] = normalize(inverse_light_matrix[1]);
+ inverse_light_matrix[2] = normalize(inverse_light_matrix[2]);
+ shadow_vec = (mat3(inverse_light_matrix) * vec3(shadow_vec, 0.0)).xy;
+#else
+ shadow_vec = light_uv_interp.zw;
+#endif
+ float angle_to_light = -atan(shadow_vec.x, shadow_vec.y);
float PI = 3.14159265358979323846264;
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
float ang*/
@@ -572,18 +580,18 @@ FRAGMENT_SHADER_CODE
vec2 point;
float sh;
if (abs_angle < 45.0 * PI / 180.0) {
- point = light_vec;
+ point = shadow_vec;
sh = 0.0 + (1.0 / 8.0);
} else if (abs_angle > 135.0 * PI / 180.0) {
- point = -light_vec;
+ point = -shadow_vec;
sh = 0.5 + (1.0 / 8.0);
} else if (angle_to_light > 0.0) {
- point = vec2(light_vec.y, -light_vec.x);
+ point = vec2(shadow_vec.y, -shadow_vec.x);
sh = 0.25 + (1.0 / 8.0);
} else {
- point = vec2(-light_vec.y, light_vec.x);
+ point = vec2(-shadow_vec.y, shadow_vec.x);
sh = 0.75 + (1.0 / 8.0);
}
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index a163490cfb..54bb7d3869 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -2466,6 +2466,7 @@ void AnimationTrackEdit::update_play_position() {
void AnimationTrackEdit::set_root(Node *p_root) {
root = p_root;
}
+
void AnimationTrackEdit::_zoom_changed() {
update();
play_position->update();
@@ -3305,6 +3306,7 @@ Ref<Animation> AnimationTrackEditor::get_current_animation() const {
return animation;
}
+
void AnimationTrackEditor::_root_removed(Node *p_root) {
root = NULL;
}
@@ -4079,6 +4081,8 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
}
void AnimationTrackEditor::show_select_node_warning(bool p_show) {
+
+ info_message->set_visible(p_show);
}
bool AnimationTrackEditor::is_key_selected(int p_track, int p_key) const {
@@ -5794,6 +5798,14 @@ AnimationTrackEditor::AnimationTrackEditor() {
timeline_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
timeline_vbox->add_constant_override("separation", 0);
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Select an AnimationPlayer node to create and edit animations."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ main_panel->add_child(info_message);
+
timeline = memnew(AnimationTimelineEdit);
timeline->set_undo_redo(undo_redo);
timeline_vbox->add_child(timeline);
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 96fd10effd..4bc41ab188 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -304,6 +304,8 @@ class AnimationTrackEditor : public VBoxContainer {
VBoxContainer *track_vbox;
AnimationBezierTrackEdit *bezier_edit;
+ Label *info_message;
+
AnimationTimelineEdit *timeline;
HSlider *zoom;
EditorSpinSlider *step;
diff --git a/editor/editor_network_profiler.cpp b/editor/editor_network_profiler.cpp
new file mode 100644
index 0000000000..b90fe96cee
--- /dev/null
+++ b/editor/editor_network_profiler.cpp
@@ -0,0 +1,192 @@
+/*************************************************************************/
+/* editor_network_profiler.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "editor_network_profiler.h"
+
+#include "core/os/os.h"
+#include "editor_scale.h"
+#include "editor_settings.h"
+
+void EditorNetworkProfiler::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_update_frame"), &EditorNetworkProfiler::_update_frame);
+ ClassDB::bind_method(D_METHOD("_activate_pressed"), &EditorNetworkProfiler::_activate_pressed);
+ ClassDB::bind_method(D_METHOD("_clear_pressed"), &EditorNetworkProfiler::_clear_pressed);
+ ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable")));
+}
+
+void EditorNetworkProfiler::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ activate->set_icon(get_icon("Play", "EditorIcons"));
+ clear_button->set_icon(get_icon("Clear", "EditorIcons"));
+ }
+}
+
+void EditorNetworkProfiler::_update_frame() {
+
+ counters_display->clear();
+
+ TreeItem *root = counters_display->create_item();
+
+ for (Map<ObjectID, MultiplayerAPI::ProfilingInfo>::Element *E = nodes_data.front(); E; E = E->next()) {
+
+ TreeItem *node = counters_display->create_item(root);
+
+ for (int j = 0; j < counters_display->get_columns(); ++j) {
+ node->set_text_align(j, j > 0 ? TreeItem::ALIGN_RIGHT : TreeItem::ALIGN_LEFT);
+ }
+
+ node->set_text(0, E->get().node_path);
+ node->set_text(1, E->get().incoming_rpc == 0 ? "-" : itos(E->get().incoming_rpc));
+ node->set_text(2, E->get().incoming_rset == 0 ? "-" : itos(E->get().incoming_rset));
+ node->set_text(3, E->get().outgoing_rpc == 0 ? "-" : itos(E->get().outgoing_rpc));
+ node->set_text(4, E->get().outgoing_rset == 0 ? "-" : itos(E->get().outgoing_rset));
+ }
+}
+
+void EditorNetworkProfiler::_activate_pressed() {
+
+ if (activate->is_pressed()) {
+ activate->set_icon(get_icon("Stop", "EditorIcons"));
+ activate->set_text(TTR("Stop"));
+ } else {
+ activate->set_icon(get_icon("Play", "EditorIcons"));
+ activate->set_text(TTR("Start"));
+ }
+ emit_signal("enable_profiling", activate->is_pressed());
+}
+
+void EditorNetworkProfiler::_clear_pressed() {
+ nodes_data.clear();
+ set_bandwidth(0, 0);
+ if (frame_delay->is_stopped()) {
+ frame_delay->set_wait_time(0.1);
+ frame_delay->start();
+ }
+}
+
+void EditorNetworkProfiler::add_node_frame_data(const MultiplayerAPI::ProfilingInfo p_frame) {
+
+ if (!nodes_data.has(p_frame.node)) {
+ nodes_data.insert(p_frame.node, p_frame);
+ } else {
+ nodes_data[p_frame.node].incoming_rpc += p_frame.incoming_rpc;
+ nodes_data[p_frame.node].incoming_rset += p_frame.incoming_rset;
+ nodes_data[p_frame.node].outgoing_rpc += p_frame.outgoing_rpc;
+ nodes_data[p_frame.node].outgoing_rset += p_frame.outgoing_rset;
+ }
+
+ if (frame_delay->is_stopped()) {
+ frame_delay->set_wait_time(0.1);
+ frame_delay->start();
+ }
+}
+
+void EditorNetworkProfiler::set_bandwidth(int p_incoming, int p_outgoing) {
+
+ incoming_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_incoming)));
+ outgoing_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_outgoing)));
+}
+
+bool EditorNetworkProfiler::is_profiling() {
+ return activate->is_pressed();
+}
+
+EditorNetworkProfiler::EditorNetworkProfiler() {
+
+ HBoxContainer *hb = memnew(HBoxContainer);
+ hb->add_constant_override("separation", 8 * EDSCALE);
+ add_child(hb);
+
+ activate = memnew(Button);
+ activate->set_toggle_mode(true);
+ activate->set_text(TTR("Start"));
+ activate->connect("pressed", this, "_activate_pressed");
+ hb->add_child(activate);
+
+ clear_button = memnew(Button);
+ clear_button->set_text(TTR("Clear"));
+ clear_button->connect("pressed", this, "_clear_pressed");
+ hb->add_child(clear_button);
+
+ hb->add_spacer();
+
+ Label *lb = memnew(Label);
+ lb->set_text("Down ");
+ hb->add_child(lb);
+
+ incoming_bandwidth_text = memnew(LineEdit);
+ incoming_bandwidth_text->set_editable(false);
+ incoming_bandwidth_text->set_custom_minimum_size(Size2(100, 0));
+ incoming_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT);
+ incoming_bandwidth_text->set_text("0.0 B/s");
+ hb->add_child(incoming_bandwidth_text);
+
+ lb = memnew(Label);
+ lb->set_text("Up ");
+ hb->add_child(lb);
+
+ outgoing_bandwidth_text = memnew(LineEdit);
+ outgoing_bandwidth_text->set_editable(false);
+ outgoing_bandwidth_text->set_custom_minimum_size(Size2(100, 0));
+ outgoing_bandwidth_text->set_align(LineEdit::Align::ALIGN_RIGHT);
+ outgoing_bandwidth_text->set_text("0.0 B/s");
+ hb->add_child(outgoing_bandwidth_text);
+
+ counters_display = memnew(Tree);
+ counters_display->set_custom_minimum_size(Size2(300, 0) * EDSCALE);
+ counters_display->set_v_size_flags(SIZE_EXPAND_FILL);
+ counters_display->set_hide_folding(true);
+ counters_display->set_hide_root(true);
+ counters_display->set_columns(5);
+ counters_display->set_column_titles_visible(true);
+ counters_display->set_column_title(0, TTR("Node"));
+ counters_display->set_column_expand(0, true);
+ counters_display->set_column_min_width(0, 60);
+ counters_display->set_column_title(1, TTR("Incoming RPC"));
+ counters_display->set_column_expand(1, false);
+ counters_display->set_column_min_width(1, 120 * EDSCALE);
+ counters_display->set_column_title(2, TTR("Incoming RSET"));
+ counters_display->set_column_expand(2, false);
+ counters_display->set_column_min_width(2, 120 * EDSCALE);
+ counters_display->set_column_title(3, TTR("Outgoing RPC"));
+ counters_display->set_column_expand(3, false);
+ counters_display->set_column_min_width(3, 120 * EDSCALE);
+ counters_display->set_column_title(4, TTR("Outgoing RSET"));
+ counters_display->set_column_expand(4, false);
+ counters_display->set_column_min_width(4, 120 * EDSCALE);
+ add_child(counters_display);
+
+ frame_delay = memnew(Timer);
+ frame_delay->set_wait_time(0.1);
+ frame_delay->set_one_shot(true);
+ add_child(frame_delay);
+ frame_delay->connect("timeout", this, "_update_frame");
+}
diff --git a/editor/editor_network_profiler.h b/editor/editor_network_profiler.h
new file mode 100644
index 0000000000..85fec340fd
--- /dev/null
+++ b/editor/editor_network_profiler.h
@@ -0,0 +1,72 @@
+/*************************************************************************/
+/* editor_network_profiler.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef EDITORNETWORKPROFILER_H
+#define EDITORNETWORKPROFILER_H
+
+#include "scene/gui/box_container.h"
+#include "scene/gui/button.h"
+#include "scene/gui/label.h"
+#include "scene/gui/split_container.h"
+#include "scene/gui/tree.h"
+
+class EditorNetworkProfiler : public VBoxContainer {
+
+ GDCLASS(EditorNetworkProfiler, VBoxContainer)
+
+private:
+ Button *activate;
+ Button *clear_button;
+ Tree *counters_display;
+ LineEdit *incoming_bandwidth_text;
+ LineEdit *outgoing_bandwidth_text;
+
+ Timer *frame_delay;
+
+ Map<ObjectID, MultiplayerAPI::ProfilingInfo> nodes_data;
+
+ void _update_frame();
+
+ void _activate_pressed();
+ void _clear_pressed();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void add_node_frame_data(const MultiplayerAPI::ProfilingInfo p_frame);
+ void set_bandwidth(int p_incoming, int p_outgoing);
+ bool is_profiling();
+
+ EditorNetworkProfiler();
+};
+
+#endif //EDITORNETWORKPROFILER_H
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index 23d28261d1..12510e27de 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -78,9 +78,6 @@ void EditorPath::_about_to_show() {
}
void EditorPath::update_path() {
- set_text("");
- set_tooltip("");
- set_icon(NULL);
for (int i = 0; i < history->get_path_size(); i++) {
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 6918fe7977..1d72e370b3 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -132,6 +132,7 @@ void ImportDock::set_edit_path(const String &p_path) {
params->paths.push_back(p_path);
import->set_disabled(false);
import_as->set_disabled(false);
+ preset->set_disabled(false);
imported->set_text(p_path.get_file());
}
@@ -287,6 +288,7 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
params->paths = p_paths;
import->set_disabled(false);
import_as->set_disabled(false);
+ preset->set_disabled(false);
imported->set_text(itos(p_paths.size()) + TTR(" Files"));
}
@@ -367,6 +369,7 @@ void ImportDock::clear() {
import->set_disabled(true);
import_as->clear();
import_as->set_disabled(true);
+ preset->set_disabled(true);
params->values.clear();
params->properties.clear();
params->update();
@@ -528,11 +531,13 @@ ImportDock::ImportDock() {
HBoxContainer *hb = memnew(HBoxContainer);
add_margin_child(TTR("Import As:"), hb);
import_as = memnew(OptionButton);
+ import_as->set_disabled(true);
import_as->connect("item_selected", this, "_importer_selected");
hb->add_child(import_as);
import_as->set_h_size_flags(SIZE_EXPAND_FILL);
preset = memnew(MenuButton);
- preset->set_text(TTR("Preset..."));
+ preset->set_text(TTR("Preset"));
+ preset->set_disabled(true);
preset->get_popup()->connect("index_pressed", this, "_preset_selected");
hb->add_child(preset);
@@ -545,6 +550,7 @@ ImportDock::ImportDock() {
add_child(hb);
import = memnew(Button);
import->set_text(TTR("Reimport"));
+ import->set_disabled(true);
import->connect("pressed", this, "_reimport_attempt");
hb->add_spacer();
hb->add_child(import);
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 173079b6de..0991832eff 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -38,7 +38,7 @@
#include "editor/animation_track_editor.h"
#include "editor/editor_settings.h"
-// For onion skinning
+// For onion skinning.
#include "editor/plugins/canvas_item_editor_plugin.h"
#include "editor/plugins/spatial_editor_plugin.h"
#include "scene/main/viewport.h"
@@ -1088,20 +1088,6 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag)
EditorNode::get_singleton()->get_inspector()->refresh();
}
-void AnimationPlayerEditor::_hide_anim_editors() {
-
- player = NULL;
- hide();
- set_process(false);
-
- track_editor->set_animation(Ref<Animation>());
- track_editor->set_root(NULL);
- track_editor->show_select_node_warning(true);
-}
-
-void AnimationPlayerEditor::_animation_about_to_show_menu() {
-}
-
void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
String current;
@@ -1489,7 +1475,7 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
player->seek(cpos, false);
player->restore_animated_values(values_backup);
- // Restor state of main editors.
+ // Restore state of main editors.
if (SpatialEditor::get_singleton()->is_visible()) {
// 3D
SpatialEditor::get_singleton()->set_state(spatial_edit_state);
@@ -1519,7 +1505,7 @@ void AnimationPlayerEditor::_stop_onion_skinning() {
_free_onion_layers();
- // Clean up the overlay
+ // Clean up the overlay.
onion.can_overlay = false;
plugin->update_overlays();
}
@@ -1557,7 +1543,6 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed);
ClassDB::bind_method(D_METHOD("_animation_key_editor_seek"), &AnimationPlayerEditor::_animation_key_editor_seek);
ClassDB::bind_method(D_METHOD("_animation_key_editor_anim_len_changed"), &AnimationPlayerEditor::_animation_key_editor_anim_len_changed);
- ClassDB::bind_method(D_METHOD("_hide_anim_editors"), &AnimationPlayerEditor::_hide_anim_editors);
ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
ClassDB::bind_method(D_METHOD("_blend_editor_next_changed"), &AnimationPlayerEditor::_blend_editor_next_changed);
ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &AnimationPlayerEditor::_unhandled_key_input);
@@ -1776,7 +1761,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
_update_player();
- // Onion skinning
+ // Onion skinning.
track_editor->connect("visibility_changed", this, "_editor_visibility_changed");
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 4ad30675ec..eed7344395 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -130,9 +130,9 @@ class AnimationPlayerEditor : public VBoxContainer {
AnimationTrackEditor *track_editor;
- // Onion skinning
+ // Onion skinning.
struct {
- // Settings
+ // Settings.
bool enabled;
bool past;
bool future;
@@ -142,11 +142,11 @@ class AnimationPlayerEditor : public VBoxContainer {
bool include_gizmos;
int get_needed_capture_count() const {
- // 'Differences only' needs a capture of the present
+ // 'Differences only' needs a capture of the present.
return (past && future ? 2 * steps : steps) + (differences_only ? 1 : 0);
}
- // Rendering
+ // Rendering.
int64_t last_frame;
int can_overlay;
Size2 capture_size;
@@ -195,8 +195,6 @@ class AnimationPlayerEditor : public VBoxContainer {
void _update_player();
void _blend_edited();
- void _hide_anim_editors();
-
void _animation_player_changed(Object *p_pl);
void _animation_key_editor_seek(float p_pos, bool p_drag);
@@ -205,7 +203,6 @@ class AnimationPlayerEditor : public VBoxContainer {
void _unhandled_key_input(const Ref<InputEvent> &p_ev);
void _animation_tool_menu(int p_option);
void _onion_skinning_menu(int p_option);
- void _animation_about_to_show_menu();
void _editor_visibility_changed();
bool _are_onion_layers_valid();
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 26fae96025..90276041a8 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -376,7 +376,7 @@ void TileMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
}
// Implementation detail of TileMapEditor::_update_palette();
-// in modern C++ this could have been inside its body
+// In modern C++ this could have been inside its body.
namespace {
struct _PaletteEntry {
int id;
@@ -393,10 +393,10 @@ void TileMapEditor::_update_palette() {
if (!node)
return;
- // Update the clear button
+ // Update the clear button.
clear_transform_button->set_disabled(!flip_h && !flip_v && !transpose);
- // Update the palette
+ // Update the palette.
Vector<int> selected = get_selected_tiles();
int selected_single = palette->get_current();
int selected_manual = manual_palette->get_current();
@@ -405,8 +405,15 @@ void TileMapEditor::_update_palette() {
manual_palette->hide();
Ref<TileSet> tileset = node->get_tileset();
- if (tileset.is_null())
+ if (tileset.is_null()) {
+ search_box->set_text("");
+ search_box->set_editable(false);
+ info_message->show();
return;
+ }
+
+ search_box->set_editable(true);
+ info_message->hide();
List<int> tiles;
tileset->get_tile_list(&tiles);
@@ -421,7 +428,6 @@ void TileMapEditor::_update_palette() {
bool sort_by_name = bool(EDITOR_DEF("editors/tile_map/sort_tiles_by_name", true));
palette->add_constant_override("hseparation", hseparation * EDSCALE);
- palette->add_constant_override("vseparation", 8 * EDSCALE);
palette->set_fixed_icon_size(Size2(min_size, min_size));
palette->set_fixed_column_width(min_size * MAX(size_slider->get_value(), 1));
@@ -479,7 +485,7 @@ void TileMapEditor::_update_palette() {
region.position += (region.size + Vector2(spacing, spacing)) * tileset->autotile_get_icon_coordinate(entries[i].id);
}
- // Transpose and flip
+ // Transpose and flip.
palette->set_item_icon_transposed(palette->get_item_count() - 1, transpose);
if (flip_h) {
region.size.x = -region.size.x;
@@ -488,14 +494,14 @@ void TileMapEditor::_update_palette() {
region.size.y = -region.size.y;
}
- // Set region
+ // Set region.
if (region.size != Size2())
palette->set_item_icon_region(palette->get_item_count() - 1, region);
- // Set icon
+ // Set icon.
palette->set_item_icon(palette->get_item_count() - 1, tex);
- // Modulation
+ // Modulation.
Color color = tileset->tile_get_modulate(entries[i].id);
palette->set_item_icon_modulate(palette->get_item_count() - 1, color);
}
@@ -511,50 +517,47 @@ void TileMapEditor::_update_palette() {
palette->select(0);
}
- if (sel_tile != TileMap::INVALID_CELL) {
- if ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) ||
- (!priority_atlastile && tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE)) {
+ if (sel_tile != TileMap::INVALID_CELL && ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || (!priority_atlastile && tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE))) {
- const Map<Vector2, uint32_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile);
+ const Map<Vector2, uint32_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile);
- Vector<Vector2> entries2;
- for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
- entries2.push_back(E->key());
+ Vector<Vector2> entries2;
+ for (const Map<Vector2, uint32_t>::Element *E = tiles2.front(); E; E = E->next()) {
+ entries2.push_back(E->key());
+ }
+ // Sort tiles in row-major order.
+ struct SwapComparator {
+ _FORCE_INLINE_ bool operator()(const Vector2 &v_l, const Vector2 &v_r) const {
+ return v_l.y != v_r.y ? v_l.y < v_r.y : v_l.x < v_r.x;
}
- // Sort tiles in row-major order
- struct SwapComparator {
- _FORCE_INLINE_ bool operator()(const Vector2 &v_l, const Vector2 &v_r) const {
- return v_l.y != v_r.y ? v_l.y < v_r.y : v_l.x < v_r.x;
- }
- };
- entries2.sort_custom<SwapComparator>();
-
- Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
+ };
+ entries2.sort_custom<SwapComparator>();
- for (int i = 0; i < entries2.size(); i++) {
+ Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
- manual_palette->add_item(String());
+ for (int i = 0; i < entries2.size(); i++) {
- if (tex.is_valid()) {
+ manual_palette->add_item(String());
- Rect2 region = tileset->tile_get_region(sel_tile);
- int spacing = tileset->autotile_get_spacing(sel_tile);
- region.size = tileset->autotile_get_size(sel_tile); // !!
- region.position += (region.size + Vector2(spacing, spacing)) * entries2[i];
+ if (tex.is_valid()) {
- if (!region.has_no_area())
- manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
+ Rect2 region = tileset->tile_get_region(sel_tile);
+ int spacing = tileset->autotile_get_spacing(sel_tile);
+ region.size = tileset->autotile_get_size(sel_tile); // !!
+ region.position += (region.size + Vector2(spacing, spacing)) * entries2[i];
- manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
- }
+ if (!region.has_no_area())
+ manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
- manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries2[i]);
+ manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
}
+
+ manual_palette->set_item_metadata(manual_palette->get_item_count() - 1, entries2[i]);
}
}
if (manual_palette->get_item_count() > 0) {
- // Only show the manual palette if at least tile exists in it
+ // Only show the manual palette if at least tile exists in it.
if (selected_manual == -1 || selected_single != palette->get_current())
selected_manual = 0;
if (selected_manual < manual_palette->get_item_count())
@@ -1951,6 +1954,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
add_child(priority_button);
search_box = memnew(LineEdit);
+ search_box->set_placeholder(TTR("Filter tiles"));
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
search_box->connect("text_entered", this, "_text_entered");
search_box->connect("text_changed", this, "_text_changed");
@@ -1973,7 +1977,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette_container->set_custom_minimum_size(Size2(mw, 0));
add_child(palette_container);
- // Add tile palette
+ // Add tile palette.
palette = memnew(ItemList);
palette->set_h_size_flags(SIZE_EXPAND_FILL);
palette->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1981,11 +1985,21 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette->set_icon_mode(ItemList::ICON_MODE_TOP);
palette->set_max_text_lines(2);
palette->set_select_mode(ItemList::SELECT_MULTI);
+ palette->add_constant_override("vseparation", 8 * EDSCALE);
palette->connect("item_selected", this, "_palette_selected");
palette->connect("multi_selected", this, "_palette_multi_selected");
palette_container->add_child(palette);
- // Add autotile override palette
+ // Add message for when no texture is selected.
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Give a TileSet resource to this TileMap to use its tiles."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ palette->add_child(info_message);
+
+ // Add autotile override palette.
manual_palette = memnew(ItemList);
manual_palette->set_h_size_flags(SIZE_EXPAND_FILL);
manual_palette->set_v_size_flags(SIZE_EXPAND_FILL);
@@ -1995,15 +2009,14 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
manual_palette->hide();
palette_container->add_child(manual_palette);
- // Add menu items
+ // Add menu items.
toolbar = memnew(HBoxContainer);
toolbar->hide();
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(toolbar);
- // Separator
toolbar->add_child(memnew(VSeparator));
- // Tools
+ // Tools.
paint_button = memnew(ToolButton);
paint_button->set_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P));
paint_button->set_tooltip(TTR("Shift+LMB: Line Draw\nShift+Ctrl+LMB: Rectangle Paint"));
@@ -2031,18 +2044,18 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
_update_button_tool();
- // Container to the right of the toolbar
+ // Container to the right of the toolbar.
toolbar_right = memnew(HBoxContainer);
toolbar_right->hide();
toolbar_right->set_h_size_flags(SIZE_EXPAND_FILL);
toolbar_right->set_alignment(BoxContainer::ALIGN_END);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(toolbar_right);
- // Tile position
+ // Tile position.
tile_info = memnew(Label);
toolbar_right->add_child(tile_info);
- // Menu
+ // Menu.
options = memnew(MenuButton);
options->set_text("TileMap");
options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("TileMap", "EditorIcons"));
@@ -2136,7 +2149,8 @@ void TileMapEditorPlugin::make_visible(bool p_visible) {
tile_map_editor->show();
tile_map_editor->get_toolbar()->show();
tile_map_editor->get_toolbar_right()->show();
- CanvasItemEditor::get_singleton()->set_current_tool(CanvasItemEditor::TOOL_SELECT); //Change to TOOL_SELECT when TileMap node is selected, to prevent accidental movement.
+ // Change to TOOL_SELECT when TileMap node is selected, to prevent accidental movement.
+ CanvasItemEditor::get_singleton()->set_current_tool(CanvasItemEditor::TOOL_SELECT);
} else {
tile_map_editor->hide();
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index c841eb1f98..e3d678c2fd 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -82,6 +82,8 @@ class TileMapEditor : public VBoxContainer {
ItemList *palette;
ItemList *manual_palette;
+ Label *info_message;
+
HBoxContainer *toolbar;
HBoxContainer *toolbar_right;
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 9096a0e0be..e0bf8dfdb2 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -579,6 +579,14 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
scroll->set_v_size_flags(SIZE_EXPAND_FILL);
scroll->set_clip_contents(true);
+ empty_message = memnew(Label);
+ empty_message->set_text(TTR("Add or select a texture on the left panel to edit the tiles bound to it."));
+ empty_message->set_valign(Label::VALIGN_CENTER);
+ empty_message->set_align(Label::ALIGN_CENTER);
+ empty_message->set_autowrap(true);
+ empty_message->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_vb->add_child(empty_message);
+
workspace_container = memnew(Control);
scroll->add_child(workspace_container);
@@ -627,7 +635,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
helper = memnew(TilesetEditorContext(this));
tile_names_visible = false;
- // config scale
+ // Config scale.
max_scale = 10.0f;
min_scale = 0.1f;
scale_ratio = 1.2f;
@@ -3123,12 +3131,28 @@ void TileSetEditor::update_workspace_tile_mode() {
}
tools[SELECT_NEXT]->set_disabled(true);
tools[SELECT_PREVIOUS]->set_disabled(true);
+
+ tools[ZOOM_OUT]->hide();
+ tools[ZOOM_1]->hide();
+ tools[ZOOM_IN]->hide();
+ tools[VISIBLE_INFO]->hide();
+
+ scroll->hide();
+ empty_message->show();
} else {
for (int i = 1; i < WORKSPACE_MODE_MAX; i++) {
tool_workspacemode[i]->set_disabled(false);
}
tools[SELECT_NEXT]->set_disabled(false);
tools[SELECT_PREVIOUS]->set_disabled(false);
+
+ tools[ZOOM_OUT]->show();
+ tools[ZOOM_1]->show();
+ tools[ZOOM_IN]->show();
+ tools[VISIBLE_INFO]->show();
+
+ scroll->show();
+ empty_message->hide();
}
if (workspace_mode != WORKSPACE_EDIT) {
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index fff9ef7731..944dc04e4e 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -138,6 +138,7 @@ class TileSetEditor : public HSplitContainer {
int current_item_index;
Sprite *preview;
ScrollContainer *scroll;
+ Label *empty_message;
Control *workspace_container;
bool draw_handles;
Control *workspace_overlay;
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index a4270786c1..d4a74c83ea 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -33,6 +33,7 @@
#include "core/io/marshalls.h"
#include "core/project_settings.h"
#include "core/ustring.h"
+#include "editor_network_profiler.h"
#include "editor_node.h"
#include "editor_profiler.h"
#include "editor_settings.h"
@@ -992,7 +993,20 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
profiler->add_frame_metric(metric, false);
else
profiler->add_frame_metric(metric, true);
-
+ } else if (p_msg == "network_profile") {
+ int frame_size = 6;
+ for (int i = 0; i < p_data.size(); i += frame_size) {
+ MultiplayerAPI::ProfilingInfo pi;
+ pi.node = p_data[i + 0];
+ pi.node_path = p_data[i + 1];
+ pi.incoming_rpc = p_data[i + 2];
+ pi.incoming_rset = p_data[i + 3];
+ pi.outgoing_rpc = p_data[i + 4];
+ pi.outgoing_rset = p_data[i + 5];
+ network_profiler->add_node_frame_data(pi);
+ }
+ } else if (p_msg == "network_bandwidth") {
+ network_profiler->set_bandwidth(p_data[0], p_data[1]);
} else if (p_msg == "kill_me") {
editor->call_deferred("stop_child_process");
@@ -1028,17 +1042,15 @@ void ScriptEditorDebugger::_performance_draw() {
which.push_back(i);
}
- Ref<Font> graph_font = get_font("font", "TextEdit");
-
if (which.empty()) {
- String text = TTR("Pick one or more items from the list to display the graph.");
-
- perf_draw->draw_string(graph_font, Point2i(MAX(0, perf_draw->get_size().x - graph_font->get_string_size(text).x), perf_draw->get_size().y + graph_font->get_ascent()) / 2, text, get_color("font_color", "Label"), perf_draw->get_size().x);
-
+ info_message->show();
return;
}
+ info_message->hide();
+
Ref<StyleBox> graph_sb = get_stylebox("normal", "TextEdit");
+ Ref<Font> graph_font = get_font("font", "TextEdit");
int cols = Math::ceil(Math::sqrt((float)which.size()));
int rows = Math::ceil((float)which.size() / cols);
@@ -1107,7 +1119,6 @@ void ScriptEditorDebugger::_notification(int p_what) {
forward->set_icon(get_icon("Forward", "EditorIcons"));
dobreak->set_icon(get_icon("Pause", "EditorIcons"));
docontinue->set_icon(get_icon("DebugContinue", "EditorIcons"));
- //scene_tree_refresh->set_icon( get_icon("Reload","EditorIcons"));
le_set->connect("pressed", this, "_live_edit_set");
le_clear->connect("pressed", this, "_live_edit_clear");
error_tree->connect("item_selected", this, "_error_selected");
@@ -1208,6 +1219,10 @@ void ScriptEditorDebugger::_notification(int p_what) {
if (profiler->is_profiling()) {
_profiler_activate(true);
}
+
+ if (network_profiler->is_profiling()) {
+ _network_profiler_activate(true);
+ }
}
}
@@ -1391,7 +1406,7 @@ void ScriptEditorDebugger::stop() {
profiler->set_enabled(true);
inspect_scene_tree->clear();
- EditorNode::get_singleton()->edit_current();
+ inspector->edit(NULL);
EditorNode::get_singleton()->get_pause_button()->set_pressed(false);
EditorNode::get_singleton()->get_pause_button()->set_disabled(true);
EditorNode::get_singleton()->get_scene_tree_dock()->hide_remote_tree();
@@ -1427,6 +1442,25 @@ void ScriptEditorDebugger::_profiler_activate(bool p_enable) {
}
}
+void ScriptEditorDebugger::_network_profiler_activate(bool p_enable) {
+
+ if (!connection.is_valid())
+ return;
+
+ if (p_enable) {
+ Array msg;
+ msg.push_back("start_network_profiling");
+ ppeer->put_var(msg);
+ print_verbose("Starting network profiling.");
+
+ } else {
+ Array msg;
+ msg.push_back("stop_network_profiling");
+ ppeer->put_var(msg);
+ print_verbose("Ending network profiling.");
+ }
+}
+
void ScriptEditorDebugger::_profiler_seeked() {
if (!connection.is_valid() || !connection->is_connected_to_host())
@@ -2020,6 +2054,7 @@ void ScriptEditorDebugger::_bind_methods() {
ClassDB::bind_method(D_METHOD("_expand_errors_list"), &ScriptEditorDebugger::_expand_errors_list);
ClassDB::bind_method(D_METHOD("_collapse_errors_list"), &ScriptEditorDebugger::_collapse_errors_list);
ClassDB::bind_method(D_METHOD("_profiler_activate"), &ScriptEditorDebugger::_profiler_activate);
+ ClassDB::bind_method(D_METHOD("_network_profiler_activate"), &ScriptEditorDebugger::_network_profiler_activate);
ClassDB::bind_method(D_METHOD("_profiler_seeked"), &ScriptEditorDebugger::_profiler_seeked);
ClassDB::bind_method(D_METHOD("_clear_errors_list"), &ScriptEditorDebugger::_clear_errors_list);
@@ -2245,6 +2280,13 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
profiler->connect("break_request", this, "_profiler_seeked");
}
+ { //network profiler
+ network_profiler = memnew(EditorNetworkProfiler);
+ network_profiler->set_name(TTR("Network Profiler"));
+ tabs->add_child(network_profiler);
+ network_profiler->connect("enable_profiling", this, "_network_profiler_activate");
+ }
+
{ //monitors
HSplitContainer *hsp = memnew(HSplitContainer);
@@ -2254,11 +2296,14 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
perf_monitors->set_column_title(0, TTR("Monitor"));
perf_monitors->set_column_title(1, TTR("Value"));
perf_monitors->set_column_titles_visible(true);
- hsp->add_child(perf_monitors);
perf_monitors->connect("item_edited", this, "_performance_select");
+ hsp->add_child(perf_monitors);
+
perf_draw = memnew(Control);
+ perf_draw->set_clip_contents(true);
perf_draw->connect("draw", this, "_performance_draw");
hsp->add_child(perf_draw);
+
hsp->set_name(TTR("Monitors"));
hsp->set_split_offset(340 * EDSCALE);
tabs->add_child(hsp);
@@ -2292,6 +2337,14 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
perf_items.push_back(it);
perf_max.write[i] = 0;
}
+
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Pick one or more items from the list to display the graph."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ perf_draw->add_child(info_message);
}
{ //vmem inspect
@@ -2303,7 +2356,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmem_hb->add_child(memnew(Label(TTR("Total:") + " ")));
vmem_total = memnew(LineEdit);
vmem_total->set_editable(false);
- vmem_total->set_custom_minimum_size(Size2(100, 1) * EDSCALE);
+ vmem_total->set_custom_minimum_size(Size2(100, 0) * EDSCALE);
vmem_hb->add_child(vmem_total);
vmem_refresh = memnew(ToolButton);
vmem_hb->add_child(vmem_refresh);
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index dc9c99591d..cc284476c0 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -50,6 +50,7 @@ class TreeItem;
class HSplitContainer;
class ItemList;
class EditorProfiler;
+class EditorNetworkProfiler;
class ScriptEditorDebuggerInspectedObject;
@@ -134,6 +135,7 @@ class ScriptEditorDebugger : public Control {
Tree *perf_monitors;
Control *perf_draw;
+ Label *info_message;
Tree *vmem_tree;
Button *vmem_refresh;
@@ -155,6 +157,7 @@ class ScriptEditorDebugger : public Control {
Map<String, int> res_path_cache;
EditorProfiler *profiler;
+ EditorNetworkProfiler *network_profiler;
EditorNode *editor;
@@ -199,6 +202,8 @@ class ScriptEditorDebugger : public Control {
void _profiler_activate(bool p_enable);
void _profiler_seeked();
+ void _network_profiler_activate(bool p_enable);
+
void _paused();
void _set_remote_object(ObjectID p_id, ScriptEditorDebuggerInspectedObject *p_obj);
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
index 349420b3f3..12b9af21e5 100644
--- a/misc/dist/html/full-size.html
+++ b/misc/dist/html/full-size.html
@@ -182,7 +182,7 @@ $GODOT_HEAD_INCLUDE
});
animationCallbacks = animationCallbacks.filter(function(value) {
return (value != animateStatusIndeterminate);
- }
+ });
switch (mode) {
case 'progress':
statusProgress.style.display = 'block';
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index e5439fd132..a001fe9123 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -541,6 +541,25 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
mesh.instance();
bool has_uvs = false;
+ Map<String, uint32_t> morph_mesh_string_lookup;
+
+ for (int i = 0; i < p_surface_indices.size(); i++) {
+ const unsigned int mesh_idx = p_surface_indices[0];
+ const aiMesh *ai_mesh = state.assimp_scene->mMeshes[mesh_idx];
+ for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) {
+
+ String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName);
+ if (!morph_mesh_string_lookup.has(ai_anim_mesh_name)) {
+ morph_mesh_string_lookup.insert(ai_anim_mesh_name, j);
+ mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
+ if (ai_anim_mesh_name.empty()) {
+ ai_anim_mesh_name = String("morph_") + itos(j);
+ }
+ mesh->add_blend_shape(ai_anim_mesh_name);
+ }
+ }
+ }
+
//
// Process Vertex Weights
//
@@ -680,6 +699,25 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
mat->set_cull_mode(SpatialMaterial::CULL_BACK);
// Now process materials
+ aiTextureType base_color = aiTextureType_BASE_COLOR;
+ {
+ String filename, path;
+ AssimpImageData image_data;
+
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, base_color, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+
+ // anything transparent must be culled
+ if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
+ mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
+ mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
+ }
+
+ mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
+ }
+ }
+
aiTextureType tex_diffuse = aiTextureType_DIFFUSE;
{
String filename, path;
@@ -731,6 +769,60 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
}
}
+ aiTextureType tex_normal_camera = aiTextureType_NORMAL_CAMERA;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_emission_color = aiTextureType_EMISSION_COLOR;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_metalness = aiTextureType_METALNESS;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture);
+ }
+ }
+
+ aiTextureType tex_roughness = aiTextureType_DIFFUSE_ROUGHNESS;
+ {
+ String filename, path;
+ Ref<ImageTexture> texture;
+ AssimpImageData image_data;
+
+ // Process texture normal map
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) {
+ AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
+ mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture);
+ }
+ }
+
aiTextureType tex_emissive = aiTextureType_EMISSIVE;
{
String filename = "";
@@ -772,16 +864,17 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
}
}
- aiTextureType tex_roughness = aiTextureType_SHININESS;
+ aiTextureType tex_ao_map = aiTextureType_AMBIENT_OCCLUSION;
{
String filename, path;
Ref<ImageTexture> texture;
AssimpImageData image_data;
// Process texture normal map
- if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) {
+ if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_ao_map, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
- mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture);
+ mat->set_feature(SpatialMaterial::FEATURE_AMBIENT_OCCLUSION, true);
+ mat->set_texture(SpatialMaterial::TEXTURE_AMBIENT_OCCLUSION, image_data.texture);
}
}
@@ -789,16 +882,15 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
Array morphs;
morphs.resize(ai_mesh->mNumAnimMeshes);
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
- Map<uint32_t, String> morph_mesh_idx_names;
+
for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) {
String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName);
- mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
+
if (ai_anim_mesh_name.empty()) {
ai_anim_mesh_name = String("morph_") + itos(j);
}
- mesh->add_blend_shape(ai_anim_mesh_name);
- morph_mesh_idx_names.insert(j, ai_anim_mesh_name);
+
Array array_copy;
array_copy.resize(VisualServer::ARRAY_MAX);
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 7166189416..9ea6b0e863 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -1520,8 +1520,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
if (ret2 < 0)
return ERR_PARSE_ERROR;
+ int message_ret = 0;
+ if (as->message) {
+ message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false);
+ if (message_ret < 0)
+ return ERR_PARSE_ERROR;
+ }
+
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
codegen.opcodes.push_back(ret2);
+ codegen.opcodes.push_back(message_ret);
#endif
} break;
case GDScriptParser::Node::TYPE_BREAKPOINT: {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index 68f2a9473e..bdeea9cef3 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -1475,20 +1475,25 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSERT) {
- CHECK_SPACE(2);
+ CHECK_SPACE(3);
#ifdef DEBUG_ENABLED
GET_VARIANT_PTR(test, 1);
+ GET_VARIANT_PTR(message, 2);
bool result = test->booleanize();
if (!result) {
-
- err_text = "Assertion failed.";
+ const String &message_str = *message;
+ if (message_str.empty()) {
+ err_text = "Assertion failed.";
+ } else {
+ err_text = "Assertion failed: " + message_str;
+ }
OPCODE_BREAK;
}
#endif
- ip += 2;
+ ip += 3;
}
DISPATCH_OPCODE;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index e96bf0238a..9c3fc9a351 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -3280,15 +3280,36 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
case GDScriptTokenizer::TK_PR_ASSERT: {
tokenizer->advance();
- Node *condition = _parse_and_reduce_expression(p_block, p_static);
- if (!condition) {
- if (_recover_from_completion()) {
- break;
- }
+
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after assert");
+ return;
+ }
+
+ tokenizer->advance();
+
+ Vector<Node *> args;
+ const bool result = _parse_arguments(p_block, args, p_static);
+ if (!result) {
return;
}
+
+ if (args.empty() || args.size() > 2) {
+ _set_error("Wrong number of arguments, expected 1 or 2");
+ return;
+ }
+
AssertNode *an = alloc_node<AssertNode>();
- an->condition = condition;
+ an->condition = _reduce_expression(args[0], p_static);
+
+ if (args.size() == 2) {
+ an->message = _reduce_expression(args[1], p_static);
+ } else {
+ ConstantNode *message_node = alloc_node<ConstantNode>();
+ message_node->value = String();
+ an->message = message_node;
+ }
+
p_block->statements.push_back(an);
if (!_end_statement()) {
@@ -3533,6 +3554,15 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
+ if (p_class->classname_used && ProjectSettings::get_singleton()->has_setting("autoload/" + p_class->name)) {
+ const String autoload_path = ProjectSettings::get_singleton()->get_setting("autoload/" + p_class->name);
+ if (autoload_path.begins_with("*")) {
+ // It's a singleton, and not just a regular AutoLoad script.
+ _set_error("The class \"" + p_class->name + "\" conflicts with the AutoLoad singleton of the same name, and is therefore redundant. Remove the class_name declaration to fix this error.");
+ }
+ return;
+ }
+
tokenizer->advance(2);
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 72aa819a8c..1e8193a63e 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -481,7 +481,12 @@ public:
struct AssertNode : public Node {
Node *condition;
- AssertNode() { type = TYPE_ASSERT; }
+ Node *message;
+ AssertNode() :
+ condition(0),
+ message(0) {
+ type = TYPE_ASSERT;
+ }
};
struct BreakpointNode : public Node {
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 07b4f7f596..97b2e4f138 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -884,9 +884,15 @@ void GridMapEditor::update_palette() {
if (mesh_library.is_null()) {
last_mesh_library = NULL;
+ search_box->set_text("");
+ search_box->set_editable(false);
+ info_message->show();
return;
}
+ search_box->set_editable(true);
+ info_message->hide();
+
Vector<int> ids;
ids = mesh_library->get_item_list();
@@ -1296,6 +1302,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
search_box = memnew(LineEdit);
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
+ search_box->set_placeholder(TTR("Filter meshes"));
hb->add_child(search_box);
search_box->connect("text_changed", this, "_text_changed");
search_box->connect("gui_input", this, "_sbox_input");
@@ -1331,6 +1338,14 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
add_child(mesh_library_palette);
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
+ info_message = memnew(Label);
+ info_message->set_text(TTR("Give a MeshLibrary resource to this GridMap to use its meshes."));
+ info_message->set_valign(Label::VALIGN_CENTER);
+ info_message->set_align(Label::ALIGN_CENTER);
+ info_message->set_autowrap(true);
+ info_message->set_anchors_and_margins_preset(PRESET_WIDE, PRESET_MODE_KEEP_SIZE, 8 * EDSCALE);
+ mesh_library_palette->add_child(info_message);
+
edit_axis = Vector3::AXIS_Y;
edit_floor[0] = -1;
edit_floor[1] = -1;
@@ -1346,7 +1361,7 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
paste_mesh = VisualServer::get_singleton()->mesh_create();
{
- //selection mesh create
+ // Selection mesh create.
PoolVector<Vector3> lines;
PoolVector<Vector3> triangles;
@@ -1424,7 +1439,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
inner_mat.instance();
inner_mat->set_albedo(Color(0.7, 0.7, 1.0, 0.2));
- //inner_mat->set_flag(SpatialMaterial::FLAG_ONTOP, true);
inner_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
inner_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
@@ -1444,7 +1458,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
selection_floor_mat->set_on_top_of_alpha();
selection_floor_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
selection_floor_mat->set_line_width(3.0);
- //selection_floor_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
d[VS::ARRAY_VERTEX] = lines;
VisualServer::get_singleton()->mesh_add_surface_from_arrays(selection_mesh, VS::PRIMITIVE_LINES, d);
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index d174ac1035..103913485f 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -197,12 +197,16 @@ class GridMapEditor : public VBoxContainer {
RID instance;
};
+ ItemList *mesh_library_palette;
+ Label *info_message;
+
+ EditorNode *editor;
+
void update_grid();
void _configure();
void _menu_option(int);
void update_palette();
void _set_display_mode(int p_mode);
- ItemList *mesh_library_palette;
void _item_selected_cbk(int idx);
void _update_cursor_transform();
void _update_cursor_instance();
@@ -227,7 +231,6 @@ class GridMapEditor : public VBoxContainer {
void _delete_selection();
void _fill_selection();
- EditorNode *editor;
bool do_input_action(Camera *p_camera, const Point2 &p_point, bool p_click);
friend class GridMapEditorPlugin;
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
index aefc51545e..4f93ef8530 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs
@@ -16,7 +16,7 @@ namespace GodotTools
{
private void AddFile(string srcPath, string dstPath, bool remap = false)
{
- AddFile(dstPath, File.ReadAllBytes(srcPath), remap);
+ AddFile(dstPath.Replace("\\", "/"), File.ReadAllBytes(srcPath), remap);
}
public override void _ExportFile(string path, string type, string[] features)
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index cd1ca2a2c7..5a84d9e3b8 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -429,6 +429,7 @@ void register_editor_internal_calls() {
mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", (void *)godot_icall_Internal_ScriptEditorEdit);
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", (void *)godot_icall_Internal_EditorNodeShowScriptScreen);
mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", (void *)godot_icall_Internal_MonoWindowsInstallRoot);
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", (void *)godot_icall_Internal_EditorRunPlay);
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", (void *)godot_icall_Internal_EditorRunStop);
mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
diff --git a/modules/mono/glue/Managed/Files/Rect2.cs b/modules/mono/glue/Managed/Files/Rect2.cs
index f3dc9d8490..99542d0c0a 100644
--- a/modules/mono/glue/Managed/Files/Rect2.cs
+++ b/modules/mono/glue/Managed/Files/Rect2.cs
@@ -157,13 +157,13 @@ namespace Godot
public bool Intersects(Rect2 b)
{
- if (_position.x > b._position.x + b._size.x)
+ if (_position.x >= b._position.x + b._size.x)
return false;
- if (_position.x + _size.x < b._position.x)
+ if (_position.x + _size.x <= b._position.x)
return false;
- if (_position.y > b._position.y + b._size.y)
+ if (_position.y >= b._position.y + b._size.y)
return false;
- if (_position.y + _size.y < b._position.y)
+ if (_position.y + _size.y <= b._position.y)
return false;
return true;
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 5a0d728953..6d91075ce3 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -159,7 +159,7 @@ void GDMonoLog::initialize() {
log_file = FileAccess::open(log_file_path, FileAccess::WRITE);
if (!log_file) {
- ERR_PRINT("Mono: Cannot create log file.");
+ ERR_PRINTS("Mono: Cannot create log file at: " + log_file_path);
}
}
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index ae5a2cde81..716c712ccc 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -208,14 +208,18 @@ String str_format(const char *p_format, ...) {
#endif
#if defined(MINGW_ENABLED) || defined(_MSC_VER) && _MSC_VER < 1900
-#define vsnprintf(m_buffer, m_count, m_format, m_argptr) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_argptr)
+#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_args_copy)
+#define gd_vscprintf(m_format, m_args_copy) _vscprintf(m_format, m_args_copy)
+#else
+#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf(m_buffer, m_count, m_format, m_args_copy)
+#define gd_vscprintf(m_format, m_args_copy) vsnprintf(NULL, 0, p_format, m_args_copy)
#endif
String str_format(const char *p_format, va_list p_list) {
va_list list;
va_copy(list, p_list);
- int len = vsnprintf(NULL, 0, p_format, list);
+ int len = gd_vscprintf(p_format, list);
va_end(list);
len += 1; // for the trailing '/0'
@@ -223,7 +227,7 @@ String str_format(const char *p_format, va_list p_list) {
char *buffer(memnew_arr(char, len));
va_copy(list, p_list);
- vsnprintf(buffer, len, p_format, list);
+ gd_vsnprintf(buffer, len, p_format, list);
va_end(list);
String res(buffer);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 6893c38733..2445456a1f 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -87,7 +87,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} else {
- if (b->is_doubleclick()) {
+ if (b->is_doubleclick() && selecting_enabled) {
selection.enabled = true;
selection.begin = 0;
@@ -195,7 +195,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
unsigned int code = k->get_scancode();
- if (k->get_command()) {
+ if (k->get_command() && is_shortcut_keys_enabled()) {
bool handled = true;
@@ -210,7 +210,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
case (KEY_C): { // COPY
-
copy_text();
} break;
@@ -275,6 +274,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
case (KEY_A): { //Select All
select();
+
} break;
#ifdef APPLE_STYLE_KEYS
case (KEY_LEFT): { // Go to start of text - like HOME key
@@ -1347,6 +1347,8 @@ int LineEdit::get_max_length() const {
}
void LineEdit::selection_fill_at_cursor() {
+ if (!selecting_enabled)
+ return;
selection.begin = cursor_pos;
selection.end = selection.cursor_start;
@@ -1361,6 +1363,8 @@ void LineEdit::selection_fill_at_cursor() {
}
void LineEdit::select_all() {
+ if (!selecting_enabled)
+ return;
if (!text.length())
return;
@@ -1377,32 +1381,7 @@ void LineEdit::set_editable(bool p_editable) {
return;
editable = p_editable;
-
- // Reorganize context menu.
- menu->clear();
-
- if (editable) {
- menu->add_item(RTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z);
- menu->add_item(RTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z);
- }
-
- if (editable) {
- menu->add_separator();
- menu->add_item(RTR("Cut"), MENU_CUT, KEY_MASK_CMD | KEY_X);
- }
-
- menu->add_item(RTR("Copy"), MENU_COPY, KEY_MASK_CMD | KEY_C);
-
- if (editable) {
- menu->add_item(RTR("Paste"), MENU_PASTE, KEY_MASK_CMD | KEY_V);
- }
-
- menu->add_separator();
- menu->add_item(RTR("Select All"), MENU_SELECT_ALL, KEY_MASK_CMD | KEY_A);
-
- if (editable) {
- menu->add_item(RTR("Clear"), MENU_CLEAR);
- }
+ _generate_context_menu();
update();
}
@@ -1438,6 +1417,8 @@ String LineEdit::get_secret_character() const {
}
void LineEdit::select(int p_from, int p_to) {
+ if (!selecting_enabled)
+ return;
if (p_from == 0 && p_to == 0) {
deselect();
@@ -1545,6 +1526,29 @@ bool LineEdit::is_clear_button_enabled() const {
return clear_button_enabled;
}
+void LineEdit::set_shortcut_keys_enabled(bool p_enabled) {
+ shortcut_keys_enabled = p_enabled;
+
+ _generate_context_menu();
+}
+
+bool LineEdit::is_shortcut_keys_enabled() const {
+ return shortcut_keys_enabled;
+}
+
+void LineEdit::set_selecting_enabled(bool p_enabled) {
+ selecting_enabled = p_enabled;
+
+ if (!selecting_enabled)
+ deselect();
+
+ _generate_context_menu();
+}
+
+bool LineEdit::is_selecting_enabled() const {
+ return selecting_enabled;
+}
+
void LineEdit::set_right_icon(const Ref<Texture> &p_icon) {
if (right_icon == p_icon) {
return;
@@ -1608,6 +1612,25 @@ void LineEdit::_create_undo_state() {
undo_stack.push_back(op);
}
+void LineEdit::_generate_context_menu() {
+ // Reorganize context menu.
+ menu->clear();
+ if (editable)
+ menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
+ if (editable)
+ menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ menu->add_separator();
+ if (is_selecting_enabled())
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ if (editable) {
+ menu->add_item(RTR("Clear"), MENU_CLEAR);
+ menu->add_separator();
+ menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0);
+ menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0);
+ }
+}
+
void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
@@ -1652,6 +1675,10 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &LineEdit::is_context_menu_enabled);
ClassDB::bind_method(D_METHOD("set_clear_button_enabled", "enable"), &LineEdit::set_clear_button_enabled);
ClassDB::bind_method(D_METHOD("is_clear_button_enabled"), &LineEdit::is_clear_button_enabled);
+ ClassDB::bind_method(D_METHOD("set_shortcut_keys_enabled", "enable"), &LineEdit::set_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("is_shortcut_keys_enabled"), &LineEdit::is_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &LineEdit::set_selecting_enabled);
+ ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &LineEdit::is_selecting_enabled);
ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text")));
ADD_SIGNAL(MethodInfo("text_entered", PropertyInfo(Variant::STRING, "new_text")));
@@ -1680,6 +1707,8 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "focus_mode", PROPERTY_HINT_ENUM, "None,Click,All"), "set_focus_mode", "get_focus_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clear_button_enabled"), "set_clear_button_enabled", "is_clear_button_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled");
ADD_GROUP("Placeholder", "placeholder_");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "placeholder_text"), "set_placeholder", "get_placeholder");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "placeholder_alpha", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_placeholder_alpha", "get_placeholder_alpha");
@@ -1707,6 +1736,8 @@ LineEdit::LineEdit() {
clear_button_enabled = false;
clear_button_status.press_attempt = false;
clear_button_status.pressing_inside = false;
+ shortcut_keys_enabled = true;
+ selecting_enabled = true;
deselect();
set_focus_mode(FOCUS_ALL);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 1d33f7d4ce..c8fe845e3e 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -75,6 +75,8 @@ private:
String ime_text;
Point2 ime_selection;
+ bool selecting_enabled;
+
bool context_menu_enabled;
PopupMenu *menu;
@@ -87,6 +89,8 @@ private:
bool clear_button_enabled;
+ bool shortcut_keys_enabled;
+
Ref<Texture> right_icon;
struct Selection {
@@ -118,6 +122,8 @@ private:
void _clear_redo();
void _create_undo_state();
+ void _generate_context_menu();
+
Timer *caret_blink_timer;
void _text_changed();
@@ -216,6 +222,12 @@ public:
void set_clear_button_enabled(bool p_enabled);
bool is_clear_button_enabled() const;
+ void set_shortcut_keys_enabled(bool p_enabled);
+ bool is_shortcut_keys_enabled() const;
+
+ void set_selecting_enabled(bool p_enabled);
+ bool is_selecting_enabled() const;
+
void set_right_icon(const Ref<Texture> &p_icon);
virtual bool is_text_field() const;
diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp
index 8d9b8ad1e0..67fa85b832 100644
--- a/scene/gui/rich_text_effect.cpp
+++ b/scene/gui/rich_text_effect.cpp
@@ -33,7 +33,7 @@
#include "core/script_language.h"
void RichTextEffect::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::INT, "_process_custom_fx", PropertyInfo(Variant::OBJECT, "char_fx", PROPERTY_HINT_RESOURCE_TYPE, "CustomFXChar")));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process_custom_fx", PropertyInfo(Variant::OBJECT, "char_fx", PROPERTY_HINT_RESOURCE_TYPE, "CharFXTransform")));
}
Variant RichTextEffect::get_bbcode() const {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 77d5c8e91f..d9ae42d6e6 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -2631,7 +2631,7 @@ void RichTextLabel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selection_enabled"), "set_selection_enabled", "is_selection_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", (PropertyHint)(PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE), "17/17:RichTextEffect", PROPERTY_USAGE_DEFAULT, "RichTextEffect"), "set_effects", "get_effects");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "custom_effects", PROPERTY_HINT_RESOURCE_TYPE, "17/17:RichTextEffect", (PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE), "RichTextEffect"), "set_effects", "get_effects");
ADD_SIGNAL(MethodInfo("meta_clicked", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
ADD_SIGNAL(MethodInfo("meta_hover_started", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 7bcef5f9ab..5173b83407 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3222,7 +3222,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (readonly)
break;
- if (k->get_shift() && !k->get_command() && !k->get_alt()) {
+ if (k->get_shift() && !k->get_command() && !k->get_alt() && is_shortcut_keys_enabled()) {
cut();
break;
}
@@ -3453,13 +3453,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
scancode_handled = false;
break;
}
- select_all();
+ if (is_shortcut_keys_enabled()) {
+ select_all();
+ }
#else
if ((!k->get_command() && !k->get_control())) {
scancode_handled = false;
break;
}
- if (!k->get_shift() && k->get_command())
+ if (!k->get_shift() && k->get_command() && is_shortcut_keys_enabled())
select_all();
else if (k->get_control()) {
if (k->get_shift())
@@ -3515,8 +3517,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
scancode_handled = false;
break;
}
-
- cut();
+ if (is_shortcut_keys_enabled()) {
+ cut();
+ }
} break;
case KEY_C: {
@@ -3526,7 +3529,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
- copy();
+ if (is_shortcut_keys_enabled()) {
+ copy();
+ }
} break;
case KEY_Z: {
@@ -3540,10 +3545,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
- if (k->get_shift())
- redo();
- else
- undo();
+ if (is_shortcut_keys_enabled()) {
+ if (k->get_shift())
+ redo();
+ else
+ undo();
+ }
} break;
case KEY_Y: {
@@ -3556,7 +3563,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
- redo();
+ if (is_shortcut_keys_enabled()) {
+ redo();
+ }
} break;
case KEY_V: {
if (readonly) {
@@ -3567,7 +3576,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
break;
}
- paste();
+ if (is_shortcut_keys_enabled()) {
+ paste();
+ }
} break;
case KEY_SPACE: {
@@ -4061,6 +4072,25 @@ int TextEdit::_get_control_height() const {
return control_height;
}
+void TextEdit::_generate_context_menu() {
+ // Reorganize context menu.
+ menu->clear();
+ if (!readonly)
+ menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
+ if (!readonly)
+ menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ menu->add_separator();
+ if (is_selecting_enabled())
+ menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ if (!readonly) {
+ menu->add_item(RTR("Clear"), MENU_CLEAR);
+ menu->add_separator();
+ menu->add_item(RTR("Undo"), MENU_UNDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_Z : 0);
+ menu->add_item(RTR("Redo"), MENU_REDO, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z : 0);
+ }
+}
+
int TextEdit::get_visible_rows() const {
return _get_control_height() / get_row_height();
}
@@ -4769,6 +4799,7 @@ void TextEdit::set_readonly(bool p_readonly) {
return;
readonly = p_readonly;
+ _generate_context_menu();
// Reorganize context menu.
menu->clear();
@@ -5108,6 +5139,8 @@ void TextEdit::paste() {
}
void TextEdit::select_all() {
+ if (!selecting_enabled)
+ return;
if (text.size() == 1 && text[0].length() == 0)
return;
@@ -5132,6 +5165,8 @@ void TextEdit::deselect() {
}
void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
+ if (!selecting_enabled)
+ return;
if (p_from_line < 0)
p_from_line = 0;
@@ -6775,6 +6810,29 @@ bool TextEdit::is_context_menu_enabled() {
return context_menu_enabled;
}
+void TextEdit::set_shortcut_keys_enabled(bool p_enabled) {
+ shortcut_keys_enabled = p_enabled;
+
+ _generate_context_menu();
+}
+
+void TextEdit::set_selecting_enabled(bool p_enabled) {
+ selecting_enabled = p_enabled;
+
+ if (!selecting_enabled)
+ deselect();
+
+ _generate_context_menu();
+}
+
+bool TextEdit::is_selecting_enabled() const {
+ return selecting_enabled;
+}
+
+bool TextEdit::is_shortcut_keys_enabled() const {
+ return shortcut_keys_enabled;
+}
+
PopupMenu *TextEdit::get_menu() const {
return menu;
}
@@ -6830,6 +6888,10 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_wrap_enabled"), &TextEdit::is_wrap_enabled);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &TextEdit::set_context_menu_enabled);
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &TextEdit::is_context_menu_enabled);
+ ClassDB::bind_method(D_METHOD("set_shortcut_keys_enabled", "enable"), &TextEdit::set_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("is_shortcut_keys_enabled"), &TextEdit::is_shortcut_keys_enabled);
+ ClassDB::bind_method(D_METHOD("set_selecting_enabled", "enable"), &TextEdit::set_selecting_enabled);
+ ClassDB::bind_method(D_METHOD("is_selecting_enabled"), &TextEdit::is_selecting_enabled);
ClassDB::bind_method(D_METHOD("cut"), &TextEdit::cut);
ClassDB::bind_method(D_METHOD("copy"), &TextEdit::copy);
@@ -6920,6 +6982,8 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "context_menu_enabled"), "set_context_menu_enabled", "is_context_menu_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shortcut_keys_enabled"), "set_shortcut_keys_enabled", "is_shortcut_keys_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hiding_enabled"), "set_hiding_enabled", "is_hiding_enabled");
@@ -7078,7 +7142,9 @@ TextEdit::TextEdit() {
minimap_char_size = Point2(1, 2);
minimap_line_spacing = 1;
+ selecting_enabled = true;
context_menu_enabled = true;
+ shortcut_keys_enabled = true;
menu = memnew(PopupMenu);
add_child(menu);
readonly = true; // Initialise to opposite first, so we get past the early-out in set_readonly.
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 9c568acd93..e98201c1eb 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -365,10 +365,15 @@ private:
int search_result_line;
int search_result_col;
+ bool selecting_enabled;
+
bool context_menu_enabled;
+ bool shortcut_keys_enabled;
int executing_line;
+ void _generate_context_menu();
+
int get_visible_rows() const;
int get_total_visible_rows() const;
@@ -737,6 +742,12 @@ public:
void set_context_menu_enabled(bool p_enable);
bool is_context_menu_enabled();
+ void set_selecting_enabled(bool p_enabled);
+ bool is_selecting_enabled() const;
+
+ void set_shortcut_keys_enabled(bool p_enabled);
+ bool is_shortcut_keys_enabled() const;
+
PopupMenu *get_menu() const;
String get_text_for_completion();
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 6c89016ea3..5483fe1d6f 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -2096,6 +2096,7 @@ SceneTree::SceneTree() {
if (ScriptDebugger::get_singleton()) {
ScriptDebugger::get_singleton()->set_request_scene_tree_message_func(_debugger_request_tree, this);
+ ScriptDebugger::get_singleton()->set_multiplayer(multiplayer);
}
root->set_physics_object_picking(GLOBAL_DEF("physics/common/enable_object_picking", true));
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index d03eb2b49e..e3af521e8c 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -101,6 +101,7 @@
#include "scene/gui/popup_menu.h"
#include "scene/gui/progress_bar.h"
#include "scene/gui/reference_rect.h"
+#include "scene/gui/rich_text_effect.h"
#include "scene/gui/rich_text_label.h"
#include "scene/gui/scroll_bar.h"
#include "scene/gui/scroll_container.h"
@@ -344,6 +345,7 @@ void register_scene_types() {
ClassDB::register_class<ColorPickerButton>();
ClassDB::register_class<RichTextLabel>();
ClassDB::register_class<RichTextEffect>();
+ ClassDB::register_class<CharFXTransform>();
ClassDB::register_class<PopupDialog>();
ClassDB::register_class<WindowDialog>();
ClassDB::register_class<AcceptDialog>();
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 5dd429fa75..4453032f67 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -713,6 +713,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
Vector<Point2> verts;
Vector<int> indices;
Vector<Color> colors;
+ Vector<Point2> uvs;
//DRAW SHADOW
if (draw_shadow) {
@@ -799,9 +800,17 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
}
}
+ //COMPUTE UV COORDINATES
+ Rect2 uv_rect = style_rect.grow(aa_on ? aa_size : 0);
+ uvs.resize(verts.size());
+ for (int i = 0; i < verts.size(); i++) {
+ uvs.write[i].x = (verts[i].x - uv_rect.position.x) / uv_rect.size.width;
+ uvs.write[i].y = (verts[i].y - uv_rect.position.y) / uv_rect.size.height;
+ }
+
//DRAWING
VisualServer *vs = VisualServer::get_singleton();
- vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors);
+ vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors, uvs);
}
float StyleBoxFlat::get_style_margin(Margin p_margin) const {
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index f5c599b67e..b7173b157e 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "visual_shader_nodes.h"
+
////////////// Scalar
String VisualShaderNodeScalarConstant::get_caption() const {
@@ -38,9 +39,11 @@ String VisualShaderNodeScalarConstant::get_caption() const {
int VisualShaderNodeScalarConstant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const {
return String();
}
@@ -48,9 +51,11 @@ String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarConstant::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -158,9 +163,11 @@ String VisualShaderNodeColorConstant::get_caption() const {
int VisualShaderNodeColorConstant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const {
return String();
}
@@ -168,9 +175,11 @@ String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const {
int VisualShaderNodeColorConstant::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const {
return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port
}
@@ -222,9 +231,11 @@ String VisualShaderNodeVec3Constant::get_caption() const {
int VisualShaderNodeVec3Constant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const {
return String();
}
@@ -232,9 +243,11 @@ String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const {
int VisualShaderNodeVec3Constant::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -280,9 +293,11 @@ String VisualShaderNodeTransformConstant::get_caption() const {
int VisualShaderNodeTransformConstant::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const {
return String();
}
@@ -290,9 +305,11 @@ String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const
int VisualShaderNodeTransformConstant::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -346,9 +363,11 @@ String VisualShaderNodeTexture::get_caption() const {
int VisualShaderNodeTexture::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
return p_port == 0 ? "uv" : "lod";
}
@@ -356,11 +375,13 @@ String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
int VisualShaderNodeTexture::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const {
if (p_port == 0 && source == SOURCE_DEPTH)
return PORT_TYPE_SCALAR;
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTexture::get_output_port_name(int p_port) const {
if (p_port == 0 && source == SOURCE_DEPTH)
return "depth";
@@ -632,9 +653,11 @@ String VisualShaderNodeCubeMap::get_caption() const {
int VisualShaderNodeCubeMap::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
return p_port == 0 ? "uv" : "lod";
}
@@ -642,9 +665,11 @@ String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const {
int VisualShaderNodeCubeMap::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
@@ -735,6 +760,7 @@ void VisualShaderNodeCubeMap::_bind_methods() {
VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() {
texture_type = TYPE_DATA;
}
+
////////////// Scalar Op
String VisualShaderNodeScalarOp::get_caption() const {
@@ -744,9 +770,11 @@ String VisualShaderNodeScalarOp::get_caption() const {
int VisualShaderNodeScalarOp::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -754,9 +782,11 @@ String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarOp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
@@ -832,9 +862,11 @@ String VisualShaderNodeVectorOp::get_caption() const {
int VisualShaderNodeVectorOp::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -842,9 +874,11 @@ String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorOp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
@@ -924,9 +958,11 @@ String VisualShaderNodeColorOp::get_caption() const {
int VisualShaderNodeColorOp::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorOp::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -934,9 +970,11 @@ String VisualShaderNodeColorOp::get_input_port_name(int p_port) const {
int VisualShaderNodeColorOp::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorOp::get_output_port_name(int p_port) const {
return "op"; //no output port means the editor will be used as port
}
@@ -1072,9 +1110,11 @@ String VisualShaderNodeTransformMult::get_caption() const {
int VisualShaderNodeTransformMult::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1082,9 +1122,11 @@ String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformMult::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const {
return "mult"; //no output port means the editor will be used as port
}
@@ -1147,9 +1189,11 @@ String VisualShaderNodeTransformVecMult::get_caption() const {
int VisualShaderNodeTransformVecMult::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1157,9 +1201,11 @@ String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformVecMult::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -1221,9 +1267,11 @@ String VisualShaderNodeScalarFunc::get_caption() const {
int VisualShaderNodeScalarFunc::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const {
return "";
}
@@ -1231,9 +1279,11 @@ String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarFunc::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -1350,9 +1400,11 @@ String VisualShaderNodeVectorFunc::get_caption() const {
int VisualShaderNodeVectorFunc::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
return "";
}
@@ -1360,9 +1412,11 @@ String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorFunc::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -1675,9 +1729,11 @@ String VisualShaderNodeDotProduct::get_caption() const {
int VisualShaderNodeDotProduct::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const {
return p_port == 0 ? "a" : "b";
}
@@ -1685,9 +1741,11 @@ String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const {
int VisualShaderNodeDotProduct::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const {
return "dot";
}
@@ -1710,9 +1768,11 @@ String VisualShaderNodeVectorLen::get_caption() const {
int VisualShaderNodeVectorLen::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
return "";
}
@@ -1720,9 +1780,11 @@ String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorLen::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const {
return "length";
}
@@ -1745,7 +1807,7 @@ int VisualShaderNodeDeterminant::get_input_port_count() const {
return 1;
}
-VisualShaderNodeScalarClamp::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const {
+VisualShaderNodeDeterminant::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
@@ -1872,7 +1934,7 @@ int VisualShaderNodeVectorDerivativeFunc::get_output_port_count() const {
return 1;
}
-VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2078,7 +2140,7 @@ int VisualShaderNodeOuterProduct::get_input_port_count() const {
return 2;
}
-VisualShaderNodeFaceForward::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const {
+VisualShaderNodeOuterProduct::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2143,7 +2205,7 @@ int VisualShaderNodeVectorScalarStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2234,7 +2296,7 @@ int VisualShaderNodeVectorSmoothStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2285,7 +2347,7 @@ int VisualShaderNodeVectorScalarSmoothStep::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
@@ -2540,6 +2602,7 @@ VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() {
}
////////////// Vector Compose
+
String VisualShaderNodeVectorCompose::get_caption() const {
return "VectorCompose";
}
@@ -2547,9 +2610,11 @@ String VisualShaderNodeVectorCompose::get_caption() const {
int VisualShaderNodeVectorCompose::get_input_port_count() const {
return 3;
}
+
VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2563,9 +2628,11 @@ String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorCompose::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const {
return "vec";
}
@@ -2590,9 +2657,11 @@ String VisualShaderNodeTransformCompose::get_caption() const {
int VisualShaderNodeTransformCompose::get_input_port_count() const {
return 4;
}
+
VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2608,9 +2677,11 @@ String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformCompose::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const {
return "xform";
}
@@ -2635,9 +2706,11 @@ String VisualShaderNodeVectorDecompose::get_caption() const {
int VisualShaderNodeVectorDecompose::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
return "vec";
}
@@ -2645,9 +2718,11 @@ String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
int VisualShaderNodeVectorDecompose::get_output_port_count() const {
return 3;
}
+
VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2679,9 +2754,11 @@ String VisualShaderNodeTransformDecompose::get_caption() const {
int VisualShaderNodeTransformDecompose::get_input_port_count() const {
return 1;
}
+
VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const {
return "xform";
}
@@ -2689,9 +2766,11 @@ String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const
int VisualShaderNodeTransformDecompose::get_output_port_count() const {
return 4;
}
+
VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const {
if (p_port == 0) {
return "x";
@@ -2726,9 +2805,11 @@ String VisualShaderNodeScalarUniform::get_caption() const {
int VisualShaderNodeScalarUniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2736,9 +2817,11 @@ String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeScalarUniform::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
@@ -2746,6 +2829,7 @@ String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const {
String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return "uniform float " + get_uniform_name() + ";\n";
}
+
String VisualShaderNodeScalarUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
@@ -2803,9 +2887,11 @@ String VisualShaderNodeColorUniform::get_caption() const {
int VisualShaderNodeColorUniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2813,9 +2899,11 @@ String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeColorUniform::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "color" : "alpha"; //no output port means the editor will be used as port
}
@@ -2843,9 +2931,11 @@ String VisualShaderNodeVec3Uniform::get_caption() const {
int VisualShaderNodeVec3Uniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2853,12 +2943,15 @@ String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const {
int VisualShaderNodeVec3Uniform::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
+
String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return "uniform vec3 " + get_uniform_name() + ";\n";
}
@@ -2879,9 +2972,11 @@ String VisualShaderNodeTransformUniform::get_caption() const {
int VisualShaderNodeTransformUniform::get_input_port_count() const {
return 0;
}
+
VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
+
String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const {
return String();
}
@@ -2889,12 +2984,15 @@ String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeTransformUniform::get_output_port_count() const {
return 1;
}
+
VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
+
String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const {
return ""; //no output port means the editor will be used as port
}
+
String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return "uniform mat4 " + get_uniform_name() + ";\n";
}
@@ -2915,9 +3013,11 @@ String VisualShaderNodeTextureUniform::get_caption() const {
int VisualShaderNodeTextureUniform::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const {
return p_port == 0 ? "uv" : "lod";
}
@@ -2925,9 +3025,11 @@ String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeTextureUniform::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
@@ -2989,6 +3091,7 @@ void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_default) {
color_default = p_default;
emit_changed();
}
+
VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get_color_default() const {
return color_default;
}
@@ -3125,9 +3228,11 @@ String VisualShaderNodeCubeMapUniform::get_caption() const {
int VisualShaderNodeCubeMapUniform::get_input_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
return p_port == 0 ? "normal" : "lod";
}
@@ -3135,9 +3240,11 @@ String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const {
int VisualShaderNodeCubeMapUniform::get_output_port_count() const {
return 2;
}
+
VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const {
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const {
return p_port == 0 ? "rgb" : "alpha";
}
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 4bc65a8f4f..1b9c3e2eff 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -924,6 +924,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String
if (r_data_type) {
*r_data_type = shader->varyings[p_identifier].type;
}
+ if (r_array_size) {
+ *r_array_size = shader->varyings[p_identifier].array_size;
+ }
if (r_type) {
*r_type = IDENTIFIER_VARYING;
}
@@ -2759,6 +2762,12 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return false;
}
+ if (shader->varyings.has(arr->name) && current_function != String("vertex")) {
+ if (r_message)
+ *r_message = RTR("Varyings can only be assigned in vertex function.");
+ return false;
+ }
+
return true;
}
@@ -4695,7 +4704,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (!uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) {
- _set_error("Invalid type for varying, only float,vec2,vec3,vec4,mat2,mat3,mat4 allowed.");
+ _set_error("Invalid type for varying, only float,vec2,vec3,vec4,mat2,mat3,mat4 or array of these types allowed.");
return ERR_PARSE_ERROR;
}
@@ -4877,13 +4886,36 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
varying.type = type;
varying.precision = precision;
varying.interpolation = interpolation;
- shader->varyings[name] = varying;
tk = _get_token();
- if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
+ if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) {
+ _set_error("Expected ';' or '['");
return ERR_PARSE_ERROR;
}
+
+ if (tk.type == TK_BRACKET_OPEN) {
+ tk = _get_token();
+ if (tk.type == TK_INT_CONSTANT && tk.constant > 0) {
+ varying.array_size = (int)tk.constant;
+
+ tk = _get_token();
+ if (tk.type == TK_BRACKET_CLOSE) {
+ tk = _get_token();
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected ';'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected ']'");
+ return ERR_PARSE_ERROR;
+ }
+ } else {
+ _set_error("Expected single integer constant > 0");
+ return ERR_PARSE_ERROR;
+ }
+ }
+
+ shader->varyings[name] = varying;
}
} break;
diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h
index 6753456323..3a5630ef42 100644
--- a/servers/visual/shader_language.h
+++ b/servers/visual/shader_language.h
@@ -519,11 +519,13 @@ public:
DataType type;
DataInterpolation interpolation;
DataPrecision precision;
+ int array_size;
Varying() :
type(TYPE_VOID),
interpolation(INTERPOLATION_FLAT),
- precision(PRECISION_DEFAULT) {}
+ precision(PRECISION_DEFAULT),
+ array_size(0) {}
};
struct Uniform {
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 75910ff1c0..019f477362 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -235,6 +235,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["TEXTURE_PIXEL_SIZE"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["SHADOW_VEC"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"].built_ins["LIGHT_UV"] = constt(ShaderLanguage::TYPE_VEC2);
diff --git a/thirdparty/assimp/code/FBX/FBXConverter.cpp b/thirdparty/assimp/code/FBX/FBXConverter.cpp
index 9bd970098e..3f64016ea4 100644
--- a/thirdparty/assimp/code/FBX/FBXConverter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXConverter.cpp
@@ -78,7 +78,7 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
- FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit )
+ FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
: defaultMaterialIndex()
, lights()
, cameras()
@@ -90,8 +90,7 @@ namespace Assimp {
, mNodeNames()
, anim_fps()
, out(out)
- , doc(doc)
- , mCurrentUnit(FbxUnit::cm) {
+ , doc(doc) {
// animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated.
@@ -2002,6 +2001,21 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
+
+ // Maya PBR
+ TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+
+ // Maya stingray
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+ TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);
}
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@@ -3589,9 +3603,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
}
// ------------------------------------------------------------------------------------------------
- void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit)
+ void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{
- FBXConverter converter(out, doc, removeEmptyBones, unit);
+ FBXConverter converter(out, doc, removeEmptyBones);
}
} // !FBX
diff --git a/thirdparty/assimp/code/FBX/FBXConverter.h b/thirdparty/assimp/code/FBX/FBXConverter.h
index b458627392..ab610058a4 100644
--- a/thirdparty/assimp/code/FBX/FBXConverter.h
+++ b/thirdparty/assimp/code/FBX/FBXConverter.h
@@ -92,7 +92,7 @@ enum class FbxUnit {
* @param doc Parsed FBX document
* @param removeEmptyBones Will remove bones, which do not have any references to vertices.
*/
-void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
+void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
/** Dummy class to encapsulate the conversion process */
class FBXConverter {
@@ -123,7 +123,7 @@ public:
};
public:
- FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit);
+ FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
~FBXConverter();
private:
diff --git a/thirdparty/assimp/code/FBX/FBXImporter.cpp b/thirdparty/assimp/code/FBX/FBXImporter.cpp
index bd359dbf29..271935a568 100644
--- a/thirdparty/assimp/code/FBX/FBXImporter.cpp
+++ b/thirdparty/assimp/code/FBX/FBXImporter.cpp
@@ -191,7 +191,7 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
}
// convert the FBX DOM to aiScene
- ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones, unit);
+ ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
// size relative to cm
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
diff --git a/thirdparty/assimp/include/assimp/material.h b/thirdparty/assimp/include/assimp/material.h
index 4b5a1293dd..206eb2a2b0 100644
--- a/thirdparty/assimp/include/assimp/material.h
+++ b/thirdparty/assimp/include/assimp/material.h
@@ -196,34 +196,40 @@ enum aiTextureType
* (#aiMaterialProperty::mSemantic) for all material properties
* *not* related to textures.
*/
- aiTextureType_NONE = 0x0,
+ aiTextureType_NONE = 0,
+
+ /** LEGACY API MATERIALS
+ * Legacy refers to materials which
+ * Were originally implemented in the specifications around 2000.
+ * These must never be removed, as most engines support them.
+ */
/** The texture is combined with the result of the diffuse
* lighting equation.
*/
- aiTextureType_DIFFUSE = 0x1,
+ aiTextureType_DIFFUSE = 1,
/** The texture is combined with the result of the specular
* lighting equation.
*/
- aiTextureType_SPECULAR = 0x2,
+ aiTextureType_SPECULAR = 2,
/** The texture is combined with the result of the ambient
* lighting equation.
*/
- aiTextureType_AMBIENT = 0x3,
+ aiTextureType_AMBIENT = 3,
/** The texture is added to the result of the lighting
* calculation. It isn't influenced by incoming light.
*/
- aiTextureType_EMISSIVE = 0x4,
+ aiTextureType_EMISSIVE = 4,
/** The texture is a height map.
*
* By convention, higher gray-scale values stand for
* higher elevations from the base height.
*/
- aiTextureType_HEIGHT = 0x5,
+ aiTextureType_HEIGHT = 5,
/** The texture is a (tangent space) normal-map.
*
@@ -231,7 +237,7 @@ enum aiTextureType
* normal maps. Assimp does (intentionally) not
* distinguish here.
*/
- aiTextureType_NORMALS = 0x6,
+ aiTextureType_NORMALS = 6,
/** The texture defines the glossiness of the material.
*
@@ -240,21 +246,21 @@ enum aiTextureType
* function defined to map the linear color values in the
* texture to a suitable exponent. Have fun.
*/
- aiTextureType_SHININESS = 0x7,
+ aiTextureType_SHININESS = 7,
/** The texture defines per-pixel opacity.
*
* Usually 'white' means opaque and 'black' means
* 'transparency'. Or quite the opposite. Have fun.
*/
- aiTextureType_OPACITY = 0x8,
+ aiTextureType_OPACITY = 8,
/** Displacement texture
*
* The exact purpose and format is application-dependent.
* Higher color values stand for higher vertex displacements.
*/
- aiTextureType_DISPLACEMENT = 0x9,
+ aiTextureType_DISPLACEMENT = 9,
/** Lightmap texture (aka Ambient Occlusion)
*
@@ -263,14 +269,28 @@ enum aiTextureType
* scaling value for the final color value of a pixel. Its
* intensity is not affected by incoming light.
*/
- aiTextureType_LIGHTMAP = 0xA,
+ aiTextureType_LIGHTMAP = 10,
/** Reflection texture
*
* Contains the color of a perfect mirror reflection.
* Rarely used, almost never for real-time applications.
*/
- aiTextureType_REFLECTION = 0xB,
+ aiTextureType_REFLECTION = 11,
+
+ /** PBR Materials
+ * PBR definitions from maya and other modelling packages now use this standard.
+ * This was originally introduced around 2012.
+ * Support for this is in game engines like Godot, Unreal or Unity3D.
+ * Modelling packages which use this are very common now.
+ */
+
+ aiTextureType_BASE_COLOR = 12,
+ aiTextureType_NORMAL_CAMERA = 13,
+ aiTextureType_EMISSION_COLOR = 14,
+ aiTextureType_METALNESS = 15,
+ aiTextureType_DIFFUSE_ROUGHNESS = 16,
+ aiTextureType_AMBIENT_OCCLUSION = 17,
/** Unknown texture
*
@@ -278,7 +298,7 @@ enum aiTextureType
* above is considered to be 'unknown'. It is still imported,
* but is excluded from any further post-processing.
*/
- aiTextureType_UNKNOWN = 0xC,
+ aiTextureType_UNKNOWN = 18,
#ifndef SWIG