32 lines
1.2 KiB
Diff
32 lines
1.2 KiB
Diff
# UNDF: UNDF-2026-000000086
|
|
--- a/modules/godot_physics_3d/godot_soft_body_3d.cpp
|
|
+++ b/modules/godot_physics_3d/godot_soft_body_3d.cpp
|
|
@@ -652,16 +652,18 @@ void GodotSoftBody3D::generate_bending_constraints(int p_n_iterations) {
|
|
|
|
- LocalVector<LocalVector<int>> node_links;
|
|
+ // FIX godot-0004: was LocalVector<int> with .has() — O(n) per link, O(n²) total, CWE-407
|
|
+ // Each node_links[i].has(j) scans the growing adjacency list linearly.
|
|
+ // For a mesh with L links and avg degree D, total ops = L * D = O(n²) for dense meshes.
|
|
+ // Fix: shadow HashSet per node for O(1) membership; LocalVector preserved for iteration.
|
|
+ LocalVector<LocalVector<int>> node_links;
|
|
+ LocalVector<HashSet<int>> node_link_set;
|
|
|
|
// Build node links.
|
|
node_links.resize(nodes.size());
|
|
+ node_link_set.resize(nodes.size());
|
|
|
|
for (Link &link : links) {
|
|
const int ia = (int)(link.n[0] - &nodes[0]);
|
|
const int ib = (int)(link.n[1] - &nodes[0]);
|
|
- if (!node_links[ia].has(ib)) {
|
|
+ if (!node_link_set[ia].has(ib)) {
|
|
node_links[ia].push_back(ib);
|
|
+ node_link_set[ia].insert(ib);
|
|
}
|
|
|
|
- if (!node_links[ib].has(ia)) {
|
|
+ if (!node_link_set[ib].has(ia)) {
|
|
node_links[ib].push_back(ia);
|
|
+ node_link_set[ib].insert(ia);
|
|
}
|
|
}
|