diff options
Diffstat (limited to 'scene/3d')
62 files changed, 697 insertions, 597 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 5123a6eb6c..78c968a3d4 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -344,10 +344,14 @@ void Area3D::_clear_monitoring() { } void Area3D::_notification(int p_what) { - if (p_what == NOTIFICATION_EXIT_TREE) { - _clear_monitoring(); - } else if (p_what == NOTIFICATION_ENTER_TREE) { - _initialize_wind(); + switch (p_what) { + case NOTIFICATION_EXIT_TREE: { + _clear_monitoring(); + } break; + + case NOTIFICATION_ENTER_TREE: { + _initialize_wind(); + } break; } } diff --git a/scene/3d/audio_listener_3d.cpp b/scene/3d/audio_listener_3d.cpp index 0eb7588958..1ead9bb384 100644 --- a/scene/3d/audio_listener_3d.cpp +++ b/scene/3d/audio_listener_3d.cpp @@ -85,9 +85,11 @@ void AudioListener3D::_notification(int p_what) { make_current(); } } break; + case NOTIFICATION_TRANSFORM_CHANGED: { _request_listener_update(); } break; + case NOTIFICATION_EXIT_WORLD: { if (!get_tree()->is_node_being_edited(this)) { if (is_current()) { @@ -100,7 +102,6 @@ void AudioListener3D::_notification(int p_what) { } get_viewport()->_audio_listener_3d_remove(this); - } break; } } diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index 3b52974b8e..b17201f86b 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -239,80 +239,82 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const { } void AudioStreamPlayer3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - velocity_tracker->reset(get_global_transform().origin); - AudioServer::get_singleton()->add_listener_changed_callback(_listener_changed_cb, this); - if (autoplay && !Engine::get_singleton()->is_editor_hint()) { - play(); - } - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + velocity_tracker->reset(get_global_transform().origin); + AudioServer::get_singleton()->add_listener_changed_callback(_listener_changed_cb, this); + if (autoplay && !Engine::get_singleton()->is_editor_hint()) { + play(); + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - stop(); - AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this); - } + case NOTIFICATION_EXIT_TREE: { + stop(); + AudioServer::get_singleton()->remove_listener_changed_callback(_listener_changed_cb, this); + } break; - if (p_what == NOTIFICATION_PAUSED) { - if (!can_process()) { - // Node can't process so we start fading out to silence - set_stream_paused(true); - } - } + case NOTIFICATION_PAUSED: { + if (!can_process()) { + // Node can't process so we start fading out to silence. + set_stream_paused(true); + } + } break; - if (p_what == NOTIFICATION_UNPAUSED) { - set_stream_paused(false); - } + case NOTIFICATION_UNPAUSED: { + set_stream_paused(false); + } break; - if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { - velocity_tracker->update_position(get_global_transform().origin); - } - } + case NOTIFICATION_TRANSFORM_CHANGED: { + if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { + velocity_tracker->update_position(get_global_transform().origin); + } + } break; - if (p_what == 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())) { - volume_vector = _update_panning(); - } + 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())) { + volume_vector = _update_panning(); + } - if (setplay.get() >= 0 && stream.is_valid()) { - active.set(); - Ref<AudioStreamPlayback> new_playback = stream->instance_playback(); - ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback."); - Map<StringName, Vector<AudioFrame>> bus_map; - bus_map[_get_actual_bus()] = volume_vector; - AudioServer::get_singleton()->start_playback_stream(new_playback, bus_map, setplay.get(), actual_pitch_scale, linear_attenuation, attenuation_filter_cutoff_hz); - stream_playbacks.push_back(new_playback); - setplay.set(-1); - } + if (setplay.get() >= 0 && stream.is_valid()) { + active.set(); + Ref<AudioStreamPlayback> new_playback = stream->instance_playback(); + ERR_FAIL_COND_MSG(new_playback.is_null(), "Failed to instantiate playback."); + Map<StringName, Vector<AudioFrame>> bus_map; + bus_map[_get_actual_bus()] = volume_vector; + AudioServer::get_singleton()->start_playback_stream(new_playback, bus_map, setplay.get(), actual_pitch_scale, linear_attenuation, attenuation_filter_cutoff_hz); + stream_playbacks.push_back(new_playback); + setplay.set(-1); + } - if (!stream_playbacks.is_empty() && active.is_set()) { - // Stop playing if no longer active. - Vector<Ref<AudioStreamPlayback>> playbacks_to_remove; - for (Ref<AudioStreamPlayback> &playback : stream_playbacks) { - if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) { - playbacks_to_remove.push_back(playback); + if (!stream_playbacks.is_empty() && active.is_set()) { + // Stop playing if no longer active. + Vector<Ref<AudioStreamPlayback>> playbacks_to_remove; + for (Ref<AudioStreamPlayback> &playback : stream_playbacks) { + if (playback.is_valid() && !AudioServer::get_singleton()->is_playback_active(playback) && !AudioServer::get_singleton()->is_playback_paused(playback)) { + playbacks_to_remove.push_back(playback); + } + } + // Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble. + for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) { + stream_playbacks.erase(playback); + } + if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) { + // This node is no longer actively playing audio. + active.clear(); + set_physics_process_internal(false); + } + if (!playbacks_to_remove.is_empty()) { + emit_signal(SNAME("finished")); } } - // Now go through and remove playbacks that have finished. Removing elements from a Vector in a range based for is asking for trouble. - for (Ref<AudioStreamPlayback> &playback : playbacks_to_remove) { - stream_playbacks.erase(playback); - } - if (!playbacks_to_remove.is_empty() && stream_playbacks.is_empty()) { - // This node is no longer actively playing audio. - active.clear(); - set_physics_process_internal(false); - } - if (!playbacks_to_remove.is_empty()) { - emit_signal(SNAME("finished")); - } - } - while (stream_playbacks.size() > max_polyphony) { - AudioServer::get_singleton()->stop_playback_stream(stream_playbacks[0]); - stream_playbacks.remove_at(0); - } + while (stream_playbacks.size() > max_polyphony) { + AudioServer::get_singleton()->stop_playback_stream(stream_playbacks[0]); + stream_playbacks.remove_at(0); + } + } break; } } diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 73a4dcd1f7..d0aeffb166 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -107,17 +107,17 @@ TypedArray<String> BoneAttachment3D::get_configuration_warnings() const { if (use_external_skeleton) { if (external_skeleton_node_cache.is_null()) { - warnings.append(TTR("External Skeleton3D node not set! Please set a path to an external Skeleton3D node.")); + warnings.push_back(RTR("External Skeleton3D node not set! Please set a path to an external Skeleton3D node.")); } } else { Skeleton3D *parent = Object::cast_to<Skeleton3D>(get_parent()); if (!parent) { - warnings.append(TTR("Parent node is not a Skeleton3D node! Please use an external Skeleton3D if you intend to use the BoneAttachment3D without it being a child of a Skeleton3D node.")); + warnings.push_back(RTR("Parent node is not a Skeleton3D node! Please use an external Skeleton3D if you intend to use the BoneAttachment3D without it being a child of a Skeleton3D node.")); } } if (bone_idx == -1) { - warnings.append(TTR("BoneAttachment3D node is not bound to any bones! Please select a bone to attach this node.")); + warnings.push_back(RTR("BoneAttachment3D node is not bound to any bones! Please select a bone to attach this node.")); } return warnings; @@ -340,17 +340,20 @@ void BoneAttachment3D::_notification(int p_what) { } _check_bind(); } break; + case NOTIFICATION_EXIT_TREE: { _check_unbind(); } break; + case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { _transform_changed(); } break; + case NOTIFICATION_INTERNAL_PROCESS: { if (_override_dirty) { _override_dirty = false; } - } + } break; } } diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 2c95010eb4..4eace17cc0 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -82,12 +82,6 @@ void Camera3D::_update_camera() { RenderingServer::get_singleton()->camera_set_transform(camera, get_camera_transform()); - // here goes listener stuff - /* - if (viewport_ptr && is_inside_scene() && is_current()) - get_viewport()->_camera_3d_transform_changed_notify(); - */ - if (get_tree()->is_node_being_edited(this) || !is_current()) { return; } @@ -108,14 +102,15 @@ void Camera3D::_notification(int p_what) { if (current || first_camera) { viewport->_camera_3d_set(this); } - } break; + case NOTIFICATION_TRANSFORM_CHANGED: { _request_camera_update(); if (doppler_tracking != DOPPLER_TRACKING_DISABLED) { velocity_tracker->update_position(get_global_transform().origin); } } break; + case NOTIFICATION_EXIT_WORLD: { if (!get_tree()->is_node_being_edited(this)) { if (is_current()) { @@ -131,13 +126,14 @@ void Camera3D::_notification(int p_what) { viewport->_camera_3d_remove(this); viewport = nullptr; } - } break; + case NOTIFICATION_BECAME_CURRENT: { if (viewport) { viewport->find_world_3d()->_register_camera(this); } } break; + case NOTIFICATION_LOST_CURRENT: { if (viewport) { viewport->find_world_3d()->_remove_camera(this); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 3ab09550fa..40c09593a4 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -689,7 +689,7 @@ TypedArray<String> CollisionObject3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (shapes.is_empty()) { - warnings.push_back(TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape3D or CollisionPolygon3D as a child to define its shape.")); + warnings.push_back(RTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape3D or CollisionPolygon3D as a child to define its shape.")); } return warnings; diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp index 7926175459..5a286d7b55 100644 --- a/scene/3d/collision_polygon_3d.cpp +++ b/scene/3d/collision_polygon_3d.cpp @@ -93,18 +93,19 @@ void CollisionPolygon3D::_notification(int p_what) { _update_in_shape_owner(); } } break; + case NOTIFICATION_ENTER_TREE: { if (parent) { _update_in_shape_owner(); } - } break; + case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { if (parent) { _update_in_shape_owner(true); } - } break; + case NOTIFICATION_UNPARENTED: { if (parent) { parent->remove_shape_owner(owner_id); @@ -170,11 +171,11 @@ TypedArray<String> CollisionPolygon3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidDynamicBody3D, CharacterBody3D, etc. to give them a shape.")); + warnings.push_back(RTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidDynamicBody3D, CharacterBody3D, etc. to give them a shape.")); } if (polygon.is_empty()) { - warnings.push_back(TTR("An empty CollisionPolygon3D has no effect on collision.")); + warnings.push_back(RTR("An empty CollisionPolygon3D has no effect on collision.")); } return warnings; diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 773095b377..d28e11a2e9 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -87,16 +87,19 @@ void CollisionShape3D::_notification(int p_what) { _update_in_shape_owner(); } } break; + case NOTIFICATION_ENTER_TREE: { if (parent) { _update_in_shape_owner(); } } break; + case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { if (parent) { _update_in_shape_owner(true); } } break; + case NOTIFICATION_UNPARENTED: { if (parent) { parent->remove_shape_owner(owner_id); @@ -115,17 +118,17 @@ TypedArray<String> CollisionShape3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - warnings.push_back(TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidDynamicBody3D, CharacterBody3D, etc. to give them a shape.")); + warnings.push_back(RTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidDynamicBody3D, CharacterBody3D, etc. to give them a shape.")); } if (!shape.is_valid()) { - warnings.push_back(TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.")); + warnings.push_back(RTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it.")); } if (shape.is_valid() && Object::cast_to<RigidDynamicBody3D>(get_parent()) && Object::cast_to<ConcavePolygonShape3D>(*shape)) { - warnings.push_back(TTR("ConcavePolygonShape3D doesn't support RigidDynamicBody3D in another mode than static.")); + warnings.push_back(RTR("ConcavePolygonShape3D doesn't support RigidDynamicBody3D in another mode than static.")); } return warnings; diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index bd5595f974..fbcabf6529 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -37,7 +37,6 @@ class CollisionObject3D; class CollisionShape3D : public Node3D { GDCLASS(CollisionShape3D, Node3D); - OBJ_CATEGORY("3D Physics Nodes"); Ref<Shape3D> shape; diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index e3d551d782..0befda4168 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -39,10 +39,6 @@ AABB CPUParticles3D::get_aabb() const { return AABB(); } -Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_particle_flags) const { - return Vector<Face3>(); -} - void CPUParticles3D::set_emitting(bool p_emitting) { if (emitting == p_emitting) { return; @@ -210,11 +206,11 @@ TypedArray<String> CPUParticles3D::get_configuration_warnings() const { anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES); if (!mesh_found) { - warnings.push_back(TTR("Nothing is visible because no mesh has been assigned.")); + warnings.push_back(RTR("Nothing is visible because no mesh has been assigned.")); } if (!anim_material_found && (get_param_max(PARAM_ANIM_SPEED) != 0.0 || get_param_max(PARAM_ANIM_OFFSET) != 0.0 || get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) { - warnings.push_back(TTR("CPUParticles3D animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\".")); + warnings.push_back(RTR("CPUParticles3D animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\".")); } return warnings; @@ -512,7 +508,7 @@ bool CPUParticles3D::get_split_scale() { } void CPUParticles3D::_validate_property(PropertyInfo &property) const { - if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { + if (property.name == "emission_sphere_radius" && (emission_shape != EMISSION_SHAPE_SPHERE && emission_shape != EMISSION_SHAPE_SPHERE_SURFACE)) { property.usage = PROPERTY_USAGE_NONE; } @@ -808,6 +804,13 @@ void CPUParticles3D::_particles_process(double p_delta) { case EMISSION_SHAPE_SPHERE: { real_t s = 2.0 * Math::randf() - 1.0; real_t t = Math_TAU * Math::randf(); + real_t x = Math::randf(); + real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); + p.transform.origin = Vector3(0, 0, 0).lerp(Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s), x); + } break; + case EMISSION_SHAPE_SPHERE_SURFACE: { + real_t s = 2.0 * Math::randf() - 1.0; + real_t t = Math_TAU * Math::randf(); real_t radius = emission_sphere_radius * Math::sqrt(1.0 - s * s); p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s); } break; @@ -1251,65 +1254,67 @@ void CPUParticles3D::_update_render_thread() { } void CPUParticles3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - set_process_internal(emitting); + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + set_process_internal(emitting); - // first update before rendering to avoid one frame delay after emitting starts - if (emitting && (time == 0)) { - _update_internal(); - } - } + // first update before rendering to avoid one frame delay after emitting starts + if (emitting && (time == 0)) { + _update_internal(); + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - _set_redraw(false); - } + case NOTIFICATION_EXIT_TREE: { + _set_redraw(false); + } break; - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - // first update before rendering to avoid one frame delay after emitting starts - if (emitting && (time == 0)) { + case NOTIFICATION_VISIBILITY_CHANGED: { + // first update before rendering to avoid one frame delay after emitting starts + if (emitting && (time == 0)) { + _update_internal(); + } + } break; + + case NOTIFICATION_INTERNAL_PROCESS: { _update_internal(); - } - } + } break; - if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - _update_internal(); - } + case NOTIFICATION_TRANSFORM_CHANGED: { + inv_emission_transform = get_global_transform().affine_inverse(); - if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - inv_emission_transform = get_global_transform().affine_inverse(); + if (!local_coords) { + int pc = particles.size(); + + float *w = particle_data.ptrw(); + const Particle *r = particles.ptr(); + float *ptr = w; + + for (int i = 0; i < pc; i++) { + Transform3D t = inv_emission_transform * r[i].transform; + + if (r[i].active) { + ptr[0] = t.basis.elements[0][0]; + ptr[1] = t.basis.elements[0][1]; + ptr[2] = t.basis.elements[0][2]; + ptr[3] = t.origin.x; + ptr[4] = t.basis.elements[1][0]; + ptr[5] = t.basis.elements[1][1]; + ptr[6] = t.basis.elements[1][2]; + ptr[7] = t.origin.y; + ptr[8] = t.basis.elements[2][0]; + ptr[9] = t.basis.elements[2][1]; + ptr[10] = t.basis.elements[2][2]; + ptr[11] = t.origin.z; + } else { + memset(ptr, 0, sizeof(float) * 12); + } - if (!local_coords) { - int pc = particles.size(); - - float *w = particle_data.ptrw(); - const Particle *r = particles.ptr(); - float *ptr = w; - - for (int i = 0; i < pc; i++) { - Transform3D t = inv_emission_transform * r[i].transform; - - if (r[i].active) { - ptr[0] = t.basis.elements[0][0]; - ptr[1] = t.basis.elements[0][1]; - ptr[2] = t.basis.elements[0][2]; - ptr[3] = t.origin.x; - ptr[4] = t.basis.elements[1][0]; - ptr[5] = t.basis.elements[1][1]; - ptr[6] = t.basis.elements[1][2]; - ptr[7] = t.origin.y; - ptr[8] = t.basis.elements[2][0]; - ptr[9] = t.basis.elements[2][1]; - ptr[10] = t.basis.elements[2][2]; - ptr[11] = t.origin.z; - } else { - memset(ptr, 0, sizeof(float) * 12); + ptr += 20; } - ptr += 20; + can_update.set(); } - - can_update.set(); - } + } break; } } @@ -1532,7 +1537,7 @@ void CPUParticles3D::_bind_methods() { ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles3D::convert_from_particles); ADD_GROUP("Emission Shape", "emission_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Sphere Surface,Box,Points,Directed Points,Ring", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_emission_shape", "get_emission_shape"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01"), "set_emission_sphere_radius", "get_emission_sphere_radius"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "emission_points"), "set_emission_points", "get_emission_points"); @@ -1629,6 +1634,7 @@ void CPUParticles3D::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE_SURFACE); BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h index bd736bdf24..521b6c615e 100644 --- a/scene/3d/cpu_particles_3d.h +++ b/scene/3d/cpu_particles_3d.h @@ -71,6 +71,7 @@ public: enum EmissionShape { EMISSION_SHAPE_POINT, EMISSION_SHAPE_SPHERE, + EMISSION_SHAPE_SPHERE_SURFACE, EMISSION_SHAPE_BOX, EMISSION_SHAPE_POINTS, EMISSION_SHAPE_DIRECTED_POINTS, @@ -201,7 +202,6 @@ protected: public: AABB get_aabb() const override; - Vector<Face3> get_faces(uint32_t p_usage_flags) const override; void set_emitting(bool p_emitting); void set_amount(int p_amount); diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index dfac9055f5..a50f75f127 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -152,10 +152,6 @@ AABB Decal::get_aabb() const { return aabb; } -Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void Decal::_validate_property(PropertyInfo &property) const { if (!distance_fade_enabled && (property.name == "distance_fade_begin" || property.name == "distance_fade_length")) { property.usage = PROPERTY_USAGE_NO_EDITOR; @@ -167,15 +163,15 @@ TypedArray<String> Decal::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (textures[TEXTURE_ALBEDO].is_null() && textures[TEXTURE_NORMAL].is_null() && textures[TEXTURE_ORM].is_null() && textures[TEXTURE_EMISSION].is_null()) { - warnings.push_back(TTR("The decal has no textures loaded into any of its texture properties, and will therefore not be visible.")); + warnings.push_back(RTR("The decal has no textures loaded into any of its texture properties, and will therefore not be visible.")); } if ((textures[TEXTURE_NORMAL].is_valid() || textures[TEXTURE_ORM].is_valid()) && textures[TEXTURE_ALBEDO].is_null()) { - warnings.push_back(TTR("The decal has a Normal and/or ORM texture, but no Albedo texture is set.\nAn Albedo texture with an alpha channel is required to blend the normal/ORM maps onto the underlying surface.\nIf you don't want the Albedo texture to be visible, set Albedo Mix to 0.")); + warnings.push_back(RTR("The decal has a Normal and/or ORM texture, but no Albedo texture is set.\nAn Albedo texture with an alpha channel is required to blend the normal/ORM maps onto the underlying surface.\nIf you don't want the Albedo texture to be visible, set Albedo Mix to 0.")); } if (cull_mask == 0) { - warnings.push_back(TTR("The decal's Cull Mask has no bits enabled, which means the decal will not paint objects on any layer.\nTo resolve this, enable at least one bit in the Cull Mask property.")); + warnings.push_back(RTR("The decal's Cull Mask has no bits enabled, which means the decal will not paint objects on any layer.\nTo resolve this, enable at least one bit in the Cull Mask property.")); } return warnings; diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 740dd2c407..d5990272c6 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -104,7 +104,6 @@ public: uint32_t get_cull_mask() const; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; Decal(); ~Decal(); diff --git a/scene/3d/fog_volume.h b/scene/3d/fog_volume.h index 68d5c58169..556a92ad3f 100644 --- a/scene/3d/fog_volume.h +++ b/scene/3d/fog_volume.h @@ -62,7 +62,6 @@ public: Ref<Material> get_material() const; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override { return Vector<Face3>(); } TypedArray<String> get_configuration_warnings() const override; FogVolume(); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index aaaa728838..33ce9fc6fe 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -36,10 +36,6 @@ AABB GPUParticles3D::get_aabb() const { return AABB(); } -Vector<Face3> GPUParticles3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void GPUParticles3D::set_emitting(bool p_emitting) { RS::get_singleton()->particles_set_emitting(particles, p_emitting); @@ -277,7 +273,7 @@ TypedArray<String> GPUParticles3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (RenderingServer::get_singleton()->is_low_end()) { - warnings.push_back(TTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose.")); + warnings.push_back(RTR("GPU-based particles are not supported by the OpenGL video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose.")); } bool meshes_found = false; @@ -304,17 +300,17 @@ TypedArray<String> GPUParticles3D::get_configuration_warnings() const { } if (!meshes_found) { - warnings.push_back(TTR("Nothing is visible because meshes have not been assigned to draw passes.")); + warnings.push_back(RTR("Nothing is visible because meshes have not been assigned to draw passes.")); } if (process_material.is_null()) { - warnings.push_back(TTR("A material to process the particles is not assigned, so no behavior is imprinted.")); + warnings.push_back(RTR("A material to process the particles is not assigned, so no behavior is imprinted.")); } else { const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr()); if (!anim_material_found && process && (process->get_param_max(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) { - warnings.push_back(TTR("Particles animation requires the usage of a BaseMaterial3D whose Billboard Mode is set to \"Particle Billboard\".")); + warnings.push_back(RTR("Particles animation requires the usage of a BaseMaterial3D whose Billboard Mode is set to \"Particle Billboard\".")); } } @@ -356,15 +352,15 @@ TypedArray<String> GPUParticles3D::get_configuration_warnings() const { } if (dp_count && skin.is_valid()) { - warnings.push_back(TTR("Using Trail meshes with a skin causes Skin to override Trail poses. Suggest removing the Skin.")); + warnings.push_back(RTR("Using Trail meshes with a skin causes Skin to override Trail poses. Suggest removing the Skin.")); } else if (dp_count == 0 && skin.is_null()) { - warnings.push_back(TTR("Trails active, but neither Trail meshes or a Skin were found.")); + warnings.push_back(RTR("Trails active, but neither Trail meshes or a Skin were found.")); } else if (dp_count > 1) { - warnings.push_back(TTR("Only one Trail mesh is supported. If you want to use more than a single mesh, a Skin is needed (see documentation).")); + warnings.push_back(RTR("Only one Trail mesh is supported. If you want to use more than a single mesh, a Skin is needed (see documentation).")); } if ((dp_count || !skin.is_null()) && (missing_trails || no_materials)) { - warnings.push_back(TTR("Trails enabled, but one or more mesh materials are either missing or not set for trails rendering.")); + warnings.push_back(RTR("Trails enabled, but one or more mesh materials are either missing or not set for trails rendering.")); } } @@ -423,38 +419,41 @@ NodePath GPUParticles3D::get_sub_emitter() const { } void GPUParticles3D::_notification(int p_what) { - if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) { - if (can_process()) { - RS::get_singleton()->particles_set_speed_scale(particles, speed_scale); - } else { - RS::get_singleton()->particles_set_speed_scale(particles, 0); - } - } - - // Use internal process when emitting and one_shot is on so that when - // the shot ends the editor can properly update - if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (one_shot && !is_emitting()) { - notify_property_list_changed(); - set_process_internal(false); - } - } + switch (p_what) { + case NOTIFICATION_PAUSED: + case NOTIFICATION_UNPAUSED: { + if (can_process()) { + RS::get_singleton()->particles_set_speed_scale(particles, speed_scale); + } else { + RS::get_singleton()->particles_set_speed_scale(particles, 0); + } + } break; + + // Use internal process when emitting and one_shot is on so that when + // the shot ends the editor can properly update. + case NOTIFICATION_INTERNAL_PROCESS: { + if (one_shot && !is_emitting()) { + notify_property_list_changed(); + set_process_internal(false); + } + } break; - if (p_what == NOTIFICATION_ENTER_TREE) { - if (sub_emitter != NodePath()) { - _attach_sub_emitter(); - } - } + case NOTIFICATION_ENTER_TREE: { + if (sub_emitter != NodePath()) { + _attach_sub_emitter(); + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - RS::get_singleton()->particles_set_subemitter(particles, RID()); - } + case NOTIFICATION_EXIT_TREE: { + RS::get_singleton()->particles_set_subemitter(particles, RID()); + } break; - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - // make sure particles are updated before rendering occurs if they were active before - if (is_visible_in_tree() && !RS::get_singleton()->particles_is_inactive(particles)) { - RS::get_singleton()->particles_request_process(particles); - } + case NOTIFICATION_VISIBILITY_CHANGED: { + // Make sure particles are updated before rendering occurs if they were active before. + if (is_visible_in_tree() && !RS::get_singleton()->particles_is_inactive(particles)) { + RS::get_singleton()->particles_request_process(particles); + } + } break; } } diff --git a/scene/3d/gpu_particles_3d.h b/scene/3d/gpu_particles_3d.h index 54ae84628a..f3eb52d124 100644 --- a/scene/3d/gpu_particles_3d.h +++ b/scene/3d/gpu_particles_3d.h @@ -98,7 +98,6 @@ protected: public: AABB get_aabb() const override; - Vector<Face3> get_faces(uint32_t p_usage_flags) const override; void set_emitting(bool p_emitting); void set_amount(int p_amount); diff --git a/scene/3d/gpu_particles_collision_3d.cpp b/scene/3d/gpu_particles_collision_3d.cpp index 54fbc720ce..6f94df284a 100644 --- a/scene/3d/gpu_particles_collision_3d.cpp +++ b/scene/3d/gpu_particles_collision_3d.cpp @@ -584,47 +584,49 @@ GPUParticlesCollisionSDF3D::~GPUParticlesCollisionSDF3D() { //////////////////////////// void GPUParticlesCollisionHeightField3D::_notification(int p_what) { - if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (update_mode == UPDATE_MODE_ALWAYS) { - RS::get_singleton()->particles_collision_height_field_update(_get_collision()); - } + switch (p_what) { + case NOTIFICATION_INTERNAL_PROCESS: { + if (update_mode == UPDATE_MODE_ALWAYS) { + RS::get_singleton()->particles_collision_height_field_update(_get_collision()); + } - if (follow_camera_mode && get_viewport()) { - Camera3D *cam = get_viewport()->get_camera_3d(); - if (cam) { - Transform3D xform = get_global_transform(); - Vector3 x_axis = xform.basis.get_axis(Vector3::AXIS_X).normalized(); - Vector3 z_axis = xform.basis.get_axis(Vector3::AXIS_Z).normalized(); - float x_len = xform.basis.get_scale().x; - float z_len = xform.basis.get_scale().z; + if (follow_camera_mode && get_viewport()) { + Camera3D *cam = get_viewport()->get_camera_3d(); + if (cam) { + Transform3D xform = get_global_transform(); + Vector3 x_axis = xform.basis.get_axis(Vector3::AXIS_X).normalized(); + Vector3 z_axis = xform.basis.get_axis(Vector3::AXIS_Z).normalized(); + float x_len = xform.basis.get_scale().x; + float z_len = xform.basis.get_scale().z; - Vector3 cam_pos = cam->get_global_transform().origin; - Transform3D new_xform = xform; + Vector3 cam_pos = cam->get_global_transform().origin; + Transform3D new_xform = xform; - while (x_axis.dot(cam_pos - new_xform.origin) > x_len) { - new_xform.origin += x_axis * x_len; - } - while (x_axis.dot(cam_pos - new_xform.origin) < -x_len) { - new_xform.origin -= x_axis * x_len; - } + while (x_axis.dot(cam_pos - new_xform.origin) > x_len) { + new_xform.origin += x_axis * x_len; + } + while (x_axis.dot(cam_pos - new_xform.origin) < -x_len) { + new_xform.origin -= x_axis * x_len; + } - while (z_axis.dot(cam_pos - new_xform.origin) > z_len) { - new_xform.origin += z_axis * z_len; - } - while (z_axis.dot(cam_pos - new_xform.origin) < -z_len) { - new_xform.origin -= z_axis * z_len; - } + while (z_axis.dot(cam_pos - new_xform.origin) > z_len) { + new_xform.origin += z_axis * z_len; + } + while (z_axis.dot(cam_pos - new_xform.origin) < -z_len) { + new_xform.origin -= z_axis * z_len; + } - if (new_xform != xform) { - set_global_transform(new_xform); - RS::get_singleton()->particles_collision_height_field_update(_get_collision()); + if (new_xform != xform) { + set_global_transform(new_xform); + RS::get_singleton()->particles_collision_height_field_update(_get_collision()); + } } } - } - } + } break; - if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - RS::get_singleton()->particles_collision_height_field_update(_get_collision()); + case NOTIFICATION_TRANSFORM_CHANGED: { + RS::get_singleton()->particles_collision_height_field_update(_get_collision()); + } break; } } diff --git a/scene/3d/gpu_particles_collision_3d.h b/scene/3d/gpu_particles_collision_3d.h index b6de1d83fc..fdd2fa4b18 100644 --- a/scene/3d/gpu_particles_collision_3d.h +++ b/scene/3d/gpu_particles_collision_3d.h @@ -50,8 +50,6 @@ public: void set_cull_mask(uint32_t p_cull_mask); uint32_t get_cull_mask() const; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override { return Vector<Face3>(); } - ~GPUParticlesCollision3D(); }; @@ -274,8 +272,6 @@ public: void set_directionality(real_t p_directionality); real_t get_directionality() const; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override { return Vector<Face3>(); } - ~GPUParticlesAttractor3D(); }; diff --git a/scene/3d/joint_3d.cpp b/scene/3d/joint_3d.cpp index bd47ab3462..c22e3f6d91 100644 --- a/scene/3d/joint_3d.cpp +++ b/scene/3d/joint_3d.cpp @@ -76,15 +76,15 @@ void Joint3D::_update_joint(bool p_only_free) { PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b); if (node_a && !body_a && node_b && !body_b) { - warning = TTR("Node A and Node B must be PhysicsBody3Ds"); + warning = RTR("Node A and Node B must be PhysicsBody3Ds"); } else if (node_a && !body_a) { - warning = TTR("Node A must be a PhysicsBody3D"); + warning = RTR("Node A must be a PhysicsBody3D"); } else if (node_b && !body_b) { - warning = TTR("Node B must be a PhysicsBody3D"); + warning = RTR("Node B must be a PhysicsBody3D"); } else if (!body_a && !body_b) { - warning = TTR("Joint is not connected to any PhysicsBody3Ds"); + warning = RTR("Joint is not connected to any PhysicsBody3Ds"); } else if (body_a == body_b) { - warning = TTR("Node A and Node B must be different PhysicsBody3Ds"); + warning = RTR("Node A and Node B must be different PhysicsBody3Ds"); } else { warning = String(); } @@ -124,7 +124,7 @@ void Joint3D::set_node_a(const NodePath &p_node_a) { return; } - if (joint.is_valid()) { + if (is_configured()) { _disconnect_signals(); } @@ -141,7 +141,7 @@ void Joint3D::set_node_b(const NodePath &p_node_b) { return; } - if (joint.is_valid()) { + if (is_configured()) { _disconnect_signals(); } @@ -166,14 +166,18 @@ int Joint3D::get_solver_priority() const { void Joint3D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_READY: { + case NOTIFICATION_POST_ENTER_TREE: { + if (is_configured()) { + _disconnect_signals(); + } _update_joint(); } break; + case NOTIFICATION_EXIT_TREE: { - if (joint.is_valid()) { + if (is_configured()) { _disconnect_signals(); - _update_joint(true); } + _update_joint(true); } break; } } @@ -182,6 +186,10 @@ void Joint3D::set_exclude_nodes_from_collision(bool p_enable) { if (exclude_from_collision == p_enable) { return; } + if (is_configured()) { + _disconnect_signals(); + } + _update_joint(true); exclude_from_collision = p_enable; _update_joint(); } diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index d88bb815bc..c95806b2d0 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -74,6 +74,43 @@ bool Light3D::is_negative() const { return negative; } +void Light3D::set_enable_distance_fade(bool p_enable) { + distance_fade_enabled = p_enable; + RS::get_singleton()->light_set_distance_fade(light, distance_fade_enabled, distance_fade_begin, distance_fade_shadow, distance_fade_length); + notify_property_list_changed(); +} + +bool Light3D::is_distance_fade_enabled() const { + return distance_fade_enabled; +} + +void Light3D::set_distance_fade_begin(real_t p_distance) { + distance_fade_begin = p_distance; + RS::get_singleton()->light_set_distance_fade(light, distance_fade_enabled, distance_fade_begin, distance_fade_shadow, distance_fade_length); +} + +real_t Light3D::get_distance_fade_begin() const { + return distance_fade_begin; +} + +void Light3D::set_distance_fade_shadow(real_t p_distance) { + distance_fade_shadow = p_distance; + RS::get_singleton()->light_set_distance_fade(light, distance_fade_enabled, distance_fade_begin, distance_fade_shadow, distance_fade_length); +} + +real_t Light3D::get_distance_fade_shadow() const { + return distance_fade_shadow; +} + +void Light3D::set_distance_fade_length(real_t p_length) { + distance_fade_length = p_length; + RS::get_singleton()->light_set_distance_fade(light, distance_fade_enabled, distance_fade_begin, distance_fade_shadow, distance_fade_length); +} + +real_t Light3D::get_distance_fade_length() const { + return distance_fade_length; +} + void Light3D::set_cull_mask(uint32_t p_cull_mask) { cull_mask = p_cull_mask; RS::get_singleton()->light_set_cull_mask(light, p_cull_mask); @@ -94,15 +131,6 @@ Color Light3D::get_color() const { return color; } -void Light3D::set_shadow_color(const Color &p_shadow_color) { - shadow_color = p_shadow_color; - RS::get_singleton()->light_set_shadow_color(light, p_shadow_color); -} - -Color Light3D::get_shadow_color() const { - return shadow_color; -} - void Light3D::set_shadow_reverse_cull_face(bool p_enable) { reverse_cull = p_enable; RS::get_singleton()->light_set_reverse_cull_face_mode(light, reverse_cull); @@ -128,10 +156,6 @@ AABB Light3D::get_aabb() const { return AABB(); } -Vector<Face3> Light3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void Light3D::set_bake_mode(BakeMode p_mode) { bake_mode = p_mode; RS::get_singleton()->light_set_bake_mode(light, RS::LightBakeMode(p_mode)); @@ -177,12 +201,11 @@ void Light3D::_update_visibility() { } void Light3D::_notification(int p_what) { - if (p_what == NOTIFICATION_VISIBILITY_CHANGED) { - _update_visibility(); - } - - if (p_what == NOTIFICATION_ENTER_TREE) { - _update_visibility(); + switch (p_what) { + case NOTIFICATION_VISIBILITY_CHANGED: + case NOTIFICATION_ENTER_TREE: { + _update_visibility(); + } break; } } @@ -196,7 +219,7 @@ bool Light3D::is_editor_only() const { } void Light3D::_validate_property(PropertyInfo &property) const { - if (!shadow && (property.name == "shadow_color" || property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur")) { + if (!shadow && (property.name == "shadow_bias" || property.name == "shadow_normal_bias" || property.name == "shadow_reverse_cull_face" || property.name == "shadow_transmittance_bias" || property.name == "shadow_fog_fade" || property.name == "shadow_blur" || property.name == "distance_fade_shadow")) { property.usage = PROPERTY_USAGE_NO_EDITOR; } @@ -204,6 +227,11 @@ void Light3D::_validate_property(PropertyInfo &property) const { // Angular distance is only used in DirectionalLight3D. property.usage = PROPERTY_USAGE_NONE; } + + if (!distance_fade_enabled && (property.name == "distance_fade_begin" || property.name == "distance_fade_shadow" || property.name == "distance_fade_length")) { + property.usage = PROPERTY_USAGE_NO_EDITOR; + } + VisualInstance3D::_validate_property(property); } @@ -223,15 +251,24 @@ void Light3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_cull_mask", "cull_mask"), &Light3D::set_cull_mask); ClassDB::bind_method(D_METHOD("get_cull_mask"), &Light3D::get_cull_mask); + ClassDB::bind_method(D_METHOD("set_enable_distance_fade", "enable"), &Light3D::set_enable_distance_fade); + ClassDB::bind_method(D_METHOD("is_distance_fade_enabled"), &Light3D::is_distance_fade_enabled); + + ClassDB::bind_method(D_METHOD("set_distance_fade_begin", "distance"), &Light3D::set_distance_fade_begin); + ClassDB::bind_method(D_METHOD("get_distance_fade_begin"), &Light3D::get_distance_fade_begin); + + ClassDB::bind_method(D_METHOD("set_distance_fade_shadow", "distance"), &Light3D::set_distance_fade_shadow); + ClassDB::bind_method(D_METHOD("get_distance_fade_shadow"), &Light3D::get_distance_fade_shadow); + + ClassDB::bind_method(D_METHOD("set_distance_fade_length", "distance"), &Light3D::set_distance_fade_length); + ClassDB::bind_method(D_METHOD("get_distance_fade_length"), &Light3D::get_distance_fade_length); + ClassDB::bind_method(D_METHOD("set_color", "color"), &Light3D::set_color); ClassDB::bind_method(D_METHOD("get_color"), &Light3D::get_color); ClassDB::bind_method(D_METHOD("set_shadow_reverse_cull_face", "enable"), &Light3D::set_shadow_reverse_cull_face); ClassDB::bind_method(D_METHOD("get_shadow_reverse_cull_face"), &Light3D::get_shadow_reverse_cull_face); - ClassDB::bind_method(D_METHOD("set_shadow_color", "shadow_color"), &Light3D::set_shadow_color); - ClassDB::bind_method(D_METHOD("get_shadow_color"), &Light3D::get_shadow_color); - ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &Light3D::set_bake_mode); ClassDB::bind_method(D_METHOD("get_bake_mode"), &Light3D::get_bake_mode); @@ -251,13 +288,17 @@ void Light3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "light_cull_mask", PROPERTY_HINT_LAYERS_3D_RENDER), "set_cull_mask", "get_cull_mask"); ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_enabled"), "set_shadow", "has_shadow"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_shadow_color", "get_shadow_color"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_normal_bias", PROPERTY_HINT_RANGE, "0,10,0.001"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_reverse_cull_face"), "set_shadow_reverse_cull_face", "get_shadow_reverse_cull_face"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_transmittance_bias", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_param", "get_param", PARAM_TRANSMITTANCE_BIAS); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_fog_fade", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_param", "get_param", PARAM_SHADOW_VOLUMETRIC_FOG_FADE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "shadow_blur", PROPERTY_HINT_RANGE, "0.1,8,0.01"), "set_param", "get_param", PARAM_SHADOW_BLUR); + ADD_GROUP("Distance Fade", "distance_fade_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "distance_fade_enabled"), "set_enable_distance_fade", "is_distance_fade_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater"), "set_distance_fade_begin", "get_distance_fade_begin"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_shadow", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater"), "set_distance_fade_shadow", "get_distance_fade_shadow"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance_fade_length", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater"), "set_distance_fade_length", "get_distance_fade_length"); ADD_GROUP("Editor", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editor_only"), "set_editor_only", "is_editor_only"); ADD_GROUP("", ""); @@ -367,13 +408,13 @@ bool DirectionalLight3D::is_blend_splits_enabled() const { return blend_splits; } -void DirectionalLight3D::set_sky_only(bool p_sky_only) { - sky_only = p_sky_only; - RS::get_singleton()->light_directional_set_sky_only(light, p_sky_only); +void DirectionalLight3D::set_sky_mode(SkyMode p_mode) { + sky_mode = p_mode; + RS::get_singleton()->light_directional_set_sky_mode(light, RS::LightDirectionalSkyMode(p_mode)); } -bool DirectionalLight3D::is_sky_only() const { - return sky_only; +DirectionalLight3D::SkyMode DirectionalLight3D::get_sky_mode() const { + return sky_mode; } void DirectionalLight3D::_validate_property(PropertyInfo &property) const { @@ -392,6 +433,12 @@ void DirectionalLight3D::_validate_property(PropertyInfo &property) const { property.usage = PROPERTY_USAGE_NONE; } + if (property.name == "distance_fade_enabled" || property.name == "distance_fade_begin" || property.name == "distance_fade_shadow" || property.name == "distance_fade_length") { + // Not relevant for DirectionalLight3D, as the light LOD system only pertains to point lights. + // For DirectionalLight3D, `directional_shadow_max_distance` can be used instead. + property.usage = PROPERTY_USAGE_NONE; + } + Light3D::_validate_property(property); } @@ -402,8 +449,8 @@ void DirectionalLight3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_splits", "enabled"), &DirectionalLight3D::set_blend_splits); ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight3D::is_blend_splits_enabled); - ClassDB::bind_method(D_METHOD("set_sky_only", "priority"), &DirectionalLight3D::set_sky_only); - ClassDB::bind_method(D_METHOD("is_sky_only"), &DirectionalLight3D::is_sky_only); + ClassDB::bind_method(D_METHOD("set_sky_mode", "mode"), &DirectionalLight3D::set_sky_mode); + ClassDB::bind_method(D_METHOD("get_sky_mode"), &DirectionalLight3D::get_sky_mode); ADD_GROUP("Directional Shadow", "directional_shadow_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 4 Splits (Slow)"), "set_shadow_mode", "get_shadow_mode"); @@ -415,11 +462,15 @@ void DirectionalLight3D::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_max_distance", PROPERTY_HINT_RANGE, "0,8192,0.1,or_greater,exp"), "set_param", "get_param", PARAM_SHADOW_MAX_DISTANCE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_shadow_pancake_size", PROPERTY_HINT_RANGE, "0,1024,0.1,or_greater,exp"), "set_param", "get_param", PARAM_SHADOW_PANCAKE_SIZE); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_in_sky_only"), "set_sky_only", "is_sky_only"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sky_mode", PROPERTY_HINT_ENUM, "Light and Sky,Light Only,Sky Only"), "set_sky_mode", "get_sky_mode"); BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS); + + BIND_ENUM_CONSTANT(SKY_MODE_LIGHT_AND_SKY); + BIND_ENUM_CONSTANT(SKY_MODE_LIGHT_ONLY); + BIND_ENUM_CONSTANT(SKY_MODE_SKY_ONLY); } DirectionalLight3D::DirectionalLight3D() : @@ -430,6 +481,7 @@ DirectionalLight3D::DirectionalLight3D() : set_param(PARAM_SHADOW_BIAS, 0.1); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); blend_splits = false; + set_sky_mode(SKY_MODE_LIGHT_AND_SKY); } void OmniLight3D::set_shadow_mode(ShadowMode p_mode) { @@ -445,7 +497,7 @@ TypedArray<String> OmniLight3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!has_shadow() && get_projector().is_valid()) { - warnings.push_back(TTR("Projector texture only works with shadows active.")); + warnings.push_back(RTR("Projector texture only works with shadows active.")); } return warnings; @@ -475,11 +527,11 @@ TypedArray<String> SpotLight3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) { - warnings.push_back(TTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows.")); + warnings.push_back(RTR("A SpotLight3D with an angle wider than 90 degrees cannot cast shadows.")); } if (!has_shadow() && get_projector().is_valid()) { - warnings.push_back(TTR("Projector texture only works with shadows active.")); + warnings.push_back(RTR("Projector texture only works with shadows active.")); } return warnings; diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h index d5d2aee43d..383fa644e5 100644 --- a/scene/3d/light_3d.h +++ b/scene/3d/light_3d.h @@ -35,7 +35,6 @@ class Light3D : public VisualInstance3D { GDCLASS(Light3D, VisualInstance3D); - OBJ_CATEGORY("3D Light Nodes"); public: enum Param { @@ -70,11 +69,14 @@ public: private: Color color; real_t param[PARAM_MAX] = {}; - Color shadow_color; bool shadow = false; bool negative = false; bool reverse_cull = false; uint32_t cull_mask = 0; + bool distance_fade_enabled = false; + real_t distance_fade_begin = 40.0; + real_t distance_fade_shadow = 50.0; + real_t distance_fade_length = 10.0; RS::LightType type = RenderingServer::LIGHT_DIRECTIONAL; bool editor_only = false; void _update_visibility(); @@ -107,15 +109,24 @@ public: void set_negative(bool p_enable); bool is_negative() const; + void set_enable_distance_fade(bool p_enable); + bool is_distance_fade_enabled() const; + + void set_distance_fade_begin(real_t p_distance); + real_t get_distance_fade_begin() const; + + void set_distance_fade_shadow(real_t p_distance); + real_t get_distance_fade_shadow() const; + + void set_distance_fade_length(real_t p_length); + real_t get_distance_fade_length() const; + void set_cull_mask(uint32_t p_cull_mask); uint32_t get_cull_mask() const; void set_color(const Color &p_color); Color get_color() const; - void set_shadow_color(const Color &p_shadow_color); - Color get_shadow_color() const; - void set_shadow_reverse_cull_face(bool p_enable); bool get_shadow_reverse_cull_face() const; @@ -126,7 +137,6 @@ public: Ref<Texture2D> get_projector() const; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; Light3D(); ~Light3D(); @@ -145,10 +155,16 @@ public: SHADOW_PARALLEL_4_SPLITS, }; + enum SkyMode { + SKY_MODE_LIGHT_AND_SKY, + SKY_MODE_LIGHT_ONLY, + SKY_MODE_SKY_ONLY, + }; + private: bool blend_splits; ShadowMode shadow_mode; - bool sky_only = false; + SkyMode sky_mode = SKY_MODE_LIGHT_AND_SKY; protected: static void _bind_methods(); @@ -161,13 +177,14 @@ public: void set_blend_splits(bool p_enable); bool is_blend_splits_enabled() const; - void set_sky_only(bool p_sky_only); - bool is_sky_only() const; + void set_sky_mode(SkyMode p_mode); + SkyMode get_sky_mode() const; DirectionalLight3D(); }; VARIANT_ENUM_CAST(DirectionalLight3D::ShadowMode) +VARIANT_ENUM_CAST(DirectionalLight3D::SkyMode) class OmniLight3D : public Light3D { GDCLASS(OmniLight3D, Light3D); diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 825742da35..191a04b6a0 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -635,7 +635,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa bsud.to_percent = 0.8; if (p_bake_step) { - p_bake_step(0.0, TTR("Finding meshes, lights and probes"), p_bake_userdata, true); + p_bake_step(0.0, RTR("Finding meshes, lights and probes"), p_bake_userdata, true); } /* STEP 1, FIND MESHES, LIGHTS AND PROBES */ Vector<Lightmapper::MeshData> mesh_data; @@ -655,7 +655,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa for (int m_i = 0; m_i < meshes_found.size(); m_i++) { if (p_bake_step) { float p = (float)(m_i) / meshes_found.size(); - p_bake_step(p * 0.1, vformat(TTR("Preparing geometry %d/%d"), m_i, meshes_found.size()), p_bake_userdata, false); + p_bake_step(p * 0.1, vformat(RTR("Preparing geometry %d/%d"), m_i, meshes_found.size()), p_bake_userdata, false); } MeshesFound &mf = meshes_found.write[m_i]; @@ -790,7 +790,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa /* STEP 2, CREATE PROBES */ if (p_bake_step) { - p_bake_step(0.3, TTR("Creating probes"), p_bake_userdata, true); + p_bake_step(0.3, RTR("Creating probes"), p_bake_userdata, true); } //bounds need to include the user probes @@ -832,7 +832,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa for (int i = 0; i < mesh_data.size(); i++) { if (p_bake_step) { float p = (float)(i) / mesh_data.size(); - p_bake_step(0.3 + p * 0.1, vformat(TTR("Creating probes from mesh %d/%d"), i, mesh_data.size()), p_bake_userdata, false); + p_bake_step(0.3 + p * 0.1, vformat(RTR("Creating probes from mesh %d/%d"), i, mesh_data.size()), p_bake_userdata, false); } for (int j = 0; j < mesh_data[i].points.size(); j += 3) { @@ -873,7 +873,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa // Add everything to lightmapper if (p_bake_step) { - p_bake_step(0.4, TTR("Preparing Lightmapper"), p_bake_userdata, true); + p_bake_step(0.4, RTR("Preparing Lightmapper"), p_bake_userdata, true); } { @@ -907,7 +907,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa // Add everything to lightmapper if (environment_mode != ENVIRONMENT_MODE_DISABLED) { if (p_bake_step) { - p_bake_step(4.1, TTR("Preparing Environment"), p_bake_userdata, true); + p_bake_step(4.1, RTR("Preparing Environment"), p_bake_userdata, true); } environment_transform = get_global_transform().basis; @@ -982,7 +982,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa } config->set_value("remap", "importer", "2d_array_texture"); - config->set_value("remap", "type", "StreamTexture2DArray"); + config->set_value("remap", "type", "CompressedTexture2DArray"); if (!config->has_section_key("params", "compress/mode")) { config->set_value("params", "compress/mode", 2); //user may want another compression, so leave it be } @@ -1046,7 +1046,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa //Obtain solved simplices if (p_bake_step) { - p_bake_step(0.8, TTR("Generating Probe Volumes"), p_bake_userdata, true); + p_bake_step(0.8, RTR("Generating Probe Volumes"), p_bake_userdata, true); } Vector<Delaunay3D::OutputSimplex> solved_simplices = Delaunay3D::tetrahedralize(points); @@ -1130,7 +1130,7 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa } if (p_bake_step) { - p_bake_step(0.9, TTR("Generating Probe Acceleration Structures"), p_bake_userdata, true); + p_bake_step(0.9, RTR("Generating Probe Acceleration Structures"), p_bake_userdata, true); } _compute_bsp_tree(points, bsp_planes, planes_tested, bsp_simplices, bsp_simplex_indices, bsp_nodes); @@ -1176,16 +1176,18 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa } void LightmapGI::_notification(int p_what) { - if (p_what == NOTIFICATION_POST_ENTER_TREE) { - if (light_data.is_valid()) { - _assign_lightmaps(); - } - } + switch (p_what) { + case NOTIFICATION_POST_ENTER_TREE: { + if (light_data.is_valid()) { + _assign_lightmaps(); + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - if (light_data.is_valid()) { - _clear_lightmaps(); - } + case NOTIFICATION_EXIT_TREE: { + if (light_data.is_valid()) { + _clear_lightmaps(); + } + } break; } } @@ -1261,10 +1263,6 @@ AABB LightmapGI::get_aabb() const { return AABB(); } -Vector<Face3> LightmapGI::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void LightmapGI::set_use_denoiser(bool p_enable) { use_denoiser = p_enable; } diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h index 66acf4f487..d29d7a7c28 100644 --- a/scene/3d/lightmap_gi.h +++ b/scene/3d/lightmap_gi.h @@ -267,7 +267,6 @@ public: GenerateProbes get_generate_probes() const; AABB get_aabb() const override; - Vector<Face3> get_faces(uint32_t p_usage_flags) const override; BakeError bake(Node *p_from_node, String p_image_data_path = "", Lightmapper::BakeStepFunc p_bake_step = nullptr, void *p_bake_userdata = nullptr); LightmapGI(); diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 58ff512130..31c33a6b61 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -219,18 +219,6 @@ AABB MeshInstance3D::get_aabb() const { return AABB(); } -Vector<Face3> MeshInstance3D::get_faces(uint32_t p_usage_flags) const { - if (!(p_usage_flags & (FACES_SOLID | FACES_ENCLOSING))) { - return Vector<Face3>(); - } - - if (mesh.is_null()) { - return Vector<Face3>(); - } - - return mesh->get_faces(); -} - Node *MeshInstance3D::create_trimesh_collision_node() { if (mesh.is_null()) { return nullptr; @@ -328,8 +316,10 @@ void MeshInstance3D::create_multiple_convex_collisions() { } void MeshInstance3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - _resolve_skeleton_path(); + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + _resolve_skeleton_path(); + } break; } } diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h index 03ee3cd608..0bf5c32410 100644 --- a/scene/3d/mesh_instance_3d.h +++ b/scene/3d/mesh_instance_3d.h @@ -93,7 +93,6 @@ public: void create_debug_tangents(); virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; MeshInstance3D(); ~MeshInstance3D(); diff --git a/scene/3d/multimesh_instance_3d.cpp b/scene/3d/multimesh_instance_3d.cpp index 34b1e86435..d197388fad 100644 --- a/scene/3d/multimesh_instance_3d.cpp +++ b/scene/3d/multimesh_instance_3d.cpp @@ -49,10 +49,6 @@ Ref<MultiMesh> MultiMeshInstance3D::get_multimesh() const { return multimesh; } -Vector<Face3> MultiMeshInstance3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - AABB MultiMeshInstance3D::get_aabb() const { if (multimesh.is_null()) { return AABB(); diff --git a/scene/3d/multimesh_instance_3d.h b/scene/3d/multimesh_instance_3d.h index d03b24eb4e..111f1e9c09 100644 --- a/scene/3d/multimesh_instance_3d.h +++ b/scene/3d/multimesh_instance_3d.h @@ -44,8 +44,6 @@ protected: // bind helpers public: - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; - void set_multimesh(const Ref<MultiMesh> &p_multimesh); Ref<MultiMesh> get_multimesh() const; diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index e90971845e..86c11b3789 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -62,6 +62,9 @@ void NavigationAgent3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_path_max_distance", "max_speed"), &NavigationAgent3D::set_path_max_distance); ClassDB::bind_method(D_METHOD("get_path_max_distance"), &NavigationAgent3D::get_path_max_distance); + ClassDB::bind_method(D_METHOD("set_navigable_layers", "navigable_layers"), &NavigationAgent3D::set_navigable_layers); + ClassDB::bind_method(D_METHOD("get_navigable_layers"), &NavigationAgent3D::get_navigable_layers); + ClassDB::bind_method(D_METHOD("set_target_location", "location"), &NavigationAgent3D::set_target_location); ClassDB::bind_method(D_METHOD("get_target_location"), &NavigationAgent3D::get_target_location); ClassDB::bind_method(D_METHOD("get_next_location"), &NavigationAgent3D::get_next_location); @@ -85,6 +88,7 @@ void NavigationAgent3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01"), "set_max_speed", "get_max_speed"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "path_max_distance", PROPERTY_HINT_RANGE, "0.01,100,0.1"), "set_path_max_distance", "get_path_max_distance"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_y"), "set_ignore_y", "get_ignore_y"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "navigable_layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_navigable_layers", "get_navigable_layers"); ADD_SIGNAL(MethodInfo("path_changed")); ADD_SIGNAL(MethodInfo("target_reached")); @@ -103,10 +107,12 @@ void NavigationAgent3D::_notification(int p_what) { } set_physics_process_internal(true); } break; + case NOTIFICATION_EXIT_TREE: { agent_parent = nullptr; set_physics_process_internal(false); } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (agent_parent) { NavigationServer3D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin); @@ -131,6 +137,18 @@ NavigationAgent3D::~NavigationAgent3D() { agent = RID(); // Pointless } +void NavigationAgent3D::set_navigable_layers(uint32_t p_layers) { + bool layers_changed = navigable_layers != p_layers; + navigable_layers = p_layers; + if (layers_changed) { + _request_repath(); + } +} + +uint32_t NavigationAgent3D::get_navigable_layers() const { + return navigable_layers; +} + void NavigationAgent3D::set_target_desired_distance(real_t p_dd) { target_desired_distance = p_dd; } @@ -179,10 +197,7 @@ real_t NavigationAgent3D::get_path_max_distance() { void NavigationAgent3D::set_target_location(Vector3 p_location) { target_location = p_location; - navigation_path.clear(); - target_reached = false; - navigation_finished = false; - update_frame_id = 0; + _request_repath(); } Vector3 NavigationAgent3D::get_target_location() const { @@ -248,7 +263,7 @@ TypedArray<String> NavigationAgent3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<Node3D>(get_parent())) { - warnings.push_back(TTR("The NavigationAgent3D can be used only under a spatial node.")); + warnings.push_back(RTR("The NavigationAgent3D can be used only under a spatial node.")); } return warnings; @@ -292,7 +307,7 @@ void NavigationAgent3D::update_navigation() { } if (reload_path) { - navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true); + navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true, navigable_layers); navigation_finished = false; nav_path_index = 0; emit_signal(SNAME("path_changed")); @@ -318,6 +333,13 @@ void NavigationAgent3D::update_navigation() { } } +void NavigationAgent3D::_request_repath() { + navigation_path.clear(); + target_reached = false; + navigation_finished = false; + update_frame_id = 0; +} + void NavigationAgent3D::_check_distance_to_target() { if (!target_reached) { if (distance_to_target() < target_desired_distance) { diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index aebd5be7e4..f4afebb36e 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -42,6 +42,8 @@ class NavigationAgent3D : public Node { RID agent; + uint32_t navigable_layers = 1; + real_t target_desired_distance = 1.0; real_t radius; real_t navigation_height_offset = 0.0; @@ -77,6 +79,9 @@ public: return agent; } + void set_navigable_layers(uint32_t p_layers); + uint32_t get_navigable_layers() const; + void set_target_desired_distance(real_t p_dd); real_t get_target_desired_distance() const { return target_desired_distance; @@ -146,6 +151,7 @@ public: private: void update_navigation(); + void _request_repath(); void _check_distance_to_target(); }; diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index ba6c50d98c..78dbecc0c5 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -63,17 +63,21 @@ void NavigationObstacle3D::_notification(int p_what) { } set_physics_process_internal(true); } break; + case NOTIFICATION_EXIT_TREE: { parent_node3d = nullptr; set_physics_process_internal(false); } break; + case NOTIFICATION_PARENTED: { parent_node3d = Object::cast_to<Node3D>(get_parent()); reevaluate_agent_radius(); } break; + case NOTIFICATION_UNPARENTED: { parent_node3d = nullptr; } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (parent_node3d) { NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin); @@ -103,7 +107,7 @@ TypedArray<String> NavigationObstacle3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<Node3D>(get_parent())) { - warnings.push_back(TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.")); + warnings.push_back(RTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.")); } return warnings; diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 1e298e0137..215e18869a 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -93,12 +93,12 @@ void NavigationRegion3D::_notification(int p_what) { add_child(dm); debug_view = dm; } - } break; + case NOTIFICATION_TRANSFORM_CHANGED: { NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform()); - } break; + case NOTIFICATION_EXIT_TREE: { NavigationServer3D::get_singleton()->region_set_map(region, RID()); @@ -181,7 +181,7 @@ TypedArray<String> NavigationRegion3D::get_configuration_warnings() const { if (is_visible_in_tree() && is_inside_tree()) { if (!navmesh.is_valid()) { - warnings.push_back(TTR("A NavigationMesh resource must be set or created for this node to work.")); + warnings.push_back(RTR("A NavigationMesh resource must be set or created for this node to work.")); } } diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index cad1201d63..62cc7c143b 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -147,8 +147,8 @@ void Node3D::_notification(int p_what) { notification(NOTIFICATION_ENTER_WORLD); _update_visibility_parent(true); - } break; + case NOTIFICATION_EXIT_TREE: { notification(NOTIFICATION_EXIT_WORLD, true); if (xform_change.in_list()) { @@ -162,6 +162,7 @@ void Node3D::_notification(int p_what) { data.top_level_active = false; _update_visibility_parent(true); } break; + case NOTIFICATION_ENTER_WORLD: { data.inside_world = true; data.viewport = nullptr; @@ -192,6 +193,7 @@ void Node3D::_notification(int p_what) { } #endif } break; + case NOTIFICATION_EXIT_WORLD: { #ifdef TOOLS_ENABLED clear_gizmos(); @@ -203,7 +205,6 @@ void Node3D::_notification(int p_what) { data.viewport = nullptr; data.inside_world = false; - } break; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -213,9 +214,6 @@ void Node3D::_notification(int p_what) { } #endif } break; - - default: { - } } } diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h index 65d0e071cf..6d857a83ea 100644 --- a/scene/3d/node_3d.h +++ b/scene/3d/node_3d.h @@ -50,7 +50,6 @@ public: class Node3D : public Node { GDCLASS(Node3D, Node); - OBJ_CATEGORY("3D"); public: enum RotationEditMode { diff --git a/scene/3d/occluder_instance_3d.cpp b/scene/3d/occluder_instance_3d.cpp index 231817526c..f848eaab2e 100644 --- a/scene/3d/occluder_instance_3d.cpp +++ b/scene/3d/occluder_instance_3d.cpp @@ -122,8 +122,10 @@ AABB Occluder3D::get_aabb() const { } void Occluder3D::_notification(int p_what) { - if (p_what == NOTIFICATION_POSTINITIALIZE) { - _update(); + switch (p_what) { + case NOTIFICATION_POSTINITIALIZE: { + _update(); + } break; } } @@ -190,7 +192,6 @@ void QuadOccluder3D::set_size(const Vector2 &p_size) { } size = p_size.max(Vector2()); - ; _update(); } @@ -235,7 +236,6 @@ void BoxOccluder3D::set_size(const Vector3 &p_size) { } size = Vector3(MAX(p_size.x, 0.0f), MAX(p_size.y, 0.0f), MAX(p_size.z, 0.0f)); - ; _update(); } @@ -433,10 +433,6 @@ AABB OccluderInstance3D::get_aabb() const { return AABB(); } -Vector<Face3> OccluderInstance3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void OccluderInstance3D::set_occluder(const Ref<Occluder3D> &p_occluder) { if (occluder == p_occluder) { return; @@ -690,25 +686,25 @@ TypedArray<String> OccluderInstance3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!bool(GLOBAL_GET("rendering/occlusion_culling/use_occlusion_culling"))) { - warnings.push_back(TTR("Occlusion culling is disabled in the Project Settings, which means occlusion culling won't be performed in the root viewport.\nTo resolve this, open the Project Settings and enable Rendering > Occlusion Culling > Use Occlusion Culling.")); + warnings.push_back(RTR("Occlusion culling is disabled in the Project Settings, which means occlusion culling won't be performed in the root viewport.\nTo resolve this, open the Project Settings and enable Rendering > Occlusion Culling > Use Occlusion Culling.")); } if (bake_mask == 0) { - warnings.push_back(TTR("The Bake Mask has no bits enabled, which means baking will not produce any occluder meshes for this OccluderInstance3D.\nTo resolve this, enable at least one bit in the Bake Mask property.")); + warnings.push_back(RTR("The Bake Mask has no bits enabled, which means baking will not produce any occluder meshes for this OccluderInstance3D.\nTo resolve this, enable at least one bit in the Bake Mask property.")); } if (occluder.is_null()) { - warnings.push_back(TTR("No occluder mesh is defined in the Occluder property, so no occlusion culling will be performed using this OccluderInstance3D.\nTo resolve this, set the Occluder property to one of the primitive occluder types or bake the scene meshes by selecting the OccluderInstance3D and pressing the Bake Occluders button at the top of the 3D editor viewport.")); + warnings.push_back(RTR("No occluder mesh is defined in the Occluder property, so no occlusion culling will be performed using this OccluderInstance3D.\nTo resolve this, set the Occluder property to one of the primitive occluder types or bake the scene meshes by selecting the OccluderInstance3D and pressing the Bake Occluders button at the top of the 3D editor viewport.")); } else { Ref<ArrayOccluder3D> arr_occluder = occluder; if (arr_occluder.is_valid() && arr_occluder->get_indices().size() < 3) { // Setting a new ArrayOccluder3D from the inspector will create an empty occluder, // so warn the user about this. - warnings.push_back(TTR("The occluder mesh has less than 3 vertices, so no occlusion culling will be performed using this OccluderInstance3D.\nTo generate a proper occluder mesh, select the OccluderInstance3D then use the Bake Occluders button at the top of the 3D editor viewport.")); + warnings.push_back(RTR("The occluder mesh has less than 3 vertices, so no occlusion culling will be performed using this OccluderInstance3D.\nTo generate a proper occluder mesh, select the OccluderInstance3D then use the Bake Occluders button at the top of the 3D editor viewport.")); } Ref<PolygonOccluder3D> poly_occluder = occluder; if (poly_occluder.is_valid() && poly_occluder->get_polygon().size() < 3) { - warnings.push_back(TTR("The polygon occluder has less than 3 vertices, so no occlusion culling will be performed using this OccluderInstance3D.\nVertices can be added in the inspector or using the polygon editing tools at the top of the 3D editor viewport.")); + warnings.push_back(RTR("The polygon occluder has less than 3 vertices, so no occlusion culling will be performed using this OccluderInstance3D.\nVertices can be added in the inspector or using the polygon editing tools at the top of the 3D editor viewport.")); } } diff --git a/scene/3d/occluder_instance_3d.h b/scene/3d/occluder_instance_3d.h index 669ddba775..ed6610074e 100644 --- a/scene/3d/occluder_instance_3d.h +++ b/scene/3d/occluder_instance_3d.h @@ -194,7 +194,6 @@ public: Ref<Occluder3D> get_occluder() const; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; void set_bake_mask(uint32_t p_mask); uint32_t get_bake_mask() const; diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp index 6e1c9ef781..7a5cb26a29 100644 --- a/scene/3d/path_3d.cpp +++ b/scene/3d/path_3d.cpp @@ -30,9 +30,6 @@ #include "path_3d.h" -void Path3D::_notification(int p_what) { -} - void Path3D::_curve_changed() { if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) { update_gizmos(); @@ -223,8 +220,8 @@ void PathFollow3D::_notification(int p_what) { _update_transform(false); } } - } break; + case NOTIFICATION_EXIT_TREE: { path = nullptr; } break; @@ -256,11 +253,11 @@ TypedArray<String> PathFollow3D::get_configuration_warnings() const { if (is_visible_in_tree() && is_inside_tree()) { if (!Object::cast_to<Path3D>(get_parent())) { - warnings.push_back(TTR("PathFollow3D only works when set as a child of a Path3D node.")); + warnings.push_back(RTR("PathFollow3D only works when set as a child of a Path3D node.")); } else { Path3D *path = Object::cast_to<Path3D>(get_parent()); if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) { - warnings.push_back(TTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.")); + warnings.push_back(RTR("PathFollow3D's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path3D's Curve resource.")); } } } diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h index 32ca5a1beb..e9ab557693 100644 --- a/scene/3d/path_3d.h +++ b/scene/3d/path_3d.h @@ -42,7 +42,6 @@ class Path3D : public Node3D { void _curve_changed(); protected: - void _notification(int p_what); static void _bind_methods(); public: diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 13a38f3b9f..dee76aef10 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -601,7 +601,7 @@ void RigidDynamicBody3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { if (Engine::get_singleton()->is_editor_hint()) { - set_notify_local_transform(true); //used for warnings and only in editor + set_notify_local_transform(true); // Used for warnings and only in editor. } } break; @@ -988,7 +988,7 @@ TypedArray<String> RigidDynamicBody3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05) { - warnings.push_back(TTR("Size changes to RigidDynamicBody will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + warnings.push_back(RTR("Size changes to RigidDynamicBody will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; @@ -1169,7 +1169,7 @@ bool CharacterBody3D::move_and_slide() { for (int i = 0; i < 3; i++) { if (locked_axis & (1 << i)) { - motion_velocity[i] = 0.0; + velocity[i] = 0.0; } } @@ -1239,7 +1239,7 @@ bool CharacterBody3D::move_and_slide() { if (moving_platform_apply_velocity_on_leave == PLATFORM_VEL_ON_LEAVE_UPWARD_ONLY && current_platform_velocity.dot(up_direction) < 0) { current_platform_velocity = current_platform_velocity.slide(up_direction); } - motion_velocity += current_platform_velocity; + velocity += current_platform_velocity; } } @@ -1247,7 +1247,7 @@ bool CharacterBody3D::move_and_slide() { } void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_floor) { - Vector3 motion = motion_velocity * p_delta; + Vector3 motion = velocity * p_delta; Vector3 motion_slide_up = motion.slide(up_direction); Vector3 prev_floor_normal = floor_normal; @@ -1267,7 +1267,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo // If the platform's ceiling push down the body. bool apply_ceiling_velocity = false; bool first_slide = true; - bool vel_dir_facing_up = motion_velocity.dot(up_direction) > 0; + bool vel_dir_facing_up = velocity.dot(up_direction) > 0; Vector3 total_travel; for (int iteration = 0; iteration < max_slides; ++iteration) { @@ -1287,26 +1287,26 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo CollisionState result_state; _set_collision_direction(result, result_state); - // If we hit a ceiling platform, we set the vertical motion_velocity to at least the platform one. + // If we hit a ceiling platform, we set the vertical velocity to at least the platform one. if (collision_state.ceiling && platform_ceiling_velocity != Vector3() && platform_ceiling_velocity.dot(up_direction) < 0) { // If ceiling sliding is on, only apply when the ceiling is flat or when the motion is upward. if (!slide_on_ceiling || motion.dot(up_direction) < 0 || (ceiling_normal + up_direction).length() < 0.01) { apply_ceiling_velocity = true; Vector3 ceiling_vertical_velocity = up_direction * up_direction.dot(platform_ceiling_velocity); - Vector3 motion_vertical_velocity = up_direction * up_direction.dot(motion_velocity); + Vector3 motion_vertical_velocity = up_direction * up_direction.dot(velocity); if (motion_vertical_velocity.dot(up_direction) > 0 || ceiling_vertical_velocity.length_squared() > motion_vertical_velocity.length_squared()) { - motion_velocity = ceiling_vertical_velocity + motion_velocity.slide(up_direction); + velocity = ceiling_vertical_velocity + velocity.slide(up_direction); } } } - if (collision_state.floor && floor_stop_on_slope && (motion_velocity.normalized() + up_direction).length() < 0.01) { + if (collision_state.floor && floor_stop_on_slope && (velocity.normalized() + up_direction).length() < 0.01) { Transform3D gt = get_global_transform(); if (result.travel.length() <= margin + CMP_EPSILON) { gt.origin -= result.travel; } set_global_transform(gt); - motion_velocity = Vector3(); + velocity = Vector3(); motion = Vector3(); last_motion = Vector3(); break; @@ -1367,11 +1367,11 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo // Scales the horizontal velocity according to the wall slope. if (vel_dir_facing_up) { - Vector3 slide_motion = motion_velocity.slide(result.collisions[0].normal); - // Keeps the vertical motion from motion_velocity and add the horizontal motion of the projection. - motion_velocity = up_direction * up_direction.dot(motion_velocity) + slide_motion.slide(up_direction); + Vector3 slide_motion = velocity.slide(result.collisions[0].normal); + // Keeps the vertical motion from velocity and add the horizontal motion of the projection. + velocity = up_direction * up_direction.dot(velocity) + slide_motion.slide(up_direction); } else { - motion_velocity = motion_velocity.slide(forward); + velocity = velocity.slide(forward); } // Allow only lateral motion along previous floor when already on floor. @@ -1401,7 +1401,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo if (stop_all_motion) { motion = Vector3(); - motion_velocity = Vector3(); + velocity = Vector3(); } } } @@ -1412,7 +1412,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo real_t motion_angle = Math::abs(Math::acos(-horizontal_normal.dot(motion_slide_up.normalized()))); if (motion_angle < wall_min_slide_angle) { motion = up_direction * motion.dot(up_direction); - motion_velocity = up_direction * motion_velocity.dot(up_direction); + velocity = up_direction * velocity.dot(up_direction); apply_default_sliding = false; } @@ -1425,7 +1425,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo const PhysicsServer3D::MotionCollision &collision = result.collisions[0]; Vector3 slide_motion = result.remainder.slide(collision.normal); - if (collision_state.floor && !collision_state.wall) { + if (collision_state.floor && !collision_state.wall && !motion_slide_up.is_equal_approx(Vector3())) { // Slide using the intersection between the motion plane and the floor plane, // in order to keep the direction intact. real_t motion_length = slide_motion.length(); @@ -1437,7 +1437,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo slide_motion *= motion_length; } - if (slide_motion.dot(motion_velocity) > 0.0) { + if (slide_motion.dot(velocity) > 0.0) { motion = slide_motion; } else { motion = Vector3(); @@ -1446,10 +1446,10 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo if (slide_on_ceiling && result_state.ceiling) { // Apply slide only in the direction of the input motion, otherwise just stop to avoid jittering when moving against a wall. if (vel_dir_facing_up) { - motion_velocity = motion_velocity.slide(collision.normal); + velocity = velocity.slide(collision.normal); } else { // Avoid acceleration in slope when falling. - motion_velocity = up_direction * up_direction.dot(motion_velocity); + velocity = up_direction * up_direction.dot(velocity); } } } @@ -1457,7 +1457,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo else { motion = result.remainder; if (result_state.ceiling && !slide_on_ceiling && vel_dir_facing_up) { - motion_velocity = motion_velocity.slide(up_direction); + velocity = velocity.slide(up_direction); motion = motion.slide(up_direction); } } @@ -1502,12 +1502,12 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo // Reset the gravity accumulation when touching the ground. if (collision_state.floor && !vel_dir_facing_up) { - motion_velocity = motion_velocity.slide(up_direction); + velocity = velocity.slide(up_direction); } } void CharacterBody3D::_move_and_slide_floating(double p_delta) { - Vector3 motion = motion_velocity * p_delta; + Vector3 motion = velocity * p_delta; platform_rid = RID(); platform_object_id = ObjectID(); @@ -1534,7 +1534,7 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { break; } - if (wall_min_slide_angle != 0 && Math::acos(wall_normal.dot(-motion_velocity.normalized())) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) { + if (wall_min_slide_angle != 0 && Math::acos(wall_normal.dot(-velocity.normalized())) < wall_min_slide_angle + FLOOR_ANGLE_THRESHOLD) { motion = Vector3(); if (result.travel.length() < margin + CMP_EPSILON) { Transform3D gt = get_global_transform(); @@ -1548,7 +1548,7 @@ void CharacterBody3D::_move_and_slide_floating(double p_delta) { motion = result.remainder.slide(wall_normal); } - if (motion.dot(motion_velocity) <= 0.0) { + if (motion.dot(velocity) <= 0.0) { motion = Vector3(); } } @@ -1723,12 +1723,12 @@ real_t CharacterBody3D::get_safe_margin() const { return margin; } -const Vector3 &CharacterBody3D::get_motion_velocity() const { - return motion_velocity; +const Vector3 &CharacterBody3D::get_velocity() const { + return velocity; } -void CharacterBody3D::set_motion_velocity(const Vector3 &p_velocity) { - motion_velocity = p_velocity; +void CharacterBody3D::set_velocity(const Vector3 &p_velocity) { + velocity = p_velocity; } bool CharacterBody3D::is_on_floor() const { @@ -1943,8 +1943,8 @@ void CharacterBody3D::_notification(int p_what) { void CharacterBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("move_and_slide"), &CharacterBody3D::move_and_slide); - ClassDB::bind_method(D_METHOD("set_motion_velocity", "motion_velocity"), &CharacterBody3D::set_motion_velocity); - ClassDB::bind_method(D_METHOD("get_motion_velocity"), &CharacterBody3D::get_motion_velocity); + ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &CharacterBody3D::set_velocity); + ClassDB::bind_method(D_METHOD("get_velocity"), &CharacterBody3D::get_velocity); ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &CharacterBody3D::set_safe_margin); ClassDB::bind_method(D_METHOD("get_safe_margin"), &CharacterBody3D::get_safe_margin); @@ -1997,7 +1997,7 @@ void CharacterBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_mode", PROPERTY_HINT_ENUM, "Grounded,Floating", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_motion_mode", "get_motion_mode"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_direction"), "set_up_direction", "get_up_direction"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "slide_on_ceiling"), "set_slide_on_ceiling_enabled", "is_slide_on_ceiling_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion_velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_motion_velocity", "get_motion_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "velocity", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_velocity", "get_velocity"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_slides", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_max_slides", "get_max_slides"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wall_min_slide_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians", PROPERTY_USAGE_DEFAULT), "set_wall_min_slide_angle", "get_wall_min_slide_angle"); ADD_GROUP("Floor", "floor_"); @@ -2006,7 +2006,7 @@ void CharacterBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "floor_block_on_wall"), "set_floor_block_on_wall_enabled", "is_floor_block_on_wall_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_max_angle", PROPERTY_HINT_RANGE, "0,180,0.1,radians"), "set_floor_max_angle", "get_floor_max_angle"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "floor_snap_length", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_floor_snap_length", "get_floor_snap_length"); - ADD_GROUP("Moving platform", "moving_platform"); + ADD_GROUP("Moving Platform", "moving_platform"); ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_apply_velocity_on_leave", PROPERTY_HINT_ENUM, "Always,Upward Only,Never", PROPERTY_USAGE_DEFAULT), "set_moving_platform_apply_velocity_on_leave", "get_moving_platform_apply_velocity_on_leave"); ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_floor_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_floor_layers", "get_moving_platform_floor_layers"); ADD_PROPERTY(PropertyInfo(Variant::INT, "moving_platform_wall_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_moving_platform_wall_layers", "get_moving_platform_wall_layers"); @@ -2159,6 +2159,37 @@ void PhysicalBone3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_po PhysicsServer3D::get_singleton()->body_apply_impulse(get_rid(), p_impulse, p_position); } +void PhysicalBone3D::set_linear_velocity(const Vector3 &p_velocity) { + linear_velocity = p_velocity; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, linear_velocity); +} + +Vector3 PhysicalBone3D::get_linear_velocity() const { + return linear_velocity; +} + +void PhysicalBone3D::set_angular_velocity(const Vector3 &p_velocity) { + angular_velocity = p_velocity; + PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity); +} + +Vector3 PhysicalBone3D::get_angular_velocity() const { + return angular_velocity; +} + +void PhysicalBone3D::set_use_custom_integrator(bool p_enable) { + if (custom_integrator == p_enable) { + return; + } + + custom_integrator = p_enable; + PhysicsServer3D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable); +} + +bool PhysicalBone3D::is_using_custom_integrator() { + return custom_integrator; +} + void PhysicalBone3D::reset_physics_simulation_state() { if (simulate_physics) { _start_physics_simulation(); @@ -2867,6 +2898,11 @@ void PhysicalBone3D::_body_state_changed(PhysicsDirectBodyState3D *p_state) { return; } + linear_velocity = p_state->get_linear_velocity(); + angular_velocity = p_state->get_angular_velocity(); + + GDVIRTUAL_CALL(_integrate_forces, p_state); + /// Update bone transform. Transform3D global_transform(p_state->get_transform()); @@ -2929,9 +2965,20 @@ void PhysicalBone3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_angular_damp", "angular_damp"), &PhysicalBone3D::set_angular_damp); ClassDB::bind_method(D_METHOD("get_angular_damp"), &PhysicalBone3D::get_angular_damp); + ClassDB::bind_method(D_METHOD("set_linear_velocity", "linear_velocity"), &PhysicalBone3D::set_linear_velocity); + ClassDB::bind_method(D_METHOD("get_linear_velocity"), &PhysicalBone3D::get_linear_velocity); + + ClassDB::bind_method(D_METHOD("set_angular_velocity", "angular_velocity"), &PhysicalBone3D::set_angular_velocity); + ClassDB::bind_method(D_METHOD("get_angular_velocity"), &PhysicalBone3D::get_angular_velocity); + + ClassDB::bind_method(D_METHOD("set_use_custom_integrator", "enable"), &PhysicalBone3D::set_use_custom_integrator); + ClassDB::bind_method(D_METHOD("is_using_custom_integrator"), &PhysicalBone3D::is_using_custom_integrator); + ClassDB::bind_method(D_METHOD("set_can_sleep", "able_to_sleep"), &PhysicalBone3D::set_can_sleep); ClassDB::bind_method(D_METHOD("is_able_to_sleep"), &PhysicalBone3D::is_able_to_sleep); + GDVIRTUAL_BIND(_integrate_forces, "state"); + ADD_GROUP("Joint", "joint_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "joint_type", PROPERTY_HINT_ENUM, "None,PinJoint,ConeJoint,HingeJoint,SliderJoint,6DOFJoint"), "set_joint_type", "get_joint_type"); ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "joint_offset"), "set_joint_offset", "get_joint_offset"); @@ -2943,10 +2990,13 @@ void PhysicalBone3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity_scale", PROPERTY_HINT_RANGE, "-10,10,0.01"), "set_gravity_scale", "get_gravity_scale"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "custom_integrator"), "set_use_custom_integrator", "is_using_custom_integrator"); ADD_PROPERTY(PropertyInfo(Variant::INT, "linear_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_linear_damp_mode", "get_linear_damp_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp"); ADD_PROPERTY(PropertyInfo(Variant::INT, "angular_damp_mode", PROPERTY_HINT_ENUM, "Combine,Replace"), "set_angular_damp_mode", "get_angular_damp_mode"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "linear_velocity"), "set_linear_velocity", "get_linear_velocity"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "can_sleep"), "set_can_sleep", "is_able_to_sleep"); BIND_ENUM_CONSTANT(DAMP_MODE_COMBINE); diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h index 67dc7382c3..6ace681021 100644 --- a/scene/3d/physics_body_3d.h +++ b/scene/3d/physics_body_3d.h @@ -354,8 +354,8 @@ public: }; bool move_and_slide(); - const Vector3 &get_motion_velocity() const; - void set_motion_velocity(const Vector3 &p_velocity); + const Vector3 &get_velocity() const; + void set_velocity(const Vector3 &p_velocity); bool is_on_floor() const; bool is_on_floor_only() const; @@ -416,7 +416,7 @@ private: real_t floor_max_angle = Math::deg2rad((real_t)45.0); real_t wall_min_slide_angle = Math::deg2rad((real_t)15.0); Vector3 up_direction = Vector3(0.0, 1.0, 0.0); - Vector3 motion_velocity; + Vector3 velocity; Vector3 floor_normal; Vector3 wall_normal; Vector3 ceiling_normal; @@ -662,9 +662,13 @@ private: real_t bounce = 0.0; real_t mass = 1.0; real_t friction = 1.0; + Vector3 linear_velocity; + Vector3 angular_velocity; real_t gravity_scale = 1.0; bool can_sleep = true; + bool custom_integrator = false; + DampMode linear_damp_mode = DAMP_MODE_COMBINE; DampMode angular_damp_mode = DAMP_MODE_COMBINE; @@ -676,6 +680,7 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; void _notification(int p_what); + GDVIRTUAL1(_integrate_forces, PhysicsDirectBodyState3D *) static void _body_state_changed_callback(void *p_instance, PhysicsDirectBodyState3D *p_state); void _body_state_changed(PhysicsDirectBodyState3D *p_state); @@ -691,6 +696,15 @@ private: public: void _on_bone_parent_changed(); + void set_linear_velocity(const Vector3 &p_velocity); + Vector3 get_linear_velocity() const override; + + void set_angular_velocity(const Vector3 &p_velocity); + Vector3 get_angular_velocity() const override; + + void set_use_custom_integrator(bool p_enable); + bool is_using_custom_integrator(); + #ifdef TOOLS_ENABLED void _set_gizmo_move_joint(bool p_move_joint); virtual Transform3D get_global_gizmo_transform() const override; diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index b251aa38ba..f5e08b92ca 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -171,8 +171,8 @@ void RayCast3D::_notification(int p_what) { exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid()); } } - } break; + case NOTIFICATION_EXIT_TREE: { if (enabled) { set_physics_process_internal(false); @@ -181,8 +181,8 @@ void RayCast3D::_notification(int p_what) { if (debug_shape) { _clear_debug_shape(); } - } break; + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { if (!enabled) { break; @@ -193,7 +193,6 @@ void RayCast3D::_notification(int p_what) { if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) { _update_debug_shape_material(true); } - } break; } } diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp index be655e71db..1bebd8e335 100644 --- a/scene/3d/reflection_probe.cpp +++ b/scene/3d/reflection_probe.cpp @@ -178,10 +178,6 @@ AABB ReflectionProbe::get_aabb() const { return aabb; } -Vector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - void ReflectionProbe::_validate_property(PropertyInfo &property) const { if (property.name == "interior/ambient_color" || property.name == "interior/ambient_color_energy") { if (ambient_mode != AMBIENT_COLOR) { diff --git a/scene/3d/reflection_probe.h b/scene/3d/reflection_probe.h index d0643496a4..424976d895 100644 --- a/scene/3d/reflection_probe.h +++ b/scene/3d/reflection_probe.h @@ -113,7 +113,6 @@ public: UpdateMode get_update_mode() const; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; ReflectionProbe(); ~ReflectionProbe(); diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp index 2770b6f40c..9979052385 100644 --- a/scene/3d/remote_transform_3d.cpp +++ b/scene/3d/remote_transform_3d.cpp @@ -111,8 +111,8 @@ void RemoteTransform3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { _update_cache(); - } break; + case NOTIFICATION_TRANSFORM_CHANGED: { if (!is_inside_tree()) { break; @@ -121,7 +121,6 @@ void RemoteTransform3D::_notification(int p_what) { if (cache.is_valid()) { _update_remote(); } - } break; } } @@ -183,7 +182,7 @@ TypedArray<String> RemoteTransform3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!has_node(remote_node) || !Object::cast_to<Node3D>(get_node(remote_node))) { - warnings.push_back(TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.")); + warnings.push_back(RTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.")); } return warnings; diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index b6b5920f69..783edf7fc6 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -32,7 +32,6 @@ #include "core/object/message_queue.h" #include "core/variant/type_info.h" -#include "editor/plugins/skeleton_3d_editor_plugin.h" #include "scene/3d/physics_body_3d.h" #include "scene/resources/skeleton_modification_3d.h" #include "scene/resources/surface_tool.h" @@ -318,11 +317,9 @@ void Skeleton3D::_notification(int p_what) { rs->skeleton_bone_set_transform(skeleton, i, bonesptr[bone_index].pose_global * skin->get_bind_pose(i)); } } - #ifdef TOOLS_ENABLED emit_signal(SceneStringNames::get_singleton()->pose_updated); #endif // TOOLS_ENABLED - } break; #ifndef _3D_DISABLED @@ -344,19 +341,14 @@ void Skeleton3D::_notification(int p_what) { if (modification_stack.is_valid()) { execute_modifications(get_physics_process_delta_time(), SkeletonModificationStack3D::EXECUTION_MODE::execution_mode_physics_process); } - } break; -#endif // _3D_DISABLED -#ifndef _3D_DISABLED case NOTIFICATION_INTERNAL_PROCESS: { if (modification_stack.is_valid()) { execute_modifications(get_process_delta_time(), SkeletonModificationStack3D::EXECUTION_MODE::execution_mode_process); } } break; -#endif // _3D_DISABLED -#ifndef _3D_DISABLED case NOTIFICATION_READY: { set_physics_process_internal(true); set_process_internal(true); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 80ff2a1f79..279c3e49a2 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -44,13 +44,13 @@ class SkinReference : public RefCounted { GDCLASS(SkinReference, RefCounted) friend class Skeleton3D; - Skeleton3D *skeleton_node; + Skeleton3D *skeleton_node = nullptr; RID skeleton; Ref<Skin> skin; uint32_t bind_count = 0; uint64_t skeleton_version = 0; Vector<uint32_t> skin_bone_indices; - uint32_t *skin_bone_indices_ptrs; + uint32_t *skin_bone_indices_ptrs = nullptr; void _skin_changed(); protected: diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index c645009c72..f29b060069 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -407,14 +407,14 @@ void SkeletonIK3D::_notification(int p_what) { set_process_priority(1); reload_chain(); } break; + case NOTIFICATION_INTERNAL_PROCESS: { if (target_node_override) { reload_goal(); } - _solve_chain(); - } break; + case NOTIFICATION_EXIT_TREE: { reload_chain(); } break; diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp index 8ee777bcbf..6724754214 100644 --- a/scene/3d/soft_dynamic_body_3d.cpp +++ b/scene/3d/soft_dynamic_body_3d.cpp @@ -378,12 +378,12 @@ TypedArray<String> SoftDynamicBody3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (mesh.is_null()) { - warnings.push_back(TTR("This body will be ignored until you set a mesh.")); + warnings.push_back(RTR("This body will be ignored until you set a mesh.")); } Transform3D t = get_transform(); if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { - warnings.push_back(TTR("Size changes to SoftDynamicBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); + warnings.push_back(RTR("Size changes to SoftDynamicBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.")); } return warnings; @@ -417,8 +417,8 @@ void SoftDynamicBody3D::_draw_soft_mesh() { PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, mesh_rid); } - if (!rendering_server_handler.is_ready(mesh_rid)) { - rendering_server_handler.prepare(mesh_rid, 0); + if (!rendering_server_handler->is_ready(mesh_rid)) { + rendering_server_handler->prepare(mesh_rid, 0); /// Necessary in order to render the mesh correctly (Soft body nodes are in global space) simulation_started = true; @@ -428,11 +428,11 @@ void SoftDynamicBody3D::_draw_soft_mesh() { _update_physics_server(); - rendering_server_handler.open(); - PhysicsServer3D::get_singleton()->soft_body_update_rendering_server(physics_rid, &rendering_server_handler); - rendering_server_handler.close(); + rendering_server_handler->open(); + PhysicsServer3D::get_singleton()->soft_body_update_rendering_server(physics_rid, rendering_server_handler); + rendering_server_handler->close(); - rendering_server_handler.commit_changes(); + rendering_server_handler->commit_changes(); } void SoftDynamicBody3D::_prepare_physics_server() { @@ -688,10 +688,12 @@ bool SoftDynamicBody3D::is_ray_pickable() const { SoftDynamicBody3D::SoftDynamicBody3D() : physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()) { + rendering_server_handler = memnew(SoftDynamicBodyRenderingServerHandler); PhysicsServer3D::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id()); } SoftDynamicBody3D::~SoftDynamicBody3D() { + memdelete(rendering_server_handler); PhysicsServer3D::get_singleton()->free(physics_rid); } diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h index c30ec701c7..e11e5c73df 100644 --- a/scene/3d/soft_dynamic_body_3d.h +++ b/scene/3d/soft_dynamic_body_3d.h @@ -36,7 +36,7 @@ class SoftDynamicBody3D; -class SoftDynamicBodyRenderingServerHandler : public RenderingServerHandler { +class SoftDynamicBodyRenderingServerHandler : public PhysicsServer3DRenderingServerHandler { friend class SoftDynamicBody3D; RID mesh; @@ -84,7 +84,7 @@ public: }; private: - SoftDynamicBodyRenderingServerHandler rendering_server_handler; + SoftDynamicBodyRenderingServerHandler *rendering_server_handler = nullptr; RID physics_rid; diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp index 8a8964f69a..230801bd52 100644 --- a/scene/3d/spring_arm_3d.cpp +++ b/scene/3d/spring_arm_3d.cpp @@ -29,23 +29,26 @@ /*************************************************************************/ #include "spring_arm_3d.h" + #include "scene/3d/camera_3d.h" void SpringArm3D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_ENTER_TREE: { if (!Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(true); } - break; - case NOTIFICATION_EXIT_TREE: + } break; + + case NOTIFICATION_EXIT_TREE: { if (!Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(false); } - break; - case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: + } break; + + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { process_spring(); - break; + } break; } } diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 331d58927b..8d813e8b2b 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -66,23 +66,25 @@ void SpriteBase3D::_propagate_color_changed() { } void SpriteBase3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - if (!pending_update) { - _im_update(); - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (!pending_update) { + _im_update(); + } - parent_sprite = Object::cast_to<SpriteBase3D>(get_parent()); - if (parent_sprite) { - pI = parent_sprite->children.push_back(this); - } - } + parent_sprite = Object::cast_to<SpriteBase3D>(get_parent()); + if (parent_sprite) { + pI = parent_sprite->children.push_back(this); + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - if (parent_sprite) { - parent_sprite->children.erase(pI); - pI = nullptr; - parent_sprite = nullptr; - } + case NOTIFICATION_EXIT_TREE: { + if (parent_sprite) { + parent_sprite->children.erase(pI); + pI = nullptr; + parent_sprite = nullptr; + } + } break; } } @@ -175,10 +177,6 @@ AABB SpriteBase3D::get_aabb() const { return aabb; } -Vector<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) { return triangle_mesh; @@ -694,10 +692,6 @@ Rect2 Sprite3D::get_item_rect() const { if (texture.is_null()) { return Rect2(0, 0, 1, 1); } - /* - if (texture.is_null()) - return CanvasItem::get_item_rect(); - */ Size2 s; @@ -1021,14 +1015,14 @@ void AnimatedSprite3D::_notification(int p_what) { return; } - float speed = frames->get_animation_speed(animation); - if (speed == 0) { - return; //do nothing - } - double remaining = get_process_delta_time(); while (remaining) { + double speed = frames->get_animation_speed(animation); + if (speed == 0) { + return; // Do nothing. + } + if (timeout <= 0) { timeout = 1.0 / speed; @@ -1206,7 +1200,7 @@ StringName AnimatedSprite3D::get_animation() const { TypedArray<String> AnimatedSprite3D::get_configuration_warnings() const { TypedArray<String> warnings = SpriteBase3D::get_configuration_warnings(); if (frames.is_null()) { - warnings.push_back(TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.")); + warnings.push_back(RTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.")); } return warnings; diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index 985103e190..92dbef0855 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -137,7 +137,7 @@ public: virtual Rect2 get_item_rect() const = 0; virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; + Ref<TriangleMesh> generate_triangle_mesh() const; SpriteBase3D(); diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index a5fd3a7dd0..f5a451ca04 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -109,16 +109,14 @@ TypedArray<String> VehicleWheel3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Object::cast_to<VehicleBody3D>(get_parent())) { - warnings.push_back(TTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.")); + warnings.push_back(RTR("VehicleWheel3D serves to provide a wheel system to a VehicleBody3D. Please use it as a child of a VehicleBody3D.")); } return warnings; } void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) { - if (m_raycastInfo.m_isInContact) - - { + if (m_raycastInfo.m_isInContact) { real_t project = m_raycastInfo.m_contactNormalWS.dot(m_raycastInfo.m_wheelDirectionWS); Vector3 chassis_velocity_at_contactPoint; Vector3 relpos = m_raycastInfo.m_contactPointWS - s->get_transform().origin; @@ -135,11 +133,7 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) { m_suspensionRelativeVelocity = projVel * inv; m_clippedInvContactDotSuspension = inv; } - - } - - else // Not in contact : position wheel in a nice (rest length) position - { + } else { // Not in contact : position wheel in a nice (rest length) position m_raycastInfo.m_suspensionLength = m_suspensionRestLength; m_suspensionRelativeVelocity = real_t(0.0); m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS; diff --git a/scene/3d/visible_on_screen_notifier_3d.cpp b/scene/3d/visible_on_screen_notifier_3d.cpp index 44d2a3e03f..41cd604a4f 100644 --- a/scene/3d/visible_on_screen_notifier_3d.cpp +++ b/scene/3d/visible_on_screen_notifier_3d.cpp @@ -71,8 +71,11 @@ bool VisibleOnScreenNotifier3D::is_on_screen() const { } void VisibleOnScreenNotifier3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_EXIT_TREE) { - on_screen = false; + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_EXIT_TREE: { + on_screen = false; + } break; } } @@ -86,10 +89,6 @@ void VisibleOnScreenNotifier3D::_bind_methods() { ADD_SIGNAL(MethodInfo("screen_exited")); } -Vector<Face3> VisibleOnScreenNotifier3D::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - VisibleOnScreenNotifier3D::VisibleOnScreenNotifier3D() { RID notifier = RS::get_singleton()->visibility_notifier_create(); RS::get_singleton()->visibility_notifier_set_aabb(notifier, aabb); @@ -161,21 +160,23 @@ void VisibleOnScreenEnabler3D::_update_enable_mode(bool p_enable) { } } void VisibleOnScreenEnabler3D::_notification(int p_what) { - if (p_what == NOTIFICATION_ENTER_TREE) { - if (Engine::get_singleton()->is_editor_hint()) { - return; - } + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } - node_id = ObjectID(); - Node *node = get_node(enable_node_path); - if (node) { - node_id = node->get_instance_id(); - node->set_process_mode(PROCESS_MODE_DISABLED); - } - } + node_id = ObjectID(); + Node *node = get_node(enable_node_path); + if (node) { + node_id = node->get_instance_id(); + node->set_process_mode(PROCESS_MODE_DISABLED); + } + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { - node_id = ObjectID(); + case NOTIFICATION_EXIT_TREE: { + node_id = ObjectID(); + } break; } } diff --git a/scene/3d/visible_on_screen_notifier_3d.h b/scene/3d/visible_on_screen_notifier_3d.h index 852c7e2ed3..fe17f1e444 100644 --- a/scene/3d/visible_on_screen_notifier_3d.h +++ b/scene/3d/visible_on_screen_notifier_3d.h @@ -57,8 +57,6 @@ public: virtual AABB get_aabb() const override; bool is_on_screen() const; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; - VisibleOnScreenNotifier3D(); ~VisibleOnScreenNotifier3D(); }; diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index 005bb5a737..669017c4b4 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -32,6 +32,14 @@ #include "scene/scene_string_names.h" +AABB VisualInstance3D::get_aabb() const { + AABB ret; + if (GDVIRTUAL_CALL(_get_aabb, ret)) { + return ret; + } + return AABB(); +} + AABB VisualInstance3D::get_transformed_aabb() const { return get_global_transform().xform(get_aabb()); } @@ -47,27 +55,21 @@ void VisualInstance3D::_update_visibility() { void VisualInstance3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - // CHECK SKELETON => moving skeleton attaching logic to MeshInstance - /* - Skeleton *skeleton=Object::cast_to<Skeleton>(get_parent()); - if (skeleton) - RenderingServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() ); - */ ERR_FAIL_COND(get_world_3d().is_null()); RenderingServer::get_singleton()->instance_set_scenario(instance, get_world_3d()->get_scenario()); _update_visibility(); - } break; + case NOTIFICATION_TRANSFORM_CHANGED: { Transform3D gt = get_global_transform(); RenderingServer::get_singleton()->instance_set_transform(instance, gt); } break; + case NOTIFICATION_EXIT_WORLD: { RenderingServer::get_singleton()->instance_set_scenario(instance, RID()); RenderingServer::get_singleton()->instance_attach_skeleton(instance, RID()); - //RS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() ); - } break; + case NOTIFICATION_VISIBILITY_CHANGED: { _update_visibility(); } break; @@ -121,6 +123,7 @@ void VisualInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_transformed_aabb"), &VisualInstance3D::get_transformed_aabb); + GDVIRTUAL_BIND(_get_aabb); ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_RENDER), "set_layer_mask", "get_layer_mask"); } @@ -220,9 +223,6 @@ GeometryInstance3D::VisibilityRangeFadeMode GeometryInstance3D::get_visibility_r return visibility_range_fade_mode; } -void GeometryInstance3D::_notification(int p_what) { -} - const StringName *GeometryInstance3D::_instance_uniform_get_remap(const StringName p_name) const { StringName *r = instance_uniform_property_remap.getptr(p_name); if (!r) { @@ -389,15 +389,15 @@ TypedArray<String> GeometryInstance3D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!Math::is_zero_approx(visibility_range_end) && visibility_range_end <= visibility_range_begin) { - warnings.push_back(TTR("The GeometryInstance3D visibility range's End distance is set to a non-zero value, but is lower than the Begin distance.\nThis means the GeometryInstance3D will never be visible.\nTo resolve this, set the End distance to 0 or to a value greater than the Begin distance.")); + warnings.push_back(RTR("The GeometryInstance3D visibility range's End distance is set to a non-zero value, but is lower than the Begin distance.\nThis means the GeometryInstance3D will never be visible.\nTo resolve this, set the End distance to 0 or to a value greater than the Begin distance.")); } if ((visibility_range_fade_mode == VISIBILITY_RANGE_FADE_SELF || visibility_range_fade_mode == VISIBILITY_RANGE_FADE_DEPENDENCIES) && !Math::is_zero_approx(visibility_range_begin) && Math::is_zero_approx(visibility_range_begin_margin)) { - warnings.push_back(TTR("The GeometryInstance3D is configured to fade in smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range Begin Margin above 0.")); + warnings.push_back(RTR("The GeometryInstance3D is configured to fade in smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range Begin Margin above 0.")); } if ((visibility_range_fade_mode == VISIBILITY_RANGE_FADE_SELF || visibility_range_fade_mode == VISIBILITY_RANGE_FADE_DEPENDENCIES) && !Math::is_zero_approx(visibility_range_end) && Math::is_zero_approx(visibility_range_end_margin)) { - warnings.push_back(TTR("The GeometryInstance3D is configured to fade out smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range End Margin above 0.")); + warnings.push_back(RTR("The GeometryInstance3D is configured to fade out smoothly over distance, but the fade transition distance is set to 0.\nTo resolve this, increase Visibility Range End Margin above 0.")); } return warnings; diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index be964e5080..f8fd4378fe 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -35,7 +35,6 @@ class VisualInstance3D : public Node3D { GDCLASS(VisualInstance3D, Node3D); - OBJ_CATEGORY("3D Visual Nodes"); RID base; RID instance; @@ -49,6 +48,7 @@ protected: void _notification(int p_what); static void _bind_methods(); + GDVIRTUAL0RC(AABB, _get_aabb) public: enum GetFacesFlags { FACES_SOLID = 1, // solid geometry @@ -58,8 +58,7 @@ public: }; RID get_instance() const; - virtual AABB get_aabb() const = 0; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const = 0; + virtual AABB get_aabb() const; virtual AABB get_transformed_aabb() const; // helper @@ -137,7 +136,6 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; - void _notification(int p_what); static void _bind_methods(); public: diff --git a/scene/3d/voxel_gi.cpp b/scene/3d/voxel_gi.cpp index bfe3c80a4f..29e495ce1b 100644 --- a/scene/3d/voxel_gi.cpp +++ b/scene/3d/voxel_gi.cpp @@ -450,17 +450,13 @@ AABB VoxelGI::get_aabb() const { return AABB(-extents, extents * 2); } -Vector<Face3> VoxelGI::get_faces(uint32_t p_usage_flags) const { - return Vector<Face3>(); -} - TypedArray<String> VoxelGI::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (RenderingServer::get_singleton()->is_low_end()) { - warnings.push_back(TTR("VoxelGIs are not supported by the OpenGL video driver.\nUse a LightmapGI instead.")); + warnings.push_back(RTR("VoxelGIs are not supported by the OpenGL video driver.\nUse a LightmapGI instead.")); } else if (probe_data.is_null()) { - warnings.push_back(TTR("No VoxelGI data set, so this node is disabled. Bake static objects to enable GI.")); + warnings.push_back(RTR("No VoxelGI data set, so this node is disabled. Bake static objects to enable GI.")); } return warnings; } diff --git a/scene/3d/voxel_gi.h b/scene/3d/voxel_gi.h index 3678bd4f3b..e1a38dd7a0 100644 --- a/scene/3d/voxel_gi.h +++ b/scene/3d/voxel_gi.h @@ -149,7 +149,6 @@ public: void bake(Node *p_from_node = nullptr, bool p_create_visual_debug = false); virtual AABB get_aabb() const override; - virtual Vector<Face3> get_faces(uint32_t p_usage_flags) const override; TypedArray<String> get_configuration_warnings() const override; diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index f56e3caa4b..bda3868fbb 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -872,7 +872,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const { if (d == 0) { w[i] = 0; } else { - w[i] = MIN(d, 254) + 1; + w[i] = MIN(d, 254u) + 1; } } } diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 98f28a8cff..f638644628 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -34,27 +34,32 @@ #include "scene/main/window.h" void WorldEnvironment::_notification(int p_what) { - if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) { - if (environment.is_valid()) { - add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - _update_current_environment(); - } - - if (camera_effects.is_valid()) { - add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - _update_current_camera_effects(); - } - - } else if (p_what == Node3D::NOTIFICATION_EXIT_WORLD || p_what == Node3D::NOTIFICATION_EXIT_TREE) { - if (environment.is_valid()) { - remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - _update_current_environment(); - } - - if (camera_effects.is_valid()) { - remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - _update_current_camera_effects(); - } + switch (p_what) { + case Node3D::NOTIFICATION_ENTER_WORLD: + case Node3D::NOTIFICATION_ENTER_TREE: { + if (environment.is_valid()) { + add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_environment(); + } + + if (camera_effects.is_valid()) { + add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_camera_effects(); + } + } break; + + case Node3D::NOTIFICATION_EXIT_WORLD: + case Node3D::NOTIFICATION_EXIT_TREE: { + if (environment.is_valid()) { + remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_environment(); + } + + if (camera_effects.is_valid()) { + remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_camera_effects(); + } + } break; } } @@ -134,7 +139,7 @@ TypedArray<String> WorldEnvironment::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (!environment.is_valid() && !camera_effects.is_valid()) { - warnings.push_back(TTR("To have any visible effect, WorldEnvironment requires its \"Environment\" property to contain an Environment, its \"Camera Effects\" property to contain a CameraEffects resource, or both.")); + warnings.push_back(RTR("To have any visible effect, WorldEnvironment requires its \"Environment\" property to contain an Environment, its \"Camera Effects\" property to contain a CameraEffects resource, or both.")); } if (!is_inside_tree()) { @@ -146,7 +151,7 @@ TypedArray<String> WorldEnvironment::get_configuration_warnings() const { } if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() != camera_effects) { - warnings.push_back(TTR("Only one WorldEnvironment is allowed per scene (or set of instantiated scenes).")); + warnings.push_back(RTR("Only one WorldEnvironment is allowed per scene (or set of instantiated scenes).")); } return warnings; diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 211c39c949..3085d84643 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -44,16 +44,17 @@ void XRCamera3D::_notification(int p_what) { if (origin != nullptr) { origin->set_tracked_camera(this); } - }; break; + } break; + case NOTIFICATION_EXIT_TREE: { // need to find our XROrigin3D parent and let it know we're no longer its camera! XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin != nullptr && origin->get_tracked_camera() == this) { origin->set_tracked_camera(nullptr); } - }; break; - }; -}; + } break; + } +} void XRCamera3D::_changed_tracker(const StringName p_tracker_name, int p_tracker_type) { if (p_tracker_name == tracker_name) { @@ -94,7 +95,7 @@ TypedArray<String> XRCamera3D::get_configuration_warnings() const { // must be child node of XROrigin3D! XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - warnings.push_back(TTR("XRCamera3D must have an XROrigin3D node as its parent.")); + warnings.push_back(RTR("XRCamera3D must have an XROrigin3D node as its parent.")); }; } @@ -422,15 +423,15 @@ TypedArray<String> XRNode3D::get_configuration_warnings() const { // must be child node of XROrigin! XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent()); if (origin == nullptr) { - warnings.push_back(TTR("XRController3D must have an XROrigin3D node as its parent.")); + warnings.push_back(RTR("XRController3D must have an XROrigin3D node as its parent.")); } if (tracker_name == "") { - warnings.push_back(TTR("No tracker name is set.")); + warnings.push_back(RTR("No tracker name is set.")); } if (pose_name == "") { - warnings.push_back(TTR("No pose is set.")); + warnings.push_back(RTR("No pose is set.")); } } @@ -447,11 +448,6 @@ void XRController3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRController3D::get_tracker_hand); - ClassDB::bind_method(D_METHOD("get_rumble"), &XRController3D::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRController3D::set_rumble); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"), "set_rumble", "get_rumble"); - ADD_PROPERTY_DEFAULT("rumble", 0.0); - ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::STRING, "name"))); ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name"))); ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value"))); @@ -557,20 +553,6 @@ Vector2 XRController3D::get_axis(const StringName &p_name) const { } } -real_t XRController3D::get_rumble() const { - if (!tracker.is_valid()) { - return 0.0; - } - - return tracker->get_rumble(); -} - -void XRController3D::set_rumble(real_t p_rumble) { - if (tracker.is_valid()) { - tracker->set_rumble(p_rumble); - } -} - XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const { // get our XRServer if (!tracker.is_valid()) { @@ -607,13 +589,13 @@ TypedArray<String> XROrigin3D::get_configuration_warnings() const { if (is_visible() && is_inside_tree()) { if (tracked_camera == nullptr) { - warnings.push_back(TTR("XROrigin3D requires an XRCamera3D child node.")); + warnings.push_back(RTR("XROrigin3D requires an XRCamera3D child node.")); } } - bool xr_enabled = GLOBAL_GET("rendering/xr/enabled"); + bool xr_enabled = GLOBAL_GET("xr/shaders/enabled"); if (!xr_enabled) { - warnings.push_back(TTR("XR is not enabled in rendering project settings. Stereoscopic output is not supported unless this is enabled.")); + warnings.push_back(RTR("XR is not enabled in rendering project settings. Stereoscopic output is not supported unless this is enabled.")); } return warnings; @@ -657,10 +639,12 @@ void XROrigin3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { set_process_internal(true); - }; break; + } break; + case NOTIFICATION_EXIT_TREE: { set_process_internal(false); - }; break; + } break; + case NOTIFICATION_INTERNAL_PROCESS: { // set our world origin to our node transform xr_server->set_world_origin(get_global_transform()); @@ -673,11 +657,9 @@ void XROrigin3D::_notification(int p_what) { // now apply this to our camera tracked_camera->set_transform(t); - }; - }; break; - default: - break; - }; + } + } break; + } // send our notification to all active XE interfaces, they may need to react to it also for (int i = 0; i < xr_server->get_interface_count(); i++) { diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h index 5675cbd944..3079e20dc7 100644 --- a/scene/3d/xr_nodes.h +++ b/scene/3d/xr_nodes.h @@ -139,9 +139,6 @@ public: float get_value(const StringName &p_name) const; Vector2 get_axis(const StringName &p_name) const; - real_t get_rumble() const; - void set_rumble(real_t p_rumble); - XRPositionalTracker::TrackerHand get_tracker_hand() const; XRController3D() {} |