summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/input/input.cpp10
-rw-r--r--core/os/os.cpp1
-rw-r--r--core/string/translation.cpp1
-rw-r--r--doc/classes/Camera3D.xml8
-rw-r--r--doc/classes/ClippedCamera3D.xml93
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp41
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp11
-rw-r--r--modules/gdscript/gdscript_editor.cpp28
-rw-r--r--modules/gdscript/gdscript_parser.cpp4
-rw-r--r--scene/3d/camera_3d.cpp244
-rw-r--r--scene/3d/camera_3d.h64
-rw-r--r--scene/3d/spring_arm_3d.cpp32
-rw-r--r--scene/animation/animation_player.cpp9
-rw-r--r--scene/gui/control.cpp10
-rw-r--r--scene/gui/tabs.cpp1
-rw-r--r--scene/main/node.cpp12
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/material.cpp13
18 files changed, 100 insertions, 483 deletions
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 05b02408a1..f9a361c761 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -35,10 +35,6 @@
#include "core/input/input_map.h"
#include "core/os/os.h"
-#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
-#endif
-
static const char *_joy_buttons[JOY_BUTTON_SDL_MAX] = {
"a",
"b",
@@ -162,9 +158,6 @@ void Input::_bind_methods() {
}
void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-
String pf = p_function;
if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" ||
pf == "is_action_just_pressed" || pf == "is_action_just_released" ||
@@ -179,10 +172,9 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
}
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
- r_options->push_back(name.quote(quote_style));
+ r_options->push_back(name.quote());
}
}
-#endif
}
void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 69366f688c..12f85858c3 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -36,7 +36,6 @@
#include "core/io/file_access.h"
#include "core/os/midi_driver.h"
#include "core/version_generated.gen.h"
-#include "servers/audio_server.h"
#include <stdarg.h>
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index 5e3b8297aa..37dc8915ab 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -35,7 +35,6 @@
#include "core/os/os.h"
#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
#include "main/main.h"
#endif
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index cd17a31e23..06e2f83f05 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -26,7 +26,7 @@
<method name="get_camera_transform" qualifiers="const">
<return type="Transform3D" />
<description>
- Returns the transform of the camera plus the vertical ([member v_offset]) and horizontal ([member h_offset]) offsets; and any other adjustments made to the position and orientation of the camera by subclassed cameras such as [ClippedCamera3D] and [XRCamera3D].
+ Returns the transform of the camera plus the vertical ([member v_offset]) and horizontal ([member h_offset]) offsets; and any other adjustments made to the position and orientation of the camera by subclassed cameras such as [XRCamera3D].
</description>
</method>
<method name="get_cull_mask_value" qualifiers="const">
@@ -42,6 +42,12 @@
Returns the camera's frustum planes in world space units as an array of [Plane]s in the following order: near, far, left, top, right, bottom. Not to be confused with [member frustum_offset].
</description>
</method>
+ <method name="get_pyramid_shape_rid">
+ <return type="RID" />
+ <description>
+ Returns the RID of a pyramid shape encompassing the camera's view frustum, ignoring the camera's near plane. The tip of the pyramid represents the position of the camera.
+ </description>
+ </method>
<method name="is_position_behind" qualifiers="const">
<return type="bool" />
<argument index="0" name="world_point" type="Vector3" />
diff --git a/doc/classes/ClippedCamera3D.xml b/doc/classes/ClippedCamera3D.xml
deleted file mode 100644
index 1a0d3499cd..0000000000
--- a/doc/classes/ClippedCamera3D.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ClippedCamera3D" inherits="Camera3D" version="4.0">
- <brief_description>
- A [Camera3D] that includes collision.
- </brief_description>
- <description>
- This node extends [Camera3D] to add collisions with [Area3D] and/or [PhysicsBody3D] nodes. The camera cannot move through colliding objects.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- <method name="add_exception">
- <return type="void" />
- <argument index="0" name="node" type="Object" />
- <description>
- Adds a collision exception so the camera does not collide with the specified node.
- </description>
- </method>
- <method name="add_exception_rid">
- <return type="void" />
- <argument index="0" name="rid" type="RID" />
- <description>
- Adds a collision exception so the camera does not collide with the specified [RID].
- </description>
- </method>
- <method name="clear_exceptions">
- <return type="void" />
- <description>
- Removes all collision exceptions.
- </description>
- </method>
- <method name="get_clip_offset" qualifiers="const">
- <return type="float" />
- <description>
- Returns the distance the camera has been offset due to a collision.
- </description>
- </method>
- <method name="get_collision_mask_value" qualifiers="const">
- <return type="bool" />
- <argument index="0" name="layer_number" type="int" />
- <description>
- Returns whether or not the specified layer of the [member collision_mask] is enabled, given a [code]layer_number[/code] between 1 and 32.
- </description>
- </method>
- <method name="remove_exception">
- <return type="void" />
- <argument index="0" name="node" type="Object" />
- <description>
- Removes a collision exception with the specified node.
- </description>
- </method>
- <method name="remove_exception_rid">
- <return type="void" />
- <argument index="0" name="rid" type="RID" />
- <description>
- Removes a collision exception with the specified [RID].
- </description>
- </method>
- <method name="set_collision_mask_value">
- <return type="void" />
- <argument index="0" name="layer_number" type="int" />
- <argument index="1" name="value" type="bool" />
- <description>
- Based on [code]value[/code], enables or disables the specified layer in the [member collision_mask], given a [code]layer_number[/code] between 1 and 32.
- </description>
- </method>
- </methods>
- <members>
- <member name="clip_to_areas" type="bool" setter="set_clip_to_areas" getter="is_clip_to_areas_enabled" default="false">
- If [code]true[/code], the camera stops on contact with [Area3D]s.
- </member>
- <member name="clip_to_bodies" type="bool" setter="set_clip_to_bodies" getter="is_clip_to_bodies_enabled" default="true">
- If [code]true[/code], the camera stops on contact with [PhysicsBody3D]s.
- </member>
- <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1">
- The camera's collision mask. Only objects in at least one collision layer matching the mask will be detected. See [url=https://docs.godotengine.org/en/latest/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information.
- </member>
- <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.0">
- The camera's collision margin. The camera can't get closer than this distance to a colliding object.
- </member>
- <member name="process_callback" type="int" setter="set_process_callback" getter="get_process_callback" enum="ClippedCamera3D.ClipProcessCallback" default="0">
- The camera's process callback. See [enum ClipProcessCallback].
- </member>
- </members>
- <constants>
- <constant name="CLIP_PROCESS_PHYSICS" value="0" enum="ClipProcessCallback">
- The camera updates with the [code]_physics_process[/code] callback.
- </constant>
- <constant name="CLIP_PROCESS_IDLE" value="1" enum="ClipProcessCallback">
- The camera updates with the [code]_process[/code] callback.
- </constant>
- </constants>
-</class>
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index fb92359818..7b0fc07fe7 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -1840,47 +1840,6 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_lines(lines, material);
p_gizmo->add_handles(handles, get_material("handles"));
-
- ClippedCamera3D *clipcam = Object::cast_to<ClippedCamera3D>(camera);
- if (clipcam) {
- Node3D *parent = Object::cast_to<Node3D>(camera->get_parent());
- if (!parent) {
- return;
- }
- Vector3 cam_normal = -camera->get_global_transform().basis.get_axis(Vector3::AXIS_Z).normalized();
- Vector3 cam_x = camera->get_global_transform().basis.get_axis(Vector3::AXIS_X).normalized();
- Vector3 cam_y = camera->get_global_transform().basis.get_axis(Vector3::AXIS_Y).normalized();
- Vector3 cam_pos = camera->get_global_transform().origin;
- Vector3 parent_pos = parent->get_global_transform().origin;
-
- Plane parent_plane(parent_pos, cam_normal);
- Vector3 ray_from = parent_plane.project(cam_pos);
-
- lines.clear();
- lines.push_back(ray_from + cam_x * 0.5 + cam_y * 0.5);
- lines.push_back(ray_from + cam_x * 0.5 + cam_y * -0.5);
-
- lines.push_back(ray_from + cam_x * 0.5 + cam_y * -0.5);
- lines.push_back(ray_from + cam_x * -0.5 + cam_y * -0.5);
-
- lines.push_back(ray_from + cam_x * -0.5 + cam_y * -0.5);
- lines.push_back(ray_from + cam_x * -0.5 + cam_y * 0.5);
-
- lines.push_back(ray_from + cam_x * -0.5 + cam_y * 0.5);
- lines.push_back(ray_from + cam_x * 0.5 + cam_y * 0.5);
-
- if (parent_plane.distance_to(cam_pos) < 0) {
- lines.push_back(ray_from);
- lines.push_back(cam_pos);
- }
-
- Transform3D local = camera->get_global_transform().affine_inverse();
- for (int i = 0; i < lines.size(); i++) {
- lines.write[i] = local.xform(lines[i]);
- }
-
- p_gizmo->add_lines(lines, material);
- }
}
//////
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index c35af9ca5b..ac031baa8c 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1035,7 +1035,10 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode *
return_type.is_meta_type = false;
p_function->set_datatype(return_type);
if (p_function->return_type) {
- push_error("Constructor cannot have an explicit return type.", p_function->return_type);
+ GDScriptParser::DataType declared_return = resolve_datatype(p_function->return_type);
+ if (declared_return.kind != GDScriptParser::DataType::BUILTIN || declared_return.builtin_type != Variant::NIL) {
+ push_error("Constructor cannot have an explicit return type.", p_function->return_type);
+ }
}
} else {
GDScriptParser::DataType return_type = resolve_datatype(p_function->return_type);
@@ -1198,7 +1201,7 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
variable_type.kind = GDScriptParser::DataType::BUILTIN;
variable_type.builtin_type = Variant::INT; // Can this ever be a float or something else?
p_for->variable->set_datatype(variable_type);
- } else {
+ } else if (p_for->list) {
resolve_node(p_for->list);
if (p_for->list->datatype.has_container_element_type()) {
variable_type = p_for->list->datatype.get_container_element_type();
@@ -1213,7 +1216,9 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
variable_type.kind = GDScriptParser::DataType::VARIANT;
}
}
- p_for->variable->set_datatype(variable_type);
+ if (p_for->variable) {
+ p_for->variable->set_datatype(variable_type);
+ }
resolve_suite(p_for->loop);
p_for->set_datatype(p_for->loop->get_datatype());
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 83805f626a..e49bf518a2 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2222,8 +2222,11 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
if (obj) {
List<String> options;
obj->get_argument_options(p_method, p_argidx, &options);
- for (const String &F : options) {
- ScriptCodeCompletionOption option(F, ScriptCodeCompletionOption::KIND_FUNCTION);
+ for (String &opt : options) {
+ if (opt.is_quoted()) {
+ opt = opt.unquote().quote(quote_style); // Handle user preference.
+ }
+ ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_FUNCTION);
r_result.insert(option.display, option);
}
}
@@ -2643,23 +2646,26 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
}
} break;
case GDScriptParser::COMPLETION_GET_NODE: {
+ // Handles the `$Node/Path` or `$"Some NodePath"` syntax specifically.
if (p_owner) {
List<String> opts;
p_owner->get_argument_options("get_node", 0, &opts);
for (const String &E : opts) {
+ r_forced = true;
String opt = E.strip_edges();
if (opt.is_quoted()) {
- r_forced = true;
- String idopt = opt.unquote();
- if (idopt.replace("/", "_").is_valid_identifier()) {
- ScriptCodeCompletionOption option(idopt, ScriptCodeCompletionOption::KIND_NODE_PATH);
- options.insert(option.display, option);
- } else {
- ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_NODE_PATH);
- options.insert(option.display, option);
- }
+ // Remove quotes so that we can handle user preferred quote style,
+ // or handle NodePaths which are valid identifiers and don't need quotes.
+ opt = opt.unquote();
}
+ // The path needs quotes if it's not a valid identifier (with an exception
+ // for "/" as path separator, which also doesn't require quotes).
+ if (!opt.replace("/", "_").is_valid_identifier()) {
+ opt = opt.quote(quote_style); // Handle user preference.
+ }
+ ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_NODE_PATH);
+ options.insert(option.display, option);
}
// Get autoloads.
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 63817e970a..ad75e8174c 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1620,6 +1620,10 @@ GDScriptParser::ForNode *GDScriptParser::parse_for() {
n_for->list = parse_expression(false);
+ if (!n_for->list) {
+ push_error(R"(Expected a list or range after "in".)");
+ }
+
consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "for" condition.)");
// Save break/continue state.
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 9aad338d15..61d73ff1e2 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -492,6 +492,7 @@ void Camera3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_frustum"), &Camera3D::get_frustum);
ClassDB::bind_method(D_METHOD("is_position_in_frustum", "world_point"), &Camera3D::is_position_in_frustum);
ClassDB::bind_method(D_METHOD("get_camera_rid"), &Camera3D::get_camera);
+ ClassDB::bind_method(D_METHOD("get_pyramid_shape_rid"), &Camera3D::get_pyramid_shape_rid);
ClassDB::bind_method(D_METHOD("set_cull_mask_value", "layer_number", "value"), &Camera3D::set_cull_mask_value);
ClassDB::bind_method(D_METHOD("get_cull_mask_value", "layer_number"), &Camera3D::get_cull_mask_value);
@@ -654,233 +655,46 @@ Vector3 Camera3D::get_doppler_tracked_velocity() const {
}
}
-Camera3D::Camera3D() {
- camera = RenderingServer::get_singleton()->camera_create();
- set_perspective(75.0, 0.05, 4000.0);
- RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers);
- //active=false;
- velocity_tracker.instantiate();
- set_notify_transform(true);
- set_disable_scale(true);
-}
-
-Camera3D::~Camera3D() {
- RenderingServer::get_singleton()->free(camera);
-}
+RID Camera3D::get_pyramid_shape_rid() {
+ if (pyramid_shape == RID()) {
+ pyramid_shape_points = get_near_plane_points();
+ pyramid_shape = PhysicsServer3D::get_singleton()->convex_polygon_shape_create();
+ PhysicsServer3D::get_singleton()->shape_set_data(pyramid_shape, pyramid_shape_points);
-////////////////////////////////////////
+ } else { //check if points changed
+ Vector<Vector3> local_points = get_near_plane_points();
-void ClippedCamera3D::set_margin(real_t p_margin) {
- margin = p_margin;
-}
-
-real_t ClippedCamera3D::get_margin() const {
- return margin;
-}
-
-void ClippedCamera3D::set_process_callback(ClipProcessCallback p_mode) {
- if (process_callback == p_mode) {
- return;
- }
- process_callback = p_mode;
- set_process_internal(process_callback == CLIP_PROCESS_IDLE);
- set_physics_process_internal(process_callback == CLIP_PROCESS_PHYSICS);
-}
-
-ClippedCamera3D::ClipProcessCallback ClippedCamera3D::get_process_callback() const {
- return process_callback;
-}
-
-Transform3D ClippedCamera3D::get_camera_transform() const {
- Transform3D t = Camera3D::get_camera_transform();
- t.origin += -t.basis.get_axis(Vector3::AXIS_Z).normalized() * clip_offset;
- return t;
-}
-
-void ClippedCamera3D::_notification(int p_what) {
- if (p_what == NOTIFICATION_INTERNAL_PROCESS || p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
- Node3D *parent = Object::cast_to<Node3D>(get_parent());
- if (!parent) {
- return;
- }
+ bool all_equal = true;
- PhysicsDirectSpaceState3D *dspace = get_world_3d()->get_direct_space_state();
- ERR_FAIL_COND(!dspace); // most likely physics set to threads
-
- Vector3 cam_fw = -get_global_transform().basis.get_axis(Vector3::AXIS_Z).normalized();
- Vector3 cam_pos = get_global_transform().origin;
- Vector3 parent_pos = parent->get_global_transform().origin;
-
- Plane parent_plane(parent_pos, cam_fw);
-
- if (parent_plane.is_point_over(cam_pos)) {
- //cam is beyond parent plane
- return;
- }
-
- Vector3 ray_from = parent_plane.project(cam_pos);
-
- clip_offset = 0; //reset by default
-
- { //check if points changed
- Vector<Vector3> local_points = get_near_plane_points();
-
- bool all_equal = true;
-
- for (int i = 0; i < 5; i++) {
- if (points[i] != local_points[i]) {
- all_equal = false;
- break;
- }
- }
-
- if (!all_equal) {
- PhysicsServer3D::get_singleton()->shape_set_data(pyramid_shape, local_points);
- points = local_points;
+ for (int i = 0; i < 5; i++) {
+ if (local_points[i] != pyramid_shape_points[i]) {
+ all_equal = false;
+ break;
}
}
- Transform3D xf = get_global_transform();
- xf.origin = ray_from;
- xf.orthonormalize();
-
- real_t closest_safe = 1.0f, closest_unsafe = 1.0f;
- if (dspace->cast_motion(pyramid_shape, xf, cam_pos - ray_from, margin, closest_safe, closest_unsafe, exclude, collision_mask, clip_to_bodies, clip_to_areas)) {
- clip_offset = cam_pos.distance_to(ray_from + (cam_pos - ray_from) * closest_safe);
+ if (!all_equal) {
+ PhysicsServer3D::get_singleton()->shape_set_data(pyramid_shape, local_points);
+ pyramid_shape_points = local_points;
}
-
- _update_camera();
- }
-
- if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
- update_gizmos();
}
-}
-
-void ClippedCamera3D::set_collision_mask(uint32_t p_mask) {
- collision_mask = p_mask;
-}
-uint32_t ClippedCamera3D::get_collision_mask() const {
- return collision_mask;
+ return pyramid_shape;
}
-void ClippedCamera3D::set_collision_mask_value(int p_layer_number, bool p_value) {
- ERR_FAIL_COND_MSG(p_layer_number < 1, "Collision layer number must be between 1 and 32 inclusive.");
- ERR_FAIL_COND_MSG(p_layer_number > 32, "Collision layer number must be between 1 and 32 inclusive.");
- uint32_t mask = get_collision_mask();
- if (p_value) {
- mask |= 1 << (p_layer_number - 1);
- } else {
- mask &= ~(1 << (p_layer_number - 1));
- }
- set_collision_mask(mask);
-}
-
-bool ClippedCamera3D::get_collision_mask_value(int p_layer_number) const {
- ERR_FAIL_COND_V_MSG(p_layer_number < 1, false, "Collision layer number must be between 1 and 32 inclusive.");
- ERR_FAIL_COND_V_MSG(p_layer_number > 32, false, "Collision layer number must be between 1 and 32 inclusive.");
- return get_collision_mask() & (1 << (p_layer_number - 1));
-}
-
-void ClippedCamera3D::add_exception_rid(const RID &p_rid) {
- exclude.insert(p_rid);
-}
-
-void ClippedCamera3D::add_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co) {
- return;
- }
- add_exception_rid(co->get_rid());
-}
-
-void ClippedCamera3D::remove_exception_rid(const RID &p_rid) {
- exclude.erase(p_rid);
+Camera3D::Camera3D() {
+ camera = RenderingServer::get_singleton()->camera_create();
+ set_perspective(75.0, 0.05, 4000.0);
+ RenderingServer::get_singleton()->camera_set_cull_mask(camera, layers);
+ //active=false;
+ velocity_tracker.instantiate();
+ set_notify_transform(true);
+ set_disable_scale(true);
}
-void ClippedCamera3D::remove_exception(const Object *p_object) {
- ERR_FAIL_NULL(p_object);
- const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co) {
- return;
+Camera3D::~Camera3D() {
+ RenderingServer::get_singleton()->free(camera);
+ if (pyramid_shape.is_valid()) {
+ PhysicsServer3D::get_singleton()->free(pyramid_shape);
}
- remove_exception_rid(co->get_rid());
-}
-
-void ClippedCamera3D::clear_exceptions() {
- exclude.clear();
-}
-
-real_t ClippedCamera3D::get_clip_offset() const {
- return clip_offset;
-}
-
-void ClippedCamera3D::set_clip_to_areas(bool p_clip) {
- clip_to_areas = p_clip;
-}
-
-bool ClippedCamera3D::is_clip_to_areas_enabled() const {
- return clip_to_areas;
-}
-
-void ClippedCamera3D::set_clip_to_bodies(bool p_clip) {
- clip_to_bodies = p_clip;
-}
-
-bool ClippedCamera3D::is_clip_to_bodies_enabled() const {
- return clip_to_bodies;
-}
-
-void ClippedCamera3D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera3D::set_margin);
- ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera3D::get_margin);
-
- ClassDB::bind_method(D_METHOD("set_process_callback", "process_callback"), &ClippedCamera3D::set_process_callback);
- ClassDB::bind_method(D_METHOD("get_process_callback"), &ClippedCamera3D::get_process_callback);
-
- ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &ClippedCamera3D::set_collision_mask);
- ClassDB::bind_method(D_METHOD("get_collision_mask"), &ClippedCamera3D::get_collision_mask);
-
- ClassDB::bind_method(D_METHOD("set_collision_mask_value", "layer_number", "value"), &ClippedCamera3D::set_collision_mask_value);
- ClassDB::bind_method(D_METHOD("get_collision_mask_value", "layer_number"), &ClippedCamera3D::get_collision_mask_value);
-
- ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &ClippedCamera3D::add_exception_rid);
- ClassDB::bind_method(D_METHOD("add_exception", "node"), &ClippedCamera3D::add_exception);
-
- ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &ClippedCamera3D::remove_exception_rid);
- ClassDB::bind_method(D_METHOD("remove_exception", "node"), &ClippedCamera3D::remove_exception);
-
- ClassDB::bind_method(D_METHOD("set_clip_to_areas", "enable"), &ClippedCamera3D::set_clip_to_areas);
- ClassDB::bind_method(D_METHOD("is_clip_to_areas_enabled"), &ClippedCamera3D::is_clip_to_areas_enabled);
-
- ClassDB::bind_method(D_METHOD("get_clip_offset"), &ClippedCamera3D::get_clip_offset);
-
- ClassDB::bind_method(D_METHOD("set_clip_to_bodies", "enable"), &ClippedCamera3D::set_clip_to_bodies);
- ClassDB::bind_method(D_METHOD("is_clip_to_bodies_enabled"), &ClippedCamera3D::is_clip_to_bodies_enabled);
-
- ClassDB::bind_method(D_METHOD("clear_exceptions"), &ClippedCamera3D::clear_exceptions);
-
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_margin", "get_margin");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "process_callback", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_callback", "get_process_callback");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
-
- ADD_GROUP("Clip To", "clip_to");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_areas", "is_clip_to_areas_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_to_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_clip_to_bodies", "is_clip_to_bodies_enabled");
-
- BIND_ENUM_CONSTANT(CLIP_PROCESS_PHYSICS);
- BIND_ENUM_CONSTANT(CLIP_PROCESS_IDLE);
-}
-
-ClippedCamera3D::ClippedCamera3D() {
- set_physics_process_internal(true);
- set_notify_local_transform(Engine::get_singleton()->is_editor_hint());
- points.resize(5);
- pyramid_shape = PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONVEX_POLYGON);
-}
-
-ClippedCamera3D::~ClippedCamera3D() {
- PhysicsServer3D::get_singleton()->free(pyramid_shape);
}
diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h
index c1af7fa4f7..6006a2ea3f 100644
--- a/scene/3d/camera_3d.h
+++ b/scene/3d/camera_3d.h
@@ -86,6 +86,9 @@ private:
DopplerTracking doppler_tracking = DOPPLER_TRACKING_DISABLED;
Ref<VelocityTracker3D> velocity_tracker;
+ RID pyramid_shape;
+ Vector<Vector3> pyramid_shape_points;
+
protected:
void _update_camera();
virtual void _request_camera_update();
@@ -168,6 +171,8 @@ public:
Vector3 get_doppler_tracked_velocity() const;
+ RID get_pyramid_shape_rid();
+
Camera3D();
~Camera3D();
};
@@ -176,63 +181,4 @@ VARIANT_ENUM_CAST(Camera3D::Projection);
VARIANT_ENUM_CAST(Camera3D::KeepAspect);
VARIANT_ENUM_CAST(Camera3D::DopplerTracking);
-class ClippedCamera3D : public Camera3D {
- GDCLASS(ClippedCamera3D, Camera3D);
-
-public:
- enum ClipProcessCallback {
- CLIP_PROCESS_PHYSICS,
- CLIP_PROCESS_IDLE,
- };
-
-private:
- ClipProcessCallback process_callback = CLIP_PROCESS_PHYSICS;
- RID pyramid_shape;
- real_t margin = 0.0;
- real_t clip_offset = 0.0;
- uint32_t collision_mask = 1;
- bool clip_to_areas = false;
- bool clip_to_bodies = true;
-
- Set<RID> exclude;
-
- Vector<Vector3> points;
-
-protected:
- void _notification(int p_what);
- static void _bind_methods();
- virtual Transform3D get_camera_transform() const override;
-
-public:
- void set_clip_to_areas(bool p_clip);
- bool is_clip_to_areas_enabled() const;
-
- void set_clip_to_bodies(bool p_clip);
- bool is_clip_to_bodies_enabled() const;
-
- void set_margin(real_t p_margin);
- real_t get_margin() const;
-
- void set_process_callback(ClipProcessCallback p_mode);
- ClipProcessCallback get_process_callback() const;
-
- void set_collision_mask(uint32_t p_mask);
- uint32_t get_collision_mask() const;
-
- void set_collision_mask_value(int p_layer_number, bool p_value);
- bool get_collision_mask_value(int p_layer_number) const;
-
- void add_exception_rid(const RID &p_rid);
- void add_exception(const Object *p_object);
- void remove_exception_rid(const RID &p_rid);
- void remove_exception(const Object *p_object);
- void clear_exceptions();
-
- real_t get_clip_offset() const;
-
- ClippedCamera3D();
- ~ClippedCamera3D();
-};
-
-VARIANT_ENUM_CAST(ClippedCamera3D::ClipProcessCallback);
#endif
diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp
index 4748a9d889..116cab19b1 100644
--- a/scene/3d/spring_arm_3d.cpp
+++ b/scene/3d/spring_arm_3d.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "spring_arm_3d.h"
+#include "scene/3d/camera_3d.h"
void SpringArm3D::_notification(int p_what) {
switch (p_what) {
@@ -133,17 +134,32 @@ void SpringArm3D::process_spring() {
Vector3 motion;
const Vector3 cast_direction(get_global_transform().basis.xform(Vector3(0, 0, 1)));
+ motion = Vector3(cast_direction * (spring_length));
+
if (shape.is_null()) {
- motion = Vector3(cast_direction * (spring_length));
- PhysicsDirectSpaceState3D::RayResult r;
- bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
- if (intersected) {
- real_t dist = get_global_transform().origin.distance_to(r.position);
- dist -= margin;
- motion_delta = dist / (spring_length);
+ Camera3D *camera = nullptr;
+ for (int i = get_child_count() - 1; 0 <= i; --i) {
+ camera = Object::cast_to<Camera3D>(get_child(i));
+ if (camera) {
+ break;
+ }
+ }
+
+ if (camera != nullptr) {
+ //use camera rotation, but spring arm position
+ Transform3D base_transform = camera->get_global_transform();
+ base_transform.origin = get_global_transform().origin;
+ get_world_3d()->get_direct_space_state()->cast_motion(camera->get_pyramid_shape_rid(), base_transform, motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask);
+ } else {
+ PhysicsDirectSpaceState3D::RayResult r;
+ bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
+ if (intersected) {
+ real_t dist = get_global_transform().origin.distance_to(r.position);
+ dist -= margin;
+ motion_delta = dist / (spring_length);
+ }
}
} else {
- motion = Vector3(cast_direction * spring_length);
get_world_3d()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask);
}
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index a8d46eac6e..2c8c4ee788 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -37,7 +37,6 @@
#ifdef TOOLS_ENABLED
#include "editor/editor_node.h"
-#include "editor/editor_settings.h"
#include "scene/2d/skeleton_2d.h"
void AnimatedValuesBackup::update_skeletons() {
@@ -1493,18 +1492,12 @@ NodePath AnimationPlayer::get_root() const {
}
void AnimationPlayer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-#else
- const String quote_style = "\"";
-#endif
-
String pf = p_function;
if (p_idx == 0 && (p_function == "play" || p_function == "play_backwards" || p_function == "remove_animation" || p_function == "has_animation" || p_function == "queue")) {
List<StringName> al;
get_animation_list(&al);
for (const StringName &name : al) {
- r_options->push_back(String(name).quote(quote_style));
+ r_options->push_back(String(name).quote());
}
}
Node::get_argument_options(p_function, p_idx, r_options);
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index e2d3807b40..38da40a402 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -38,7 +38,6 @@
#include "core/os/os.h"
#include "core/string/print_string.h"
#include "core/string/translation.h"
-
#include "scene/gui/label.h"
#include "scene/gui/panel.h"
#include "scene/main/canvas_layer.h"
@@ -48,7 +47,6 @@
#include "servers/text_server.h"
#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
#endif
@@ -2762,12 +2760,6 @@ bool Control::is_visibility_clip_disabled() const {
}
void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-#else
- const String quote_style = "\"";
-#endif
-
Node::get_argument_options(p_function, p_idx, r_options);
if (p_idx == 0) {
@@ -2787,7 +2779,7 @@ void Control::get_argument_options(const StringName &p_function, int p_idx, List
sn.sort_custom<StringName::AlphCompare>();
for (const StringName &name : sn) {
- r_options->push_back(String(name).quote(quote_style));
+ r_options->push_back(String(name).quote());
}
}
}
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index ba8dba847c..f305bf7013 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -156,6 +156,7 @@ void Tabs::gui_input(const Ref<InputEvent> &p_event) {
if (scrolling_enabled && buttons_visible) {
if (missing_right) {
offset++;
+ _ensure_no_over_offset(); // Avoid overreaching when scrolling fast.
update();
}
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index b1ba9de85c..0876c30dd1 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -41,10 +41,6 @@
#include "scene/scene_string_names.h"
#include "viewport.h"
-#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
-#endif
-
#include <stdint.h>
VARIANT_ENUM_CAST(Node::ProcessMode);
@@ -2536,17 +2532,11 @@ NodePath Node::get_import_path() const {
}
static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-#else
- const String quote_style = "\"";
-#endif
-
if (p_node != p_base && !p_node->get_owner()) {
return;
}
String n = p_base->get_path_to(p_node);
- r_options->push_back(n.quote(quote_style));
+ r_options->push_back(n.quote());
for (int i = 0; i < p_node->get_child_count(); i++) {
_add_nodes_to_options(p_base, p_node->get_child(i), r_options);
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 4a82010833..bf8f7291be 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -448,7 +448,6 @@ void register_scene_types() {
GDREGISTER_VIRTUAL_CLASS(VisualInstance3D);
GDREGISTER_VIRTUAL_CLASS(GeometryInstance3D);
GDREGISTER_CLASS(Camera3D);
- GDREGISTER_CLASS(ClippedCamera3D);
GDREGISTER_CLASS(AudioListener3D);
GDREGISTER_CLASS(XRCamera3D);
GDREGISTER_CLASS(XRController3D);
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 3a6af3afb0..08851dbc58 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -32,11 +32,6 @@
#include "core/config/engine.h"
#include "core/version.h"
-
-#ifdef TOOLS_ENABLED
-#include "editor/editor_settings.h"
-#endif
-
#include "scene/main/scene_tree.h"
#include "scene/scene_string_names.h"
@@ -268,19 +263,13 @@ void ShaderMaterial::_bind_methods() {
}
void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-#ifdef TOOLS_ENABLED
- const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
-#else
- const String quote_style = "\"";
-#endif
-
String f = p_function.operator String();
if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
if (shader.is_valid()) {
List<PropertyInfo> pl;
shader->get_param_list(&pl);
for (const PropertyInfo &E : pl) {
- r_options->push_back(E.name.replace_first("shader_param/", "").quote(quote_style));
+ r_options->push_back(E.name.replace_first("shader_param/", "").quote());
}
}
}