Saxum/extern/bullet/Extras/CDTestFramework/Opcode/OPC_ArraySAP.h
Fabian Klemp aeb6218d2d Renaming.
2014-10-24 11:49:46 +02:00

160 lines
5.8 KiB
C++

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
* OPCODE - Optimized Collision Detection
* Copyright (C) 2001 Pierre Terdiman
* Homepage: http://www.codercorner.com/Opcode.htm
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Contains an array-based version of the sweep-and-prune algorithm
* \file OPC_ArraySAP.h
* \author Pierre Terdiman
* \date December, 2, 2007
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef OPC_ARRAYSAP_H
#define OPC_ARRAYSAP_H
#pragma pack(1)
struct OPCODE_API ASAP_Pair
{
uword id0;
uword id1;
const void* object0;
const void* object1;
//#ifdef PAIR_USER_DATA
void* userData;
//#endif
inline_ const void* GetObject0() const { return (const void*)(size_t(object0) & ~3); }
inline_ const void* GetObject1() const { return (const void*)(size_t(object1) & ~3); }
inline_ size_t IsInArray() const { return size_t(object0) & 1; }
inline_ size_t IsRemoved() const { return size_t(object1) & 1; }
inline_ size_t IsNew() const { return size_t(object0) & 2; }
private:
inline_ void SetInArray() { object0 = (const void*)(size_t(object0) | 1); }
inline_ void SetRemoved() { object1 = (const void*)(size_t(object1) | 1); }
inline_ void SetNew() { object0 = (const void*)(size_t(object0) | 2); }
inline_ void ClearInArray() { object0 = (const void*)(size_t(object0) & ~1); }
inline_ void ClearRemoved() { object1 = (const void*)(size_t(object1) & ~1); }
inline_ void ClearNew() { object0 = (const void*)(size_t(object0) & ~2); }
friend class ArraySAP;
};
#pragma pack()
class OPCODE_API ASAP_PairManager
{
public:
ASAP_PairManager();
~ASAP_PairManager();
void Purge();
void ShrinkMemory();
const ASAP_Pair* AddPair (uword id0, uword id1, const void* object0, const void* object1);
bool RemovePair (uword id0, uword id1);
bool RemovePairs (const BitArray& array);
const ASAP_Pair* FindPair (uword id0, uword id1) const;
inline_ udword GetPairIndex(const ASAP_Pair* pair) const
{
return ((udword)((size_t(pair) - size_t(mActivePairs)))/sizeof(ASAP_Pair));
}
udword mHashSize;
udword mMask;
udword mNbActivePairs;
udword* mHashTable;
udword* mNext;
ASAP_Pair* mActivePairs;
inline_ ASAP_Pair* FindPair(uword id0, uword id1, udword hash_value) const;
void RemovePair(uword id0, uword id1, udword hash_value, udword pair_index);
void ReallocPairs();
};
typedef void* (*SAP_CreatePair)(const void* object0, const void* object1, void* user_data);
typedef void (*SAP_DeletePair)(const void* object0, const void* object1, void* user_data, void* pair_user_data);
// Forward declarations
class ASAP_EndPoint;
class ASAP_Box;
struct IAABB;
struct CreateData;
class OPCODE_API ArraySAP : public Allocateable
{
public:
ArraySAP();
~ArraySAP();
udword AddObject(void* object, uword guid, const AABB& box);
bool RemoveObject(udword handle);
bool UpdateObject(udword handle, const AABB& box);
udword DumpPairs(SAP_CreatePair create_cb, SAP_DeletePair delete_cb, void* cb_user_data, ASAP_Pair** pairs=null);
private:
Container mData;
ASAP_PairManager mPairs;
inline_ void AddPair(const void* object0, const void* object1, uword id0, uword id1)
{
ASSERT(object0);
ASAP_Pair* UP = (ASAP_Pair*)mPairs.AddPair(id0, id1, null, null);
ASSERT(UP);
if(UP->object0)
{
// Persistent pair
}
else
{
// New pair
ASSERT(!(int(object0)&1));
ASSERT(!(int(object1)&1));
UP->object0 = object0;
UP->object1 = object1;
UP->SetInArray();
mData.Add(mPairs.GetPairIndex(UP));
UP->SetNew();
}
UP->ClearRemoved();
}
inline_ void RemovePair(const void* object0, const void* object1, uword id0, uword id1)
{
ASAP_Pair* UP = (ASAP_Pair*)mPairs.FindPair(id0, id1);
if(UP)
{
if(!UP->IsInArray())
{
UP->SetInArray();
mData.Add(mPairs.GetPairIndex(UP));
}
UP->SetRemoved();
}
}
udword mNbBoxes;
udword mMaxNbBoxes;
ASAP_Box* mBoxes;
ASAP_EndPoint* mEndPoints[3];
udword mFirstFree;
void ResizeBoxArray();
// For batch creation
Container mCreated;
void BatchCreate();
void InsertEndPoints(udword axis, const ASAP_EndPoint* end_points, udword nb_endpoints);
bool CompleteBoxPruning2(udword nb, const IAABB* array, const Axes& axes, const CreateData* batched);
bool BipartiteBoxPruning2(udword nb0, const IAABB* array0, udword nb1, const IAABB* array1, const Axes& axes, const CreateData* batched, const udword* box_indices);
// For batch removal
Container mRemoved;
void BatchRemove();
};
#endif // OPC_ARRAYSAP_H