Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BVH precision] Make scene culling use precision-proof version of BVH::ray_query() #100480

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix BVH::ray_query() numerical precision
  • Loading branch information
Flarkk committed Dec 16, 2024
commit 4456c090298fe3487dc3a0f0b0abbd04d00ffa1a
9 changes: 4 additions & 5 deletions core/math/dynamic_bvh.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ class DynamicBVH {
template <typename QueryResult>
_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 <typename QueryResult>
_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;
Expand Down Expand Up @@ -416,13 +416,12 @@ void DynamicBVH::convex_query(const Plane *p_planes, int p_plane_count, const Ve
} while (depth > 0);
}
template <typename QueryResult>
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;
Expand All @@ -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];

Expand Down
4 changes: 3 additions & 1 deletion editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9579,7 +9579,9 @@ Vector<Node3D *> 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;
}
Expand Down
4 changes: 3 additions & 1 deletion modules/godot_physics_3d/godot_soft_body_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
6 changes: 4 additions & 2 deletions servers/rendering/renderer_scene_cull.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1279,8 +1279,10 @@ Vector<ObjectID> 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);
Vector3 segment = p_to - p_from;
real_t length = segment.length();
scenario->indexers[Scenario::INDEXER_GEOMETRY].ray_query(p_from, segment / length, length, cull_ray);
scenario->indexers[Scenario::INDEXER_VOLUMES].ray_query(p_from, segment / length, length, cull_ray);
return cull_ray.instances;
}

Expand Down
Loading