Advertisement
Guest User

b2BroadPhase.h

a guest
Jun 21st, 2018
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty.  In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18.  
  19. #ifndef B2_BROAD_PHASE_H
  20. #define B2_BROAD_PHASE_H
  21.  
  22. #include <Box2D/Common/b2Settings.h>
  23. #include <Box2D/Collision/b2Collision.h>
  24. #include <Box2D/Collision/b2DynamicTree.h>
  25. //#include <algorithm>
  26. #include <stdlib.h>
  27.  
  28. #include <string>
  29. #include <stdio.h>
  30.  
  31. struct b2Pair
  32. {
  33.     int32 proxyIdA;
  34.     int32 proxyIdB;
  35. };
  36.  
  37. /// The broad-phase is used for computing pairs and performing volume queries and ray casts.
  38. /// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
  39. /// It is up to the client to consume the new pairs and to track subsequent overlap.
  40. class b2BroadPhase
  41. {
  42. public:
  43.  
  44.     enum
  45.     {
  46.         e_nullProxy = -1
  47.     };
  48.  
  49.     b2BroadPhase();
  50.     ~b2BroadPhase();
  51.  
  52.     /// Create a proxy with an initial AABB. Pairs are not reported until
  53.     /// UpdatePairs is called.
  54.     int32 CreateProxy(const b2AABB& aabb, void* userData);
  55.  
  56.     /// Destroy a proxy. It is up to the client to remove any pairs.
  57.     void DestroyProxy(int32 proxyId);
  58.  
  59.     /// Call MoveProxy as many times as you like, then when you are done
  60.     /// call UpdatePairs to finalized the proxy pairs (for your time step).
  61.     void MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement);
  62.  
  63.     /// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
  64.     void TouchProxy(int32 proxyId);
  65.  
  66.     /// Get the fat AABB for a proxy.
  67.     const b2AABB& GetFatAABB(int32 proxyId) const;
  68.  
  69.     /// Get user data from a proxy. Returns NULL if the id is invalid.
  70.     void* GetUserData(int32 proxyId) const;
  71.  
  72.     /// Test overlap of fat AABBs.
  73.     bool TestOverlap(int32 proxyIdA, int32 proxyIdB) const;
  74.  
  75.     /// Get the number of proxies.
  76.     int32 GetProxyCount() const;
  77.  
  78.     /// Update the pairs. This results in pair callbacks. This can only add pairs.
  79.     template <typename T>
  80.     void UpdatePairs(T* callback);
  81.  
  82.     /// Query an AABB for overlapping proxies. The callback class
  83.     /// is called for each proxy that overlaps the supplied AABB.
  84.     template <typename T>
  85.     void Query(T* callback, const b2AABB& aabb) const;
  86.  
  87.     /// Ray-cast against the proxies in the tree. This relies on the callback
  88.     /// to perform a exact ray-cast in the case were the proxy contains a shape.
  89.     /// The callback also performs the any collision filtering. This has performance
  90.     /// roughly equal to k * log(n), where k is the number of collisions and n is the
  91.     /// number of proxies in the tree.
  92.     /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
  93.     /// @param callback a callback class that is called for each proxy that is hit by the ray.
  94.     template <typename T>
  95.     void RayCast(T* callback, const b2RayCastInput& input) const;
  96.  
  97.     /// Get the height of the embedded tree.
  98.     int32 GetTreeHeight() const;
  99.  
  100.     /// Get the balance of the embedded tree.
  101.     int32 GetTreeBalance() const;
  102.  
  103.     /// Get the quality metric of the embedded tree.
  104.     float32 GetTreeQuality() const;
  105.  
  106.     /// Shift the world origin. Useful for large worlds.
  107.     /// The shift formula is: position -= newOrigin
  108.     /// @param newOrigin the new origin with respect to the old origin
  109.     void ShiftOrigin(const b2Vec2& newOrigin);
  110.  
  111. private:
  112.  
  113.     friend class b2DynamicTree;
  114.  
  115.     void BufferMove(int32 proxyId);
  116.     void UnBufferMove(int32 proxyId);
  117.  
  118.     bool QueryCallback(int32 proxyId);
  119.  
  120.     b2DynamicTree m_tree;
  121.  
  122.     int32 m_proxyCount;
  123.  
  124.     int32* m_moveBuffer;
  125.     int32 m_moveCapacity;
  126.     int32 m_moveCount;
  127.  
  128.     b2Pair* m_pairBuffer;
  129.     int32 m_pairCapacity;
  130.     int32 m_pairCount;
  131.  
  132.     int32 m_queryProxyId;
  133. };
  134.  
  135. //The return value of this function should represent whether elem1 is considered less than,
  136. //equal to, or greater than elem2 by returning, respectively, a negative value, zero or a positive value.
  137. inline int b2PairCompareQSort(const void * elem1, const void * elem2)
  138. {
  139.    b2Pair* pair1 = (b2Pair*) elem1;
  140.    b2Pair* pair2 = (b2Pair*) elem2;
  141.  
  142.    if (pair1->proxyIdA < pair2->proxyIdA)
  143.    {
  144.       return -1;
  145.    }
  146.  
  147.    if (pair1->proxyIdA == pair2->proxyIdA)
  148.    {
  149.       if( pair1->proxyIdB < pair2->proxyIdB ) {
  150.          return -1;
  151.       }
  152.       else if(pair1->proxyIdB > pair2->proxyIdB) {
  153.          return 1;
  154.       }
  155.       else {
  156.          return 0;
  157.       }
  158.    }
  159.    else {
  160.       return 1;
  161.    }
  162.  
  163. }
  164.  
  165. /// This is used to sort pairs.
  166. inline bool b2PairLessThan(const b2Pair& pair1, const b2Pair& pair2)
  167. {
  168.     if (pair1.proxyIdA < pair2.proxyIdA)
  169.     {
  170.         return true;
  171.     }
  172.  
  173.     if (pair1.proxyIdA == pair2.proxyIdA)
  174.     {
  175.         return pair1.proxyIdB < pair2.proxyIdB;
  176.     }
  177.  
  178.     return false;
  179. }
  180.  
  181. inline void* b2BroadPhase::GetUserData(int32 proxyId) const
  182. {
  183.     return m_tree.GetUserData(proxyId);
  184. }
  185.  
  186. inline bool b2BroadPhase::TestOverlap(int32 proxyIdA, int32 proxyIdB) const
  187. {
  188.     const b2AABB& aabbA = m_tree.GetFatAABB(proxyIdA);
  189.     const b2AABB& aabbB = m_tree.GetFatAABB(proxyIdB);
  190.     return b2TestOverlap(aabbA, aabbB);
  191. }
  192.  
  193. inline const b2AABB& b2BroadPhase::GetFatAABB(int32 proxyId) const
  194. {
  195.     return m_tree.GetFatAABB(proxyId);
  196. }
  197.  
  198. inline int32 b2BroadPhase::GetProxyCount() const
  199. {
  200.     return m_proxyCount;
  201. }
  202.  
  203. inline int32 b2BroadPhase::GetTreeHeight() const
  204. {
  205.     return m_tree.GetHeight();
  206. }
  207.  
  208. inline int32 b2BroadPhase::GetTreeBalance() const
  209. {
  210.     return m_tree.GetMaxBalance();
  211. }
  212.  
  213. inline float32 b2BroadPhase::GetTreeQuality() const
  214. {
  215.     return m_tree.GetAreaRatio();
  216. }
  217.  
  218. template <typename T>
  219. void b2BroadPhase::UpdatePairs(T* callback)
  220. {
  221.  
  222.     printf("\n");
  223.     printf("{");
  224.     printf("%d",m_moveCount);
  225.     printf("|");
  226.     fflush(stdout);
  227.  
  228.     // Reset pair buffer
  229.     m_pairCount = 0;
  230.  
  231.     // Perform tree queries for all moving proxies.
  232.     for (int32 i = 0; i < m_moveCount; ++i)
  233.     {
  234.         m_queryProxyId = m_moveBuffer[i];
  235.         if (m_queryProxyId == e_nullProxy)
  236.         {
  237.             continue;
  238.         }
  239.  
  240.         // We have to query the tree with the fat AABB so that
  241.         // we don't fail to create a pair that may touch later.
  242.         const b2AABB& fatAABB = m_tree.GetFatAABB(m_queryProxyId);
  243.  
  244.         // Query tree, create pairs and add them pair buffer.
  245.         m_tree.Query(this, fatAABB);
  246.     }
  247.  
  248.     // Reset move buffer
  249.     m_moveCount = 0;
  250.  
  251.     // Sort the pair buffer to expose duplicates.
  252.     //std::sort(m_pairBuffer, m_pairBuffer + m_pairCount, b2PairLessThan);
  253.  
  254.     // FIX from http://www.box2d.org/forum/viewtopic.php?f=7&t=4756&start=0 to get rid of stl dependency
  255.     qsort(m_pairBuffer, sizeof(m_pairBuffer) / sizeof(struct b2Pair) , sizeof(struct b2Pair), b2PairCompareQSort);
  256.     // Send the pairs back to the client.
  257.  
  258.     int32 i = 0;
  259.  
  260.     printf("|");
  261.     printf("%d",m_pairCount);
  262.     printf("}");
  263.     fflush(stdout);
  264.  
  265.     while (i < m_pairCount)
  266.     {
  267.         b2Pair* primaryPair = m_pairBuffer + i;
  268.         void* userDataA = m_tree.GetUserData(primaryPair->proxyIdA);
  269.         void* userDataB = m_tree.GetUserData(primaryPair->proxyIdB);
  270.  
  271.         callback->AddPair(userDataA, userDataB);
  272.         ++i;
  273.  
  274.         // Skip any duplicate pairs.
  275.         while (i < m_pairCount)
  276.         {
  277.             b2Pair* pair = m_pairBuffer + i;
  278.             if (pair->proxyIdA != primaryPair->proxyIdA || pair->proxyIdB != primaryPair->proxyIdB)
  279.             {
  280.                 break;
  281.             }
  282.             ++i;
  283.         }
  284.     }
  285.  
  286.     printf("{*}");
  287.     fflush(stdout);
  288.  
  289.     // Try to keep the tree balanced.
  290.     //m_tree.Rebalance(4);
  291. }
  292.  
  293. template <typename T>
  294. inline void b2BroadPhase::Query(T* callback, const b2AABB& aabb) const
  295. {
  296.     m_tree.Query(callback, aabb);
  297. }
  298.  
  299. template <typename T>
  300. inline void b2BroadPhase::RayCast(T* callback, const b2RayCastInput& input) const
  301. {
  302.     m_tree.RayCast(callback, input);
  303. }
  304.  
  305. inline void b2BroadPhase::ShiftOrigin(const b2Vec2& newOrigin)
  306. {
  307.     m_tree.ShiftOrigin(newOrigin);
  308. }
  309.  
  310. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement