summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/SpriteFrames.xml7
-rw-r--r--editor/connections_dialog.cpp16
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp10
-rw-r--r--main/performance.cpp5
-rw-r--r--main/performance.h1
-rw-r--r--platform/android/export/export.cpp9
-rw-r--r--scene/2d/animated_sprite.cpp12
-rw-r--r--scene/2d/animated_sprite.h1
-rw-r--r--scene/2d/collision_object_2d.cpp25
-rw-r--r--scene/2d/collision_object_2d.h4
-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/register_scene_types.cpp8
-rw-r--r--scene/resources/animation.cpp8
-rwxr-xr-xscene/resources/default_theme/make_header.py26
-rw-r--r--scene/resources/visual_shader_nodes.cpp112
-rw-r--r--scene/resources/visual_shader_nodes.h24
-rw-r--r--servers/audio_server.cpp9
-rw-r--r--servers/audio_server.h5
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp10
-rw-r--r--servers/visual/shader_language.cpp8
22 files changed, 302 insertions, 125 deletions
diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml
index 91129b5850..68373ebc4f 100644
--- a/doc/classes/SpriteFrames.xml
+++ b/doc/classes/SpriteFrames.xml
@@ -127,6 +127,13 @@
Changes the animation's name to [code]newname[/code].
</description>
</method>
+ <method name="get_animation_names">
+ <return type="PoolStringArray">
+ </return>
+ <description>
+ Returns an array containing the names associated to each animation. Values are placed in alphabetical order.
+ </description>
+ </method>
<method name="set_animation_loop">
<return type="void">
</return>
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 7f93917744..8933fd7fe8 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -428,6 +428,13 @@ void ConnectionsDock::_make_or_edit_connection() {
bool oshot = connect_dialog->get_oneshot();
cToMake.flags = CONNECT_PERSIST | (defer ? CONNECT_DEFERRED : 0) | (oshot ? CONNECT_ONESHOT : 0);
+ bool add_script_function = connect_dialog->get_make_callback();
+ PoolStringArray script_function_args;
+ if (add_script_function) {
+ // pick up args here before "it" is deleted by update_tree
+ script_function_args = it->get_metadata(0).operator Dictionary()["args"];
+ }
+
if (connect_dialog->is_editing()) {
_disconnect(*it);
_connect(cToMake);
@@ -435,9 +442,12 @@ void ConnectionsDock::_make_or_edit_connection() {
_connect(cToMake);
}
- if (connect_dialog->get_make_callback()) {
- PoolStringArray args = it->get_metadata(0).operator Dictionary()["args"];
- editor->emit_signal("script_add_function_request", target, cToMake.method, args);
+ // IMPORTANT NOTE: _disconnect and _connect cause an update_tree,
+ // which will delete the object "it" is pointing to
+ it = NULL;
+
+ if (add_script_function) {
+ editor->emit_signal("script_add_function_request", target, cToMake.method, script_function_args);
hide();
}
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/main/performance.cpp b/main/performance.cpp
index fc915e2e76..70e0a5f7aa 100644
--- a/main/performance.cpp
+++ b/main/performance.cpp
@@ -32,6 +32,7 @@
#include "message_queue.h"
#include "os/os.h"
#include "scene/main/scene_tree.h"
+#include "servers/audio_server.h"
#include "servers/physics_2d_server.h"
#include "servers/physics_server.h"
#include "servers/visual_server.h"
@@ -68,6 +69,7 @@ void Performance::_bind_methods() {
BIND_ENUM_CONSTANT(PHYSICS_3D_ACTIVE_OBJECTS);
BIND_ENUM_CONSTANT(PHYSICS_3D_COLLISION_PAIRS);
BIND_ENUM_CONSTANT(PHYSICS_3D_ISLAND_COUNT);
+ BIND_ENUM_CONSTANT(AUDIO_OUTPUT_LATENCY);
BIND_ENUM_CONSTANT(MONITOR_MAX);
}
@@ -104,6 +106,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const {
"physics_3d/active_objects",
"physics_3d/collision_pairs",
"physics_3d/islands",
+ "audio/output_latency",
};
@@ -147,6 +150,7 @@ float Performance::get_monitor(Monitor p_monitor) const {
case PHYSICS_3D_ACTIVE_OBJECTS: return PhysicsServer::get_singleton()->get_process_info(PhysicsServer::INFO_ACTIVE_OBJECTS);
case PHYSICS_3D_COLLISION_PAIRS: return PhysicsServer::get_singleton()->get_process_info(PhysicsServer::INFO_COLLISION_PAIRS);
case PHYSICS_3D_ISLAND_COUNT: return PhysicsServer::get_singleton()->get_process_info(PhysicsServer::INFO_ISLAND_COUNT);
+ case AUDIO_OUTPUT_LATENCY: return AudioServer::get_singleton()->get_output_latency();
default: {}
}
@@ -186,6 +190,7 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const
MONITOR_TYPE_QUANTITY,
MONITOR_TYPE_QUANTITY,
MONITOR_TYPE_QUANTITY,
+ MONITOR_TYPE_TIME,
};
diff --git a/main/performance.h b/main/performance.h
index 464226b517..de00df5ff9 100644
--- a/main/performance.h
+++ b/main/performance.h
@@ -77,6 +77,7 @@ public:
PHYSICS_3D_COLLISION_PAIRS,
PHYSICS_3D_ISLAND_COUNT,
//physics
+ AUDIO_OUTPUT_LATENCY,
MONITOR_MAX
};
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index c3ff157f99..c562a47b00 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -228,7 +228,7 @@ class EditorExportAndroid : public EditorExportPlatform {
};
Vector<Device> devices;
- bool devices_changed;
+ volatile bool devices_changed;
Mutex *device_lock;
Thread *device_thread;
volatile bool quit_request;
@@ -1154,7 +1154,10 @@ public:
virtual bool poll_devices() {
bool dc = devices_changed;
- devices_changed = false;
+ if (dc) {
+ // don't clear unless we're reporting true, to avoid race
+ devices_changed = false;
+ }
return dc;
}
@@ -1857,9 +1860,9 @@ public:
run_icon->create_from_image(img);
device_lock = Mutex::create();
- device_thread = Thread::create(_device_poll_thread, this);
devices_changed = true;
quit_request = false;
+ device_thread = Thread::create(_device_poll_thread, this);
}
~EditorExportAndroid() {
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index e3d1592be0..b56eedabc7 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -192,6 +192,16 @@ void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
}
}
+Vector<String> SpriteFrames::get_animation_names() const {
+
+ Vector<String> names;
+ for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
+ names.push_back(E->key());
+ }
+ names.sort();
+ return names;
+}
+
void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) {
ERR_FAIL_COND(p_fps < 0);
@@ -283,6 +293,8 @@ void SpriteFrames::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation);
ClassDB::bind_method(D_METHOD("rename_animation", "anim", "newname"), &SpriteFrames::rename_animation);
+ ClassDB::bind_method(D_METHOD("get_animation_names"), &SpriteFrames::get_animation_names);
+
ClassDB::bind_method(D_METHOD("set_animation_speed", "anim", "speed"), &SpriteFrames::set_animation_speed);
ClassDB::bind_method(D_METHOD("get_animation_speed", "anim"), &SpriteFrames::get_animation_speed);
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index 806052a696..f6586aff36 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -72,6 +72,7 @@ public:
void rename_animation(const StringName &p_prev, const StringName &p_next);
void get_animation_list(List<StringName> *r_animations) const;
+ Vector<String> get_animation_names() const;
void set_animation_speed(const StringName &p_anim, float p_fps);
float get_animation_speed(const StringName &p_anim) const;
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/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/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/animation.cpp b/scene/resources/animation.cpp
index e57a2b68c8..8acfdc482a 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -2329,13 +2329,14 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
int iterations = 10;
- float low = 0;
- float high = bt->values[idx + 1].time - bt->values[idx].time;
+ float duration = bt->values[idx + 1].time - bt->values[idx].time; // time duration between our two keyframes
+ float low = 0; // 0% of the current animation segment
+ float high = 1; // 100% of the current animation segment
float middle = 0;
Vector2 start(0, bt->values[idx].value.value);
Vector2 start_out = start + bt->values[idx].value.out_handle;
- Vector2 end(high, bt->values[idx + 1].value.value);
+ Vector2 end(duration, bt->values[idx + 1].value.value);
Vector2 end_in = end + bt->values[idx + 1].value.in_handle;
//narrow high and low as much as possible
@@ -2355,7 +2356,6 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
//interpolate the result:
Vector2 low_pos = _bezier_interp(low, start, start_out, end_in, end);
Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end);
-
float c = (t - low_pos.x) / (high_pos.x - low_pos.x);
return low_pos.linear_interpolate(high_pos, c).y;
diff --git a/scene/resources/default_theme/make_header.py b/scene/resources/default_theme/make_header.py
index db449f9417..73b1ae0b0b 100755
--- a/scene/resources/default_theme/make_header.py
+++ b/scene/resources/default_theme/make_header.py
@@ -4,15 +4,16 @@ import os
import glob
import string
+enc = "utf-8"
# Generate include files
f = open("theme_data.h", "wb")
-f.write("// THIS FILE HAS BEEN AUTOGENERATED, DON'T EDIT!!\n")
+f.write(b"// THIS FILE HAS BEEN AUTOGENERATED, DON\'T EDIT!!\n")
# Generate png image block
-f.write("\n// png image block\n");
+f.write(b"\n// png image block\n")
pixmaps = glob.glob("*.png")
pixmaps.sort()
@@ -21,22 +22,23 @@ for x in pixmaps:
var_str = x[:-4] + "_png"
- f.write("\nstatic const unsigned char " + var_str + "[] = {\n\t")
+ s = "\nstatic const unsigned char " + var_str + "[] = {\n\t"
+ f.write(s.encode(enc))
pngf = open(x, "rb")
b = pngf.read(1)
while(len(b) == 1):
- f.write(hex(ord(b)))
+ f.write(hex(ord(b)).encode(enc))
b = pngf.read(1)
if (len(b) == 1):
- f.write(", ")
+ f.write(b", ")
- f.write("\n};\n")
+ f.write(b"\n};\n")
pngf.close()
# Generate shaders block
-f.write("\n// shaders block\n");
+f.write(b"\n// shaders block\n");
shaders = glob.glob("*.gsl")
shaders.sort()
@@ -45,7 +47,8 @@ for x in shaders:
var_str = x[:-4] + "_shader_code"
- f.write("\nstatic const char *" + var_str + " = \n")
+ s = "\nstatic const char *" + var_str + " = \n"
+ f.write(s.encode(enc))
sf = open(x, "rb")
@@ -55,12 +58,13 @@ for x in shaders:
b = b[:-2]
if (b.endswith("\n")):
b = b[:-1]
- f.write(" \"" + b)
+ s = ' \"' + b
+ f.write(s.encode(enc))
b = sf.readline()
if (b != ""):
- f.write("\"\n")
+ f.write(b'"\n')
- f.write("\";\n")
+ f.write(b'";\n')
sf.close()
f.close()
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/audio_server.cpp b/servers/audio_server.cpp
index f2df7119e7..69c1318a48 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -234,6 +234,13 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
todo -= to_copy;
to_mix -= to_copy;
}
+
+ // Calculate latency for Performance.AUDIO_OUTPUT_LATENCY
+ if (OS::get_singleton()) {
+ uint64_t ticks = OS::get_singleton()->get_ticks_usec();
+ output_latency = (ticks - output_latency_ticks) / 1000000.f;
+ output_latency_ticks = ticks;
+ }
}
void AudioServer::_mix_step() {
@@ -1178,6 +1185,8 @@ AudioServer::AudioServer() {
mix_frames = 0;
channel_count = 0;
to_mix = 0;
+ output_latency = 0;
+ output_latency_ticks = 0;
}
AudioServer::~AudioServer() {
diff --git a/servers/audio_server.h b/servers/audio_server.h
index b7fcd9c093..f928acc7b5 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -190,6 +190,9 @@ private:
Mutex *audio_data_lock;
+ float output_latency;
+ uint64_t output_latency_ticks;
+
void init_channels_and_buffers();
void _mix_step();
@@ -306,6 +309,8 @@ public:
String get_device();
void set_device(String device);
+ float get_output_latency() { return output_latency; }
+
AudioServer();
virtual ~AudioServer();
};
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++) {