java-topology/defects/bullet/patch/bullet-0001-ghostobject-hashset-overlapping.patch

64 lines
2.9 KiB
Diff

# UNDF: UNDF-2026-000000017
--- a/src/BulletCollision/CollisionDispatch/btGhostObject.h
+++ b/src/BulletCollision/CollisionDispatch/btGhostObject.h
@@ -25,6 +25,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "LinearMath/btHashMap.h"
class btCollisionShape;
class btConvexShape;
@@ -42,6 +43,8 @@ class btGhostObject : public btCollisionObject
protected:
btAlignedObjectArray<btCollisionObject*> m_overlappingObjects;
+ /// O(1) membership index for m_overlappingObjects — eliminates findLinearSearch
+ btHashMap<btHashPtr, int> m_overlappingIndex;
--- a/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
+++ b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp
@@ -32,27 +32,35 @@ void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,
btBroadphaseProxy* thisProxy)
{
btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
btAssert(otherObject);
- ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
- int index = m_overlappingObjects.findLinearSearch(otherObject);
- if (index == m_overlappingObjects.size())
- {
- //not found
+ // O(1) hash membership check — replaces O(N) findLinearSearch
+ if (!m_overlappingIndex.find(btHashPtr(otherObject)))
+ {
m_overlappingObjects.push_back(otherObject);
+ m_overlappingIndex.insert(btHashPtr(otherObject),
+ m_overlappingObjects.size() - 1);
}
}
void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,
btDispatcher* dispatcher,
btBroadphaseProxy* thisProxy)
{
btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
btAssert(otherObject);
- int index = m_overlappingObjects.findLinearSearch(otherObject);
- if (index < m_overlappingObjects.size())
- {
- m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size() - 1];
- m_overlappingObjects.pop_back();
+ int* idxPtr = m_overlappingIndex.find(btHashPtr(otherObject));
+ if (idxPtr)
+ {
+ int index = *idxPtr;
+ int last = m_overlappingObjects.size() - 1;
+ if (index != last)
+ {
+ // swap with last and fix up the moved element's index
+ m_overlappingObjects[index] = m_overlappingObjects[last];
+ m_overlappingIndex.insert(btHashPtr(m_overlappingObjects[index]), index);
+ }
+ m_overlappingObjects.pop_back();
+ m_overlappingIndex.remove(btHashPtr(otherObject));
}
}