# 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 m_overlappingObjects; + /// O(1) membership index for m_overlappingObjects — eliminates findLinearSearch + btHashMap 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)); } }