b2BroadPhase.h
Go to the documentation of this file.
00001 /*
00002 * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
00003 *
00004 * This software is provided 'as-is', without any express or implied
00005 * warranty.  In no event will the authors be held liable for any damages
00006 * arising from the use of this software.
00007 * Permission is granted to anyone to use this software for any purpose,
00008 * including commercial applications, and to alter it and redistribute it
00009 * freely, subject to the following restrictions:
00010 * 1. The origin of this software must not be misrepresented; you must not
00011 * claim that you wrote the original software. If you use this software
00012 * in a product, an acknowledgment in the product documentation would be
00013 * appreciated but is not required.
00014 * 2. Altered source versions must be plainly marked as such, and must not be
00015 * misrepresented as being the original software.
00016 * 3. This notice may not be removed or altered from any source distribution.
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         // Reset pair buffer
00188         m_pairCount = 0;
00189 
00190         // Perform tree queries for all moving proxies.
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                 // We have to query the tree with the fat AABB so that
00200                 // we don't fail to create a pair that may touch later.
00201                 const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
00202 
00203                 // Query tree, create pairs and add them pair buffer.
00204                 m_tree.Query(this, fatAABB);
00205         }
00206 
00207         // Reset move buffer
00208         m_moveCount = 0;
00209 
00210         // Sort the pair buffer to expose duplicates.
00211         std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
00212 
00213         // Send the pairs back to the client.
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                 // Skip any duplicate pairs.
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         // Try to keep the tree balanced.
00237         //m_tree.Rebalance(4);
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


mvsim
Author(s):
autogenerated on Thu Sep 7 2017 09:27:47