summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/arvr_nodes.cpp15
-rw-r--r--scene/3d/arvr_nodes.h2
-rw-r--r--scene/3d/audio_stream_player_3d.cpp162
-rw-r--r--scene/3d/audio_stream_player_3d.h4
-rw-r--r--scene/3d/bone_attachment.cpp6
-rw-r--r--scene/3d/collision_shape.cpp3
-rw-r--r--scene/3d/gi_probe.cpp50
-rw-r--r--scene/3d/interpolated_camera.cpp4
-rw-r--r--scene/3d/light.cpp20
-rw-r--r--scene/3d/light.h10
-rw-r--r--scene/3d/path.cpp4
-rw-r--r--scene/3d/physics_body.cpp228
-rw-r--r--scene/3d/physics_body.h52
-rw-r--r--scene/3d/spatial.cpp2
-rw-r--r--scene/3d/vehicle_body.cpp8
-rw-r--r--scene/3d/vehicle_body.h2
16 files changed, 326 insertions, 246 deletions
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp
index caf313190b..966dd88a2c 100644
--- a/scene/3d/arvr_nodes.cpp
+++ b/scene/3d/arvr_nodes.cpp
@@ -31,7 +31,6 @@
#include "arvr_nodes.h"
#include "core/os/input.h"
#include "servers/arvr/arvr_interface.h"
-#include "servers/arvr/arvr_positional_tracker.h"
#include "servers/arvr_server.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -142,6 +141,7 @@ void ARVRController::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_joystick_axis", "axis"), &ARVRController::get_joystick_axis);
ClassDB::bind_method(D_METHOD("get_is_active"), &ARVRController::get_is_active);
+ ClassDB::bind_method(D_METHOD("get_hand"), &ARVRController::get_hand);
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::INT, "button")));
ADD_SIGNAL(MethodInfo("button_release", PropertyInfo(Variant::INT, "button")));
@@ -204,6 +204,19 @@ bool ARVRController::get_is_active() const {
return is_active;
};
+ARVRPositionalTracker::TrackerHand ARVRController::get_hand() const {
+ // get our ARVRServer
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, ARVRPositionalTracker::TRACKER_HAND_UNKNOWN);
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, controller_id);
+ if (tracker == NULL) {
+ return ARVRPositionalTracker::TRACKER_HAND_UNKNOWN;
+ };
+
+ return tracker->get_hand();
+};
+
String ARVRController::get_configuration_warning() const {
if (!is_visible() || !is_inside_tree())
return String();
diff --git a/scene/3d/arvr_nodes.h b/scene/3d/arvr_nodes.h
index 4c14be71b5..5269ec0248 100644
--- a/scene/3d/arvr_nodes.h
+++ b/scene/3d/arvr_nodes.h
@@ -33,6 +33,7 @@
#include "scene/3d/camera.h"
#include "scene/3d/spatial.h"
+#include "servers/arvr/arvr_positional_tracker.h"
/**
@author Bastiaan Olij <mux213@gmail.com>
@@ -84,6 +85,7 @@ public:
float get_joystick_axis(int p_axis) const;
bool get_is_active() const;
+ ARVRPositionalTracker::TrackerHand get_hand() const;
String get_configuration_warning() const;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index a69bec2fc8..b8c6a86f55 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -72,34 +72,13 @@ void AudioStreamPlayer3D::_mix_audio() {
//mix!
- int buffers = 0;
- int first = 0;
-
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
-
- case AudioServer::SPEAKER_MODE_STEREO: {
- buffers = 1;
- first = 0;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
- buffers = 2;
- first = 1;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
-
- buffers = 3;
- first = 1;
-
- } break;
- }
+ int buffers = AudioServer::get_singleton()->get_channel_count();
for (int k = 0; k < buffers; k++) {
AudioFrame vol_inc = (current.vol[k] - prev_outputs[i].vol[k]) / float(buffer_size);
AudioFrame vol = current.vol[k];
- AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, first + k);
+ AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
current.filter.set_mode(AudioFilterSW::HIGHSHELF);
current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate());
@@ -146,7 +125,7 @@ void AudioStreamPlayer3D::_mix_audio() {
if (current.reverb_bus_index >= 0) {
- AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, first + k);
+ AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k);
if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) {
AudioFrame rvol_inc = (current.reverb_vol[k] - prev_outputs[i].reverb_vol[k]) / float(buffer_size);
@@ -341,49 +320,57 @@ void AudioStreamPlayer3D::_notification(int p_what) {
flat_pos.y = 0;
flat_pos.normalize();
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
+ unsigned int cc = AudioServer::get_singleton()->get_channel_count();
+ if (cc == 1) {
+ // Stereo pair
+ float c = flat_pos.x * 0.5 + 0.5;
- case AudioServer::SPEAKER_MODE_STEREO: {
-
- float c = flat_pos.x * 0.5 + 0.5;
- output.vol[0].l = 1.0 - c;
- output.vol[0].r = c;
-
- output.vol[0] *= multiplier;
+ output.vol[0].l = 1.0 - c;
+ output.vol[0].r = c;
+ } else {
+ Vector3 camtopos = global_pos - camera->get_global_transform().origin;
+ float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
+ float angle = Math::rad2deg(Math::acos(c));
+ float av = angle * (flat_pos.x < 0 ? -1 : 1) / 180.0;
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
+ if (cc >= 1) {
+ // Stereo pair
+ float fl = Math::abs(1.0 - Math::abs(-0.8 - av));
+ float fr = Math::abs(1.0 - Math::abs(0.8 - av));
- float xl = Vector3(-1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+ output.vol[0].l = fl;
+ output.vol[0].r = fr;
+ }
- output.vol[0].l = xl;
- output.vol[1].r = 1.0 - xl;
- output.vol[0].r = xr;
- output.vol[1].l = 1.0 - xr;
+ if (cc >= 2) {
+ // Center pair
+ float center = 1.0 - Math::sin(Math::acos(c));
- output.vol[0] *= multiplier;
- output.vol[1] *= multiplier;
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
+ output.vol[1].l = center;
+ output.vol[1].r = center;
+ }
- float xl = Vector3(-1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+ if (cc >= 3) {
+ // Side pair
+ float sl = Math::abs(1.0 - Math::abs(-0.4 - av));
+ float sr = Math::abs(1.0 - Math::abs(0.4 - av));
- output.vol[0].l = xl;
- output.vol[1].r = 1.0 - xl;
- output.vol[0].r = xr;
- output.vol[1].l = 1.0 - xr;
+ output.vol[2].l = sl;
+ output.vol[2].r = sr;
+ }
- float c = flat_pos.x * 0.5 + 0.5;
- output.vol[2].l = 1.0 - c;
- output.vol[2].r = c;
+ if (cc >= 4) {
+ // Rear pair
+ float rl = Math::abs(1.0 - Math::abs(-0.2 - av));
+ float rr = Math::abs(1.0 - Math::abs(0.2 - av));
- output.vol[0] *= multiplier;
- output.vol[1] *= multiplier;
- output.vol[2] *= multiplier;
+ output.vol[3].l = rl;
+ output.vol[3].r = rr;
+ }
+ }
- } break;
+ for (int k = 0; k < cc; k++) {
+ output.vol[k] *= multiplier;
}
bool filled_reverb = false;
@@ -422,41 +409,30 @@ void AudioStreamPlayer3D::_notification(int p_what) {
rev_pos.y = 0;
rev_pos.normalize();
- switch (AudioServer::get_singleton()->get_speaker_mode()) {
-
- case AudioServer::SPEAKER_MODE_STEREO: {
-
- float c = rev_pos.x * 0.5 + 0.5;
- output.reverb_vol[0].l = 1.0 - c;
- output.reverb_vol[0].r = c;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_51: {
-
- float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
-
- output.reverb_vol[0].l = xl;
- output.reverb_vol[1].r = 1.0 - xl;
- output.reverb_vol[0].r = xr;
- output.reverb_vol[1].l = 1.0 - xr;
-
- } break;
- case AudioServer::SPEAKER_SURROUND_71: {
-
- float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
- float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+ if (cc >= 1) {
+ // Stereo pair
+ float c = rev_pos.x * 0.5 + 0.5;
+ output.reverb_vol[0].l = 1.0 - c;
+ output.reverb_vol[0].r = c;
+ }
- output.reverb_vol[0].l = xl;
- output.reverb_vol[1].r = 1.0 - xl;
- output.reverb_vol[0].r = xr;
- output.reverb_vol[1].l = 1.0 - xr;
+ if (cc >= 3) {
+ // Center pair + Side pair
+ float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+ float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
- float c = rev_pos.x * 0.5 + 0.5;
- output.reverb_vol[2].l = 1.0 - c;
- output.reverb_vol[2].r = c;
+ output.reverb_vol[1].l = xl;
+ output.reverb_vol[1].r = xr;
+ output.reverb_vol[2].l = 1.0 - xr;
+ output.reverb_vol[2].r = 1.0 - xl;
+ }
- } break;
+ if (cc >= 4) {
+ // Rear pair
+ // FIXME: Not sure what math should be done here
+ float c = rev_pos.x * 0.5 + 0.5;
+ output.reverb_vol[3].l = 1.0 - c;
+ output.reverb_vol[3].r = c;
}
for (int i = 0; i < vol_index_max; i++) {
@@ -530,13 +506,15 @@ void AudioStreamPlayer3D::_notification(int p_what) {
setseek = setplay;
active = true;
setplay = -1;
- _change_notify("playing"); //update property in editor
+ //do not update, this makes it easier to animate (will shut off otherise)
+ ///_change_notify("playing"); //update property in editor
}
//stop playing if no longer active
if (!active) {
set_fixed_process_internal(false);
- _change_notify("playing"); //update property in editor
+ //do not update, this makes it easier to animate (will shut off otherise)
+ //_change_notify("playing"); //update property in editor
emit_signal("finished");
}
}
@@ -877,7 +855,7 @@ void AudioStreamPlayer3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "is_playing");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "0,65536,1"), "set_max_distance", "get_max_distance");
ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode");
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 8603cab5a4..b729b55f7e 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -40,12 +40,12 @@ private:
AudioFilterSW filter;
AudioFilterSW::Processor filter_process[6];
- AudioFrame vol[3];
+ AudioFrame vol[4];
float filter_gain;
float pitch_scale;
int bus_index;
int reverb_bus_index;
- AudioFrame reverb_vol[3];
+ AudioFrame reverb_vol[4];
Viewport *viewport; //pointer only used for reference to previous mix
Output() {
diff --git a/scene/3d/bone_attachment.cpp b/scene/3d/bone_attachment.cpp
index e1a5329fb0..2580b645e2 100644
--- a/scene/3d/bone_attachment.cpp
+++ b/scene/3d/bone_attachment.cpp
@@ -71,7 +71,8 @@ void BoneAttachment::_get_property_list(List<PropertyInfo> *p_list) const {
void BoneAttachment::_check_bind() {
- if (Skeleton *sk = Object::cast_to<Skeleton>(get_parent())) {
+ Skeleton *sk = Object::cast_to<Skeleton>(get_parent());
+ if (sk) {
int idx = sk->find_bone(bone_name);
if (idx != -1) {
@@ -86,7 +87,8 @@ void BoneAttachment::_check_unbind() {
if (bound) {
- if (Skeleton *sk = Object::cast_to<Skeleton>(get_parent())) {
+ Skeleton *sk = Object::cast_to<Skeleton>(get_parent());
+ if (sk) {
int idx = sk->find_bone(bone_name);
if (idx != -1) {
diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp
index 5f1151f8e9..f49d89122d 100644
--- a/scene/3d/collision_shape.cpp
+++ b/scene/3d/collision_shape.cpp
@@ -50,7 +50,8 @@ void CollisionShape::make_convex_from_brothers() {
for (int i = 0; i < p->get_child_count(); i++) {
Node *n = p->get_child(i);
- if (MeshInstance *mi = Object::cast_to<MeshInstance>(n)) {
+ MeshInstance *mi = Object::cast_to<MeshInstance>(n);
+ if (mi) {
Ref<Mesh> m = mi->get_mesh();
if (m.is_valid()) {
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index bb54a43028..66364d40f9 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -696,22 +696,6 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons
p_baker->bake_cells[p_idx].normal[2] += normal_accum.z;
p_baker->bake_cells[p_idx].alpha += alpha;
- static const Vector3 side_normals[6] = {
- Vector3(-1, 0, 0),
- Vector3(1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, 1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, 1),
- };
-
- /*
- for(int i=0;i<6;i++) {
- if (normal.dot(side_normals[i])>CMP_EPSILON) {
- p_baker->bake_cells[p_idx].used_sides|=(1<<i);
- }
- }*/
-
} else {
//go down
@@ -1092,7 +1076,7 @@ void GIProbe::_plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_b
void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) {
MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node);
- if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT)) {
+ if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) {
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
@@ -1113,25 +1097,29 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) {
}
}
- if (Spatial *s = Object::cast_to<Spatial>(p_at_node)) {
+ Spatial *s = Object::cast_to<Spatial>(p_at_node);
+ if (s) {
- Array meshes = p_at_node->call("get_meshes");
- for (int i = 0; i < meshes.size(); i += 2) {
+ if (s->is_visible_in_tree()) {
- Transform mxf = meshes[i];
- Ref<Mesh> mesh = meshes[i + 1];
- if (!mesh.is_valid())
- continue;
+ Array meshes = p_at_node->call("get_meshes");
+ for (int i = 0; i < meshes.size(); i += 2) {
- Rect3 aabb = mesh->get_aabb();
+ Transform mxf = meshes[i];
+ Ref<Mesh> mesh = meshes[i + 1];
+ if (!mesh.is_valid())
+ continue;
- Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf);
+ Rect3 aabb = mesh->get_aabb();
- if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) {
- Baker::PlotMesh pm;
- pm.local_xform = xf;
- pm.mesh = mesh;
- p_baker->mesh_list.push_back(pm);
+ Transform xf = get_global_transform().affine_inverse() * (s->get_global_transform() * mxf);
+
+ if (Rect3(-extents, extents * 2).intersects(xf.xform(aabb))) {
+ Baker::PlotMesh pm;
+ pm.local_xform = xf;
+ pm.mesh = mesh;
+ p_baker->mesh_list.push_back(pm);
+ }
}
}
}
diff --git a/scene/3d/interpolated_camera.cpp b/scene/3d/interpolated_camera.cpp
index 157ae42571..0f281b694d 100644
--- a/scene/3d/interpolated_camera.cpp
+++ b/scene/3d/interpolated_camera.cpp
@@ -55,8 +55,8 @@ void InterpolatedCamera::_notification(int p_what) {
Transform local_transform = get_global_transform();
local_transform = local_transform.interpolate_with(target_xform, delta);
set_global_transform(local_transform);
-
- if (Camera *cam = Object::cast_to<Camera>(node)) {
+ Camera *cam = Object::cast_to<Camera>(node);
+ if (cam) {
if (cam->get_projection() == get_projection()) {
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index 09b253b309..096f787873 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -230,7 +230,6 @@ void Light::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_contact", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_CONTACT_SHADOW_SIZE);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "shadow_max_distance", PROPERTY_HINT_RANGE, "0,65536,0.1"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face");
ADD_GROUP("Editor", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only");
@@ -308,6 +307,16 @@ DirectionalLight::ShadowMode DirectionalLight::get_shadow_mode() const {
return shadow_mode;
}
+void DirectionalLight::set_shadow_depth_range(ShadowDepthRange p_range) {
+ shadow_depth_range = p_range;
+ VS::get_singleton()->light_directional_set_shadow_depth_range_mode(light, VS::LightDirectionalShadowDepthRangeMode(p_range));
+}
+
+DirectionalLight::ShadowDepthRange DirectionalLight::get_shadow_depth_range() const {
+
+ return shadow_depth_range;
+}
+
void DirectionalLight::set_blend_splits(bool p_enable) {
blend_splits = p_enable;
@@ -324,6 +333,9 @@ void DirectionalLight::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight::set_shadow_mode);
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight::get_shadow_mode);
+ ClassDB::bind_method(D_METHOD("set_shadow_depth_range", "mode"), &DirectionalLight::set_shadow_depth_range);
+ ClassDB::bind_method(D_METHOD("get_shadow_depth_range"), &DirectionalLight::get_shadow_depth_range);
+
ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight::set_blend_splits);
ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight::is_blend_splits_enabled);
@@ -335,10 +347,15 @@ void DirectionalLight::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE);
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_depth_range", PROPERTY_HINT_ENUM, "Stable,Optimized"), "set_shadow_depth_range", "get_shadow_depth_range");
+ ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_max_distance", PROPERTY_HINT_RANGE, "0,65536,0.1"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE);
BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL);
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS);
+
+ BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_STABLE);
+ BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_OPTIMIZED);
}
DirectionalLight::DirectionalLight()
@@ -349,6 +366,7 @@ DirectionalLight::DirectionalLight()
set_param(PARAM_SHADOW_MAX_DISTANCE, 200);
set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
+ set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE);
blend_splits = false;
}
diff --git a/scene/3d/light.h b/scene/3d/light.h
index 5d589d33e5..6aa0220265 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -133,9 +133,15 @@ public:
SHADOW_PARALLEL_4_SPLITS
};
+ enum ShadowDepthRange {
+ SHADOW_DEPTH_RANGE_STABLE = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE,
+ SHADOW_DEPTH_RANGE_OPTIMIZED = VS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED,
+ };
+
private:
bool blend_splits;
ShadowMode shadow_mode;
+ ShadowDepthRange shadow_depth_range;
protected:
static void _bind_methods();
@@ -144,6 +150,9 @@ public:
void set_shadow_mode(ShadowMode p_mode);
ShadowMode get_shadow_mode() const;
+ void set_shadow_depth_range(ShadowDepthRange p_mode);
+ ShadowDepthRange get_shadow_depth_range() const;
+
void set_blend_splits(bool p_enable);
bool is_blend_splits_enabled() const;
@@ -151,6 +160,7 @@ public:
};
VARIANT_ENUM_CAST(DirectionalLight::ShadowMode)
+VARIANT_ENUM_CAST(DirectionalLight::ShadowDepthRange)
class OmniLight : public Light {
diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp
index ed4d88417c..60245fe6ce 100644
--- a/scene/3d/path.cpp
+++ b/scene/3d/path.cpp
@@ -155,8 +155,8 @@ void PathFollow::_notification(int p_what) {
Node *parent = get_parent();
if (parent) {
-
- if ((path = Object::cast_to<Path>(parent))) {
+ path = Object::cast_to<Path>(parent);
+ if (path) {
_update_transform();
}
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 9590394211..7525eb5069 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -912,35 +912,24 @@ RigidBody::~RigidBody() {
//////////////////////////////////////////////////////
//////////////////////////
-Dictionary KinematicBody::_move(const Vector3 &p_motion) {
+Ref<KinematicCollision> KinematicBody::_move(const Vector3 &p_motion) {
Collision col;
- if (move(p_motion, col)) {
- Dictionary d;
- d["position"] = col.collision;
- d["normal"] = col.normal;
- d["local_shape"] = col.local_shape;
- d["travel"] = col.travel;
- d["remainder"] = col.remainder;
- d["collider_id"] = col.collider;
- if (col.collider) {
- d["collider"] = ObjectDB::get_instance(col.collider);
- } else {
- d["collider"] = Variant();
+ if (move_and_collide(p_motion, col)) {
+ if (motion_cache.is_null()) {
+ motion_cache.instance();
+ motion_cache->owner = this;
}
- d["collider_velocity"] = col.collider_vel;
- d["collider_shape_index"] = col.collider_shape;
- d["collider_metadata"] = col.collider_metadata;
-
- return d;
+ motion_cache->collision = col;
- } else {
- return Dictionary();
+ return motion_cache;
}
+
+ return Ref<KinematicCollision>();
}
-bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) {
+bool KinematicBody::move_and_collide(const Vector3 &p_motion, Collision &r_collision) {
Transform gt = get_global_transform();
PhysicsServer::MotionResult result;
@@ -964,7 +953,7 @@ bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) {
return colliding;
}
-Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) {
+Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_slides, float p_floor_max_angle) {
Vector3 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
Vector3 lv = p_linear_velocity;
@@ -975,11 +964,11 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
colliders.clear();
floor_velocity = Vector3();
- while (p_max_bounces) {
+ while (p_max_slides) {
Collision collision;
- bool collided = move(motion, collision);
+ bool collided = move_and_collide(motion, collision);
if (collided) {
@@ -1017,7 +1006,7 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
break;
}
- p_max_bounces--;
+ p_max_slides--;
if (motion == Vector3())
break;
}
@@ -1059,79 +1048,36 @@ float KinematicBody::get_safe_margin() const {
return margin;
}
-
-int KinematicBody::get_collision_count() const {
+int KinematicBody::get_slide_count() const {
return colliders.size();
}
-Vector3 KinematicBody::get_collision_position(int p_collision) const {
-
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].collision;
-}
-Vector3 KinematicBody::get_collision_normal(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].normal;
+KinematicBody::Collision KinematicBody::get_slide_collision(int p_bounce) const {
+ ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Collision());
+ return colliders[p_bounce];
}
-Vector3 KinematicBody::get_collision_travel(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].travel;
-}
-Vector3 KinematicBody::get_collision_remainder(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].remainder;
-}
-Object *KinematicBody::get_collision_local_shape(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
- uint32_t owner = shape_find_owner(colliders[p_collision].local_shape);
- return shape_owner_get_owner(owner);
-}
-Object *KinematicBody::get_collision_collider(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+Ref<KinematicCollision> KinematicBody::_get_slide_collision(int p_bounce) {
- if (colliders[p_collision].collider) {
- return ObjectDB::get_instance(colliders[p_collision].collider);
+ ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision>());
+ if (p_bounce >= slide_colliders.size()) {
+ slide_colliders.resize(p_bounce + 1);
}
- return NULL;
-}
-ObjectID KinematicBody::get_collision_collider_id(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0);
-
- return colliders[p_collision].collider;
-}
-Object *KinematicBody::get_collision_collider_shape(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
- Object *collider = get_collision_collider(p_collision);
- if (collider) {
- CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider);
- if (obj2d) {
- uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape);
- return obj2d->shape_owner_get_owner(owner);
- }
+ if (slide_colliders[p_bounce].is_null()) {
+ slide_colliders[p_bounce].instance();
+ slide_colliders[p_bounce]->owner = this;
}
- return NULL;
-}
-int KinematicBody::get_collision_collider_shape_index(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1);
- return colliders[p_collision].collider_shape;
-}
-Vector3 KinematicBody::get_collision_collider_velocity(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- return colliders[p_collision].collider_vel;
-}
-Variant KinematicBody::get_collision_collider_metadata(int p_collision) const {
- ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant());
- return colliders[p_collision].collider_metadata;
+ slide_colliders[p_bounce]->collision = colliders[p_bounce];
+ return slide_colliders[p_bounce];
}
void KinematicBody::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody::_move);
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
+ ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec"), &KinematicBody::_move);
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_slides", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody::test_move);
@@ -1143,18 +1089,8 @@ void KinematicBody::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
ClassDB::bind_method(D_METHOD("get_safe_margin"), &KinematicBody::get_safe_margin);
- ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody::get_collision_count);
- ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody::get_collision_position);
- ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody::get_collision_normal);
- ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody::get_collision_travel);
- ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody::get_collision_remainder);
- ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody::get_collision_local_shape);
- ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody::get_collision_collider);
- ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody::get_collision_collider_id);
- ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody::get_collision_collider_shape);
- ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody::get_collision_collider_shape_index);
- ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody::get_collision_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody::get_collision_collider_metadata);
+ ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody::get_slide_count);
+ ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody::_get_slide_collision);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
@@ -1169,4 +1105,106 @@ KinematicBody::KinematicBody()
on_wall = false;
}
KinematicBody::~KinematicBody() {
+
+ if (motion_cache.is_valid()) {
+ motion_cache->owner = NULL;
+ }
+
+ for (int i = 0; i < slide_colliders.size(); i++) {
+ if (slide_colliders[i].is_valid()) {
+ slide_colliders[i]->owner = NULL;
+ }
+ }
+}
+///////////////////////////////////////
+
+Vector3 KinematicCollision::get_position() const {
+
+ return collision.collision;
+}
+Vector3 KinematicCollision::get_normal() const {
+ return collision.normal;
+}
+Vector3 KinematicCollision::get_travel() const {
+ return collision.travel;
+}
+Vector3 KinematicCollision::get_remainder() const {
+ return collision.remainder;
+}
+Object *KinematicCollision::get_local_shape() const {
+ ERR_FAIL_COND_V(!owner, NULL);
+ uint32_t ownerid = owner->shape_find_owner(collision.local_shape);
+ return owner->shape_owner_get_owner(ownerid);
+}
+
+Object *KinematicCollision::get_collider() const {
+
+ if (collision.collider) {
+ return ObjectDB::get_instance(collision.collider);
+ }
+
+ return NULL;
+}
+ObjectID KinematicCollision::get_collider_id() const {
+
+ return collision.collider;
+}
+Object *KinematicCollision::get_collider_shape() const {
+
+ Object *collider = get_collider();
+ if (collider) {
+ CollisionObject *obj2d = Object::cast_to<CollisionObject>(collider);
+ if (obj2d) {
+ uint32_t ownerid = obj2d->shape_find_owner(collision.collider_shape);
+ return obj2d->shape_owner_get_owner(ownerid);
+ }
+ }
+
+ return NULL;
+}
+int KinematicCollision::get_collider_shape_index() const {
+
+ return collision.collider_shape;
+}
+Vector3 KinematicCollision::get_collider_velocity() const {
+
+ return collision.collider_vel;
+}
+Variant KinematicCollision::get_collider_metadata() const {
+
+ return Variant();
+}
+
+void KinematicCollision::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision::get_position);
+ ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision::get_normal);
+ ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision::get_travel);
+ ClassDB::bind_method(D_METHOD("get_remainder"), &KinematicCollision::get_remainder);
+ ClassDB::bind_method(D_METHOD("get_local_shape"), &KinematicCollision::get_local_shape);
+ ClassDB::bind_method(D_METHOD("get_collider"), &KinematicCollision::get_collider);
+ ClassDB::bind_method(D_METHOD("get_collider_id"), &KinematicCollision::get_collider_id);
+ ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicCollision::get_collider_shape);
+ ClassDB::bind_method(D_METHOD("get_collider_shape_index"), &KinematicCollision::get_collider_shape_index);
+ ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicCollision::get_collider_velocity);
+ ClassDB::bind_method(D_METHOD("get_collider_metadata"), &KinematicCollision::get_collider_metadata);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "position"), "", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "normal"), "", "get_normal");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "travel"), "", "get_travel");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "remainder"), "", "get_remainder");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "local_shape"), "", "get_local_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider"), "", "get_collider");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_id"), "", "get_collider_id");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "collider_shape"), "", "get_collider_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collider_shape_index"), "", "get_collider_shape_index");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "collider_velocity"), "", "get_collider_velocity");
+ ADD_PROPERTY(PropertyInfo(Variant::NIL, "collider_metadata", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT), "", "get_collider_metadata");
+}
+
+KinematicCollision::KinematicCollision() {
+ collision.collider = 0;
+ collision.collider_shape = 0;
+ collision.local_shape = 0;
+ owner = NULL;
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index 23d752ad76..f88b3860dc 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -261,6 +261,8 @@ public:
VARIANT_ENUM_CAST(RigidBody::Mode);
VARIANT_ENUM_CAST(RigidBody::AxisLock);
+class KinematicCollision;
+
class KinematicBody : public PhysicsBody {
GDCLASS(KinematicBody, PhysicsBody);
@@ -286,42 +288,62 @@ private:
bool on_ceiling;
bool on_wall;
Vector<Collision> colliders;
+ Vector<Ref<KinematicCollision> > slide_colliders;
+ Ref<KinematicCollision> motion_cache;
_FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
- Dictionary _move(const Vector3 &p_motion);
+ Ref<KinematicCollision> _move(const Vector3 &p_motion);
+ Ref<KinematicCollision> _get_slide_collision(int p_bounce);
protected:
static void _bind_methods();
public:
- bool move(const Vector3 &p_motion, Collision &r_collision);
+ bool move_and_collide(const Vector3 &p_motion, Collision &r_collision);
bool test_move(const Transform &p_from, const Vector3 &p_motion);
void set_safe_margin(float p_margin);
float get_safe_margin() const;
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, 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;
Vector3 get_floor_velocity() const;
- int get_collision_count() const;
- Vector3 get_collision_position(int p_collision) const;
- Vector3 get_collision_normal(int p_collision) const;
- Vector3 get_collision_travel(int p_collision) const;
- Vector3 get_collision_remainder(int p_collision) const;
- Object *get_collision_local_shape(int p_collision) const;
- Object *get_collision_collider(int p_collision) const;
- ObjectID get_collision_collider_id(int p_collision) const;
- Object *get_collision_collider_shape(int p_collision) const;
- int get_collision_collider_shape_index(int p_collision) const;
- Vector3 get_collision_collider_velocity(int p_collision) const;
- Variant get_collision_collider_metadata(int p_collision) const;
+ int get_slide_count() const;
+ Collision get_slide_collision(int p_bounce) const;
KinematicBody();
~KinematicBody();
};
+class KinematicCollision : public Reference {
+
+ GDCLASS(KinematicCollision, Reference);
+
+ KinematicBody *owner;
+ friend class KinematicBody;
+ KinematicBody::Collision collision;
+
+protected:
+ static void _bind_methods();
+
+public:
+ Vector3 get_position() const;
+ Vector3 get_normal() const;
+ Vector3 get_travel() const;
+ Vector3 get_remainder() const;
+ Object *get_local_shape() const;
+ Object *get_collider() const;
+ ObjectID get_collider_id() const;
+ Object *get_collider_shape() const;
+ int get_collider_shape_index() const;
+ Vector3 get_collider_velocity() const;
+ Variant get_collider_metadata() const;
+
+ KinematicCollision();
+};
+
#endif // PHYSICS_BODY__H
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index 7db3bb18bd..91fe426b99 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -175,7 +175,6 @@ void Spatial::_notification(int p_what) {
if (get_script_instance()) {
- Variant::CallError err;
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, NULL, 0);
}
#ifdef TOOLS_ENABLED
@@ -207,7 +206,6 @@ void Spatial::_notification(int p_what) {
if (get_script_instance()) {
- Variant::CallError err;
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, NULL, 0);
}
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index d6b3206fbf..3518113130 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -102,6 +102,14 @@ void VehicleWheel::_notification(int p_what) {
}
}
+String VehicleWheel::get_configuration_warning() const {
+ if (!Object::cast_to<VehicleBody>(get_parent())) {
+ return TTR("VehicleWheel serves to provide a wheel system to a VehicleBody. Please use it as a child of a VehicleBody.");
+ }
+
+ return String();
+}
+
void VehicleWheel::_update(PhysicsDirectBodyState *s) {
if (m_raycastInfo.m_isInContact)
diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h
index d67209c58f..eb661adb90 100644
--- a/scene/3d/vehicle_body.h
+++ b/scene/3d/vehicle_body.h
@@ -131,6 +131,8 @@ public:
void set_roll_influence(float p_value);
float get_roll_influence() const;
+ String get_configuration_warning() const;
+
VehicleWheel();
};