summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/http_client.cpp36
-rw-r--r--core/io/http_client.h1
-rw-r--r--core/io/stream_peer_ssl.cpp17
-rw-r--r--core/io/stream_peer_ssl.h8
-rw-r--r--doc/classes/Array.xml11
-rw-r--r--doc/classes/Line2D.xml3
-rw-r--r--editor/filesystem_dock.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.cpp80
-rwxr-xr-xmodules/mbedtls/stream_peer_mbed_tls.h6
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java2
-rw-r--r--platform/iphone/app_delegate.mm2
-rw-r--r--platform/uwp/os_uwp.cpp2
-rw-r--r--scene/2d/collision_object_2d.cpp25
-rw-r--r--scene/2d/collision_object_2d.h4
-rw-r--r--scene/2d/line_2d.cpp3
-rw-r--r--scene/2d/line_2d.h4
-rw-r--r--scene/2d/line_builder.cpp13
-rw-r--r--scene/2d/node_2d.cpp1
-rw-r--r--scene/2d/physics_body_2d.cpp109
-rw-r--r--scene/2d/physics_body_2d.h17
-rw-r--r--scene/gui/scroll_bar.cpp6
-rw-r--r--scene/register_scene_types.cpp8
-rw-r--r--scene/resources/visual_shader_nodes.cpp112
-rw-r--r--scene/resources/visual_shader_nodes.h24
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp10
-rw-r--r--servers/visual/shader_language.cpp8
27 files changed, 367 insertions, 157 deletions
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index fcbb22b5de..f1620f1493 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -279,6 +279,7 @@ void HTTPClient::close() {
chunk_left = 0;
read_until_eof = false;
response_num = 0;
+ handshaking = false;
}
Error HTTPClient::poll() {
@@ -327,16 +328,40 @@ Error HTTPClient::poll() {
} break;
case StreamPeerTCP::STATUS_CONNECTED: {
if (ssl) {
- Ref<StreamPeerSSL> ssl = StreamPeerSSL::create();
- Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
- if (err != OK) {
+ Ref<StreamPeerSSL> ssl;
+ if (!handshaking) {
+ // Connect the StreamPeerSSL and start handshaking
+ ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create());
+ ssl->set_blocking_handshake_enabled(false);
+ Error err = ssl->connect_to_stream(tcp_connection, ssl_verify_host, conn_host);
+ if (err != OK) {
+ close();
+ status = STATUS_SSL_HANDSHAKE_ERROR;
+ return ERR_CANT_CONNECT;
+ }
+ connection = ssl;
+ handshaking = true;
+ } else {
+ // We are already handshaking, which means we can use your already active SSL connection
+ ssl = static_cast<Ref<StreamPeerSSL> >(connection);
+ ssl->poll(); // Try to finish the handshake
+ }
+
+ if (ssl->get_status() == StreamPeerSSL::STATUS_CONNECTED) {
+ // Handshake has been successfull
+ handshaking = false;
+ status = STATUS_CONNECTED;
+ return OK;
+ } else if (ssl->get_status() != StreamPeerSSL::STATUS_HANDSHAKING) {
+ // Handshake has failed
close();
status = STATUS_SSL_HANDSHAKE_ERROR;
return ERR_CANT_CONNECT;
}
- connection = ssl;
+ // ... we will need to poll more for handshake to finish
+ } else {
+ status = STATUS_CONNECTED;
}
- status = STATUS_CONNECTED;
return OK;
} break;
case StreamPeerTCP::STATUS_ERROR:
@@ -669,6 +694,7 @@ HTTPClient::HTTPClient() {
response_num = 0;
ssl = false;
blocking = false;
+ handshaking = false;
read_chunk_size = 4096;
}
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 38ec82ce8c..82b56b01db 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -165,6 +165,7 @@ private:
bool ssl;
bool ssl_verify_host;
bool blocking;
+ bool handshaking;
Vector<uint8_t> response_str;
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index 012ba78c6d..c71af6b641 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -52,6 +52,14 @@ bool StreamPeerSSL::is_available() {
return available;
}
+void StreamPeerSSL::set_blocking_handshake_enabled(bool p_enabled) {
+ blocking_handshake = p_enabled;
+}
+
+bool StreamPeerSSL::is_blocking_handshake_enabled() const {
+ return blocking_handshake;
+}
+
PoolByteArray StreamPeerSSL::get_project_cert_array() {
PoolByteArray out;
@@ -84,16 +92,21 @@ PoolByteArray StreamPeerSSL::get_project_cert_array() {
void StreamPeerSSL::_bind_methods() {
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
- ClassDB::bind_method(D_METHOD("accept_stream", "stream"), &StreamPeerSSL::accept_stream);
+ ClassDB::bind_method(D_METHOD("accept_stream"), &StreamPeerSSL::accept_stream);
ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerSSL::get_status);
ClassDB::bind_method(D_METHOD("disconnect_from_stream"), &StreamPeerSSL::disconnect_from_stream);
+ ClassDB::bind_method(D_METHOD("set_blocking_handshake_enabled", "enabled"), &StreamPeerSSL::set_blocking_handshake_enabled);
+ ClassDB::bind_method(D_METHOD("is_blocking_handshake_enabled"), &StreamPeerSSL::is_blocking_handshake_enabled);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "blocking_handshake"), "set_blocking_handshake_enabled", "is_blocking_handshake_enabled");
BIND_ENUM_CONSTANT(STATUS_DISCONNECTED);
BIND_ENUM_CONSTANT(STATUS_CONNECTED);
- BIND_ENUM_CONSTANT(STATUS_ERROR_NO_CERTIFICATE);
+ BIND_ENUM_CONSTANT(STATUS_ERROR);
BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
}
StreamPeerSSL::StreamPeerSSL() {
+ blocking_handshake = true;
}
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index 77301a7c87..870704e875 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -49,14 +49,20 @@ protected:
friend class Main;
static bool initialize_certs;
+ bool blocking_handshake;
+
public:
enum Status {
STATUS_DISCONNECTED,
+ STATUS_HANDSHAKING,
STATUS_CONNECTED,
- STATUS_ERROR_NO_CERTIFICATE,
+ STATUS_ERROR,
STATUS_ERROR_HOSTNAME_MISMATCH
};
+ void set_blocking_handshake_enabled(bool p_enabled);
+ bool is_blocking_handshake_enabled() const;
+
virtual void poll() = 0;
virtual Error accept_stream(Ref<StreamPeer> p_base) = 0;
virtual Error connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs = false, const String &p_for_hostname = String()) = 0;
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 35c120cd6a..7fcb827252 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -4,7 +4,16 @@
Generic array datatype.
</brief_description>
<description>
- Generic array, contains several elements of any type, accessible by numerical index starting at 0. Negative indices can be used to count from the right, like in Python. Arrays are always passed by reference.
+ Generic array, contains several elements of any type, accessible by a numerical index starting at 0. Negative indices can be used to count from the back, like in Python (-1 is the last element, -2 the second to last, etc.). Example:
+ [codeblock]
+ var array = ["One", 2, 3, "Four"]
+ print(array[0]) # One
+ print(array[2]) # 3
+ print(array[-1]) # Four
+ array[2] = "Three"
+ print(array[-2]) # Three
+ [/codeblock]
+ Arrays are always passed by reference.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml
index 19be34978d..c1682e71e5 100644
--- a/doc/classes/Line2D.xml
+++ b/doc/classes/Line2D.xml
@@ -117,5 +117,8 @@
<constant name="LINE_TEXTURE_TILE" value="1" enum="LineTextureMode">
Tiles the texture over the line. The texture need to be imported with Repeat Enabled for it to work properly.
</constant>
+ <constant name="LINE_TEXTURE_STRETCH" value="2" enum="LineTextureMode">
+ Stretches the texture across the line. Import the texture with Repeat Disabled for best results.
+ </constant>
</constants>
</class>
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index eebf1b6ab8..f65fb5365b 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -1862,7 +1862,7 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_file_option"), &FileSystemDock::_file_option);
ClassDB::bind_method(D_METHOD("_folder_option"), &FileSystemDock::_folder_option);
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm);
- ClassDB::bind_method(D_METHOD("_move_operation_confirm"), &FileSystemDock::_move_operation_confirm);
+ ClassDB::bind_method(D_METHOD("_move_operation_confirm", "to_path", "overwrite"), &FileSystemDock::_move_operation_confirm, DEFVAL(false));
ClassDB::bind_method(D_METHOD("_move_with_overwrite"), &FileSystemDock::_move_with_overwrite);
ClassDB::bind_method(D_METHOD("_rename_operation_confirm"), &FileSystemDock::_rename_operation_confirm);
ClassDB::bind_method(D_METHOD("_duplicate_operation_confirm"), &FileSystemDock::_duplicate_operation_confirm);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 9a351c26fa..682ca744ff 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -768,17 +768,17 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("VectorOp", "Operators", "VisualShaderNodeVectorOp"));
add_options.push_back(AddOption("ColorOp", "Operators", "VisualShaderNodeColorOp"));
add_options.push_back(AddOption("TransformMult", "Operators", "VisualShaderNodeTransformMult"));
- add_options.push_back(AddOption("TransformVecMult", "Operators", "VisualShaderNodeTransformVecMult"));
+ add_options.push_back(AddOption("TransformVectorMult", "Operators", "VisualShaderNodeTransformVecMult"));
add_options.push_back(AddOption("ScalarFunc", "Functions", "VisualShaderNodeScalarFunc"));
add_options.push_back(AddOption("VectorFunc", "Functions", "VisualShaderNodeVectorFunc"));
add_options.push_back(AddOption("DotProduct", "Functions", "VisualShaderNodeDotProduct"));
add_options.push_back(AddOption("VectorLen", "Functions", "VisualShaderNodeVectorLen"));
add_options.push_back(AddOption("ScalarInterp", "Interpolation", "VisualShaderNodeScalarInterp"));
add_options.push_back(AddOption("VectorInterp", "Interpolation", "VisualShaderNodeVectorInterp"));
- add_options.push_back(AddOption("VectorConstruct", "Construct", "VisualShaderNodeVectorConstruct"));
- add_options.push_back(AddOption("TransformConstruct", "Construct", "VisualShaderNodeTransformConstruct"));
- add_options.push_back(AddOption("VectorDestruct", "Destruct", "VisualShaderNodeVectorDestruct"));
- add_options.push_back(AddOption("TransformDestruct", "Destruct", "VisualShaderNodeTransformDestruct"));
+ add_options.push_back(AddOption("VectorCompose", "Compose", "VisualShaderNodeVectorCompose"));
+ add_options.push_back(AddOption("TransformCompose", "Compose", "VisualShaderNodeTransformCompose"));
+ add_options.push_back(AddOption("VectorDecompose", "Decompose", "VisualShaderNodeVectorDecompose"));
+ add_options.push_back(AddOption("TransformDecompose", "Decompose", "VisualShaderNodeTransformDecompose"));
add_options.push_back(AddOption("Scalar", "Uniforms", "VisualShaderNodeScalarUniform"));
add_options.push_back(AddOption("Vector", "Uniforms", "VisualShaderNodeVec3Uniform"));
add_options.push_back(AddOption("Color", "Uniforms", "VisualShaderNodeColorUniform"));
diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp
index a63e53ec1f..884c26ddfe 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.cpp
+++ b/modules/mbedtls/stream_peer_mbed_tls.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "stream_peer_mbed_tls.h"
+#include "mbedtls/platform_util.h"
+#include "os/file_access.h"
static void my_debug(void *ctx, int level,
const char *file, int line,
@@ -81,6 +83,36 @@ int StreamPeerMbedTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
return got;
}
+void StreamPeerMbedTLS::_cleanup() {
+
+ mbedtls_ssl_free(&ssl);
+ mbedtls_ssl_config_free(&conf);
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+
+ base = Ref<StreamPeer>();
+ status = STATUS_DISCONNECTED;
+}
+
+Error StreamPeerMbedTLS::_do_handshake() {
+ int ret = 0;
+ while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
+ if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
+ ERR_PRINTS("TLS handshake error: " + itos(ret));
+ _print_error(ret);
+ disconnect_from_stream();
+ status = STATUS_ERROR;
+ return FAILED;
+ } else if (!blocking_handshake) {
+ // Will retry via poll later
+ return OK;
+ }
+ }
+
+ status = STATUS_CONNECTED;
+ return OK;
+}
+
Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname) {
base = p_base;
@@ -95,6 +127,7 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
if (ret != 0) {
ERR_PRINTS(" failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
+ _cleanup();
return FAILED;
}
@@ -112,29 +145,24 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
mbedtls_ssl_set_bio(&ssl, this, bio_send, bio_recv, NULL);
- while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
- if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
- ERR_PRINTS("TLS handshake error: " + itos(ret));
- _print_error(ret);
- status = STATUS_ERROR_HOSTNAME_MISMATCH;
- return FAILED;
- }
- }
+ status = STATUS_HANDSHAKING;
- connected = true;
- status = STATUS_CONNECTED;
+ if ((ret = _do_handshake()) != OK) {
+ status = STATUS_ERROR_HOSTNAME_MISMATCH;
+ return FAILED;
+ }
return OK;
}
Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base) {
- return ERR_UNAVAILABLE;
+ return OK;
}
Error StreamPeerMbedTLS::put_data(const uint8_t *p_data, int p_bytes) {
- ERR_FAIL_COND_V(!connected, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
Error err;
int sent = 0;
@@ -155,7 +183,7 @@ Error StreamPeerMbedTLS::put_data(const uint8_t *p_data, int p_bytes) {
Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
- ERR_FAIL_COND_V(!connected, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
r_sent = 0;
@@ -177,7 +205,7 @@ Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, in
Error StreamPeerMbedTLS::get_data(uint8_t *p_buffer, int p_bytes) {
- ERR_FAIL_COND_V(!connected, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
Error err;
@@ -199,7 +227,7 @@ Error StreamPeerMbedTLS::get_data(uint8_t *p_buffer, int p_bytes) {
Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
- ERR_FAIL_COND_V(!connected, ERR_UNCONFIGURED);
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
r_received = 0;
@@ -218,27 +246,30 @@ Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r
void StreamPeerMbedTLS::poll() {
- ERR_FAIL_COND(!connected);
+ ERR_FAIL_COND(status != STATUS_CONNECTED && status != STATUS_HANDSHAKING);
ERR_FAIL_COND(!base.is_valid());
+ if (status == STATUS_HANDSHAKING) {
+ _do_handshake();
+ return;
+ }
+
int ret = mbedtls_ssl_read(&ssl, NULL, 0);
if (ret < 0 && ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
_print_error(ret);
disconnect_from_stream();
- return;
}
}
int StreamPeerMbedTLS::get_available_bytes() const {
- ERR_FAIL_COND_V(!connected, 0);
+ ERR_FAIL_COND_V(status != STATUS_CONNECTED, 0);
return mbedtls_ssl_get_bytes_avail(&ssl);
}
StreamPeerMbedTLS::StreamPeerMbedTLS() {
- connected = false;
status = STATUS_DISCONNECTED;
}
@@ -248,17 +279,10 @@ StreamPeerMbedTLS::~StreamPeerMbedTLS() {
void StreamPeerMbedTLS::disconnect_from_stream() {
- if (!connected)
+ if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING)
return;
- mbedtls_ssl_free(&ssl);
- mbedtls_ssl_config_free(&conf);
- mbedtls_ctr_drbg_free(&ctr_drbg);
- mbedtls_entropy_free(&entropy);
-
- base = Ref<StreamPeer>();
- connected = false;
- status = STATUS_DISCONNECTED;
+ _cleanup();
}
StreamPeerMbedTLS::Status StreamPeerMbedTLS::get_status() const {
diff --git a/modules/mbedtls/stream_peer_mbed_tls.h b/modules/mbedtls/stream_peer_mbed_tls.h
index 2b96a194a1..7f4e5a4513 100755
--- a/modules/mbedtls/stream_peer_mbed_tls.h
+++ b/modules/mbedtls/stream_peer_mbed_tls.h
@@ -48,8 +48,6 @@ private:
Status status;
String hostname;
- bool connected;
-
Ref<StreamPeer> base;
static StreamPeerSSL *_create_func();
@@ -57,9 +55,11 @@ private:
static int bio_recv(void *ctx, unsigned char *buf, size_t len);
static int bio_send(void *ctx, const unsigned char *buf, size_t len);
+ void _cleanup();
protected:
static mbedtls_x509_crt cacert;
+
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
@@ -67,6 +67,8 @@ protected:
static void _bind_methods();
+ Error _do_handshake();
+
public:
virtual void poll();
virtual Error accept_stream(Ref<StreamPeer> p_base);
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 8a2d789dc5..ef798fc790 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -297,7 +297,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
runOnUiThread(new Runnable() {
@Override
public void run() {
- view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on")));
+ view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
}
});
}
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index dd5ce4ab10..cc4985eb0c 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -643,7 +643,7 @@ static int frame_count = 0;
view_controller.view = glView;
window.rootViewController = view_controller;
- _set_keep_screen_on(bool(GLOBAL_DEF("display/window/keep_screen_on", true)) ? YES : NO);
+ _set_keep_screen_on(bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)) ? YES : NO);
glView.useCADisplayLink =
bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
printf("cadisaplylink: %d", glView.useCADisplayLink);
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 8cdd13df90..6e6e0fb1aa 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -290,7 +290,7 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
if (is_keep_screen_on())
display_request->RequestActive();
- set_keep_screen_on(GLOBAL_DEF("display/window/keep_screen_on", true));
+ set_keep_screen_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
return OK;
}
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index d05c818ae1..cabd7fddc2 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -38,10 +38,14 @@ void CollisionObject2D::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
+ Transform2D global_transform = get_global_transform();
+
if (area)
- Physics2DServer::get_singleton()->area_set_transform(rid, get_global_transform());
+ Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
else
- Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, get_global_transform());
+ Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform);
+
+ last_transform = global_transform;
RID space = get_world_2d()->get_space();
if (area) {
@@ -60,10 +64,18 @@ void CollisionObject2D::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
+ Transform2D global_transform = get_global_transform();
+
+ if (only_update_transform_changes && global_transform == last_transform) {
+ return;
+ }
+
if (area)
- Physics2DServer::get_singleton()->area_set_transform(rid, get_global_transform());
+ Physics2DServer::get_singleton()->area_set_transform(rid, global_transform);
else
- Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, get_global_transform());
+ Physics2DServer::get_singleton()->body_set_state(rid, Physics2DServer::BODY_STATE_TRANSFORM, global_transform);
+
+ last_transform = global_transform;
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -318,6 +330,10 @@ void CollisionObject2D::_mouse_exit() {
emit_signal(SceneStringNames::get_singleton()->mouse_exited);
}
+void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
+ only_update_transform_changes = p_enable;
+}
+
void CollisionObject2D::_update_pickable() {
if (!is_inside_tree())
return;
@@ -384,6 +400,7 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
pickable = true;
set_notify_transform(true);
total_subshapes = 0;
+ only_update_transform_changes = false;
if (p_area) {
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 6da63d1a0b..29a00bd9f9 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -65,6 +65,8 @@ class CollisionObject2D : public Node2D {
int total_subshapes;
Map<uint32_t, ShapeData> shapes;
+ Transform2D last_transform;
+ bool only_update_transform_changes; //this is used for sync physics in KinematicBody
protected:
CollisionObject2D(RID p_rid, bool p_area);
@@ -78,6 +80,8 @@ protected:
void _mouse_enter();
void _mouse_exit();
+ void set_only_update_transform_changes(bool p_enable);
+
public:
uint32_t create_shape_owner(Object *p_owner);
void remove_shape_owner(uint32_t owner);
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index 3e61dd05f4..e9e895b5bb 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -349,7 +349,7 @@ void Line2D::_bind_methods() {
ADD_GROUP("Fill", "");
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
- ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile"), "set_texture_mode", "get_texture_mode");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile,Stretch"), "set_texture_mode", "get_texture_mode");
ADD_GROUP("Capping", "");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "begin_cap_mode", PROPERTY_HINT_ENUM, "None,Box,Round"), "set_begin_cap_mode", "get_begin_cap_mode");
@@ -368,6 +368,7 @@ void Line2D::_bind_methods() {
BIND_ENUM_CONSTANT(LINE_TEXTURE_NONE);
BIND_ENUM_CONSTANT(LINE_TEXTURE_TILE);
+ BIND_ENUM_CONSTANT(LINE_TEXTURE_STRETCH);
ClassDB::bind_method(D_METHOD("_gradient_changed"), &Line2D::_gradient_changed);
}
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index 24c48982cd..6918018c12 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -52,8 +52,8 @@ public:
enum LineTextureMode {
LINE_TEXTURE_NONE = 0,
- LINE_TEXTURE_TILE
- // TODO STRETCH mode
+ LINE_TEXTURE_TILE,
+ LINE_TEXTURE_STRETCH
};
Line2D();
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 845788bada..74ad3e79d0 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -146,7 +146,9 @@ void LineBuilder::build() {
float current_distance1 = 0.f;
float total_distance = 0.f;
_interpolate_color = gradient != NULL;
- bool distance_required = _interpolate_color || texture_mode == Line2D::LINE_TEXTURE_TILE;
+ bool distance_required = _interpolate_color ||
+ texture_mode == Line2D::LINE_TEXTURE_TILE ||
+ texture_mode == Line2D::LINE_TEXTURE_STRETCH;
if (distance_required)
total_distance = calculate_total_distance(points);
if (_interpolate_color)
@@ -170,7 +172,7 @@ void LineBuilder::build() {
if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
uvx0 = 0.5f / tile_aspect;
}
- new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, 1.f, 1.f));
+ new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, fmin(uvx0 * 2, 1.f), 1.f));
total_distance += width;
current_distance0 += hw;
current_distance1 = current_distance0;
@@ -292,6 +294,9 @@ void LineBuilder::build() {
if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
uvx0 = current_distance0 / (width * tile_aspect);
uvx1 = current_distance1 / (width * tile_aspect);
+ } else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) {
+ uvx0 = current_distance0 / total_distance;
+ uvx1 = current_distance1 / total_distance;
}
strip_add_quad(pos_up1, pos_down1, color1, uvx1);
@@ -378,6 +383,8 @@ void LineBuilder::build() {
}
if (texture_mode == Line2D::LINE_TEXTURE_TILE) {
uvx1 = current_distance1 / (width * tile_aspect);
+ } else if (texture_mode == Line2D::LINE_TEXTURE_STRETCH) {
+ uvx1 = current_distance1 / total_distance;
}
strip_add_quad(pos_up1, pos_down1, color1, uvx1);
@@ -386,7 +393,7 @@ void LineBuilder::build() {
if (end_cap_mode == Line2D::LINE_CAP_ROUND) {
// Note: color is not used in case we don't interpolate...
Color color = _interpolate_color ? gradient->get_color(gradient->get_points_count() - 1) : Color(0, 0, 0);
- new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f, 0.f, 1.f, 1.f));
+ new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f / tile_aspect, 0.f, 1.0f / tile_aspect, 1.f));
}
}
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index 3813bd96fe..7252602a93 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -130,7 +130,6 @@ void Node2D::_update_xform_values() {
void Node2D::_update_transform() {
- Transform2D mat(angle, pos);
_mat.set_rotation_and_scale(angle, _scale);
_mat.elements[2] = pos;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 713d1daeef..8787a2c735 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -971,11 +971,11 @@ RigidBody2D::~RigidBody2D() {
//////////////////////////
-Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes) {
+Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
Collision col;
- if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes)) {
+ if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
if (motion_cache.is_null()) {
motion_cache.instance();
motion_cache->owner = this;
@@ -1026,7 +1026,7 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
}
}
-bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes) {
+bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
Transform2D gt = get_global_transform();
Physics2DServer::MotionResult result;
@@ -1039,23 +1039,36 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
r_collision.collision = result.collision_point;
r_collision.normal = result.collision_normal;
r_collision.collider = result.collider_id;
+ r_collision.collider_rid = result.collider;
r_collision.travel = result.motion;
r_collision.remainder = result.remainder;
r_collision.local_shape = result.collision_local_shape;
}
- gt.elements[2] += result.motion;
- set_global_transform(gt);
+ if (!p_test_only) {
+ gt.elements[2] += result.motion;
+ set_global_transform(gt);
+ }
return colliding;
}
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
- Vector2 motion = (floor_velocity + p_linear_velocity) * get_physics_process_delta_time();
+ Vector2 floor_motion = floor_velocity;
+ if (on_floor && on_floor_body.is_valid()) {
+ //this approach makes sure there is less delay between the actual body velocity and the one we saved
+ Physics2DDirectBodyState *bs = Physics2DServer::get_singleton()->body_get_direct_state(on_floor_body);
+ if (bs) {
+ floor_motion = bs->get_linear_velocity();
+ }
+ }
+
+ Vector2 motion = (floor_motion + p_linear_velocity) * get_physics_process_delta_time();
Vector2 lv = p_linear_velocity;
on_floor = false;
+ on_floor_body = RID();
on_ceiling = false;
on_wall = false;
colliders.clear();
@@ -1096,6 +1109,7 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
on_floor = true;
+ on_floor_body = collision.collider_rid;
floor_velocity = collision.collider_vel;
Vector2 rel_v = lv - floor_velocity;
@@ -1133,20 +1147,29 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
return lv;
}
-bool KinematicBody2D::snap_to_floor(const Vector2 &p_direction, float p_floor_max_angle) {
+Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction, bool p_infinite_inertia, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
+
+ bool was_on_floor = on_floor;
+
+ Vector2 ret = move_and_slide(p_linear_velocity, p_floor_direction, p_infinite_inertia, p_slope_stop_min_velocity, p_max_slides, p_floor_max_angle);
+ if (!was_on_floor || p_snap == Vector2()) {
+ return ret;
+ }
+ Collision col;
Transform2D gt = get_global_transform();
- Physics2DServer::MotionResult result;
- bool colliding = Physics2DServer::get_singleton()->body_test_motion(get_rid(), gt, p_direction, false, margin, &result, false);
- if (colliding) {
- gt.elements[2] += result.motion;
- if (Math::acos(p_direction.normalized().dot(-result.collision_normal)) < p_floor_max_angle) {
+
+ if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
+ gt.elements[2] += col.travel;
+ if (p_floor_direction != Vector2() && Math::acos(p_floor_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
on_floor = true;
+ on_floor_body = col.collider_rid;
+ floor_velocity = col.collider_vel;
}
set_global_transform(gt);
}
- return colliding;
+ return ret;
}
bool KinematicBody2D::is_on_floor() const {
@@ -1210,11 +1233,60 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
return slide_colliders[p_bounce];
}
+void KinematicBody2D::set_sync_to_physics(bool p_enable) {
+
+ if (sync_to_physics == p_enable) {
+ return;
+ }
+ sync_to_physics = p_enable;
+ if (p_enable) {
+ Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
+ set_only_update_transform_changes(true);
+ set_notify_local_transform(true);
+ } else {
+ Physics2DServer::get_singleton()->body_set_force_integration_callback(get_rid(), NULL, "");
+ set_only_update_transform_changes(false);
+ set_notify_local_transform(false);
+ }
+}
+
+bool KinematicBody2D::is_sync_to_physics_enabled() const {
+ return sync_to_physics;
+}
+
+void KinematicBody2D::_direct_state_changed(Object *p_state) {
+
+ if (!sync_to_physics)
+ return;
+
+ Physics2DDirectBodyState *state = Object::cast_to<Physics2DDirectBodyState>(p_state);
+
+ last_valid_transform = state->get_transform();
+ set_notify_local_transform(false);
+ set_global_transform(last_valid_transform);
+ set_notify_local_transform(true);
+}
+
+void KinematicBody2D::_notification(int p_what) {
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+ last_valid_transform = get_global_transform();
+ }
+
+ if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
+ //used by sync to physics, send the new transform to the physics
+ Transform2D new_transform = get_global_transform();
+ Physics2DServer::get_singleton()->body_set_state(get_rid(), Physics2DServer::BODY_STATE_TRANSFORM, new_transform);
+ //but then revert changes
+ set_notify_local_transform(false);
+ set_global_transform(last_valid_transform);
+ set_notify_local_transform(true);
+ }
+}
void KinematicBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
- ClassDB::bind_method(D_METHOD("snap_to_floor", "motion", "max_floor_angle"), &KinematicBody2D::snap_to_floor, DEFVAL(Math::deg2rad(45.0)));
+ ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "floor_normal", "infinite_inertia", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(true), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec", "infinite_inertia"), &KinematicBody2D::test_move);
@@ -1229,7 +1301,13 @@ void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody2D::get_slide_count);
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody2D::_get_slide_collision);
+ ClassDB::bind_method(D_METHOD("set_sync_to_physics", "enable"), &KinematicBody2D::set_sync_to_physics);
+ ClassDB::bind_method(D_METHOD("is_sync_to_physics_enabled"), &KinematicBody2D::is_sync_to_physics_enabled);
+
+ ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody2D::_direct_state_changed);
+
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "motion/sync_to_physics"), "set_sync_to_physics", "is_sync_to_physics_enabled");
}
KinematicBody2D::KinematicBody2D() :
@@ -1240,6 +1318,7 @@ KinematicBody2D::KinematicBody2D() :
on_floor = false;
on_ceiling = false;
on_wall = false;
+ sync_to_physics = false;
}
KinematicBody2D::~KinematicBody2D() {
if (motion_cache.is_valid()) {
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 1873c977a9..7bda6ce817 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -276,6 +276,7 @@ public:
Vector2 normal;
Vector2 collider_vel;
ObjectID collider;
+ RID collider_rid;
int collider_shape;
Variant collider_metadata;
Vector2 remainder;
@@ -287,9 +288,11 @@ private:
float margin;
Vector2 floor_velocity;
+ RID on_floor_body;
bool on_floor;
bool on_ceiling;
bool on_wall;
+ bool sync_to_physics;
Vector<Collision> colliders;
Vector<Ref<KinematicCollision2D> > slide_colliders;
@@ -297,15 +300,19 @@ private:
_FORCE_INLINE_ bool _ignores_mode(Physics2DServer::BodyMode) const;
- Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true);
+ Ref<KinematicCollision2D> _move(const Vector2 &p_motion, bool p_infinite_inertia = true, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
Ref<KinematicCollision2D> _get_slide_collision(int p_bounce);
+ Transform2D last_valid_transform;
+ void _direct_state_changed(Object *p_state);
+
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
- bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true);
- bool snap_to_floor(const Vector2 &p_direction, float p_floor_max_angle = Math::deg2rad((float)45));
+ bool move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes = true, bool p_test_only = false);
+
bool test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia);
bool separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision);
@@ -314,6 +321,7 @@ public:
float get_safe_margin() const;
Vector2 move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ Vector2 move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_floor_direction = Vector2(0, 0), bool p_infinite_inertia = true, float p_slope_stop_min_velocity = 5, int p_max_slides = 4, float p_floor_max_angle = Math::deg2rad((float)45));
bool is_on_floor() const;
bool is_on_wall() const;
bool is_on_ceiling() const;
@@ -322,6 +330,9 @@ public:
int get_slide_count() const;
Collision get_slide_collision(int p_bounce) const;
+ void set_sync_to_physics(bool p_enable);
+ bool is_sync_to_physics_enabled() const;
+
KinematicBody2D();
~KinematicBody2D();
};
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 6ec67aca6b..e5bd1c453d 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -257,9 +257,7 @@ void ScrollBar::_notification(int p_what) {
Point2 ofs;
- VisualServer *vs = VisualServer::get_singleton();
-
- vs->canvas_item_add_texture_rect(ci, Rect2(Point2(), decr->get_size()), decr->get_rid());
+ decr->draw(ci, Point2());
if (orientation == HORIZONTAL)
ofs.x += decr->get_width();
@@ -280,7 +278,7 @@ void ScrollBar::_notification(int p_what) {
else
ofs.height += area.height;
- vs->canvas_item_add_texture_rect(ci, Rect2(ofs, decr->get_size()), incr->get_rid());
+ incr->draw(ci, ofs);
Rect2 grabber_rect;
if (orientation == HORIZONTAL) {
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 8dd378c319..8f78e137b4 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -477,10 +477,10 @@ void register_scene_types() {
ClassDB::register_class<VisualShaderNodeVectorLen>();
ClassDB::register_class<VisualShaderNodeScalarInterp>();
ClassDB::register_class<VisualShaderNodeVectorInterp>();
- ClassDB::register_class<VisualShaderNodeVectorConstruct>();
- ClassDB::register_class<VisualShaderNodeTransformConstruct>();
- ClassDB::register_class<VisualShaderNodeVectorDestruct>();
- ClassDB::register_class<VisualShaderNodeTransformDestruct>();
+ ClassDB::register_class<VisualShaderNodeVectorCompose>();
+ ClassDB::register_class<VisualShaderNodeTransformCompose>();
+ ClassDB::register_class<VisualShaderNodeVectorDecompose>();
+ ClassDB::register_class<VisualShaderNodeTransformDecompose>();
ClassDB::register_class<VisualShaderNodeTexture>();
ClassDB::register_class<VisualShaderNodeCubeMap>();
ClassDB::register_virtual_class<VisualShaderNodeUniform>();
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 90af312870..e850aaa44c 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -183,7 +183,7 @@ VisualShaderNodeVec3Constant::VisualShaderNodeVec3Constant() {
////////////// Transform
String VisualShaderNodeTransformConstant::get_caption() const {
- return "Transform4x3";
+ return "Transform";
}
int VisualShaderNodeTransformConstant::get_input_port_count() const {
@@ -681,7 +681,7 @@ VisualShaderNodeScalarOp::VisualShaderNodeScalarOp() {
////////////// Vector Op
String VisualShaderNodeVectorOp::get_caption() const {
- return "VecOp";
+ return "VectorOp";
}
int VisualShaderNodeVectorOp::get_input_port_count() const {
@@ -905,7 +905,7 @@ VisualShaderNodeColorOp::VisualShaderNodeColorOp() {
////////////// Transform Mult
String VisualShaderNodeTransformMult::get_caption() const {
- return "TransMult";
+ return "TransformMult";
}
int VisualShaderNodeTransformMult::get_input_port_count() const {
@@ -971,7 +971,7 @@ VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() {
////////////// TransformVec Mult
String VisualShaderNodeTransformVecMult::get_caption() const {
- return "TransVecMult";
+ return "TransformVectorMult";
}
int VisualShaderNodeTransformVecMult::get_input_port_count() const {
@@ -1150,7 +1150,7 @@ VisualShaderNodeScalarFunc::VisualShaderNodeScalarFunc() {
////////////// Vector Func
String VisualShaderNodeVectorFunc::get_caption() const {
- return "VecFunc";
+ return "VectorFunc";
}
int VisualShaderNodeVectorFunc::get_input_port_count() const {
@@ -1251,7 +1251,7 @@ VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() {
////////////// Dot Product
String VisualShaderNodeDotProduct::get_caption() const {
- return "DotProd";
+ return "DotProduct";
}
int VisualShaderNodeDotProduct::get_input_port_count() const {
@@ -1286,7 +1286,7 @@ VisualShaderNodeDotProduct::VisualShaderNodeDotProduct() {
////////////// Vector Len
String VisualShaderNodeVectorLen::get_caption() const {
- return "VecLen";
+ return "VectorLen";
}
int VisualShaderNodeVectorLen::get_input_port_count() const {
@@ -1362,7 +1362,7 @@ VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() {
////////////// Vector Interp
String VisualShaderNodeVectorInterp::get_caption() const {
- return "VecInterp";
+ return "VectorInterp";
}
int VisualShaderNodeVectorInterp::get_input_port_count() const {
@@ -1401,18 +1401,18 @@ VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() {
set_input_port_default_value(2, Vector3());
}
-////////////// Vector Construct
-String VisualShaderNodeVectorConstruct::get_caption() const {
- return "VecConstr";
+////////////// Vector Compose
+String VisualShaderNodeVectorCompose::get_caption() const {
+ return "VectorCompose";
}
-int VisualShaderNodeVectorConstruct::get_input_port_count() const {
+int VisualShaderNodeVectorCompose::get_input_port_count() const {
return 3;
}
-VisualShaderNodeVectorConstruct::PortType VisualShaderNodeVectorConstruct::get_input_port_type(int p_port) const {
+VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeVectorConstruct::get_input_port_name(int p_port) const {
+String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "x";
} else if (p_port == 1) {
@@ -1422,40 +1422,40 @@ String VisualShaderNodeVectorConstruct::get_input_port_name(int p_port) const {
}
}
-int VisualShaderNodeVectorConstruct::get_output_port_count() const {
+int VisualShaderNodeVectorCompose::get_output_port_count() const {
return 1;
}
-VisualShaderNodeVectorConstruct::PortType VisualShaderNodeVectorConstruct::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
-String VisualShaderNodeVectorConstruct::get_output_port_name(int p_port) const {
+String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const {
return "vec";
}
-String VisualShaderNodeVectorConstruct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
return "\t" + p_output_vars[0] + " = vec3( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n";
}
-VisualShaderNodeVectorConstruct::VisualShaderNodeVectorConstruct() {
+VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() {
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, 0.0);
}
-////////////// Transform Construct
+////////////// Transform Compose
-String VisualShaderNodeTransformConstruct::get_caption() const {
- return "TransConstr";
+String VisualShaderNodeTransformCompose::get_caption() const {
+ return "TransformCompose";
}
-int VisualShaderNodeTransformConstruct::get_input_port_count() const {
+int VisualShaderNodeTransformCompose::get_input_port_count() const {
return 4;
}
-VisualShaderNodeTransformConstruct::PortType VisualShaderNodeTransformConstruct::get_input_port_type(int p_port) const {
+VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
-String VisualShaderNodeTransformConstruct::get_input_port_name(int p_port) const {
+String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const {
if (p_port == 0) {
return "x";
} else if (p_port == 1) {
@@ -1467,21 +1467,21 @@ String VisualShaderNodeTransformConstruct::get_input_port_name(int p_port) const
}
}
-int VisualShaderNodeTransformConstruct::get_output_port_count() const {
+int VisualShaderNodeTransformCompose::get_output_port_count() const {
return 1;
}
-VisualShaderNodeTransformConstruct::PortType VisualShaderNodeTransformConstruct::get_output_port_type(int p_port) const {
+VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_output_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
-String VisualShaderNodeTransformConstruct::get_output_port_name(int p_port) const {
+String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const {
return "xform";
}
-String VisualShaderNodeTransformConstruct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
return "\t" + p_output_vars[0] + " = mat4( vec4(" + p_input_vars[0] + ", 0.0) , vec4(" + p_input_vars[1] + ", 0.0) , vec4(" + p_input_vars[2] + ",0.0), vec4(" + p_input_vars[3] + ",1.0) );\n";
}
-VisualShaderNodeTransformConstruct::VisualShaderNodeTransformConstruct() {
+VisualShaderNodeTransformCompose::VisualShaderNodeTransformCompose() {
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
@@ -1489,28 +1489,28 @@ VisualShaderNodeTransformConstruct::VisualShaderNodeTransformConstruct() {
set_input_port_default_value(3, Vector3());
}
-////////////// Vector Destruct
-String VisualShaderNodeVectorDestruct::get_caption() const {
- return "VecDestr";
+////////////// Vector Decompose
+String VisualShaderNodeVectorDecompose::get_caption() const {
+ return "VectorDecompose";
}
-int VisualShaderNodeVectorDestruct::get_input_port_count() const {
+int VisualShaderNodeVectorDecompose::get_input_port_count() const {
return 1;
}
-VisualShaderNodeVectorDestruct::PortType VisualShaderNodeVectorDestruct::get_input_port_type(int p_port) const {
+VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
-String VisualShaderNodeVectorDestruct::get_input_port_name(int p_port) const {
+String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const {
return "vec";
}
-int VisualShaderNodeVectorDestruct::get_output_port_count() const {
+int VisualShaderNodeVectorDecompose::get_output_port_count() const {
return 3;
}
-VisualShaderNodeVectorDestruct::PortType VisualShaderNodeVectorDestruct::get_output_port_type(int p_port) const {
+VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeVectorDestruct::get_output_port_name(int p_port) const {
+String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const {
if (p_port == 0) {
return "x";
} else if (p_port == 1) {
@@ -1520,7 +1520,7 @@ String VisualShaderNodeVectorDestruct::get_output_port_name(int p_port) const {
}
}
-String VisualShaderNodeVectorDestruct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+String VisualShaderNodeVectorDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
String code;
code += "\t" + p_output_vars[0] + " = " + p_input_vars[0] + ".x;\n";
code += "\t" + p_output_vars[1] + " = " + p_input_vars[0] + ".y;\n";
@@ -1528,33 +1528,33 @@ String VisualShaderNodeVectorDestruct::generate_code(Shader::Mode p_mode, Visual
return code;
}
-VisualShaderNodeVectorDestruct::VisualShaderNodeVectorDestruct() {
+VisualShaderNodeVectorDecompose::VisualShaderNodeVectorDecompose() {
set_input_port_default_value(0, Vector3());
}
-////////////// Transform Destruct
+////////////// Transform Decompose
-String VisualShaderNodeTransformDestruct::get_caption() const {
- return "TransDestr";
+String VisualShaderNodeTransformDecompose::get_caption() const {
+ return "TransformDecompose";
}
-int VisualShaderNodeTransformDestruct::get_input_port_count() const {
+int VisualShaderNodeTransformDecompose::get_input_port_count() const {
return 1;
}
-VisualShaderNodeTransformDestruct::PortType VisualShaderNodeTransformDestruct::get_input_port_type(int p_port) const {
+VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_input_port_type(int p_port) const {
return PORT_TYPE_TRANSFORM;
}
-String VisualShaderNodeTransformDestruct::get_input_port_name(int p_port) const {
+String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const {
return "xform";
}
-int VisualShaderNodeTransformDestruct::get_output_port_count() const {
+int VisualShaderNodeTransformDecompose::get_output_port_count() const {
return 4;
}
-VisualShaderNodeTransformDestruct::PortType VisualShaderNodeTransformDestruct::get_output_port_type(int p_port) const {
+VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const {
return PORT_TYPE_VECTOR;
}
-String VisualShaderNodeTransformDestruct::get_output_port_name(int p_port) const {
+String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const {
if (p_port == 0) {
return "x";
} else if (p_port == 1) {
@@ -1566,7 +1566,7 @@ String VisualShaderNodeTransformDestruct::get_output_port_name(int p_port) const
}
}
-String VisualShaderNodeTransformDestruct::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
+String VisualShaderNodeTransformDecompose::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const {
String code;
code += "\t" + p_output_vars[0] + " = " + p_input_vars[0] + "[0].xyz;\n";
code += "\t" + p_output_vars[1] + " = " + p_input_vars[0] + "[1].xyz;\n";
@@ -1575,7 +1575,7 @@ String VisualShaderNodeTransformDestruct::generate_code(Shader::Mode p_mode, Vis
return code;
}
-VisualShaderNodeTransformDestruct::VisualShaderNodeTransformDestruct() {
+VisualShaderNodeTransformDecompose::VisualShaderNodeTransformDecompose() {
set_input_port_default_value(0, Transform());
}
@@ -1658,7 +1658,7 @@ VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
////////////// Vector Uniform
String VisualShaderNodeVec3Uniform::get_caption() const {
- return "VecUniform";
+ return "VectorUniform";
}
int VisualShaderNodeVec3Uniform::get_input_port_count() const {
@@ -1694,7 +1694,7 @@ VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
////////////// Transform Uniform
String VisualShaderNodeTransformUniform::get_caption() const {
- return "TransUniform";
+ return "TransformUniform";
}
int VisualShaderNodeTransformUniform::get_input_port_count() const {
@@ -1730,7 +1730,7 @@ VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
////////////// Texture Uniform
String VisualShaderNodeTextureUniform::get_caption() const {
- return "TexUniform";
+ return "TextureUniform";
}
int VisualShaderNodeTextureUniform::get_input_port_count() const {
@@ -1848,7 +1848,7 @@ VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
////////////// CubeMap Uniform
String VisualShaderNodeCubeMapUniform::get_caption() const {
- return "CubeMap";
+ return "CubeMapUniform";
}
int VisualShaderNodeCubeMapUniform::get_input_port_count() const {
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index cf46ee3189..2ede36fbc8 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -621,8 +621,8 @@ public:
///////////////////////////////////////
-class VisualShaderNodeVectorConstruct : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorConstruct, VisualShaderNode)
+class VisualShaderNodeVectorCompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorCompose, VisualShaderNode)
public:
virtual String get_caption() const;
@@ -637,13 +637,13 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeVectorConstruct();
+ VisualShaderNodeVectorCompose();
};
///////////////////////////////////////
-class VisualShaderNodeTransformConstruct : public VisualShaderNode {
- GDCLASS(VisualShaderNodeTransformConstruct, VisualShaderNode)
+class VisualShaderNodeTransformCompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformCompose, VisualShaderNode)
public:
virtual String get_caption() const;
@@ -658,13 +658,13 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeTransformConstruct();
+ VisualShaderNodeTransformCompose();
};
///////////////////////////////////////
-class VisualShaderNodeVectorDestruct : public VisualShaderNode {
- GDCLASS(VisualShaderNodeVectorDestruct, VisualShaderNode)
+class VisualShaderNodeVectorDecompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeVectorDecompose, VisualShaderNode)
public:
virtual String get_caption() const;
@@ -679,13 +679,13 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeVectorDestruct();
+ VisualShaderNodeVectorDecompose();
};
///////////////////////////////////////
-class VisualShaderNodeTransformDestruct : public VisualShaderNode {
- GDCLASS(VisualShaderNodeTransformDestruct, VisualShaderNode)
+class VisualShaderNodeTransformDecompose : public VisualShaderNode {
+ GDCLASS(VisualShaderNodeTransformDecompose, VisualShaderNode)
public:
virtual String get_caption() const;
@@ -700,7 +700,7 @@ public:
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
- VisualShaderNodeTransformDestruct();
+ VisualShaderNodeTransformDecompose();
};
///////////////////////////////////////
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index faabed84e9..a473e0beb2 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -984,10 +984,18 @@ int Physics2DServerSW::body_test_ray_separation(RID p_body, const Transform2D &p
Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
+ if ((using_threads && !doing_sync)) {
+ ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
+ ERR_FAIL_V(NULL);
+ }
+
+ if (!body_owner.owns(p_body))
+ return NULL;
+
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, NULL);
- if ((using_threads && !doing_sync) || body->get_space()->is_locked()) {
+ if (body->get_space()->is_locked()) {
ERR_EXPLAIN("Body state is inaccessible right now, wait for iteration or physics process notification.");
ERR_FAIL_V(NULL);
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 346b04f070..fd1eb77143 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -2545,7 +2545,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
TkPos pos = _get_tkpos();
tk = _get_token();
- if (tk.type == TK_PERIOD) {
+ if (tk.type == TK_CURSOR) {
+ //do nothing
+ } else if (tk.type == TK_PERIOD) {
StringName identifier;
if (_get_completable_identifier(p_block, COMPLETION_INDEX, identifier)) {
@@ -4130,8 +4132,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
switch (completion_type) {
case COMPLETION_NONE: {
- //do none
- return ERR_PARSE_ERROR;
+ //do nothing
+ return OK;
} break;
case COMPLETION_RENDER_MODE: {
for (int i = 0; i < p_render_modes.size(); i++) {