First stage in refactoring Bullet: moved Bullet Collision and Dynamics and LinearMath into src folder, and all files in Collision Detection and Dynamics have bt prefix.
Made all buildsystems to work again (jam, msvc, cmake)
This commit is contained in:
499
src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
Normal file
499
src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
Normal file
@@ -0,0 +1,499 @@
|
||||
|
||||
//Bullet Continuous Collision Detection and Physics Library
|
||||
//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
|
||||
//
|
||||
// AxisSweep3
|
||||
//
|
||||
// Copyright (c) 2006 Simon Hobbs
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
#include "btAxisSweep3.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
BroadphaseProxy* AxisSweep3::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask)
|
||||
{
|
||||
unsigned short handleId = AddHandle(min,max, userPtr,collisionFilterGroup,collisionFilterMask);
|
||||
|
||||
Handle* handle = GetHandle(handleId);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void AxisSweep3::DestroyProxy(BroadphaseProxy* proxy)
|
||||
{
|
||||
Handle* handle = static_cast<Handle*>(proxy);
|
||||
RemoveHandle(handle->m_handleId);
|
||||
}
|
||||
|
||||
void AxisSweep3::SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)
|
||||
{
|
||||
Handle* handle = static_cast<Handle*>(proxy);
|
||||
UpdateHandle(handle->m_handleId,aabbMin,aabbMax);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AxisSweep3::AxisSweep3(const SimdPoint3& worldAabbMin,const SimdPoint3& worldAabbMax, int maxHandles)
|
||||
:OverlappingPairCache()
|
||||
{
|
||||
//assert(bounds.HasVolume());
|
||||
|
||||
// 1 handle is reserved as sentinel
|
||||
assert(maxHandles > 1 && maxHandles < 32767);
|
||||
|
||||
// init bounds
|
||||
m_worldAabbMin = worldAabbMin;
|
||||
m_worldAabbMax = worldAabbMax;
|
||||
|
||||
SimdVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
|
||||
|
||||
m_quantize = SimdVector3(65535.0f,65535.0f,65535.0f) / aabbSize;
|
||||
|
||||
// allocate handles buffer and put all handles on free list
|
||||
m_pHandles = new Handle[maxHandles];
|
||||
m_maxHandles = maxHandles;
|
||||
m_numHandles = 0;
|
||||
|
||||
// handle 0 is reserved as the null index, and is also used as the sentinel
|
||||
m_firstFreeHandle = 1;
|
||||
{
|
||||
for (int i = m_firstFreeHandle; i < maxHandles; i++)
|
||||
m_pHandles[i].SetNextFree(i + 1);
|
||||
m_pHandles[maxHandles - 1].SetNextFree(0);
|
||||
}
|
||||
|
||||
{
|
||||
// allocate edge buffers
|
||||
for (int i = 0; i < 3; i++)
|
||||
m_pEdges[i] = new Edge[maxHandles * 2];
|
||||
}
|
||||
//removed overlap management
|
||||
|
||||
// make boundary sentinels
|
||||
|
||||
m_pHandles[0].m_clientObject = 0;
|
||||
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
m_pHandles[0].m_minEdges[axis] = 0;
|
||||
m_pHandles[0].m_maxEdges[axis] = 1;
|
||||
|
||||
m_pEdges[axis][0].m_pos = 0;
|
||||
m_pEdges[axis][0].m_handle = 0;
|
||||
m_pEdges[axis][1].m_pos = 0xffff;
|
||||
m_pEdges[axis][1].m_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
AxisSweep3::~AxisSweep3()
|
||||
{
|
||||
|
||||
for (int i = 2; i >= 0; i--)
|
||||
delete[] m_pEdges[i];
|
||||
delete[] m_pHandles;
|
||||
}
|
||||
|
||||
void AxisSweep3::Quantize(unsigned short* out, const SimdPoint3& point, int isMax) const
|
||||
{
|
||||
SimdPoint3 clampedPoint(point);
|
||||
/*
|
||||
if (isMax)
|
||||
clampedPoint += SimdVector3(10,10,10);
|
||||
else
|
||||
{
|
||||
clampedPoint -= SimdVector3(10,10,10);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
clampedPoint.setMax(m_worldAabbMin);
|
||||
clampedPoint.setMin(m_worldAabbMax);
|
||||
|
||||
SimdVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
|
||||
out[0] = (unsigned short)(((int)v.getX() & 0xfffc) | isMax);
|
||||
out[1] = (unsigned short)(((int)v.getY() & 0xfffc) | isMax);
|
||||
out[2] = (unsigned short)(((int)v.getZ() & 0xfffc) | isMax);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned short AxisSweep3::AllocHandle()
|
||||
{
|
||||
assert(m_firstFreeHandle);
|
||||
|
||||
unsigned short handle = m_firstFreeHandle;
|
||||
m_firstFreeHandle = GetHandle(handle)->GetNextFree();
|
||||
m_numHandles++;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void AxisSweep3::FreeHandle(unsigned short handle)
|
||||
{
|
||||
assert(handle > 0 && handle < m_maxHandles);
|
||||
|
||||
GetHandle(handle)->SetNextFree(m_firstFreeHandle);
|
||||
m_firstFreeHandle = handle;
|
||||
|
||||
m_numHandles--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned short AxisSweep3::AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask)
|
||||
{
|
||||
// quantize the bounds
|
||||
unsigned short min[3], max[3];
|
||||
Quantize(min, aabbMin, 0);
|
||||
Quantize(max, aabbMax, 1);
|
||||
|
||||
// allocate a handle
|
||||
unsigned short handle = AllocHandle();
|
||||
assert(handle!= 0xcdcd);
|
||||
|
||||
Handle* pHandle = GetHandle(handle);
|
||||
|
||||
pHandle->m_handleId = handle;
|
||||
//pHandle->m_pOverlaps = 0;
|
||||
pHandle->m_clientObject = pOwner;
|
||||
pHandle->m_collisionFilterGroup = collisionFilterGroup;
|
||||
pHandle->m_collisionFilterMask = collisionFilterMask;
|
||||
|
||||
// compute current limit of edge arrays
|
||||
int limit = m_numHandles * 2;
|
||||
|
||||
// insert new edges just inside the max boundary edge
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
m_pHandles[0].m_maxEdges[axis] += 2;
|
||||
|
||||
m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
|
||||
|
||||
m_pEdges[axis][limit - 1].m_pos = min[axis];
|
||||
m_pEdges[axis][limit - 1].m_handle = handle;
|
||||
|
||||
m_pEdges[axis][limit].m_pos = max[axis];
|
||||
m_pEdges[axis][limit].m_handle = handle;
|
||||
|
||||
pHandle->m_minEdges[axis] = limit - 1;
|
||||
pHandle->m_maxEdges[axis] = limit;
|
||||
}
|
||||
|
||||
// now sort the new edges to their correct position
|
||||
SortMinDown(0, pHandle->m_minEdges[0], false);
|
||||
SortMaxDown(0, pHandle->m_maxEdges[0], false);
|
||||
SortMinDown(1, pHandle->m_minEdges[1], false);
|
||||
SortMaxDown(1, pHandle->m_maxEdges[1], false);
|
||||
SortMinDown(2, pHandle->m_minEdges[2], true);
|
||||
SortMaxDown(2, pHandle->m_maxEdges[2], true);
|
||||
|
||||
//PrintAxis(1);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
void AxisSweep3::RemoveHandle(unsigned short handle)
|
||||
{
|
||||
Handle* pHandle = GetHandle(handle);
|
||||
|
||||
//explicitly remove the pairs containing the proxy
|
||||
//we could do it also in the SortMinUp (passing true)
|
||||
//todo: compare performance
|
||||
RemoveOverlappingPairsContainingProxy(pHandle);
|
||||
|
||||
|
||||
// compute current limit of edge arrays
|
||||
int limit = m_numHandles * 2;
|
||||
int axis;
|
||||
|
||||
for (axis = 0;axis<3;axis++)
|
||||
{
|
||||
Edge* pEdges = m_pEdges[axis];
|
||||
int maxEdge= pHandle->m_maxEdges[axis];
|
||||
pEdges[maxEdge].m_pos = 0xffff;
|
||||
int minEdge = pHandle->m_minEdges[axis];
|
||||
pEdges[minEdge].m_pos = 0xffff;
|
||||
}
|
||||
|
||||
// remove the edges by sorting them up to the end of the list
|
||||
for ( axis = 0; axis < 3; axis++)
|
||||
{
|
||||
Edge* pEdges = m_pEdges[axis];
|
||||
int max = pHandle->m_maxEdges[axis];
|
||||
pEdges[max].m_pos = 0xffff;
|
||||
|
||||
SortMaxUp(axis,max,false);
|
||||
|
||||
int i = pHandle->m_minEdges[axis];
|
||||
pEdges[i].m_pos = 0xffff;
|
||||
|
||||
SortMinUp(axis,i,false);
|
||||
|
||||
pEdges[limit-1].m_handle = 0;
|
||||
pEdges[limit-1].m_pos = 0xffff;
|
||||
|
||||
}
|
||||
|
||||
// free the handle
|
||||
FreeHandle(handle);
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool AxisSweep3::TestOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB)
|
||||
{
|
||||
//optimization 1: check the array index (memory address), instead of the m_pos
|
||||
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
if (axis != ignoreAxis)
|
||||
{
|
||||
if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] ||
|
||||
pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//optimization 2: only 2 axis need to be tested
|
||||
|
||||
/*for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
if (m_pEdges[axis][pHandleA->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleB->m_minEdges[axis]].m_pos ||
|
||||
m_pEdges[axis][pHandleB->m_maxEdges[axis]].m_pos < m_pEdges[axis][pHandleA->m_minEdges[axis]].m_pos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AxisSweep3::UpdateHandle(unsigned short handle, const SimdPoint3& aabbMin,const SimdPoint3& aabbMax)
|
||||
{
|
||||
// assert(bounds.IsFinite());
|
||||
//assert(bounds.HasVolume());
|
||||
|
||||
Handle* pHandle = GetHandle(handle);
|
||||
|
||||
// quantize the new bounds
|
||||
unsigned short min[3], max[3];
|
||||
Quantize(min, aabbMin, 0);
|
||||
Quantize(max, aabbMax, 1);
|
||||
|
||||
// update changed edges
|
||||
for (int axis = 0; axis < 3; axis++)
|
||||
{
|
||||
unsigned short emin = pHandle->m_minEdges[axis];
|
||||
unsigned short emax = pHandle->m_maxEdges[axis];
|
||||
|
||||
int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
|
||||
int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
|
||||
|
||||
m_pEdges[axis][emin].m_pos = min[axis];
|
||||
m_pEdges[axis][emax].m_pos = max[axis];
|
||||
|
||||
// expand (only adds overlaps)
|
||||
if (dmin < 0)
|
||||
SortMinDown(axis, emin);
|
||||
|
||||
if (dmax > 0)
|
||||
SortMaxUp(axis, emax);
|
||||
|
||||
// shrink (only removes overlaps)
|
||||
if (dmin > 0)
|
||||
SortMinUp(axis, emin);
|
||||
|
||||
if (dmax < 0)
|
||||
SortMaxDown(axis, emax);
|
||||
}
|
||||
|
||||
//PrintAxis(1);
|
||||
}
|
||||
|
||||
// sorting a min edge downwards can only ever *add* overlaps
|
||||
void AxisSweep3::SortMinDown(int axis, unsigned short edge, bool updateOverlaps)
|
||||
{
|
||||
Edge* pEdge = m_pEdges[axis] + edge;
|
||||
Edge* pPrev = pEdge - 1;
|
||||
Handle* pHandleEdge = GetHandle(pEdge->m_handle);
|
||||
|
||||
while (pEdge->m_pos < pPrev->m_pos)
|
||||
{
|
||||
Handle* pHandlePrev = GetHandle(pPrev->m_handle);
|
||||
|
||||
if (pPrev->IsMax())
|
||||
{
|
||||
// if previous edge is a maximum check the bounds and add an overlap if necessary
|
||||
if (updateOverlaps && TestOverlap(axis,pHandleEdge, pHandlePrev))
|
||||
{
|
||||
AddOverlappingPair(pHandleEdge,pHandlePrev);
|
||||
|
||||
//AddOverlap(pEdge->m_handle, pPrev->m_handle);
|
||||
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandlePrev->m_maxEdges[axis]++;
|
||||
}
|
||||
else
|
||||
pHandlePrev->m_minEdges[axis]++;
|
||||
|
||||
pHandleEdge->m_minEdges[axis]--;
|
||||
|
||||
// swap the edges
|
||||
Edge swap = *pEdge;
|
||||
*pEdge = *pPrev;
|
||||
*pPrev = swap;
|
||||
|
||||
// decrement
|
||||
pEdge--;
|
||||
pPrev--;
|
||||
}
|
||||
}
|
||||
|
||||
// sorting a min edge upwards can only ever *remove* overlaps
|
||||
void AxisSweep3::SortMinUp(int axis, unsigned short edge, bool updateOverlaps)
|
||||
{
|
||||
Edge* pEdge = m_pEdges[axis] + edge;
|
||||
Edge* pNext = pEdge + 1;
|
||||
Handle* pHandleEdge = GetHandle(pEdge->m_handle);
|
||||
|
||||
while (pEdge->m_pos > pNext->m_pos)
|
||||
{
|
||||
Handle* pHandleNext = GetHandle(pNext->m_handle);
|
||||
|
||||
if (pNext->IsMax())
|
||||
{
|
||||
// if next edge is maximum remove any overlap between the two handles
|
||||
if (updateOverlaps)
|
||||
{
|
||||
Handle* handle0 = GetHandle(pEdge->m_handle);
|
||||
Handle* handle1 = GetHandle(pNext->m_handle);
|
||||
BroadphasePair tmpPair(*handle0,*handle1);
|
||||
RemoveOverlappingPair(tmpPair);
|
||||
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandleNext->m_maxEdges[axis]--;
|
||||
}
|
||||
else
|
||||
pHandleNext->m_minEdges[axis]--;
|
||||
|
||||
pHandleEdge->m_minEdges[axis]++;
|
||||
|
||||
// swap the edges
|
||||
Edge swap = *pEdge;
|
||||
*pEdge = *pNext;
|
||||
*pNext = swap;
|
||||
|
||||
// increment
|
||||
pEdge++;
|
||||
pNext++;
|
||||
}
|
||||
}
|
||||
|
||||
// sorting a max edge downwards can only ever *remove* overlaps
|
||||
void AxisSweep3::SortMaxDown(int axis, unsigned short edge, bool updateOverlaps)
|
||||
{
|
||||
Edge* pEdge = m_pEdges[axis] + edge;
|
||||
Edge* pPrev = pEdge - 1;
|
||||
Handle* pHandleEdge = GetHandle(pEdge->m_handle);
|
||||
|
||||
while (pEdge->m_pos < pPrev->m_pos)
|
||||
{
|
||||
Handle* pHandlePrev = GetHandle(pPrev->m_handle);
|
||||
|
||||
if (!pPrev->IsMax())
|
||||
{
|
||||
// if previous edge was a minimum remove any overlap between the two handles
|
||||
if (updateOverlaps)
|
||||
{
|
||||
Handle* handle0 = GetHandle(pEdge->m_handle);
|
||||
Handle* handle1 = GetHandle(pPrev->m_handle);
|
||||
BroadphasePair* pair = FindPair(handle0,handle1);
|
||||
//assert(pair);
|
||||
|
||||
if (pair)
|
||||
{
|
||||
RemoveOverlappingPair(*pair);
|
||||
}
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandlePrev->m_minEdges[axis]++;;
|
||||
}
|
||||
else
|
||||
pHandlePrev->m_maxEdges[axis]++;
|
||||
|
||||
pHandleEdge->m_maxEdges[axis]--;
|
||||
|
||||
// swap the edges
|
||||
Edge swap = *pEdge;
|
||||
*pEdge = *pPrev;
|
||||
*pPrev = swap;
|
||||
|
||||
// decrement
|
||||
pEdge--;
|
||||
pPrev--;
|
||||
}
|
||||
}
|
||||
|
||||
// sorting a max edge upwards can only ever *add* overlaps
|
||||
void AxisSweep3::SortMaxUp(int axis, unsigned short edge, bool updateOverlaps)
|
||||
{
|
||||
Edge* pEdge = m_pEdges[axis] + edge;
|
||||
Edge* pNext = pEdge + 1;
|
||||
Handle* pHandleEdge = GetHandle(pEdge->m_handle);
|
||||
|
||||
while (pEdge->m_pos > pNext->m_pos)
|
||||
{
|
||||
Handle* pHandleNext = GetHandle(pNext->m_handle);
|
||||
|
||||
if (!pNext->IsMax())
|
||||
{
|
||||
// if next edge is a minimum check the bounds and add an overlap if necessary
|
||||
if (updateOverlaps && TestOverlap(axis, pHandleEdge, pHandleNext))
|
||||
{
|
||||
Handle* handle0 = GetHandle(pEdge->m_handle);
|
||||
Handle* handle1 = GetHandle(pNext->m_handle);
|
||||
AddOverlappingPair(handle0,handle1);
|
||||
}
|
||||
|
||||
// update edge reference in other handle
|
||||
pHandleNext->m_minEdges[axis]--;
|
||||
}
|
||||
else
|
||||
pHandleNext->m_maxEdges[axis]--;
|
||||
|
||||
pHandleEdge->m_maxEdges[axis]++;
|
||||
|
||||
// swap the edges
|
||||
Edge swap = *pEdge;
|
||||
*pEdge = *pNext;
|
||||
*pNext = swap;
|
||||
|
||||
// increment
|
||||
pEdge++;
|
||||
pNext++;
|
||||
}
|
||||
}
|
||||
115
src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
Normal file
115
src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
Normal file
@@ -0,0 +1,115 @@
|
||||
//Bullet Continuous Collision Detection and Physics Library
|
||||
//Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
//
|
||||
// AxisSweep3.h
|
||||
//
|
||||
// Copyright (c) 2006 Simon Hobbs
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
#ifndef AXIS_SWEEP_3_H
|
||||
#define AXIS_SWEEP_3_H
|
||||
|
||||
#include "LinearMath/SimdPoint3.h"
|
||||
#include "LinearMath/SimdVector3.h"
|
||||
#include "btOverlappingPairCache.h"
|
||||
#include "btBroadphaseProxy.h"
|
||||
|
||||
/// AxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
|
||||
/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats.
|
||||
/// The TestOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos
|
||||
class AxisSweep3 : public OverlappingPairCache
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
|
||||
class Edge
|
||||
{
|
||||
public:
|
||||
unsigned short m_pos; // low bit is min/max
|
||||
unsigned short m_handle;
|
||||
|
||||
unsigned short IsMax() const {return m_pos & 1;}
|
||||
};
|
||||
|
||||
public:
|
||||
class Handle : public BroadphaseProxy
|
||||
{
|
||||
public:
|
||||
|
||||
// indexes into the edge arrays
|
||||
unsigned short m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12
|
||||
unsigned short m_handleId;
|
||||
unsigned short m_pad;
|
||||
|
||||
//void* m_pOwner; this is now in BroadphaseProxy.m_clientObject
|
||||
|
||||
inline void SetNextFree(unsigned short next) {m_minEdges[0] = next;}
|
||||
inline unsigned short GetNextFree() const {return m_minEdges[0];}
|
||||
}; // 24 bytes + 24 for Edge structures = 44 bytes total per entry
|
||||
|
||||
|
||||
private:
|
||||
SimdPoint3 m_worldAabbMin; // overall system bounds
|
||||
SimdPoint3 m_worldAabbMax; // overall system bounds
|
||||
|
||||
SimdVector3 m_quantize; // scaling factor for quantization
|
||||
|
||||
int m_numHandles; // number of active handles
|
||||
int m_maxHandles; // max number of handles
|
||||
Handle* m_pHandles; // handles pool
|
||||
unsigned short m_firstFreeHandle; // free handles list
|
||||
|
||||
Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
|
||||
|
||||
|
||||
// allocation/deallocation
|
||||
unsigned short AllocHandle();
|
||||
void FreeHandle(unsigned short handle);
|
||||
|
||||
|
||||
bool TestOverlap(int ignoreAxis,const Handle* pHandleA, const Handle* pHandleB);
|
||||
|
||||
//Overlap* AddOverlap(unsigned short handleA, unsigned short handleB);
|
||||
//void RemoveOverlap(unsigned short handleA, unsigned short handleB);
|
||||
|
||||
void Quantize(unsigned short* out, const SimdPoint3& point, int isMax) const;
|
||||
|
||||
void SortMinDown(int axis, unsigned short edge, bool updateOverlaps = true);
|
||||
void SortMinUp(int axis, unsigned short edge, bool updateOverlaps = true);
|
||||
void SortMaxDown(int axis, unsigned short edge, bool updateOverlaps = true);
|
||||
void SortMaxUp(int axis, unsigned short edge, bool updateOverlaps = true);
|
||||
|
||||
public:
|
||||
AxisSweep3(const SimdPoint3& worldAabbMin,const SimdPoint3& worldAabbMax, int maxHandles = 16384);
|
||||
virtual ~AxisSweep3();
|
||||
|
||||
virtual void RefreshOverlappingPairs()
|
||||
{
|
||||
//this is replace by sweep and prune
|
||||
}
|
||||
|
||||
unsigned short AddHandle(const SimdPoint3& aabbMin,const SimdPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask);
|
||||
void RemoveHandle(unsigned short handle);
|
||||
void UpdateHandle(unsigned short handle, const SimdPoint3& aabbMin,const SimdPoint3& aabbMax);
|
||||
inline Handle* GetHandle(unsigned short index) const {return m_pHandles + index;}
|
||||
|
||||
|
||||
//Broadphase Interface
|
||||
virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
|
||||
virtual void DestroyProxy(BroadphaseProxy* proxy);
|
||||
virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax);
|
||||
|
||||
};
|
||||
|
||||
#endif //AXIS_SWEEP_3_H
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BROADPHASE_INTERFACE_H
|
||||
#define BROADPHASE_INTERFACE_H
|
||||
|
||||
|
||||
|
||||
struct DispatcherInfo;
|
||||
class Dispatcher;
|
||||
struct BroadphaseProxy;
|
||||
#include "LinearMath/SimdVector3.h"
|
||||
|
||||
///BroadphaseInterface for aabb-overlapping object pairs
|
||||
class BroadphaseInterface
|
||||
{
|
||||
public:
|
||||
virtual ~BroadphaseInterface() {}
|
||||
|
||||
virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0;
|
||||
virtual void DestroyProxy(BroadphaseProxy* proxy)=0;
|
||||
virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)=0;
|
||||
virtual void CleanProxyFromPairs(BroadphaseProxy* proxy)=0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //BROADPHASE_INTERFACE_H
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btBroadphaseProxy.h"
|
||||
|
||||
167
src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
Normal file
167
src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BROADPHASE_PROXY_H
|
||||
#define BROADPHASE_PROXY_H
|
||||
|
||||
|
||||
|
||||
/// Dispatcher uses these types
|
||||
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
|
||||
/// to facilitate type checking
|
||||
enum BroadphaseNativeTypes
|
||||
{
|
||||
// polyhedral convex shapes
|
||||
BOX_SHAPE_PROXYTYPE,
|
||||
TRIANGLE_SHAPE_PROXYTYPE,
|
||||
TETRAHEDRAL_SHAPE_PROXYTYPE,
|
||||
CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
|
||||
CONVEX_HULL_SHAPE_PROXYTYPE,
|
||||
//implicit convex shapes
|
||||
IMPLICIT_CONVEX_SHAPES_START_HERE,
|
||||
SPHERE_SHAPE_PROXYTYPE,
|
||||
MULTI_SPHERE_SHAPE_PROXYTYPE,
|
||||
CONE_SHAPE_PROXYTYPE,
|
||||
CONVEX_SHAPE_PROXYTYPE,
|
||||
CYLINDER_SHAPE_PROXYTYPE,
|
||||
MINKOWSKI_SUM_SHAPE_PROXYTYPE,
|
||||
MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
|
||||
//concave shapes
|
||||
CONCAVE_SHAPES_START_HERE,
|
||||
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
|
||||
TRIANGLE_MESH_SHAPE_PROXYTYPE,
|
||||
///used for demo integration FAST/Swift collision library and Bullet
|
||||
FAST_CONCAVE_MESH_PROXYTYPE,
|
||||
|
||||
EMPTY_SHAPE_PROXYTYPE,
|
||||
STATIC_PLANE_PROXYTYPE,
|
||||
CONCAVE_SHAPES_END_HERE,
|
||||
|
||||
COMPOUND_SHAPE_PROXYTYPE,
|
||||
|
||||
MAX_BROADPHASE_COLLISION_TYPES
|
||||
};
|
||||
|
||||
|
||||
///BroadphaseProxy
|
||||
struct BroadphaseProxy
|
||||
{
|
||||
|
||||
//Usually the client CollisionObject or Rigidbody class
|
||||
void* m_clientObject;
|
||||
short int m_collisionFilterGroup;
|
||||
short int m_collisionFilterMask;
|
||||
|
||||
//used for memory pools
|
||||
BroadphaseProxy() :m_clientObject(0){}
|
||||
|
||||
BroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask)
|
||||
:m_clientObject(userPtr),
|
||||
m_collisionFilterGroup(collisionFilterGroup),
|
||||
m_collisionFilterMask(collisionFilterMask)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool IsPolyhedral(int proxyType)
|
||||
{
|
||||
return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE);
|
||||
}
|
||||
|
||||
static inline bool IsConvex(int proxyType)
|
||||
{
|
||||
return (proxyType < CONCAVE_SHAPES_START_HERE);
|
||||
}
|
||||
|
||||
static inline bool IsConcave(int proxyType)
|
||||
{
|
||||
return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
|
||||
(proxyType < CONCAVE_SHAPES_END_HERE));
|
||||
}
|
||||
static inline bool IsCompound(int proxyType)
|
||||
{
|
||||
return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class CollisionAlgorithm;
|
||||
|
||||
struct BroadphaseProxy;
|
||||
|
||||
//Increase SIMPLE_MAX_ALGORITHMS to allow multiple Dispatchers caching their own algorithms
|
||||
#define SIMPLE_MAX_ALGORITHMS 1
|
||||
|
||||
/// contains a pair of aabb-overlapping objects
|
||||
struct BroadphasePair
|
||||
{
|
||||
BroadphasePair ()
|
||||
:
|
||||
m_pProxy0(0),
|
||||
m_pProxy1(0)
|
||||
{
|
||||
for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
|
||||
{
|
||||
m_algorithms[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BroadphasePair(const BroadphasePair& other)
|
||||
: m_pProxy0(other.m_pProxy0),
|
||||
m_pProxy1(other.m_pProxy1)
|
||||
{
|
||||
for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
|
||||
{
|
||||
m_algorithms[i] = other.m_algorithms[i];
|
||||
}
|
||||
}
|
||||
BroadphasePair(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1)
|
||||
{
|
||||
|
||||
//keep them sorted, so the std::set operations work
|
||||
if (&proxy0 < &proxy1)
|
||||
{
|
||||
m_pProxy0 = &proxy0;
|
||||
m_pProxy1 = &proxy1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pProxy0 = &proxy1;
|
||||
m_pProxy1 = &proxy0;
|
||||
}
|
||||
|
||||
for (int i=0;i<SIMPLE_MAX_ALGORITHMS;i++)
|
||||
{
|
||||
m_algorithms[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BroadphaseProxy* m_pProxy0;
|
||||
BroadphaseProxy* m_pProxy1;
|
||||
|
||||
mutable CollisionAlgorithm* m_algorithms[SIMPLE_MAX_ALGORITHMS];
|
||||
};
|
||||
|
||||
|
||||
//comparison for set operation, see Solid DT_Encounter
|
||||
inline bool operator<(const BroadphasePair& a, const BroadphasePair& b)
|
||||
{
|
||||
return a.m_pProxy0 < b.m_pProxy0 ||
|
||||
(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1);
|
||||
}
|
||||
|
||||
|
||||
#endif //BROADPHASE_PROXY_H
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btCollisionAlgorithm.h"
|
||||
#include "btDispatcher.h"
|
||||
|
||||
CollisionAlgorithm::CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci)
|
||||
{
|
||||
m_dispatcher = ci.m_dispatcher;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef COLLISION_ALGORITHM_H
|
||||
#define COLLISION_ALGORITHM_H
|
||||
|
||||
struct BroadphaseProxy;
|
||||
class Dispatcher;
|
||||
|
||||
struct CollisionAlgorithmConstructionInfo
|
||||
{
|
||||
CollisionAlgorithmConstructionInfo()
|
||||
:m_dispatcher(0)
|
||||
{
|
||||
}
|
||||
CollisionAlgorithmConstructionInfo(Dispatcher* dispatcher,int temp)
|
||||
:m_dispatcher(dispatcher)
|
||||
{
|
||||
}
|
||||
|
||||
Dispatcher* m_dispatcher;
|
||||
|
||||
int GetDispatcherId();
|
||||
|
||||
};
|
||||
|
||||
|
||||
///CollisionAlgorithm is an collision interface that is compatible with the Broadphase and Dispatcher.
|
||||
///It is persistent over frames
|
||||
class CollisionAlgorithm
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
Dispatcher* m_dispatcher;
|
||||
|
||||
protected:
|
||||
int GetDispatcherId();
|
||||
|
||||
public:
|
||||
|
||||
CollisionAlgorithm() {};
|
||||
|
||||
CollisionAlgorithm(const CollisionAlgorithmConstructionInfo& ci);
|
||||
|
||||
virtual ~CollisionAlgorithm() {};
|
||||
|
||||
virtual void ProcessCollision (BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,const struct DispatcherInfo& dispatchInfo) = 0;
|
||||
|
||||
virtual float CalculateTimeOfImpact(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1,const struct DispatcherInfo& dispatchInfo) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //COLLISION_ALGORITHM_H
|
||||
22
src/BulletCollision/BroadphaseCollision/btDispatcher.cpp
Normal file
22
src/BulletCollision/BroadphaseCollision/btDispatcher.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btDispatcher.h"
|
||||
|
||||
Dispatcher::~Dispatcher()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
99
src/BulletCollision/BroadphaseCollision/btDispatcher.h
Normal file
99
src/BulletCollision/BroadphaseCollision/btDispatcher.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef _DISPATCHER_H
|
||||
#define _DISPATCHER_H
|
||||
|
||||
class CollisionAlgorithm;
|
||||
struct BroadphaseProxy;
|
||||
class RigidBody;
|
||||
struct CollisionObject;
|
||||
class ManifoldResult;
|
||||
class OverlappingPairCache;
|
||||
|
||||
enum CollisionDispatcherId
|
||||
{
|
||||
RIGIDBODY_DISPATCHER = 0,
|
||||
USERCALLBACK_DISPATCHER
|
||||
};
|
||||
|
||||
class PersistentManifold;
|
||||
|
||||
struct DispatcherInfo
|
||||
{
|
||||
enum DispatchFunc
|
||||
{
|
||||
DISPATCH_DISCRETE = 1,
|
||||
DISPATCH_CONTINUOUS
|
||||
};
|
||||
DispatcherInfo()
|
||||
:m_dispatchFunc(DISPATCH_DISCRETE),
|
||||
m_timeOfImpact(1.f),
|
||||
m_useContinuous(false),
|
||||
m_debugDraw(0),
|
||||
m_enableSatConvex(false)
|
||||
{
|
||||
|
||||
}
|
||||
float m_timeStep;
|
||||
int m_stepCount;
|
||||
int m_dispatchFunc;
|
||||
float m_timeOfImpact;
|
||||
bool m_useContinuous;
|
||||
class IDebugDraw* m_debugDraw;
|
||||
bool m_enableSatConvex;
|
||||
|
||||
};
|
||||
|
||||
/// Dispatcher can be used in combination with broadphase to dispatch overlapping pairs.
|
||||
/// For example for pairwise collision detection or user callbacks (game logic).
|
||||
class Dispatcher
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
virtual ~Dispatcher() ;
|
||||
|
||||
virtual CollisionAlgorithm* FindAlgorithm(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) = 0;
|
||||
|
||||
//
|
||||
// asume dispatchers to have unique id's in the range [0..max dispacher]
|
||||
//
|
||||
virtual int GetUniqueId() = 0;
|
||||
|
||||
virtual PersistentManifold* GetNewManifold(void* body0,void* body1)=0;
|
||||
|
||||
virtual void ReleaseManifold(PersistentManifold* manifold)=0;
|
||||
|
||||
virtual void ClearManifold(PersistentManifold* manifold)=0;
|
||||
|
||||
virtual bool NeedsCollision(BroadphaseProxy& proxy0,BroadphaseProxy& proxy1) = 0;
|
||||
|
||||
virtual bool NeedsResponse(const CollisionObject& colObj0,const CollisionObject& colObj1)=0;
|
||||
|
||||
virtual ManifoldResult* GetNewManifoldResult(CollisionObject* obj0,CollisionObject* obj1,PersistentManifold* manifold) =0;
|
||||
|
||||
virtual void ReleaseManifoldResult(ManifoldResult*)=0;
|
||||
|
||||
virtual void DispatchAllCollisionPairs(OverlappingPairCache* pairCache,DispatcherInfo& dispatchInfo)=0;
|
||||
|
||||
virtual int GetNumManifolds() const = 0;
|
||||
|
||||
virtual PersistentManifold* GetManifoldByIndexInternal(int index) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //_DISPATCHER_H
|
||||
@@ -0,0 +1,203 @@
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "btOverlappingPairCache.h"
|
||||
|
||||
#include "btDispatcher.h"
|
||||
#include "btCollisionAlgorithm.h"
|
||||
|
||||
int gOverlappingPairs = 0;
|
||||
|
||||
OverlappingPairCache::OverlappingPairCache():
|
||||
m_blockedForChanges(false)
|
||||
//m_NumOverlapBroadphasePair(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OverlappingPairCache::~OverlappingPairCache()
|
||||
{
|
||||
//todo/test: show we erase/delete data, or is it automatic
|
||||
}
|
||||
|
||||
|
||||
void OverlappingPairCache::RemoveOverlappingPair(BroadphasePair& findPair)
|
||||
{
|
||||
|
||||
std::set<BroadphasePair>::iterator it = m_overlappingPairSet.find(findPair);
|
||||
// assert(it != m_overlappingPairSet.end());
|
||||
|
||||
if (it != m_overlappingPairSet.end())
|
||||
{
|
||||
gOverlappingPairs--;
|
||||
BroadphasePair* pair = (BroadphasePair*)(&(*it));
|
||||
CleanOverlappingPair(*pair);
|
||||
m_overlappingPairSet.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OverlappingPairCache::CleanOverlappingPair(BroadphasePair& pair)
|
||||
{
|
||||
for (int dispatcherId=0;dispatcherId<SIMPLE_MAX_ALGORITHMS;dispatcherId++)
|
||||
{
|
||||
if (pair.m_algorithms[dispatcherId])
|
||||
{
|
||||
{
|
||||
delete pair.m_algorithms[dispatcherId];
|
||||
pair.m_algorithms[dispatcherId]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void OverlappingPairCache::AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
|
||||
{
|
||||
//don't add overlap with own
|
||||
assert(proxy0 != proxy1);
|
||||
|
||||
if (!NeedsCollision(proxy0,proxy1))
|
||||
return;
|
||||
|
||||
|
||||
BroadphasePair pair(*proxy0,*proxy1);
|
||||
|
||||
m_overlappingPairSet.insert(pair);
|
||||
gOverlappingPairs++;
|
||||
|
||||
}
|
||||
|
||||
///this FindPair becomes really slow. Either sort the list to speedup the query, or
|
||||
///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
|
||||
///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
|
||||
///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
|
||||
BroadphasePair* OverlappingPairCache::FindPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1)
|
||||
{
|
||||
if (!NeedsCollision(proxy0,proxy1))
|
||||
return 0;
|
||||
|
||||
BroadphasePair tmpPair(*proxy0,*proxy1);
|
||||
std::set<BroadphasePair>::iterator it = m_overlappingPairSet.find(tmpPair);
|
||||
if ((it == m_overlappingPairSet.end()))
|
||||
return 0;
|
||||
|
||||
//assert(it != m_overlappingPairSet.end());
|
||||
BroadphasePair* pair = (BroadphasePair*)(&(*it));
|
||||
return pair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void OverlappingPairCache::CleanProxyFromPairs(BroadphaseProxy* proxy)
|
||||
{
|
||||
|
||||
class CleanPairCallback : public OverlapCallback
|
||||
{
|
||||
BroadphaseProxy* m_cleanProxy;
|
||||
OverlappingPairCache* m_pairCache;
|
||||
|
||||
public:
|
||||
CleanPairCallback(BroadphaseProxy* cleanProxy,OverlappingPairCache* pairCache)
|
||||
:m_cleanProxy(cleanProxy),
|
||||
m_pairCache(pairCache)
|
||||
{
|
||||
}
|
||||
virtual bool ProcessOverlap(BroadphasePair& pair)
|
||||
{
|
||||
if ((pair.m_pProxy0 == m_cleanProxy) ||
|
||||
(pair.m_pProxy1 == m_cleanProxy))
|
||||
{
|
||||
m_pairCache->CleanOverlappingPair(pair);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CleanPairCallback cleanPairs(proxy,this);
|
||||
|
||||
ProcessAllOverlappingPairs(&cleanPairs);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OverlappingPairCache::RemoveOverlappingPairsContainingProxy(BroadphaseProxy* proxy)
|
||||
{
|
||||
|
||||
class RemovePairCallback : public OverlapCallback
|
||||
{
|
||||
BroadphaseProxy* m_obsoleteProxy;
|
||||
|
||||
public:
|
||||
RemovePairCallback(BroadphaseProxy* obsoleteProxy)
|
||||
:m_obsoleteProxy(obsoleteProxy)
|
||||
{
|
||||
}
|
||||
virtual bool ProcessOverlap(BroadphasePair& pair)
|
||||
{
|
||||
return ((pair.m_pProxy0 == m_obsoleteProxy) ||
|
||||
(pair.m_pProxy1 == m_obsoleteProxy));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
RemovePairCallback removeCallback(proxy);
|
||||
|
||||
ProcessAllOverlappingPairs(&removeCallback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void OverlappingPairCache::ProcessAllOverlappingPairs(OverlapCallback* callback)
|
||||
{
|
||||
std::set<BroadphasePair>::iterator it = m_overlappingPairSet.begin();
|
||||
for (; !(it==m_overlappingPairSet.end());)
|
||||
{
|
||||
|
||||
BroadphasePair* pair = (BroadphasePair*)(&(*it));
|
||||
if (callback->ProcessOverlap(*pair))
|
||||
{
|
||||
CleanOverlappingPair(*pair);
|
||||
|
||||
std::set<BroadphasePair>::iterator it2 = it;
|
||||
//why does next line not compile under OS X??
|
||||
#ifdef MAC_OSX_FIXED_STL_SET
|
||||
it2++;
|
||||
it = m_overlappingPairSet.erase(it);
|
||||
assert(it == it2);
|
||||
#else
|
||||
it++;
|
||||
m_overlappingPairSet.erase(it2);
|
||||
#endif //MAC_OSX_FIXED_STL_SET
|
||||
|
||||
gOverlappingPairs--;
|
||||
} else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef OVERLAPPING_PAIR_CACHE_H
|
||||
#define OVERLAPPING_PAIR_CACHE_H
|
||||
|
||||
|
||||
#include "btBroadphaseInterface.h"
|
||||
#include "btBroadphaseProxy.h"
|
||||
#include "LinearMath/SimdPoint3.h"
|
||||
#include <set>
|
||||
|
||||
|
||||
struct OverlapCallback
|
||||
{
|
||||
virtual ~OverlapCallback()
|
||||
{
|
||||
}
|
||||
//return true for deletion of the pair
|
||||
virtual bool ProcessOverlap(BroadphasePair& pair) = 0;
|
||||
};
|
||||
|
||||
///OverlappingPairCache maintains the objects with overlapping AABB
|
||||
///Typically managed by the Broadphase, Axis3Sweep or SimpleBroadphase
|
||||
class OverlappingPairCache : public BroadphaseInterface
|
||||
{
|
||||
//avoid brute-force finding all the time
|
||||
std::set<BroadphasePair> m_overlappingPairSet;
|
||||
|
||||
//during the dispatch, check that user doesn't destroy/create proxy
|
||||
bool m_blockedForChanges;
|
||||
|
||||
public:
|
||||
|
||||
OverlappingPairCache();
|
||||
virtual ~OverlappingPairCache();
|
||||
|
||||
void ProcessAllOverlappingPairs(OverlapCallback*);
|
||||
|
||||
void RemoveOverlappingPair(BroadphasePair& pair);
|
||||
|
||||
void CleanOverlappingPair(BroadphasePair& pair);
|
||||
|
||||
void AddOverlappingPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
|
||||
|
||||
BroadphasePair* FindPair(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1);
|
||||
|
||||
|
||||
void CleanProxyFromPairs(BroadphaseProxy* proxy);
|
||||
|
||||
void RemoveOverlappingPairsContainingProxy(BroadphaseProxy* proxy);
|
||||
|
||||
|
||||
inline bool NeedsCollision(BroadphaseProxy* proxy0,BroadphaseProxy* proxy1) const
|
||||
{
|
||||
bool collides = proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask;
|
||||
collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
|
||||
|
||||
return collides;
|
||||
}
|
||||
|
||||
|
||||
|
||||
virtual void RefreshOverlappingPairs() =0;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif //OVERLAPPING_PAIR_CACHE_H
|
||||
|
||||
238
src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
Normal file
238
src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "btSimpleBroadphase.h"
|
||||
#include <BulletCollision/BroadphaseCollision/btDispatcher.h>
|
||||
#include <BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h>
|
||||
|
||||
#include "LinearMath/SimdVector3.h"
|
||||
#include "LinearMath/SimdTransform.h"
|
||||
#include "LinearMath/SimdMatrix3x3.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
void SimpleBroadphase::validate()
|
||||
{
|
||||
for (int i=0;i<m_numProxies;i++)
|
||||
{
|
||||
for (int j=i+1;j<m_numProxies;j++)
|
||||
{
|
||||
assert(m_pProxies[i] != m_pProxies[j]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SimpleBroadphase::SimpleBroadphase(int maxProxies)
|
||||
:OverlappingPairCache(),
|
||||
m_firstFreeProxy(0),
|
||||
m_numProxies(0),
|
||||
m_maxProxies(maxProxies)
|
||||
{
|
||||
|
||||
m_proxies = new SimpleBroadphaseProxy[maxProxies];
|
||||
m_freeProxies = new int[maxProxies];
|
||||
m_pProxies = new SimpleBroadphaseProxy*[maxProxies];
|
||||
|
||||
|
||||
int i;
|
||||
for (i=0;i<m_maxProxies;i++)
|
||||
{
|
||||
m_freeProxies[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
SimpleBroadphase::~SimpleBroadphase()
|
||||
{
|
||||
delete[] m_proxies;
|
||||
delete []m_freeProxies;
|
||||
delete [] m_pProxies;
|
||||
|
||||
/*int i;
|
||||
for (i=m_numProxies-1;i>=0;i--)
|
||||
{
|
||||
BP_Proxy* proxy = m_pProxies[i];
|
||||
destroyProxy(proxy);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
BroadphaseProxy* SimpleBroadphase::CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask)
|
||||
{
|
||||
if (m_numProxies >= m_maxProxies)
|
||||
{
|
||||
assert(0);
|
||||
return 0; //should never happen, but don't let the game crash ;-)
|
||||
}
|
||||
assert(min[0]<= max[0] && min[1]<= max[1] && min[2]<= max[2]);
|
||||
|
||||
int freeIndex= m_freeProxies[m_firstFreeProxy];
|
||||
SimpleBroadphaseProxy* proxy = new (&m_proxies[freeIndex])SimpleBroadphaseProxy(min,max,shapeType,userPtr,collisionFilterGroup,collisionFilterMask);
|
||||
m_firstFreeProxy++;
|
||||
|
||||
SimpleBroadphaseProxy* proxy1 = &m_proxies[0];
|
||||
|
||||
int index = proxy - proxy1;
|
||||
assert(index == freeIndex);
|
||||
|
||||
m_pProxies[m_numProxies] = proxy;
|
||||
m_numProxies++;
|
||||
//validate();
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
class RemovingOverlapCallback : public OverlapCallback
|
||||
{
|
||||
protected:
|
||||
virtual bool ProcessOverlap(BroadphasePair& pair)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
};
|
||||
|
||||
class RemovePairContainingProxy
|
||||
{
|
||||
|
||||
BroadphaseProxy* m_targetProxy;
|
||||
public:
|
||||
virtual ~RemovePairContainingProxy()
|
||||
{
|
||||
}
|
||||
protected:
|
||||
virtual bool ProcessOverlap(BroadphasePair& pair)
|
||||
{
|
||||
SimpleBroadphaseProxy* proxy0 = static_cast<SimpleBroadphaseProxy*>(pair.m_pProxy0);
|
||||
SimpleBroadphaseProxy* proxy1 = static_cast<SimpleBroadphaseProxy*>(pair.m_pProxy1);
|
||||
|
||||
return ((m_targetProxy == proxy0 || m_targetProxy == proxy1));
|
||||
};
|
||||
};
|
||||
|
||||
void SimpleBroadphase::DestroyProxy(BroadphaseProxy* proxyOrg)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
||||
SimpleBroadphaseProxy* proxy0 = static_cast<SimpleBroadphaseProxy*>(proxyOrg);
|
||||
SimpleBroadphaseProxy* proxy1 = &m_proxies[0];
|
||||
|
||||
int index = proxy0 - proxy1;
|
||||
assert (index < m_maxProxies);
|
||||
m_freeProxies[--m_firstFreeProxy] = index;
|
||||
|
||||
//RemoveOverlappingPairsContainingProxy(proxyOrg);
|
||||
|
||||
assert(0);
|
||||
//then remove non-overlapping ones
|
||||
/*for (i=0;i<GetNumOverlappingPairs();i++)
|
||||
{
|
||||
BroadphasePair& pair = GetOverlappingPair(i);
|
||||
|
||||
SimpleBroadphaseProxy* proxy0 = GetSimpleProxyFromProxy(pair.m_pProxy0);
|
||||
SimpleBroadphaseProxy* proxy1 = GetSimpleProxyFromProxy(pair.m_pProxy1);
|
||||
if ((proxy0==proxyOrg) || (proxy1==proxyOrg))
|
||||
{
|
||||
RemoveOverlappingPair(pair);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
for (i=0;i<m_numProxies;i++)
|
||||
{
|
||||
if (m_pProxies[i] == proxyOrg)
|
||||
{
|
||||
m_pProxies[i] = m_pProxies[m_numProxies-1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_numProxies--;
|
||||
//validate();
|
||||
|
||||
}
|
||||
|
||||
void SimpleBroadphase::SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax)
|
||||
{
|
||||
SimpleBroadphaseProxy* sbp = GetSimpleProxyFromProxy(proxy);
|
||||
sbp->m_min = aabbMin;
|
||||
sbp->m_max = aabbMax;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool SimpleBroadphase::AabbOverlap(SimpleBroadphaseProxy* proxy0,SimpleBroadphaseProxy* proxy1)
|
||||
{
|
||||
return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] &&
|
||||
proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] &&
|
||||
proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2];
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//then remove non-overlapping ones
|
||||
class CheckOverlapCallback : public OverlapCallback
|
||||
{
|
||||
public:
|
||||
virtual bool ProcessOverlap(BroadphasePair& pair)
|
||||
{
|
||||
return (!SimpleBroadphase::AabbOverlap(static_cast<SimpleBroadphaseProxy*>(pair.m_pProxy0),static_cast<SimpleBroadphaseProxy*>(pair.m_pProxy1)));
|
||||
}
|
||||
};
|
||||
|
||||
void SimpleBroadphase::RefreshOverlappingPairs()
|
||||
{
|
||||
//first check for new overlapping pairs
|
||||
int i,j;
|
||||
|
||||
for (i=0;i<m_numProxies;i++)
|
||||
{
|
||||
BroadphaseProxy* proxy0 = m_pProxies[i];
|
||||
for (j=i+1;j<m_numProxies;j++)
|
||||
{
|
||||
BroadphaseProxy* proxy1 = m_pProxies[j];
|
||||
SimpleBroadphaseProxy* p0 = GetSimpleProxyFromProxy(proxy0);
|
||||
SimpleBroadphaseProxy* p1 = GetSimpleProxyFromProxy(proxy1);
|
||||
|
||||
if (AabbOverlap(p0,p1))
|
||||
{
|
||||
if ( !FindPair(proxy0,proxy1))
|
||||
{
|
||||
AddOverlappingPair(proxy0,proxy1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CheckOverlapCallback checkOverlap;
|
||||
|
||||
ProcessAllOverlappingPairs(&checkOverlap);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
92
src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
Normal file
92
src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SIMPLE_BROADPHASE_H
|
||||
#define SIMPLE_BROADPHASE_H
|
||||
|
||||
|
||||
#include "btOverlappingPairCache.h"
|
||||
|
||||
|
||||
struct SimpleBroadphaseProxy : public BroadphaseProxy
|
||||
{
|
||||
SimdVector3 m_min;
|
||||
SimdVector3 m_max;
|
||||
|
||||
SimpleBroadphaseProxy() {};
|
||||
|
||||
SimpleBroadphaseProxy(const SimdPoint3& minpt,const SimdPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask)
|
||||
:BroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
|
||||
m_min(minpt),m_max(maxpt)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks
|
||||
class SimpleBroadphase : public OverlappingPairCache
|
||||
{
|
||||
|
||||
SimpleBroadphaseProxy* m_proxies;
|
||||
int* m_freeProxies;
|
||||
int m_firstFreeProxy;
|
||||
|
||||
SimpleBroadphaseProxy** m_pProxies;
|
||||
int m_numProxies;
|
||||
|
||||
|
||||
|
||||
int m_maxProxies;
|
||||
|
||||
|
||||
inline SimpleBroadphaseProxy* GetSimpleProxyFromProxy(BroadphaseProxy* proxy)
|
||||
{
|
||||
SimpleBroadphaseProxy* proxy0 = static_cast<SimpleBroadphaseProxy*>(proxy);
|
||||
return proxy0;
|
||||
}
|
||||
|
||||
|
||||
void validate();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
virtual void RefreshOverlappingPairs();
|
||||
public:
|
||||
SimpleBroadphase(int maxProxies=16384);
|
||||
virtual ~SimpleBroadphase();
|
||||
|
||||
|
||||
static bool AabbOverlap(SimpleBroadphaseProxy* proxy0,SimpleBroadphaseProxy* proxy1);
|
||||
|
||||
|
||||
virtual BroadphaseProxy* CreateProxy( const SimdVector3& min, const SimdVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask);
|
||||
|
||||
|
||||
virtual void DestroyProxy(BroadphaseProxy* proxy);
|
||||
virtual void SetAabb(BroadphaseProxy* proxy,const SimdVector3& aabbMin,const SimdVector3& aabbMax);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //SIMPLE_BROADPHASE_H
|
||||
|
||||
Reference in New Issue
Block a user