summaryrefslogtreecommitdiff
path: root/scene/3d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d')
-rw-r--r--scene/3d/audio_stream_player_3d.cpp9
-rw-r--r--scene/3d/audio_stream_player_3d.h3
-rw-r--r--scene/3d/fog_volume.cpp2
-rw-r--r--scene/3d/joint_3d.cpp2
-rw-r--r--scene/3d/label_3d.cpp26
-rw-r--r--scene/3d/label_3d.h1
-rw-r--r--scene/3d/navigation_agent_3d.cpp51
-rw-r--r--scene/3d/navigation_agent_3d.h2
-rw-r--r--scene/3d/visual_instance_3d.cpp9
-rw-r--r--scene/3d/visual_instance_3d.h1
10 files changed, 90 insertions, 16 deletions
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 735ce0bb07..7c1fb3779f 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -273,7 +273,8 @@ void AudioStreamPlayer3D::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// Update anything related to position first, if possible of course.
Vector<AudioFrame> volume_vector;
- if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count())) {
+ if (setplay.get() > 0 || (active.is_set() && last_mix_count != AudioServer::get_singleton()->get_mix_count()) || force_update_panning) {
+ force_update_panning = false;
volume_vector = _update_panning();
}
@@ -318,6 +319,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
}
+// Interacts with PhysicsServer3D, so can only be called during _physics_process
Area3D *AudioStreamPlayer3D::_get_overriding_area() {
//check if any area is diverting sound into a bus
Ref<World3D> world_3d = get_world_3d();
@@ -356,6 +358,7 @@ Area3D *AudioStreamPlayer3D::_get_overriding_area() {
return nullptr;
}
+// Interacts with PhysicsServer3D, so can only be called during _physics_process
StringName AudioStreamPlayer3D::_get_actual_bus() {
Area3D *overriding_area = _get_overriding_area();
if (overriding_area && overriding_area->is_overriding_audio_bus() && !overriding_area->is_using_reverb_bus()) {
@@ -364,6 +367,7 @@ StringName AudioStreamPlayer3D::_get_actual_bus() {
return bus;
}
+// Interacts with PhysicsServer3D, so can only be called during _physics_process
Vector<AudioFrame> AudioStreamPlayer3D::_update_panning() {
Vector<AudioFrame> output_volume_vector;
output_volume_vector.resize(4);
@@ -537,6 +541,7 @@ float AudioStreamPlayer3D::get_unit_db() const {
void AudioStreamPlayer3D::set_unit_size(float p_volume) {
unit_size = p_volume;
+ update_gizmos();
}
float AudioStreamPlayer3D::get_unit_size() const {
@@ -665,6 +670,7 @@ void AudioStreamPlayer3D::_bus_layout_changed() {
void AudioStreamPlayer3D::set_max_distance(float p_metres) {
ERR_FAIL_COND(p_metres < 0.0);
max_distance = p_metres;
+ update_gizmos();
}
float AudioStreamPlayer3D::get_max_distance() const {
@@ -725,6 +731,7 @@ float AudioStreamPlayer3D::get_attenuation_filter_db() const {
void AudioStreamPlayer3D::set_attenuation_model(AttenuationModel p_model) {
ERR_FAIL_INDEX((int)p_model, 4);
attenuation_model = p_model;
+ update_gizmos();
}
AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model() const {
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 53cdd2e630..bc47a8de93 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -82,12 +82,13 @@ private:
int max_polyphony = 1;
uint64_t last_mix_count = -1;
+ bool force_update_panning = false;
static void _calc_output_vol(const Vector3 &source_dir, real_t tightness, Vector<AudioFrame> &output);
void _calc_reverb_vol(Area3D *area, Vector3 listener_area_pos, Vector<AudioFrame> direct_path_vol, Vector<AudioFrame> &reverb_vol);
- static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer3D *>(self)->_update_panning(); }
+ static void _listener_changed_cb(void *self) { reinterpret_cast<AudioStreamPlayer3D *>(self)->force_update_panning = true; }
void _set_playing(bool p_enable);
bool _is_active() const;
diff --git a/scene/3d/fog_volume.cpp b/scene/3d/fog_volume.cpp
index 8d05254a25..8fbadb4b7b 100644
--- a/scene/3d/fog_volume.cpp
+++ b/scene/3d/fog_volume.cpp
@@ -41,7 +41,7 @@ void FogVolume::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_material"), &FogVolume::get_material);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "extents", PROPERTY_HINT_RANGE, "0.01,1024,0.01,or_greater"), "set_extents", "get_extents");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "shape", PROPERTY_HINT_ENUM, "Ellipsoid,Box,World"), "set_shape", "get_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "shape", PROPERTY_HINT_ENUM, "Ellipsoid (Local),Cone (Local),Cylinder (Local),Box (Local),World (Global)"), "set_shape", "get_shape");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "FogMaterial,ShaderMaterial"), "set_material", "get_material");
}
diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp
index c22e3f6d91..b6fc83e599 100644
--- a/scene/3d/joint_3d.cpp
+++ b/scene/3d/joint_3d.cpp
@@ -49,6 +49,7 @@ void Joint3D::_disconnect_signals() {
void Joint3D::_body_exit_tree() {
_disconnect_signals();
_update_joint(true);
+ update_configuration_warnings();
}
void Joint3D::_update_joint(bool p_only_free) {
@@ -65,7 +66,6 @@ void Joint3D::_update_joint(bool p_only_free) {
if (p_only_free || !is_inside_tree()) {
PhysicsServer3D::get_singleton()->joint_clear(joint);
warning = String();
- update_configuration_warnings();
return;
}
diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp
index 2d7da48ab1..78da22a0c3 100644
--- a/scene/3d/label_3d.cpp
+++ b/scene/3d/label_3d.cpp
@@ -788,6 +788,11 @@ Ref<Font> Label3D::get_font() const {
}
Ref<Font> Label3D::_get_font_or_default() const {
+ if (theme_font.is_valid()) {
+ theme_font->disconnect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
+ theme_font.unref();
+ }
+
if (font_override.is_valid() && font_override->get_data_count() > 0) {
return font_override;
}
@@ -799,7 +804,12 @@ Ref<Font> Label3D::_get_font_or_default() const {
for (const StringName &E : theme_types) {
if (Theme::get_project_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- return Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ Ref<Font> f = Theme::get_project_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
+ }
+ return f;
}
}
}
@@ -811,13 +821,23 @@ Ref<Font> Label3D::_get_font_or_default() const {
for (const StringName &E : theme_types) {
if (Theme::get_default()->has_theme_item(Theme::DATA_TYPE_FONT, "font", E)) {
- return Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", E);
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
+ }
+ return f;
}
}
}
// If they don't exist, use any type to return the default/empty value.
- return Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ Ref<Font> f = Theme::get_default()->get_theme_item(Theme::DATA_TYPE_FONT, "font", StringName());
+ if (f.is_valid()) {
+ theme_font = f;
+ theme_font->connect(CoreStringNames::get_singleton()->changed, Callable(const_cast<Label3D *>(this), "_font_changed"));
+ }
+ return f;
}
void Label3D::set_font_size(int p_size) {
diff --git a/scene/3d/label_3d.h b/scene/3d/label_3d.h
index f57797a247..62f4c3fe96 100644
--- a/scene/3d/label_3d.h
+++ b/scene/3d/label_3d.h
@@ -96,6 +96,7 @@ private:
int font_size = 16;
Ref<Font> font_override;
+ mutable Ref<Font> theme_font;
Color modulate = Color(1, 1, 1, 1);
Point2 lbl_offset;
int outline_render_priority = -1;
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 88f676d031..947d6012d5 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -102,18 +102,32 @@ void NavigationAgent3D::_bind_methods() {
void NavigationAgent3D::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_READY: {
- agent_parent = Object::cast_to<Node3D>(get_parent());
- if (agent_parent != nullptr) {
- // place agent on navigation map first or else the RVO agent callback creation fails silently later
- NavigationServer3D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_3d()->get_navigation_map());
- set_avoidance_enabled(avoidance_enabled);
- }
+ case NOTIFICATION_POST_ENTER_TREE: {
+ // need to use POST_ENTER_TREE cause with normal ENTER_TREE not all required Nodes are ready.
+ // cannot use READY as ready does not get called if Node is readded to SceneTree
+ set_agent_parent(get_parent());
set_physics_process_internal(true);
} break;
+ case NOTIFICATION_PARENTED: {
+ if (is_inside_tree() && (get_parent() != agent_parent)) {
+ // only react to PARENTED notifications when already inside_tree and parent changed, e.g. users switch nodes around
+ // PARENTED notification fires also when Node is added in scripts to a parent
+ // this would spam transforms fails and world fails while Node is outside SceneTree
+ // when node gets reparented when joining the tree POST_ENTER_TREE takes care of this
+ set_agent_parent(get_parent());
+ set_physics_process_internal(true);
+ }
+ } break;
+
+ case NOTIFICATION_UNPARENTED: {
+ // if agent has no parent no point in processing it until reparented
+ set_agent_parent(nullptr);
+ set_physics_process_internal(false);
+ } break;
+
case NOTIFICATION_EXIT_TREE: {
- agent_parent = nullptr;
+ set_agent_parent(nullptr);
set_physics_process_internal(false);
} break;
@@ -139,7 +153,11 @@ void NavigationAgent3D::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (agent_parent) {
- NavigationServer3D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin);
+ if (avoidance_enabled) {
+ // agent_position on NavigationServer is avoidance only and has nothing to do with pathfinding
+ // no point in flooding NavigationServer queue with agent position updates that get send to the void if avoidance is not used
+ NavigationServer3D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin);
+ }
_check_distance_to_target();
}
} break;
@@ -174,6 +192,21 @@ bool NavigationAgent3D::get_avoidance_enabled() const {
return avoidance_enabled;
}
+void NavigationAgent3D::set_agent_parent(Node *p_agent_parent) {
+ // remove agent from any avoidance map before changing parent or there will be leftovers on the RVO map
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ if (Object::cast_to<Node3D>(p_agent_parent) != nullptr) {
+ // place agent on navigation map first or else the RVO agent callback creation fails silently later
+ agent_parent = Object::cast_to<Node3D>(p_agent_parent);
+ NavigationServer3D::get_singleton()->agent_set_map(get_rid(), agent_parent->get_world_3d()->get_navigation_map());
+ // create new avoidance callback if enabled
+ set_avoidance_enabled(avoidance_enabled);
+ } else {
+ agent_parent = nullptr;
+ NavigationServer3D::get_singleton()->agent_set_map(get_rid(), RID());
+ }
+}
+
void NavigationAgent3D::set_navigable_layers(uint32_t p_layers) {
bool layers_changed = navigable_layers != p_layers;
navigable_layers = p_layers;
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 28bcffd5b4..633bf091d1 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -84,6 +84,8 @@ public:
void set_avoidance_enabled(bool p_enabled);
bool get_avoidance_enabled() const;
+ void set_agent_parent(Node *p_agent_parent);
+
void set_navigable_layers(uint32_t p_layers);
uint32_t get_navigable_layers() const;
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 273e01989a..e40c8bfa2b 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -496,3 +496,12 @@ void GeometryInstance3D::_bind_methods() {
GeometryInstance3D::GeometryInstance3D() {
//RS::get_singleton()->instance_geometry_set_baked_light_texture_index(get_instance(),0);
}
+
+GeometryInstance3D::~GeometryInstance3D() {
+ if (material_overlay.is_valid()) {
+ set_material_overlay(Ref<Material>());
+ }
+ if (material_override.is_valid()) {
+ set_material_override(Ref<Material>());
+ }
+}
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index f8fd4378fe..e5f98bd65e 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -188,6 +188,7 @@ public:
TypedArray<String> get_configuration_warnings() const override;
GeometryInstance3D();
+ virtual ~GeometryInstance3D();
};
VARIANT_ENUM_CAST(GeometryInstance3D::ShadowCastingSetting);