diff options
Diffstat (limited to 'scene/3d')
39 files changed, 477 insertions, 637 deletions
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp index 99c5276636..749cf4ff9d 100644 --- a/scene/3d/area_3d.cpp +++ b/scene/3d/area_3d.cpp @@ -211,7 +211,7 @@ void Area3D::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); - if (!node) { //node may have been deleted in previous frame or at other legiminate point + if (!node) { //node may have been deleted in previous frame or at other legitimate point continue; } //ERR_CONTINUE(!node); @@ -240,7 +240,7 @@ void Area3D::_clear_monitoring() { Object *obj = ObjectDB::get_instance(E->key()); Node *node = Object::cast_to<Node>(obj); - if (!node) { //node may have been deleted in previous frame or at other legiminate point + if (!node) { //node may have been deleted in previous frame or at other legitimate point continue; } //ERR_CONTINUE(!node); @@ -640,10 +640,10 @@ void Area3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area3D::set_reverb_uniformity); ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area3D::get_reverb_uniformity); - ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); - ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); - ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"))); + ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape"))); + ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); + ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"))); ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::INT, "area_id"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape"))); diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 578ea823f0..95ffbe48c1 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -78,6 +78,7 @@ void BakedLightmapData::clear_users() { } void BakedLightmapData::_set_user_data(const Array &p_data) { + ERR_FAIL_COND(p_data.size() <= 0); ERR_FAIL_COND((p_data.size() % 4) != 0); for (int i = 0; i < p_data.size(); i += 4) { @@ -448,7 +449,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const ERR_FAIL_COND_V(p_simplex_indices.size() <= 1, 0); //should not happen, this is a bug // Failed to separate the tetrahedrons using planes - // this means Delaunay borked at some point. + // this means Delaunay broke at some point. // Luckily, because we are using tetrahedrons, we can resort to // less precise but still working ways to generate the separating plane // this will most likely look bad when interpolating, but at least it will not crash. @@ -510,7 +511,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const node.plane = best_plane; if (indices_under.size() == 0) { - //noting to do here + //nothing to do here node.under = BSPNode::EMPTY_LEAF; } else if (indices_under.size() == 1) { node.under = -(indices_under[0] + 1); @@ -519,7 +520,7 @@ int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const } if (indices_over.size() == 0) { - //noting to do here + //nothing to do here node.over = BSPNode::EMPTY_LEAF; } else if (indices_over.size() == 1) { node.over = -(indices_over[0] + 1); @@ -659,7 +660,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d } // create mesh data for insert - //get the base material textures, help compute altlas size and bounds + //get the base material textures, help compute atlas size and bounds for (int m_i = 0; m_i < meshes_found.size(); m_i++) { if (p_bake_step) { float p = (float)(m_i) / meshes_found.size(); @@ -973,7 +974,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_d for (int i = 0; i < lightmapper->get_bake_texture_count(); i++) { images.push_back(lightmapper->get_bake_texture(i)); } - //we assume they are all the same, so lets create a large one for saving + //we assume they are all the same, so let's create a large one for saving Ref<Image> large_image; large_image.instance(); diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index f0623c625e..cd8d02233b 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -102,7 +102,7 @@ void Camera3D::_update_camera() { void Camera3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_WORLD: { - // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD + // Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD // and Spatial will handle it first, including clearing its reference to the Viewport, // therefore making it impossible to subclasses to access it viewport = get_viewport(); @@ -715,7 +715,7 @@ void ClippedCamera3D::_notification(int p_what) { Vector3 ray_from = parent_plane.project(cam_pos); - clip_offset = 0; //reset by defau;t + clip_offset = 0; //reset by default { //check if points changed Vector<Vector3> local_points = get_near_plane_points(); diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index b7da4822e2..39880db29c 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -30,6 +30,8 @@ #include "collision_object_3d.h" +#include "core/config/engine.h" +#include "mesh_instance_3d.h" #include "scene/scene_string_names.h" #include "servers/physics_server_3d.h" @@ -110,6 +112,42 @@ void CollisionObject3D::_update_pickable() { } } +void CollisionObject3D::_update_debug_shapes() { + for (Set<uint32_t>::Element *shapedata_idx = debug_shapes_to_update.front(); shapedata_idx; shapedata_idx = shapedata_idx->next()) { + if (shapes.has(shapedata_idx->get())) { + ShapeData &shapedata = shapes[shapedata_idx->get()]; + for (int i = 0; i < shapedata.shapes.size(); i++) { + ShapeData::ShapeBase &s = shapedata.shapes.write[i]; + if (s.debug_shape) { + s.debug_shape->queue_delete(); + s.debug_shape = nullptr; + } + if (s.shape.is_null() || shapedata.disabled) { + continue; + } + + Ref<Mesh> mesh = s.shape->get_debug_mesh(); + MeshInstance3D *mi = memnew(MeshInstance3D); + mi->set_transform(shapedata.xform); + mi->set_mesh(mesh); + add_child(mi); + mi->force_update_transform(); + s.debug_shape = mi; + } + } + } + debug_shapes_to_update.clear(); +} + +void CollisionObject3D::_update_shape_data(uint32_t p_owner) { + if (is_inside_tree() && get_tree()->is_debugging_collisions_hint() && !Engine::get_singleton()->is_editor_hint()) { + if (debug_shapes_to_update.is_empty()) { + call_deferred("_update_debug_shapes"); + } + debug_shapes_to_update.insert(p_owner); + } +} + void CollisionObject3D::set_ray_pickable(bool p_ray_pickable) { ray_pickable = p_ray_pickable; _update_pickable(); @@ -141,6 +179,8 @@ void CollisionObject3D::_bind_methods() { ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject3D::shape_owner_clear_shapes); ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner); + ClassDB::bind_method(D_METHOD("_update_debug_shapes"), &CollisionObject3D::_update_debug_shapes); + BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx"))); ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_position"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx"))); @@ -188,6 +228,7 @@ void CollisionObject3D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl PhysicsServer3D::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled); } } + _update_shape_data(p_owner); } bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const { @@ -223,6 +264,8 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf PhysicsServer3D::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform); } } + + _update_shape_data(p_owner); } Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const { @@ -245,6 +288,7 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3 ShapeData::ShapeBase s; s.index = total_subshapes; s.shape = p_shape; + if (area) { PhysicsServer3D::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform, sd.disabled); } else { @@ -253,6 +297,8 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3 sd.shapes.push_back(s); total_subshapes++; + + _update_shape_data(p_owner); } int CollisionObject3D::shape_owner_get_shape_count(uint32_t p_owner) const { @@ -279,13 +325,19 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) ERR_FAIL_COND(!shapes.has(p_owner)); ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size()); - int index_to_remove = shapes[p_owner].shapes[p_shape].index; + const ShapeData::ShapeBase &s = shapes[p_owner].shapes[p_shape]; + int index_to_remove = s.index; + if (area) { PhysicsServer3D::get_singleton()->area_remove_shape(rid, index_to_remove); } else { PhysicsServer3D::get_singleton()->body_remove_shape(rid, index_to_remove); } + if (s.debug_shape) { + s.debug_shape->queue_delete(); + } + shapes[p_owner].shapes.remove(p_shape); for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) { diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h index b7473ca12a..fe20176984 100644 --- a/scene/3d/collision_object_3d.h +++ b/scene/3d/collision_object_3d.h @@ -45,6 +45,7 @@ class CollisionObject3D : public Node3D { Object *owner = nullptr; Transform xform; struct ShapeBase { + Node *debug_shape = nullptr; Ref<Shape3D> shape; int index = 0; }; @@ -60,8 +61,12 @@ class CollisionObject3D : public Node3D { bool capture_input_on_drag = false; bool ray_pickable = true; + Set<uint32_t> debug_shapes_to_update; + void _update_pickable(); + void _update_shape_data(uint32_t p_owner); + protected: CollisionObject3D(RID p_rid, bool p_area); @@ -72,6 +77,8 @@ protected: virtual void _mouse_enter(); virtual void _mouse_exit(); + void _update_debug_shapes(); + public: uint32_t create_shape_owner(Object *p_owner); void remove_shape_owner(uint32_t owner); diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index 914c8eab7a..242d82ab4c 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -100,9 +100,6 @@ void CollisionShape3D::_notification(int p_what) { if (parent) { _update_in_shape_owner(); } - if (get_tree()->is_debugging_collisions_hint()) { - _update_debug_shape(); - } } break; case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { if (parent) { @@ -163,8 +160,6 @@ void CollisionShape3D::_bind_methods() { ClassDB::bind_method(D_METHOD("make_convex_from_siblings"), &CollisionShape3D::make_convex_from_siblings); ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_siblings", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); - ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape3D::_update_debug_shape); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape3D"), "set_shape", "get_shape"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled"); } @@ -224,34 +219,9 @@ CollisionShape3D::~CollisionShape3D() { //RenderingServer::get_singleton()->free(indicator); } -void CollisionShape3D::_update_debug_shape() { - debug_shape_dirty = false; - - if (debug_shape) { - debug_shape->queue_delete(); - debug_shape = nullptr; - } - - Ref<Shape3D> s = get_shape(); - if (s.is_null()) { - return; - } - - Ref<Mesh> mesh = s->get_debug_mesh(); - MeshInstance3D *mi = memnew(MeshInstance3D); - mi->set_mesh(mesh); - add_child(mi); - debug_shape = mi; -} - void CollisionShape3D::_shape_changed() { // If this is a heightfield shape our center may have changed if (parent) { _update_in_shape_owner(true); } - - if (is_inside_tree() && get_tree()->is_debugging_collisions_hint() && !debug_shape_dirty) { - debug_shape_dirty = true; - call_deferred("_update_debug_shape"); - } } diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h index f55c09ffaa..5512417f75 100644 --- a/scene/3d/collision_shape_3d.h +++ b/scene/3d/collision_shape_3d.h @@ -43,14 +43,10 @@ class CollisionShape3D : public Node3D { uint32_t owner_id = 0; CollisionObject3D *parent = nullptr; - Node *debug_shape = nullptr; - bool debug_shape_dirty; - void resource_changed(RES res); bool disabled = false; protected: - void _update_debug_shape(); void _shape_changed(); void _update_in_shape_owner(bool p_xform_only = false); diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index 0f10f2b85f..7d6abe458a 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -109,6 +109,7 @@ Color Decal::get_modulate() const { void Decal::set_enable_distance_fade(bool p_enable) { distance_fade_enabled = p_enable; RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length); + notify_property_list_changed(); } bool Decal::is_distance_fade_enabled() const { @@ -153,6 +154,12 @@ 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_NOEDITOR; + } +} + void Decal::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents); diff --git a/scene/3d/decal.h b/scene/3d/decal.h index 095579d775..ce19e76de1 100644 --- a/scene/3d/decal.h +++ b/scene/3d/decal.h @@ -64,6 +64,7 @@ private: protected: static void _bind_methods(); + void _validate_property(PropertyInfo &property) const override; public: void set_extents(const Vector3 &p_extents); diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 8a8bfe50b9..43f820e5d4 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -415,13 +415,16 @@ Vector3i GIProbe::get_estimated_cell_size() const { void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) { static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 }; + p_from_node = p_from_node ? p_from_node : get_parent(); + ERR_FAIL_NULL(p_from_node); + Voxelizer baker; baker.begin_bake(subdiv_value[subdiv], AABB(-extents, extents * 2.0)); List<PlotMesh> mesh_list; - _find_meshes(p_from_node ? p_from_node : get_parent(), mesh_list); + _find_meshes(p_from_node, mesh_list); if (bake_begin_function) { bake_begin_function(mesh_list.size() + 1); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index 17a61b3e4d..e2cfc2ed87 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -348,7 +348,7 @@ void GPUParticles3D::_notification(int p_what) { } } - // Use internal process when emitting and one_shot are on so that when + // 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()) { diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp index b0a10b5547..f109640aef 100644 --- a/scene/3d/light_3d.cpp +++ b/scene/3d/light_3d.cpp @@ -65,6 +65,8 @@ void Light3D::set_shadow(bool p_enable) { if (type == RenderingServer::LIGHT_SPOT || type == RenderingServer::LIGHT_OMNI) { update_configuration_warning(); } + + notify_property_list_changed(); } bool Light3D::has_shadow() const { @@ -202,6 +204,10 @@ 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")) { + property.usage = PROPERTY_USAGE_NOEDITOR; + } + if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") { property.usage = 0; } diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp deleted file mode 100644 index eaddec7601..0000000000 --- a/scene/3d/navigation_3d.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************/ -/* navigation_3d.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "navigation_3d.h" - -#include "servers/navigation_server_3d.h" - -Vector<Vector3> Navigation3D::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const { - return NavigationServer3D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize); -} - -Vector3 Navigation3D::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision) const { - return NavigationServer3D::get_singleton()->map_get_closest_point_to_segment(map, p_from, p_to, p_use_collision); -} - -Vector3 Navigation3D::get_closest_point(const Vector3 &p_point) const { - return NavigationServer3D::get_singleton()->map_get_closest_point(map, p_point); -} - -Vector3 Navigation3D::get_closest_point_normal(const Vector3 &p_point) const { - return NavigationServer3D::get_singleton()->map_get_closest_point_normal(map, p_point); -} - -RID Navigation3D::get_closest_point_owner(const Vector3 &p_point) const { - return NavigationServer3D::get_singleton()->map_get_closest_point_owner(map, p_point); -} - -void Navigation3D::set_up_vector(const Vector3 &p_up) { - up = p_up; - NavigationServer3D::get_singleton()->map_set_up(map, up); -} - -Vector3 Navigation3D::get_up_vector() const { - return up; -} - -void Navigation3D::set_cell_size(float p_cell_size) { - cell_size = p_cell_size; - NavigationServer3D::get_singleton()->map_set_cell_size(map, cell_size); -} - -void Navigation3D::set_edge_connection_margin(float p_edge_connection_margin) { - edge_connection_margin = p_edge_connection_margin; - NavigationServer3D::get_singleton()->map_set_edge_connection_margin(map, edge_connection_margin); -} - -void Navigation3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_rid"), &Navigation3D::get_rid); - - ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation3D::get_simple_path, DEFVAL(true)); - ClassDB::bind_method(D_METHOD("get_closest_point_to_segment", "start", "end", "use_collision"), &Navigation3D::get_closest_point_to_segment, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("get_closest_point", "to_point"), &Navigation3D::get_closest_point); - ClassDB::bind_method(D_METHOD("get_closest_point_normal", "to_point"), &Navigation3D::get_closest_point_normal); - ClassDB::bind_method(D_METHOD("get_closest_point_owner", "to_point"), &Navigation3D::get_closest_point_owner); - - ClassDB::bind_method(D_METHOD("set_up_vector", "up"), &Navigation3D::set_up_vector); - ClassDB::bind_method(D_METHOD("get_up_vector"), &Navigation3D::get_up_vector); - - ClassDB::bind_method(D_METHOD("set_cell_size", "cell_size"), &Navigation3D::set_cell_size); - ClassDB::bind_method(D_METHOD("get_cell_size"), &Navigation3D::get_cell_size); - - ClassDB::bind_method(D_METHOD("set_edge_connection_margin", "margin"), &Navigation3D::set_edge_connection_margin); - ClassDB::bind_method(D_METHOD("get_edge_connection_margin"), &Navigation3D::get_edge_connection_margin); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "up_vector"), "set_up_vector", "get_up_vector"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cell_size"), "set_cell_size", "get_cell_size"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "edge_connection_margin"), "set_edge_connection_margin", "get_edge_connection_margin"); -} - -void Navigation3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_READY: { - NavigationServer3D::get_singleton()->map_set_active(map, true); - } break; - case NOTIFICATION_EXIT_TREE: { - NavigationServer3D::get_singleton()->map_set_active(map, false); - } break; - } -} - -Navigation3D::Navigation3D() { - map = NavigationServer3D::get_singleton()->map_create(); - - set_cell_size(0.3); - set_edge_connection_margin(5.0); // Five meters, depends a lot on the agent's radius -} - -Navigation3D::~Navigation3D() { - NavigationServer3D::get_singleton()->free(map); -} diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h deleted file mode 100644 index b89725a3f5..0000000000 --- a/scene/3d/navigation_3d.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************/ -/* navigation_3d.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef NAVIGATION_3D_H -#define NAVIGATION_3D_H - -#include "scene/3d/navigation_region_3d.h" -#include "scene/3d/node_3d.h" - -class Navigation3D : public Node3D { - GDCLASS(Navigation3D, Node3D); - - RID map; - - Vector3 up = Vector3(0, 1, 0); - real_t cell_size; - real_t edge_connection_margin; - -protected: - static void _bind_methods(); - void _notification(int p_what); - -public: - RID get_rid() const { - return map; - } - - void set_up_vector(const Vector3 &p_up); - Vector3 get_up_vector() const; - - void set_cell_size(float p_cell_size); - float get_cell_size() const { - return cell_size; - } - - void set_edge_connection_margin(float p_edge_connection_margin); - float get_edge_connection_margin() const { - return edge_connection_margin; - } - - Vector<Vector3> get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize = true) const; - Vector3 get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, bool p_use_collision = false) const; - Vector3 get_closest_point(const Vector3 &p_point) const; - Vector3 get_closest_point_normal(const Vector3 &p_point) const; - RID get_closest_point_owner(const Vector3 &p_point) const; - - Navigation3D(); - ~Navigation3D(); -}; - -#endif // NAVIGATION_H diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp index 8917cc4664..21ca3d70dd 100644 --- a/scene/3d/navigation_agent_3d.cpp +++ b/scene/3d/navigation_agent_3d.cpp @@ -31,7 +31,6 @@ #include "navigation_agent_3d.h" #include "core/config/engine.h" -#include "scene/3d/navigation_3d.h" #include "servers/navigation_server_3d.h" void NavigationAgent3D::_bind_methods() { @@ -47,9 +46,6 @@ void NavigationAgent3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_ignore_y", "ignore"), &NavigationAgent3D::set_ignore_y); ClassDB::bind_method(D_METHOD("get_ignore_y"), &NavigationAgent3D::get_ignore_y); - ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationAgent3D::set_navigation_node); - ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationAgent3D::get_navigation_node); - ClassDB::bind_method(D_METHOD("set_neighbor_dist", "neighbor_dist"), &NavigationAgent3D::set_neighbor_dist); ClassDB::bind_method(D_METHOD("get_neighbor_dist"), &NavigationAgent3D::get_neighbor_dist); @@ -101,28 +97,10 @@ void NavigationAgent3D::_notification(int p_what) { agent_parent = Object::cast_to<Node3D>(get_parent()); NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done"); - - // Search the navigation node and set it - { - Navigation3D *nav = nullptr; - Node *p = get_parent(); - while (p != nullptr) { - nav = Object::cast_to<Navigation3D>(p); - if (nav != nullptr) { - p = nullptr; - } else { - p = p->get_parent(); - } - } - - set_navigation(nav); - } - set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { agent_parent = nullptr; - set_navigation(nullptr); set_physics_process_internal(false); } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { @@ -154,25 +132,6 @@ NavigationAgent3D::~NavigationAgent3D() { agent = RID(); // Pointless } -void NavigationAgent3D::set_navigation(Navigation3D *p_nav) { - if (navigation == p_nav) { - return; // Pointless - } - - navigation = p_nav; - NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); -} - -void NavigationAgent3D::set_navigation_node(Node *p_nav) { - Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav); - ERR_FAIL_COND(nav == nullptr); - set_navigation(nav); -} - -Node *NavigationAgent3D::get_navigation_node() const { - return Object::cast_to<Node>(navigation); -} - void NavigationAgent3D::set_target_desired_distance(real_t p_dd) { target_desired_distance = p_dd; } @@ -303,7 +262,7 @@ void NavigationAgent3D::update_navigation() { if (agent_parent == nullptr) { return; } - if (navigation == nullptr) { + if (!agent_parent->is_inside_tree()) { return; } if (update_frame_id == Engine::get_singleton()->get_physics_frames()) { @@ -337,7 +296,7 @@ void NavigationAgent3D::update_navigation() { } if (reload_path) { - navigation_path = NavigationServer3D::get_singleton()->map_get_path(navigation->get_rid(), o, target_location, true); + navigation_path = NavigationServer3D::get_singleton()->map_get_path(agent_parent->get_world_3d()->get_navigation_map(), o, target_location, true); navigation_finished = false; nav_path_index = 0; emit_signal("path_changed"); diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h index bd890a051b..22db889618 100644 --- a/scene/3d/navigation_agent_3d.h +++ b/scene/3d/navigation_agent_3d.h @@ -35,13 +35,11 @@ #include "scene/main/node.h" class Node3D; -class Navigation3D; class NavigationAgent3D : public Node { GDCLASS(NavigationAgent3D, Node); Node3D *agent_parent = nullptr; - Navigation3D *navigation = nullptr; RID agent; @@ -76,14 +74,6 @@ public: NavigationAgent3D(); virtual ~NavigationAgent3D(); - void set_navigation(Navigation3D *p_nav); - const Navigation3D *get_navigation() const { - return navigation; - } - - void set_navigation_node(Node *p_nav); - Node *get_navigation_node() const; - RID get_rid() const { return agent; } diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp index 01bf7de913..df03bca4fd 100644 --- a/scene/3d/navigation_obstacle_3d.cpp +++ b/scene/3d/navigation_obstacle_3d.cpp @@ -31,55 +31,38 @@ #include "navigation_obstacle_3d.h" #include "scene/3d/collision_shape_3d.h" -#include "scene/3d/navigation_3d.h" #include "scene/3d/physics_body_3d.h" #include "servers/navigation_server_3d.h" void NavigationObstacle3D::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle3D::set_navigation_node); - ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle3D::get_navigation_node); } void NavigationObstacle3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { - update_agent_shape(); - - // Search the navigation node and set it - { - Navigation3D *nav = nullptr; - Node *p = get_parent(); - while (p != nullptr) { - nav = Object::cast_to<Navigation3D>(p); - if (nav != nullptr) { - p = nullptr; - } else { - p = p->get_parent(); - } - } - - set_navigation(nav); - } - set_physics_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { - set_navigation(nullptr); set_physics_process_internal(false); } break; + case NOTIFICATION_PARENTED: { + parent_node3d = Object::cast_to<Node3D>(get_parent()); + update_agent_shape(); + } break; + case NOTIFICATION_UNPARENTED: { + parent_node3d = nullptr; + } break; case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { - Node3D *spatial = Object::cast_to<Node3D>(get_parent()); - if (spatial) { - NavigationServer3D::get_singleton()->agent_set_position(agent, spatial->get_global_transform().origin); - } - - PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent()); - if (rigid) { - Vector3 v = rigid->get_linear_velocity(); - NavigationServer3D::get_singleton()->agent_set_velocity(agent, v); - NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v); + if (parent_node3d) { + NavigationServer3D::get_singleton()->agent_set_position(agent, parent_node3d->get_global_transform().origin); + + PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent()); + if (rigid) { + Vector3 v = rigid->get_linear_velocity(); + NavigationServer3D::get_singleton()->agent_set_velocity(agent, v); + NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v); + } } - } break; } } @@ -93,29 +76,10 @@ NavigationObstacle3D::~NavigationObstacle3D() { agent = RID(); // Pointless } -void NavigationObstacle3D::set_navigation(Navigation3D *p_nav) { - if (navigation == p_nav) { - return; // Pointless - } - - navigation = p_nav; - NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid()); -} - -void NavigationObstacle3D::set_navigation_node(Node *p_nav) { - Navigation3D *nav = Object::cast_to<Navigation3D>(p_nav); - ERR_FAIL_COND(nav == nullptr); - set_navigation(nav); -} - -Node *NavigationObstacle3D::get_navigation_node() const { - return Object::cast_to<Node>(navigation); -} - String NavigationObstacle3D::get_configuration_warning() const { String warning = Node::get_configuration_warning(); - if (!Object::cast_to<Node3D>(get_parent())) { + if (!parent_node3d) { if (!warning.is_empty()) { warning += "\n\n"; } @@ -126,40 +90,38 @@ String NavigationObstacle3D::get_configuration_warning() const { } void NavigationObstacle3D::update_agent_shape() { - Node *node = get_parent(); - - // Estimate the radius of this physics body - real_t radius = 0.0; - for (int i(0); i < node->get_child_count(); i++) { - // For each collision shape - CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(node->get_child(i)); - if (cs) { - // Take the distance between the Body center to the shape center - real_t r = cs->get_transform().origin.length(); - if (cs->get_shape().is_valid()) { - // and add the enclosing shape radius - r += cs->get_shape()->get_enclosing_radius(); + if (parent_node3d) { + // Estimate the radius of this physics body + real_t radius = 0.0; + for (int i(0); i < parent_node3d->get_child_count(); i++) { + // For each collision shape + CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(parent_node3d->get_child(i)); + if (cs) { + // Take the distance between the Body center to the shape center + real_t r = cs->get_transform().origin.length(); + if (cs->get_shape().is_valid()) { + // and add the enclosing shape radius + r += cs->get_shape()->get_enclosing_radius(); + } + Vector3 s = cs->get_global_transform().basis.get_scale(); + r *= MAX(s.x, MAX(s.y, s.z)); + // Takes the biggest radius + radius = MAX(radius, r); } - Vector3 s = cs->get_global_transform().basis.get_scale(); - r *= MAX(s.x, MAX(s.y, s.z)); - // Takes the biggest radius - radius = MAX(radius, r); } - } - Node3D *spa = Object::cast_to<Node3D>(node); - if (spa) { - Vector3 s = spa->get_global_transform().basis.get_scale(); + + Vector3 s = parent_node3d->get_global_transform().basis.get_scale(); radius *= MAX(s.x, MAX(s.y, s.z)); - } - if (radius == 0.0) { - radius = 1.0; // Never a 0 radius - } + if (radius == 0.0) { + radius = 1.0; // Never a 0 radius + } - // Initialize the Agent as an object - NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); - NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0); - NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0); - NavigationServer3D::get_singleton()->agent_set_radius(agent, radius); - NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0); + // Initialize the Agent as an object + NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0); + NavigationServer3D::get_singleton()->agent_set_max_neighbors(agent, 0); + NavigationServer3D::get_singleton()->agent_set_time_horizon(agent, 0.0); + NavigationServer3D::get_singleton()->agent_set_radius(agent, radius); + NavigationServer3D::get_singleton()->agent_set_max_speed(agent, 0.0); + } } diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h index b8d05b8a87..b1bb53724a 100644 --- a/scene/3d/navigation_obstacle_3d.h +++ b/scene/3d/navigation_obstacle_3d.h @@ -31,15 +31,13 @@ #ifndef NAVIGATION_OBSTACLE_H #define NAVIGATION_OBSTACLE_H +#include "scene/3d/node_3d.h" #include "scene/main/node.h" -class Navigation3D; - class NavigationObstacle3D : public Node { GDCLASS(NavigationObstacle3D, Node); - Navigation3D *navigation = nullptr; - + Node3D *parent_node3d = nullptr; RID agent; protected: @@ -50,14 +48,6 @@ public: NavigationObstacle3D(); virtual ~NavigationObstacle3D(); - void set_navigation(Navigation3D *p_nav); - const Navigation3D *get_navigation() const { - return navigation; - } - - void set_navigation_node(Node *p_nav); - Node *get_navigation_node() const; - RID get_rid() const { return agent; } diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp index 19bde94222..3ca704e4b8 100644 --- a/scene/3d/navigation_region_3d.cpp +++ b/scene/3d/navigation_region_3d.cpp @@ -32,7 +32,6 @@ #include "core/os/thread.h" #include "mesh_instance_3d.h" -#include "navigation_3d.h" #include "servers/navigation_server_3d.h" void NavigationRegion3D::set_enabled(bool p_enabled) { @@ -48,9 +47,7 @@ void NavigationRegion3D::set_enabled(bool p_enabled) { if (!enabled) { NavigationServer3D::get_singleton()->region_set_map(region, RID()); } else { - if (navigation) { - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); - } + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } if (debug_view) { @@ -69,22 +66,21 @@ bool NavigationRegion3D::is_enabled() const { return enabled; } +void NavigationRegion3D::set_layers(uint32_t p_layers) { + NavigationServer3D::get_singleton()->region_set_layers(region, p_layers); +} + +uint32_t NavigationRegion3D::get_layers() const { + return NavigationServer3D::get_singleton()->region_get_layers(region); +} + ///////////////////////////// void NavigationRegion3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { - Node3D *c = this; - while (c) { - navigation = Object::cast_to<Navigation3D>(c); - if (navigation) { - if (enabled) { - NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid()); - } - break; - } - - c = c->get_parent_spatial(); + if (enabled) { + NavigationServer3D::get_singleton()->region_set_map(region, get_world_3d()->get_navigation_map()); } if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) { @@ -105,15 +101,12 @@ void NavigationRegion3D::_notification(int p_what) { } break; case NOTIFICATION_EXIT_TREE: { - if (navigation) { - NavigationServer3D::get_singleton()->region_set_map(region, RID()); - } + NavigationServer3D::get_singleton()->region_set_map(region, RID()); if (debug_view) { debug_view->queue_delete(); debug_view = nullptr; } - navigation = nullptr; } break; } } @@ -198,19 +191,7 @@ String NavigationRegion3D::get_configuration_warning() const { warning += TTR("A NavigationMesh resource must be set or created for this node to work."); } - const Node3D *c = this; - while (c) { - if (Object::cast_to<Navigation3D>(c)) { - return warning; - } - - c = Object::cast_to<Node3D>(c->get_parent()); - } - - if (!warning.is_empty()) { - warning += "\n\n"; - } - return warning + TTR("NavigationRegion3D must be a child or grandchild to a Navigation3D node. It only provides navigation data."); + return warning; } void NavigationRegion3D::_bind_methods() { @@ -220,11 +201,15 @@ void NavigationRegion3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &NavigationRegion3D::set_enabled); ClassDB::bind_method(D_METHOD("is_enabled"), &NavigationRegion3D::is_enabled); + ClassDB::bind_method(D_METHOD("set_layers", "layers"), &NavigationRegion3D::set_layers); + ClassDB::bind_method(D_METHOD("get_layers"), &NavigationRegion3D::get_layers); + ClassDB::bind_method(D_METHOD("bake_navigation_mesh"), &NavigationRegion3D::bake_navigation_mesh); ClassDB::bind_method(D_METHOD("_bake_finished", "nav_mesh"), &NavigationRegion3D::_bake_finished); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "navmesh", PROPERTY_HINT_RESOURCE_TYPE, "NavigationMesh"), "set_navigation_mesh", "get_navigation_mesh"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "layers", PROPERTY_HINT_LAYERS_3D_NAVIGATION), "set_layers", "get_layers"); ADD_SIGNAL(MethodInfo("navigation_mesh_changed")); ADD_SIGNAL(MethodInfo("bake_finished")); diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h index 6ae15c9360..52fa2d6159 100644 --- a/scene/3d/navigation_region_3d.h +++ b/scene/3d/navigation_region_3d.h @@ -35,8 +35,6 @@ #include "scene/resources/mesh.h" #include "scene/resources/navigation_mesh.h" -class Navigation3D; - class NavigationRegion3D : public Node3D { GDCLASS(NavigationRegion3D, Node3D); @@ -44,7 +42,6 @@ class NavigationRegion3D : public Node3D { RID region; Ref<NavigationMesh> navmesh; - Navigation3D *navigation = nullptr; Node *debug_view = nullptr; Thread bake_thread; @@ -58,6 +55,9 @@ public: void set_enabled(bool p_enabled); bool is_enabled() const; + void set_layers(uint32_t p_layers); + uint32_t get_layers() const; + void set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh); Ref<NavigationMesh> get_navigation_mesh() const; diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp index 4575716f7a..ba0f8cc870 100644 --- a/scene/3d/node_3d.cpp +++ b/scene/3d/node_3d.cpp @@ -48,7 +48,7 @@ a) If above is invalid, don't keep invalidating upwards 2) If a node sets a GLOBAL, it is converted to LOCAL (and forces validation of everything pending below) - drawback: setting/reading globals is useful and used very very often, and using affine inverses is slow + drawback: setting/reading globals is useful and used very often, and using affine inverses is slow --- diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 6d135c8283..e225c1f22d 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -416,13 +416,13 @@ void RigidBody3D::_direct_state_changed(Object *p_state) { } } - //process remotions + //process removals for (int i = 0; i < toremove_count; i++) { _body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape); } - //process aditions + //process additions for (int i = 0; i < toadd_count; i++) { _body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape); diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp index 0463bed9d6..de9c75621b 100644 --- a/scene/3d/physics_joint_3d.cpp +++ b/scene/3d/physics_joint_3d.cpp @@ -46,24 +46,15 @@ void Joint3D::_disconnect_signals() { } } -void Joint3D::_body_exit_tree(const ObjectID &p_body_id) { +void Joint3D::_body_exit_tree() { _disconnect_signals(); - Object *object = ObjectDB::get_instance(p_body_id); - PhysicsBody3D *body = Object::cast_to<PhysicsBody3D>(object); - ERR_FAIL_NULL(body); - RID body_rid = body->get_rid(); - if (ba == body_rid) { - a = NodePath(); - } - if (bb == body_rid) { - b = NodePath(); - } - _update_joint(); + _update_joint(true); } void Joint3D::_update_joint(bool p_only_free) { if (ba.is_valid() && bb.is_valid()) { PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb); + PhysicsServer3D::get_singleton()->body_remove_collision_exception(bb, ba); } ba = RID(); @@ -133,12 +124,12 @@ void Joint3D::_update_joint(bool p_only_free) { if (body_a) { ba = body_a->get_rid(); - body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree), make_binds(body_a->get_instance_id())); + body_a->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); } if (body_b) { bb = body_b->get_rid(); - body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree), make_binds(body_b->get_instance_id())); + body_b->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Joint3D::_body_exit_tree)); } PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision); diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h index 8d0a16e432..f624ba602b 100644 --- a/scene/3d/physics_joint_3d.h +++ b/scene/3d/physics_joint_3d.h @@ -51,7 +51,7 @@ class Joint3D : public Node3D { protected: void _disconnect_signals(); - void _body_exit_tree(const ObjectID &p_body_id); + void _body_exit_tree(); void _update_joint(bool p_only_free = false); void _notification(int p_what); diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp index bfe79f15f5..66f3e539a2 100644 --- a/scene/3d/ray_cast_3d.cpp +++ b/scene/3d/ray_cast_3d.cpp @@ -37,10 +37,13 @@ void RayCast3D::set_target_position(const Vector3 &p_point) { target_position = p_point; - if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) { - update_gizmo(); - } - if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) { + update_gizmo(); + + if (Engine::get_singleton()->is_editor_hint()) { + if (is_inside_tree()) { + _update_debug_shape_vertices(); + } + } else if (debug_shape) { _update_debug_shape(); } } @@ -146,6 +149,9 @@ bool RayCast3D::get_exclude_parent_body() const { void RayCast3D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { + if (Engine::get_singleton()->is_editor_hint()) { + _update_debug_shape_vertices(); + } if (enabled && !Engine::get_singleton()->is_editor_hint()) { set_physics_process_internal(true); } else { @@ -183,10 +189,7 @@ void RayCast3D::_notification(int p_what) { bool prev_collision_state = collided; _update_raycast_state(); if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) { - if (debug_material.is_valid()) { - Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D>>(debug_material); - line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6)); - } + _update_debug_shape_material(true); } } break; @@ -310,6 +313,12 @@ void RayCast3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_collide_with_bodies", "enable"), &RayCast3D::set_collide_with_bodies); ClassDB::bind_method(D_METHOD("is_collide_with_bodies_enabled"), &RayCast3D::is_collide_with_bodies_enabled); + ClassDB::bind_method(D_METHOD("set_debug_shape_custom_color", "debug_shape_custom_color"), &RayCast3D::set_debug_shape_custom_color); + ClassDB::bind_method(D_METHOD("get_debug_shape_custom_color"), &RayCast3D::get_debug_shape_custom_color); + + ClassDB::bind_method(D_METHOD("set_debug_shape_thickness", "debug_shape_thickness"), &RayCast3D::set_debug_shape_thickness); + ClassDB::bind_method(D_METHOD("get_debug_shape_thickness"), &RayCast3D::get_debug_shape_thickness); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "target_position"), "set_target_position", "get_target_position"); @@ -318,16 +327,80 @@ void RayCast3D::_bind_methods() { ADD_GROUP("Collide With", "collide_with"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_areas", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_areas", "is_collide_with_areas_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with_bodies", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collide_with_bodies", "is_collide_with_bodies_enabled"); + + ADD_GROUP("Debug Shape", "debug_shape"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_shape_custom_color"), "set_debug_shape_custom_color", "get_debug_shape_custom_color"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_shape_thickness", PROPERTY_HINT_RANGE, "1,5"), "set_debug_shape_thickness", "get_debug_shape_thickness"); } -void RayCast3D::_create_debug_shape() { - if (!debug_material.is_valid()) { - debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); +float RayCast3D::get_debug_shape_thickness() const { + return debug_shape_thickness; +} + +void RayCast3D::_update_debug_shape_vertices() { + debug_shape_vertices.clear(); + debug_line_vertices.clear(); + + if (target_position == Vector3()) { + return; + } + + debug_line_vertices.push_back(Vector3()); + debug_line_vertices.push_back(target_position); + + if (debug_shape_thickness > 1) { + float scale_factor = 100.0; + Vector3 dir = Vector3(target_position).normalized(); + // Draw truncated pyramid + Vector3 normal = (fabs(dir.x) + fabs(dir.y) > CMP_EPSILON) ? Vector3(-dir.y, dir.x, 0).normalized() : Vector3(0, -dir.z, dir.y).normalized(); + normal *= debug_shape_thickness / scale_factor; + int vertices_strip_order[14] = { 4, 5, 0, 1, 2, 5, 6, 4, 7, 0, 3, 2, 7, 6 }; + for (int v = 0; v < 14; v++) { + Vector3 vertex = vertices_strip_order[v] < 4 ? normal : normal / 3.0 + target_position; + debug_shape_vertices.push_back(vertex.rotated(dir, Math_PI * (0.5 * (vertices_strip_order[v] % 4) + 0.25))); + } + } +} + +void RayCast3D::set_debug_shape_thickness(const float p_debug_shape_thickness) { + debug_shape_thickness = p_debug_shape_thickness; + update_gizmo(); + + if (Engine::get_singleton()->is_editor_hint()) { + if (is_inside_tree()) { + _update_debug_shape_vertices(); + } + } else if (debug_shape) { + _update_debug_shape(); + } +} + +const Vector<Vector3> &RayCast3D::get_debug_shape_vertices() const { + return debug_shape_vertices; +} - Ref<StandardMaterial3D> line_material = static_cast<Ref<StandardMaterial3D>>(debug_material); - line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); - line_material->set_albedo(Color(1.0, 0.8, 0.6)); +const Vector<Vector3> &RayCast3D::get_debug_line_vertices() const { + return debug_line_vertices; +} + +void RayCast3D::set_debug_shape_custom_color(const Color &p_color) { + debug_shape_custom_color = p_color; + if (debug_material.is_valid()) { + _update_debug_shape_material(); } +} + +Ref<StandardMaterial3D> RayCast3D::get_debug_material() { + _update_debug_shape_material(); + return debug_material; +} + +const Color &RayCast3D::get_debug_shape_custom_color() const { + return debug_shape_custom_color; +} + +void RayCast3D::_create_debug_shape() { + _update_debug_shape_material(); Ref<ArrayMesh> mesh = memnew(ArrayMesh); @@ -338,6 +411,35 @@ void RayCast3D::_create_debug_shape() { debug_shape = mi; } +void RayCast3D::_update_debug_shape_material(bool p_check_collision) { + if (!debug_material.is_valid()) { + Ref<StandardMaterial3D> material = memnew(StandardMaterial3D); + debug_material = material; + + material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED); + material->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA); + } + + Color color = debug_shape_custom_color; + if (color == Color(0.0, 0.0, 0.0)) { + // Use the default debug shape color defined in the Project Settings. + color = get_tree()->get_debug_collisions_color(); + } + + if (p_check_collision) { + if ((color.get_h() < 0.055 || color.get_h() > 0.945) && color.get_s() > 0.5 && color.get_v() > 0.5) { + // If base color is already quite reddish, highlight collision with green color + color = Color(0.0, 1.0, 0.0, color.a); + } else { + // Else, highlight collision with red color + color = Color(1.0, 0, 0, color.a); + } + } + + Ref<StandardMaterial3D> material = static_cast<Ref<StandardMaterial3D>>(debug_material); + material->set_albedo(color); +} + void RayCast3D::_update_debug_shape() { if (!enabled) { return; @@ -353,26 +455,28 @@ void RayCast3D::_update_debug_shape() { return; } - Vector<Vector3> verts; - verts.push_back(Vector3()); - verts.push_back(target_position); + _update_debug_shape_vertices(); - if (mesh->get_surface_count() == 0) { - Array a; - a.resize(Mesh::ARRAY_MAX); - a[Mesh::ARRAY_VERTEX] = verts; + mesh->clear_surfaces(); - uint32_t flags = Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + Array a; + a.resize(Mesh::ARRAY_MAX); + uint32_t flags = 0; + int surface_count = 0; + + if (!debug_line_vertices.is_empty()) { + a[Mesh::ARRAY_VERTEX] = debug_line_vertices; mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a, Array(), Dictionary(), flags); - mesh->surface_set_material(0, debug_material); - } else { - Vector<uint8_t> byte_array; - int array_size = sizeof(Vector3) * verts.size(); - byte_array.resize(array_size); - copymem(byte_array.ptrw(), verts.ptr(), array_size); + mesh->surface_set_material(surface_count, debug_material); + ++surface_count; + } - RS::get_singleton()->mesh_surface_update_region(mesh->get_rid(), 0, 0, byte_array); + if (!debug_shape_vertices.is_empty()) { + a[Mesh::ARRAY_VERTEX] = debug_shape_vertices; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLE_STRIP, a, Array(), Dictionary(), flags); + mesh->surface_set_material(surface_count, debug_material); + ++surface_count; } } diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h index ae92189527..968cede9f2 100644 --- a/scene/3d/ray_cast_3d.h +++ b/scene/3d/ray_cast_3d.h @@ -51,9 +51,15 @@ class RayCast3D : public Node3D { Node *debug_shape = nullptr; Ref<Material> debug_material; + Color debug_shape_custom_color = Color(0.0, 0.0, 0.0); + int debug_shape_thickness = 2; + Vector<Vector3> debug_shape_vertices; + Vector<Vector3> debug_line_vertices; void _create_debug_shape(); void _update_debug_shape(); + void _update_debug_shape_material(bool p_check_collision = false); + void _update_debug_shape_vertices(); void _clear_debug_shape(); bool collide_with_areas = false; @@ -86,6 +92,17 @@ public: void set_exclude_parent_body(bool p_exclude_parent_body); bool get_exclude_parent_body() const; + const Color &get_debug_shape_custom_color() const; + void set_debug_shape_custom_color(const Color &p_color); + + const Vector<Vector3> &get_debug_shape_vertices() const; + const Vector<Vector3> &get_debug_line_vertices() const; + + Ref<StandardMaterial3D> get_debug_material(); + + float get_debug_shape_thickness() const; + void set_debug_shape_thickness(const float p_debug_thickness); + void force_raycast_update(); bool is_colliding() const; Object *get_collider() const; diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index be62fe801f..db5fc7593e 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -439,6 +439,17 @@ String Skeleton3D::get_bone_name(int p_bone) const { return bones[p_bone].name; } +void Skeleton3D::set_bone_name(int p_bone, const String &p_name) { + ERR_FAIL_INDEX(p_bone, bones.size()); + + for (int i = 0; i < bones.size(); i++) { + if (i != p_bone) { + ERR_FAIL_COND(bones[i].name == p_name); + } + } + + bones.write[p_bone].name = p_name; +} bool Skeleton3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const { int parent_of_bone = get_bone_parent(p_bone); @@ -869,6 +880,7 @@ void Skeleton3D::_bind_methods() { ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton3D::add_bone); ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton3D::find_bone); ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name); + ClassDB::bind_method(D_METHOD("set_bone_name", "bone_idx", "name"), &Skeleton3D::set_bone_name); ClassDB::bind_method(D_METHOD("get_bone_parent", "bone_idx"), &Skeleton3D::get_bone_parent); ClassDB::bind_method(D_METHOD("set_bone_parent", "bone_idx", "parent_idx"), &Skeleton3D::set_bone_parent); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index 9772bfcc95..2941ac2c45 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -143,6 +143,7 @@ public: void add_bone(const String &p_name); int find_bone(const String &p_name) const; String get_bone_name(int p_bone) const; + void set_bone_name(int p_bone, const String &p_name); bool is_bone_parent_of(int p_bone_id, int p_parent_bone_id) const; diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp index cb486a12ae..85da546430 100644 --- a/scene/3d/skeleton_ik_3d.cpp +++ b/scene/3d/skeleton_ik_3d.cpp @@ -63,7 +63,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain chain.chain_root.bone = p_task->root_bone; chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(chain.chain_root.bone); chain.chain_root.current_pos = chain.chain_root.initial_transform.origin; - chain.chain_root.pb = p_task->skeleton->get_physical_bone(chain.chain_root.bone); chain.middle_chain_item = nullptr; // Holds all IDs that are composing a single chain in reverse order @@ -96,8 +95,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain if (!child_ci) { child_ci = sub_chain->add_child(chain_ids[i]); - child_ci->pb = p_task->skeleton->get_physical_bone(child_ci->bone); - child_ci->initial_transform = p_task->skeleton->get_bone_global_pose(child_ci->bone); child_ci->current_pos = child_ci->initial_transform.origin; @@ -123,7 +120,7 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain if (p_force_simple_chain) { // NOTE: - // This is an "hack" that force to create only one tip per chain since the solver of multi tip (end effector) + // This is a "hack" that force to create only one tip per chain since the solver of multi tip (end effector) // is not yet created. // Remove this code when this is done break; @@ -132,20 +129,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain return true; } -void FabrikInverseKinematic::update_chain(const Skeleton3D *p_sk, ChainItem *p_chain_item) { - if (!p_chain_item) { - return; - } - - p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone); - p_chain_item->current_pos = p_chain_item->initial_transform.origin; - - ChainItem *items = p_chain_item->children.ptrw(); - for (int i = 0; i < p_chain_item->children.size(); i += 1) { - update_chain(p_sk, items + i); - } -} - void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) { real_t distance_to_goal(1e4); real_t previous_distance_to_goal(0); @@ -263,7 +246,7 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_ p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform; } else { // End effector in local transform - const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors.write[0].tip_bone)); + const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors[0].tip_bone)); // Update the end_effector (local transform) by blending with current pose p_task->end_effectors.write[0].goal_transform = end_effector_pose.interpolate_with(p_inverse_transf * p_task->goal_global_transform, blending_delta); @@ -285,9 +268,11 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true); } - make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta); + // Update the initial root transform + p_task->chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone); + p_task->chain.chain_root.current_pos = p_task->chain.chain_root.initial_transform.origin; - update_chain(p_task->skeleton, &p_task->chain.chain_root); + make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta); if (p_use_magnet && p_task->chain.middle_chain_item) { p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta); @@ -310,6 +295,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove const real_t rot_angle(Math::acos(CLAMP(initial_ori.dot(ci->current_ori), -1, 1))); new_bone_pose.basis.rotate(rot_axis, rot_angle); } + } else { // Set target orientation to tip if (override_tip_basis) { @@ -319,6 +305,10 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove } } + // IK should not affect scale, so undo any scaling + new_bone_pose.basis.orthonormalize(); + new_bone_pose.basis.scale(p_task->skeleton->get_bone_global_pose(ci->bone).basis.get_scale()); + p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true); if (!ci->children.is_empty()) { diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h index eefecf68bb..c98f55804c 100644 --- a/scene/3d/skeleton_ik_3d.h +++ b/scene/3d/skeleton_ik_3d.h @@ -52,7 +52,6 @@ class FabrikInverseKinematic { // Bone info BoneId bone = -1; - PhysicalBone3D *pb = nullptr; real_t length = 0.0; /// Positions relative to root bone @@ -107,8 +106,6 @@ private: /// Init a chain that starts from the root to tip static bool build_chain(Task *p_task, bool p_force_simple_chain = true); - static void update_chain(const Skeleton3D *p_sk, ChainItem *p_chain_item); - static void solve_simple(Task *p_task, bool p_solve_magnet); /// Special solvers that solve only chains with one end effector static void solve_simple_backwards(Chain &r_chain, bool p_solve_magnet); diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 2d8f22ab37..3fde4d6ef3 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -37,7 +37,6 @@ #include "scene/3d/collision_object_3d.h" #include "scene/3d/physics_body_3d.h" #include "scene/3d/skeleton_3d.h" -#include "servers/physics_server_3d.h" SoftBodyRenderingServerHandler::SoftBodyRenderingServerHandler() {} @@ -48,27 +47,28 @@ void SoftBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) { mesh = p_mesh; surface = p_surface; -#ifndef _MSC_VER -#warning Softbody is not working, needs to be redone considering that these functions no longer exist -#endif -#if 0 - const uint32_t surface_format = RS::get_singleton()->mesh_surface_get_format(mesh, surface); - const int surface_vertex_len = RS::get_singleton()->mesh_surface_get_array_len(mesh, p_surface); - const int surface_index_len = RS::get_singleton()->mesh_surface_get_array_index_len(mesh, p_surface); + + RS::SurfaceData surface_data = RS::get_singleton()->mesh_get_surface(mesh, surface); + uint32_t surface_offsets[RS::ARRAY_MAX]; + uint32_t vertex_stride; + uint32_t attrib_stride; + uint32_t skin_stride; + RS::get_singleton()->mesh_surface_make_offsets_from_format(surface_data.format, surface_data.vertex_count, surface_data.index_count, surface_offsets, vertex_stride, attrib_stride, skin_stride); - buffer = RS::get_singleton()->mesh_surface_get_array(mesh, surface); - stride = RS::get_singleton()->mesh_surface_make_offsets_from_format(surface_format, surface_vertex_len, surface_index_len, surface_offsets); + buffer = surface_data.vertex_data; + stride = vertex_stride; offset_vertices = surface_offsets[RS::ARRAY_VERTEX]; offset_normal = surface_offsets[RS::ARRAY_NORMAL]; -#endif } void SoftBodyRenderingServerHandler::clear() { - if (mesh.is_valid()) { - buffer.resize(0); - } + buffer.resize(0); + stride = 0; + offset_vertices = 0; + offset_normal = 0; + surface = 0; mesh = RID(); } @@ -77,7 +77,7 @@ void SoftBodyRenderingServerHandler::open() { } void SoftBodyRenderingServerHandler::close() { - //write_buffer.release(); + write_buffer = nullptr; } void SoftBodyRenderingServerHandler::commit_changes() { @@ -309,6 +309,8 @@ void SoftBody3D::_notification(int p_what) { } void SoftBody3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_physics_rid"), &SoftBody3D::get_physics_rid); + ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody3D::set_collision_mask); ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody3D::get_collision_mask); @@ -337,18 +339,9 @@ void SoftBody3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_linear_stiffness", "linear_stiffness"), &SoftBody3D::set_linear_stiffness); ClassDB::bind_method(D_METHOD("get_linear_stiffness"), &SoftBody3D::get_linear_stiffness); - ClassDB::bind_method(D_METHOD("set_angular_stiffness", "angular_stiffness"), &SoftBody3D::set_angular_stiffness); - ClassDB::bind_method(D_METHOD("get_angular_stiffness"), &SoftBody3D::get_angular_stiffness); - - ClassDB::bind_method(D_METHOD("set_volume_stiffness", "volume_stiffness"), &SoftBody3D::set_volume_stiffness); - ClassDB::bind_method(D_METHOD("get_volume_stiffness"), &SoftBody3D::get_volume_stiffness); - ClassDB::bind_method(D_METHOD("set_pressure_coefficient", "pressure_coefficient"), &SoftBody3D::set_pressure_coefficient); ClassDB::bind_method(D_METHOD("get_pressure_coefficient"), &SoftBody3D::get_pressure_coefficient); - ClassDB::bind_method(D_METHOD("set_pose_matching_coefficient", "pose_matching_coefficient"), &SoftBody3D::set_pose_matching_coefficient); - ClassDB::bind_method(D_METHOD("get_pose_matching_coefficient"), &SoftBody3D::get_pose_matching_coefficient); - ClassDB::bind_method(D_METHOD("set_damping_coefficient", "damping_coefficient"), &SoftBody3D::set_damping_coefficient); ClassDB::bind_method(D_METHOD("get_damping_coefficient"), &SoftBody3D::get_damping_coefficient); @@ -366,12 +359,9 @@ void SoftBody3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "simulation_precision", PROPERTY_HINT_RANGE, "1,100,1"), "set_simulation_precision", "get_simulation_precision"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "total_mass", PROPERTY_HINT_RANGE, "0.01,10000,1"), "set_total_mass", "get_total_mass"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_linear_stiffness", "get_linear_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_angular_stiffness", "get_angular_stiffness"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_stiffness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_volume_stiffness", "get_volume_stiffness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure_coefficient"), "set_pressure_coefficient", "get_pressure_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "damping_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_damping_coefficient", "get_damping_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drag_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drag_coefficient", "get_drag_coefficient"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pose_matching_coefficient", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_pose_matching_coefficient", "get_pose_matching_coefficient"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ray_pickable"), "set_ray_pickable", "is_ray_pickable"); } @@ -612,34 +602,10 @@ real_t SoftBody3D::get_linear_stiffness() { return PhysicsServer3D::get_singleton()->soft_body_get_linear_stiffness(physics_rid); } -void SoftBody3D::set_angular_stiffness(real_t p_angular_stiffness) { - PhysicsServer3D::get_singleton()->soft_body_set_angular_stiffness(physics_rid, p_angular_stiffness); -} - -real_t SoftBody3D::get_angular_stiffness() { - return PhysicsServer3D::get_singleton()->soft_body_get_angular_stiffness(physics_rid); -} - -void SoftBody3D::set_volume_stiffness(real_t p_volume_stiffness) { - PhysicsServer3D::get_singleton()->soft_body_set_volume_stiffness(physics_rid, p_volume_stiffness); -} - -real_t SoftBody3D::get_volume_stiffness() { - return PhysicsServer3D::get_singleton()->soft_body_get_volume_stiffness(physics_rid); -} - real_t SoftBody3D::get_pressure_coefficient() { return PhysicsServer3D::get_singleton()->soft_body_get_pressure_coefficient(physics_rid); } -void SoftBody3D::set_pose_matching_coefficient(real_t p_pose_matching_coefficient) { - PhysicsServer3D::get_singleton()->soft_body_set_pose_matching_coefficient(physics_rid, p_pose_matching_coefficient); -} - -real_t SoftBody3D::get_pose_matching_coefficient() { - return PhysicsServer3D::get_singleton()->soft_body_get_pose_matching_coefficient(physics_rid); -} - void SoftBody3D::set_pressure_coefficient(real_t p_pressure_coefficient) { PhysicsServer3D::get_singleton()->soft_body_set_pressure_coefficient(physics_rid, p_pressure_coefficient); } @@ -768,7 +734,9 @@ void SoftBody3D::_reset_points_offsets() { PinnedPoint *w = pinned_points.ptrw(); for (int i = pinned_points.size() - 1; 0 <= i; --i) { if (!r[i].spatial_attachment) { - w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path)); + if (!r[i].spatial_attachment_path.is_empty() && has_node(r[i].spatial_attachment_path)) { + w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path)); + } } if (!r[i].spatial_attachment) { diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h index 6e24a530bd..f98df39209 100644 --- a/scene/3d/soft_body_3d.h +++ b/scene/3d/soft_body_3d.h @@ -32,10 +32,11 @@ #define SOFT_PHYSICS_BODY_H #include "scene/3d/mesh_instance_3d.h" +#include "servers/physics_server_3d.h" class SoftBody3D; -class SoftBodyRenderingServerHandler { +class SoftBodyRenderingServerHandler : public RenderingServerHandler { friend class SoftBody3D; RID mesh; @@ -57,9 +58,9 @@ private: void commit_changes(); public: - void set_vertex(int p_vertex_id, const void *p_vector3); - void set_normal(int p_vertex_id, const void *p_vector3); - void set_aabb(const AABB &p_aabb); + void set_vertex(int p_vertex_id, const void *p_vector3) override; + void set_normal(int p_vertex_id, const void *p_vector3) override; + void set_aabb(const AABB &p_aabb) override; }; class SoftBody3D : public MeshInstance3D { @@ -122,6 +123,8 @@ public: void prepare_physics_server(); void become_mesh_owner(); + RID get_physics_rid() const { return physics_rid; } + void set_collision_mask(uint32_t p_mask); uint32_t get_collision_mask() const; @@ -149,18 +152,9 @@ public: void set_linear_stiffness(real_t p_linear_stiffness); real_t get_linear_stiffness(); - void set_angular_stiffness(real_t p_angular_stiffness); - real_t get_angular_stiffness(); - - void set_volume_stiffness(real_t p_volume_stiffness); - real_t get_volume_stiffness(); - void set_pressure_coefficient(real_t p_pressure_coefficient); real_t get_pressure_coefficient(); - void set_pose_matching_coefficient(real_t p_pose_matching_coefficient); - real_t get_pose_matching_coefficient(); - void set_damping_coefficient(real_t p_damping_coefficient); real_t get_damping_coefficient(); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index cb2df9130f..0be54e7243 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -366,7 +366,7 @@ void Sprite3D::_draw() { } Rect2 base_rect; - if (region) { + if (region_enabled) { base_rect = region_rect; } else { base_rect = Rect2(0, 0, texture->get_width(), texture->get_height()); @@ -511,23 +511,24 @@ Ref<Texture2D> Sprite3D::get_texture() const { return texture; } -void Sprite3D::set_region(bool p_region) { - if (p_region == region) { +void Sprite3D::set_region_enabled(bool p_region_enabled) { + if (p_region_enabled == region_enabled) { return; } - region = p_region; + region_enabled = p_region_enabled; _queue_update(); + notify_property_list_changed(); } -bool Sprite3D::is_region() const { - return region; +bool Sprite3D::is_region_enabled() const { + return region_enabled; } void Sprite3D::set_region_rect(const Rect2 &p_region_rect) { bool changed = region_rect != p_region_rect; region_rect = p_region_rect; - if (region && changed) { + if (region_enabled && changed) { _queue_update(); } } @@ -594,7 +595,7 @@ Rect2 Sprite3D::get_item_rect() const { Size2i s; - if (region) { + if (region_enabled) { s = region_rect.size; } else { s = texture->get_size(); @@ -623,14 +624,18 @@ void Sprite3D::_validate_property(PropertyInfo &property) const { if (property.name == "frame_coords") { property.usage |= PROPERTY_USAGE_KEYING_INCREMENTS; } + + if (!region_enabled && property.name == "region_rect") { + property.usage = PROPERTY_USAGE_NOEDITOR; + } } void Sprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite3D::set_texture); ClassDB::bind_method(D_METHOD("get_texture"), &Sprite3D::get_texture); - ClassDB::bind_method(D_METHOD("set_region", "enabled"), &Sprite3D::set_region); - ClassDB::bind_method(D_METHOD("is_region"), &Sprite3D::is_region); + ClassDB::bind_method(D_METHOD("set_region_enabled", "enabled"), &Sprite3D::set_region_enabled); + ClassDB::bind_method(D_METHOD("is_region_enabled"), &Sprite3D::is_region_enabled); ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite3D::set_region_rect); ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite3D::get_region_rect); @@ -654,14 +659,14 @@ void Sprite3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "frame"), "set_frame", "get_frame"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "frame_coords", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_frame_coords", "get_frame_coords"); ADD_GROUP("Region", "region_"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region_enabled", "is_region_enabled"); ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect"); ADD_SIGNAL(MethodInfo("frame_changed")); } Sprite3D::Sprite3D() { - region = false; + region_enabled = false; frame = 0; vframes = 1; hframes = 1; @@ -687,7 +692,7 @@ void AnimatedSprite3D::_draw() { Ref<Texture2D> texture = frames->get_frame(animation, frame); if (!texture.is_valid()) { - return; //no texuture no life + return; //no texture no life } Vector2 tsize = texture->get_size(); if (tsize.x == 0 || tsize.y == 0) { diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h index a9ce2d8eee..b48660eb2d 100644 --- a/scene/3d/sprite_3d.h +++ b/scene/3d/sprite_3d.h @@ -31,8 +31,8 @@ #ifndef SPRITE_3D_H #define SPRITE_3D_H -#include "scene/2d/animated_sprite_2d.h" #include "scene/3d/visual_instance_3d.h" +#include "scene/resources/sprite_frames.h" class SpriteBase3D : public GeometryInstance3D { GDCLASS(SpriteBase3D, GeometryInstance3D); @@ -107,8 +107,8 @@ public: void set_flip_v(bool p_flip); bool is_flipped_v() const; - void set_region(bool p_region); - bool is_region() const; + void set_region_enabled(bool p_region_enabled); + bool is_region_enabled() const; void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; @@ -147,7 +147,7 @@ class Sprite3D : public SpriteBase3D { GDCLASS(Sprite3D, SpriteBase3D); Ref<Texture2D> texture; - bool region; + bool region_enabled; Rect2 region_rect; int frame; @@ -167,8 +167,8 @@ public: void set_texture(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_texture() const; - void set_region(bool p_region); - bool is_region() const; + void set_region_enabled(bool p_region_enabled); + bool is_region_enabled() const; void set_region_rect(const Rect2 &p_region_rect); Rect2 get_region_rect() const; diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp index 0d25e2f21f..5b0b3b89d3 100644 --- a/scene/3d/vehicle_body_3d.cpp +++ b/scene/3d/vehicle_body_3d.cpp @@ -407,7 +407,7 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) { PhysicsDirectSpaceState3D *ss = s->get_space_state(); - bool col = ss->intersect_ray(source, target, rr, exclude); + bool col = ss->intersect_ray(source, target, rr, exclude, get_collision_mask()); wheel.m_raycastInfo.m_groundObject = nullptr; @@ -563,7 +563,7 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const b2invmass); // FIXME: rel_vel assignment here is overwritten by the following assignment. - // What seems to be intended in the next next assignment is: rel_vel = normal.dot(rel_vel); + // What seems to be intended in the next assignment is: rel_vel = normal.dot(rel_vel); // Investigate why. real_t rel_vel = jac.getRelativeVelocity( s->get_linear_velocity(), diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp index 17c8596e8f..1b9ce0201f 100644 --- a/scene/3d/voxelizer.cpp +++ b/scene/3d/voxelizer.cpp @@ -151,7 +151,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co Vector2 uv; Vector3 lnormal; get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal); - if (lnormal == Vector3()) { //just in case normal as nor provided + if (lnormal == Vector3()) { //just in case normal is not provided lnormal = normal; } @@ -183,7 +183,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co Vector3 lnormal; Vector2 uv; get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal); - if (lnormal == Vector3()) { //just in case normal as nor provided + if (lnormal == Vector3()) { //just in case normal is not provided lnormal = normal; } @@ -344,7 +344,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material Ref<Image> img_albedo; if (albedo_tex.is_valid()) { - img_albedo = albedo_tex->get_data(); + img_albedo = albedo_tex->get_image(); mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative } else { mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive @@ -358,7 +358,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material Ref<Image> img_emission; if (emission_tex.is_valid()) { - img_emission = emission_tex->get_data(); + img_emission = emission_tex->get_image(); } if (mat->get_emission_operator() == StandardMaterial3D::EMISSION_OP_ADD) { diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index cf1c319acc..214ffd6bd5 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -35,51 +35,69 @@ void WorldEnvironment::_notification(int p_what) { if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) { if (environment.is_valid()) { - if (get_viewport()->find_world_3d()->get_environment().is_valid()) { - WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_environment(environment); add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); + _update_current_environment(); } if (camera_effects.is_valid()) { - if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) { - WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_camera_effects(camera_effects); 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() && get_viewport()->find_world_3d()->get_environment() == environment) { - get_viewport()->find_world_3d()->set_environment(Ref<Environment>()); + 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() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) { - get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); + 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(); } } } -void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) { - if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) { +void WorldEnvironment::_update_current_environment() { + WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()))); + + if (first) { + get_viewport()->find_world_3d()->set_environment(first->environment); + } else { get_viewport()->find_world_3d()->set_environment(Ref<Environment>()); + } + get_tree()->call_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning"); +} + +void WorldEnvironment::_update_current_camera_effects() { + WorldEnvironment *first = Object::cast_to<WorldEnvironment>(get_tree()->get_first_node_in_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()))); + if (first) { + get_viewport()->find_world_3d()->set_camera_effects(first->camera_effects); + } else { + get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); + } + + get_tree()->call_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), "update_configuration_warning"); +} + +void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) { + if (environment == p_environment) { + return; + } + if (is_inside_tree() && environment.is_valid()) { remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - //clean up } environment = p_environment; + if (is_inside_tree() && environment.is_valid()) { - if (get_viewport()->find_world_3d()->get_environment().is_valid()) { - WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_environment(environment); add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } - update_configuration_warning(); + if (is_inside_tree()) { + _update_current_environment(); + } else { + update_configuration_warning(); + } } Ref<Environment> WorldEnvironment::get_environment() const { @@ -87,22 +105,24 @@ Ref<Environment> WorldEnvironment::get_environment() const { } void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) { + if (camera_effects == p_camera_effects) { + return; + } + if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) { - get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>()); remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); - //clean up } camera_effects = p_camera_effects; if (is_inside_tree() && camera_effects.is_valid()) { - if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) { - WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding."); - } - get_viewport()->find_world_3d()->set_camera_effects(camera_effects); add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id())); } - update_configuration_warning(); + if (is_inside_tree()) { + _update_current_camera_effects(); + } else { + update_configuration_warning(); + } } Ref<CameraEffects> WorldEnvironment::get_camera_effects() const { @@ -123,14 +143,18 @@ String WorldEnvironment::get_configuration_warning() const { return warning; } - List<Node *> nodes; - get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), &nodes); + if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() != environment) { + if (!warning.is_empty()) { + warning += "\n\n"; + } + warning += TTR("Only the first Environment has an effect in a scene (or set of instantiated scenes)."); + } - if (nodes.size() > 1) { + if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() != camera_effects) { if (!warning.is_empty()) { warning += "\n\n"; } - warning += TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes)."); + warning += TTR("Only the first CameraEffects has an effect in a scene (or set of instantiated scenes)."); } return warning; diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h index 3dfba20bf0..e3f28d6d6b 100644 --- a/scene/3d/world_environment.h +++ b/scene/3d/world_environment.h @@ -41,6 +41,9 @@ class WorldEnvironment : public Node { Ref<Environment> environment; Ref<CameraEffects> camera_effects; + void _update_current_environment(); + void _update_current_camera_effects(); + protected: void _notification(int p_what); static void _bind_methods(); diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 7fed34c7c6..63be4352d5 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -190,8 +190,8 @@ void XRController3D::_notification(int p_what) { ERR_FAIL_NULL(xr_server); // find the tracker for our controller - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); + if (!tracker.is_valid()) { // this controller is currently turned off is_active = false; button_states = 0; @@ -277,8 +277,8 @@ String XRController3D::get_controller_name() const { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, String()); - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); + if (!tracker.is_valid()) { return String("Not connected"); }; @@ -290,8 +290,8 @@ int XRController3D::get_joystick_id() const { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, 0); - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); + if (!tracker.is_valid()) { // No tracker? no joystick id... (0 is our first joystick) return -1; }; @@ -322,8 +322,8 @@ real_t XRController3D::get_rumble() const { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, 0.0); - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); + if (!tracker.is_valid()) { return 0.0; }; @@ -335,8 +335,8 @@ void XRController3D::set_rumble(real_t p_rumble) { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL(xr_server); - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (tracker != nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); + if (tracker.is_valid()) { tracker->set_rumble(p_rumble); }; }; @@ -354,8 +354,8 @@ XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN); - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id); + if (!tracker.is_valid()) { return XRPositionalTracker::TRACKER_HAND_UNKNOWN; }; @@ -404,8 +404,8 @@ void XRAnchor3D::_notification(int p_what) { ERR_FAIL_NULL(xr_server); // find the tracker for our anchor - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); + if (!tracker.is_valid()) { // this anchor is currently not available is_active = false; } else { @@ -475,8 +475,8 @@ String XRAnchor3D::get_anchor_name() const { XRServer *xr_server = XRServer::get_singleton(); ERR_FAIL_NULL_V(xr_server, String()); - XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); - if (tracker == nullptr) { + Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id); + if (!tracker.is_valid()) { return String("Not connected"); }; |