diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h index 26fc517f7f94..993deace071d 100644 --- a/core/math/dynamic_bvh.h +++ b/core/math/dynamic_bvh.h @@ -310,7 +310,7 @@ class DynamicBVH { template _FORCE_INLINE_ void convex_query(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count, QueryResult &r_result); template - _FORCE_INLINE_ void ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResult &r_result); + _FORCE_INLINE_ void ray_query(const Vector3 &p_from, const Vector3 &p_dir, real_t p_length, QueryResult &r_result); void set_index(uint32_t p_index); uint32_t get_index() const; @@ -416,13 +416,12 @@ void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Ve } while (depth > 0); } template -void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResult &r_result) { +void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_dir, real_t p_length, QueryResult &r_result) { if (!bvh_root) { return; } - Vector3 ray_dir = (p_to - p_from); - ray_dir.normalize(); + Vector3 ray_dir = p_dir; ///what about division by zero? --> just set rayDirection[i] to INF/B3_LARGE_FLOAT Vector3 inv_dir; @@ -431,7 +430,7 @@ void DynamicBVH::ray_query(const Vector3 &p_from, const Vector3 &p_to, QueryResu inv_dir[2] = ray_dir[2] == real_t(0.0) ? real_t(1e20) : real_t(1.0) / ray_dir[2]; unsigned int signs[3] = { inv_dir[0] < 0.0, inv_dir[1] < 0.0, inv_dir[2] < 0.0 }; - real_t lambda_max = ray_dir.dot(p_to - p_from); + real_t lambda_max = p_length; Vector3 bounds[2]; diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 6593d69a20f7..b1ef889bd542 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -2023,8 +2023,9 @@ - - + + + Returns an array of object IDs intersecting with the provided 3D ray. Only 3D nodes that inherit from [VisualInstance3D] are considered, such as [MeshInstance3D] or [DirectionalLight3D]. Use [method @GlobalScope.instance_from_id] to obtain the actual nodes. A scenario RID must be provided, which is available in the [World3D] you want to query. This forces an update for all resources queued to update. [b]Warning:[/b] This function is primarily intended for editor usage. For in-game use cases, prefer physics collision. diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 6f5f304159d7..41bac5d6e744 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -9579,7 +9579,9 @@ Vector Node3DEditor::gizmo_bvh_ray_query(const Vector3 &p_ray_start, c } } result; - gizmo_bvh.ray_query(p_ray_start, p_ray_end, result); + Vector3 segment = p_ray_end - p_ray_start; + real_t length = segment.length(); + gizmo_bvh.ray_query(p_ray_start, segment / length, length, result); return result.nodes; } diff --git a/modules/godot_physics_3d/godot_soft_body_3d.cpp b/modules/godot_physics_3d/godot_soft_body_3d.cpp index e8be227d09d3..4f06e465572d 100644 --- a/modules/godot_physics_3d/godot_soft_body_3d.cpp +++ b/modules/godot_physics_3d/godot_soft_body_3d.cpp @@ -1153,7 +1153,9 @@ void GodotSoftBody3D::query_ray(const Vector3 &p_from, const Vector3 &p_to, Godo query_result.result_callback = p_result_callback; query_result.userdata = p_userdata; - face_tree.ray_query(p_from, p_to, query_result); + Vector3 segment = p_to - p_from; + real_t length = segment.length(); + face_tree.ray_query(p_from, segment / length, length, query_result); } void GodotSoftBody3D::initialize_face_tree() { diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index f369aec569ec..3bf542dd9e24 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -1872,15 +1872,18 @@ void RuntimeNodeSelect::_find_3d_items_at_pos(const Point2 &p_pos, Vector items = RS::get_singleton()->instances_cull_ray(pos, to, root->get_world_3d()->get_scenario()); + Vector items = RS::get_singleton()->instances_cull_ray(pos, ray, dist, root->get_world_3d()->get_scenario()); for (int i = 0; i < items.size(); i++) { Object *obj = ObjectDB::get_instance(items[i]); GeometryInstance3D *geo_instance = nullptr; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 709c0e76c19c..6859145d6bde 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1261,7 +1261,7 @@ Vector RendererSceneCull::instances_cull_aabb(const AABB &p_aabb, RID return cull_aabb.instances; } -Vector RendererSceneCull::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { +Vector RendererSceneCull::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_dist, RID p_scenario) const { Vector instances; Scenario *scenario = scenario_owner.get_or_null(p_scenario); ERR_FAIL_NULL_V(scenario, instances); @@ -1279,8 +1279,8 @@ Vector RendererSceneCull::instances_cull_ray(const Vector3 &p_from, co }; CullRay cull_ray; - scenario->indexers[Scenario::INDEXER_GEOMETRY].ray_query(p_from, p_to, cull_ray); - scenario->indexers[Scenario::INDEXER_VOLUMES].ray_query(p_from, p_to, cull_ray); + scenario->indexers[Scenario::INDEXER_GEOMETRY].ray_query(p_from, p_dir, p_dist, cull_ray); + scenario->indexers[Scenario::INDEXER_VOLUMES].ray_query(p_from, p_dir, p_dist, cull_ray); return cull_ray.instances; } diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index d56daea240df..36790229e2a7 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -1082,7 +1082,7 @@ class RendererSceneCull : public RenderingMethod { // don't use these in a game! virtual Vector instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const; - virtual Vector instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; + virtual Vector instances_cull_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_dist, RID p_scenario = RID()) const; virtual Vector instances_cull_convex(const Vector &p_convex, RID p_scenario = RID()) const; virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled); diff --git a/servers/rendering/rendering_method.h b/servers/rendering/rendering_method.h index 34f11924ceb7..8a82ca91ea52 100644 --- a/servers/rendering/rendering_method.h +++ b/servers/rendering/rendering_method.h @@ -102,7 +102,7 @@ class RenderingMethod { // don't use these in a game! virtual Vector instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; - virtual Vector instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0; + virtual Vector instances_cull_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_dist, RID p_scenario = RID()) const = 0; virtual Vector instances_cull_convex(const Vector &p_convex, RID p_scenario = RID()) const = 0; virtual void instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) = 0; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 5cc96a01ccfb..b078b83b14aa 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -894,7 +894,7 @@ class RenderingServerDefault : public RenderingServer { // don't use these in a game! FUNC2RC(Vector, instances_cull_aabb, const AABB &, RID) - FUNC3RC(Vector, instances_cull_ray, const Vector3 &, const Vector3 &, RID) + FUNC4RC(Vector, instances_cull_ray, const Vector3 &, const Vector3 &, real_t, RID) FUNC2RC(Vector, instances_cull_convex, const Vector &, RID) FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool) diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 9d3acdd42bc2..c7712e1c31d6 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -87,8 +87,8 @@ PackedInt64Array RenderingServer::_instances_cull_aabb_bind(const AABB &p_aabb, return to_int_array(ids); } -PackedInt64Array RenderingServer::_instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const { - Vector ids = instances_cull_ray(p_from, p_to, p_scenario); +PackedInt64Array RenderingServer::_instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_dir, real_t p_dist, RID p_scenario) const { + Vector ids = instances_cull_ray(p_from, p_dir, p_dist, p_scenario); return to_int_array(ids); } @@ -3174,7 +3174,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("instance_geometry_get_shader_parameter_list", "instance"), &RenderingServer::_instance_geometry_get_shader_parameter_list); ClassDB::bind_method(D_METHOD("instances_cull_aabb", "aabb", "scenario"), &RenderingServer::_instances_cull_aabb_bind, DEFVAL(RID())); - ClassDB::bind_method(D_METHOD("instances_cull_ray", "from", "to", "scenario"), &RenderingServer::_instances_cull_ray_bind, DEFVAL(RID())); + ClassDB::bind_method(D_METHOD("instances_cull_ray", "from", "direction", "distance", "scenario"), &RenderingServer::_instances_cull_ray_bind, DEFVAL(RID())); ClassDB::bind_method(D_METHOD("instances_cull_convex", "convex", "scenario"), &RenderingServer::_instances_cull_convex_bind, DEFVAL(RID())); BIND_ENUM_CONSTANT(INSTANCE_NONE); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 23dbc821135b..dec41172289f 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -1405,11 +1405,11 @@ class RenderingServer : public Object { // Don't use these in a game! virtual Vector instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0; - virtual Vector instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0; + virtual Vector instances_cull_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t p_dist, RID p_scenario = RID()) const = 0; virtual Vector instances_cull_convex(const Vector &p_convex, RID p_scenario = RID()) const = 0; PackedInt64Array _instances_cull_aabb_bind(const AABB &p_aabb, RID p_scenario = RID()) const; - PackedInt64Array _instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const; + PackedInt64Array _instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_dir, real_t p_dist, RID p_scenario = RID()) const; PackedInt64Array _instances_cull_convex_bind(const TypedArray &p_convex, RID p_scenario = RID()) const; enum InstanceFlags {