Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef B2_BROAD_PHASE_H
00020 #define B2_BROAD_PHASE_H
00021
00022 #include <Box2D/Common/b2Settings.h>
00023 #include <Box2D/Collision/b2Collision.h>
00024 #include <Box2D/Collision/b2DynamicTree.h>
00025 #include <algorithm>
00026
00027 struct b2Pair
00028 {
00029 int32 proxyIdA;
00030 int32 proxyIdB;
00031 };
00032
00036 class b2BroadPhase
00037 {
00038 public:
00039
00040 enum
00041 {
00042 e_nullProxy = -1
00043 };
00044
00045 b2BroadPhase();
00046 ~b2BroadPhase();
00047
00050 int32 CreateProxy(const b2AABB& aabb, void* userData);
00051
00053 void DestroyProxy(int32 proxyId);
00054
00057 void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);
00058
00060 void TouchProxy(int32 proxyId);
00061
00063 const b2AABB& GetFatAABB(int32 proxyId) const;
00064
00066 void* GetUserData(int32 proxyId) const;
00067
00069 bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;
00070
00072 int32 GetProxyCount() const;
00073
00075 template <typename T>
00076 void UpdatePairs(T* callback);
00077
00080 template <typename T>
00081 void Query(T* callback, const b2AABB& aabb) const;
00082
00090 template <typename T>
00091 void RayCast(T* callback, const b2RayCastInput& input) const;
00092
00094 int32 GetTreeHeight() const;
00095
00097 int32 GetTreeBalance() const;
00098
00100 float32 GetTreeQuality() const;
00101
00105 void ShiftOrigin(const b2Vec2& newOrigin);
00106
00107 private:
00108
00109 friend class b2DynamicTree;
00110
00111 void BufferMove(int32 proxyId);
00112 void UnBufferMove(int32 proxyId);
00113
00114 bool QueryCallback(int32 proxyId);
00115
00116 b2DynamicTree m_tree;
00117
00118 int32 m_proxyCount;
00119
00120 int32* m_moveBuffer;
00121 int32 m_moveCapacity;
00122 int32 m_moveCount;
00123
00124 b2Pair* m_pairBuffer;
00125 int32 m_pairCapacity;
00126 int32 m_pairCount;
00127
00128 int32 m_queryProxyId;
00129 };
00130
00132 inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)
00133 {
00134 if (pair1.proxyIdA < pair2.proxyIdA)
00135 {
00136 return true;
00137 }
00138
00139 if (pair1.proxyIdA == pair2.proxyIdA)
00140 {
00141 return pair1.proxyIdB < pair2.proxyIdB;
00142 }
00143
00144 return false;
00145 }
00146
00147 inline void* b2BroadPhase::GetUserData(int32 proxyId) const
00148 {
00149 return m_tree.GetUserData(proxyId);
00150 }
00151
00152 inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const
00153 {
00154 const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);
00155 const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);
00156 return b2TestOverlap(aabbA, aabbB);
00157 }
00158
00159 inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const
00160 {
00161 return m_tree.GetFatAABB(proxyId);
00162 }
00163
00164 inline int32 b2BroadPhase::GetProxyCount() const
00165 {
00166 return m_proxyCount;
00167 }
00168
00169 inline int32 b2BroadPhase::GetTreeHeight() const
00170 {
00171 return m_tree.GetHeight();
00172 }
00173
00174 inline int32 b2BroadPhase::GetTreeBalance() const
00175 {
00176 return m_tree.GetMaxBalance();
00177 }
00178
00179 inline float32 b2BroadPhase::GetTreeQuality() const
00180 {
00181 return m_tree.GetAreaRatio();
00182 }
00183
00184 template <typename T>
00185 void b2BroadPhase::UpdatePairs(T* callback)
00186 {
00187
00188 m_pairCount = 0;
00189
00190
00191 for (int32 i = 0; i < m_moveCount; ++i)
00192 {
00193 m_queryProxyId = m_moveBuffer[i];
00194 if (m_queryProxyId == e_nullProxy)
00195 {
00196 continue;
00197 }
00198
00199
00200
00201 const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
00202
00203
00204 m_tree.Query(this, fatAABB);
00205 }
00206
00207
00208 m_moveCount = 0;
00209
00210
00211 std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
00212
00213
00214 int32 i = 0;
00215 while (i < m_pairCount)
00216 {
00217 b2Pair* primaryPair = m_pairBuffer + i;
00218 void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);
00219 void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);
00220
00221 callback->AddPair(userDataA, userDataB);
00222 ++i;
00223
00224
00225 while (i < m_pairCount)
00226 {
00227 b2Pair* pair = m_pairBuffer + i;
00228 if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)
00229 {
00230 break;
00231 }
00232 ++i;
00233 }
00234 }
00235
00236
00237
00238 }
00239
00240 template <typename T>
00241 inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const
00242 {
00243 m_tree.Query(callback, aabb);
00244 }
00245
00246 template <typename T>
00247 inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const
00248 {
00249 m_tree.RayCast(callback, input);
00250 }
00251
00252 inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin)
00253 {
00254 m_tree.ShiftOrigin(newOrigin);
00255 }
00256
00257 #endif