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 | #include <Box2D/Collision/b2BroadPhase.h> |
20 | #include <string.h> |
21 | |
22 | b2BroadPhase::b2BroadPhase() |
23 | { |
24 | m_proxyCount = 0; |
25 | |
26 | m_pairCapacity = 16; |
27 | m_pairCount = 0; |
28 | m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); |
29 | |
30 | m_moveCapacity = 16; |
31 | m_moveCount = 0; |
32 | m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32)); |
33 | } |
34 | |
35 | b2BroadPhase::~b2BroadPhase() |
36 | { |
37 | b2Free(m_moveBuffer); |
38 | b2Free(m_pairBuffer); |
39 | } |
40 | |
41 | int32 b2BroadPhase::CreateProxy(const b2AABB& aabb, void* userData) |
42 | { |
43 | int32 proxyId = m_tree.CreateProxy(aabb, userData); |
44 | ++m_proxyCount; |
45 | BufferMove(proxyId); |
46 | return proxyId; |
47 | } |
48 | |
49 | void b2BroadPhase::DestroyProxy(int32 proxyId) |
50 | { |
51 | UnBufferMove(proxyId); |
52 | --m_proxyCount; |
53 | m_tree.DestroyProxy(proxyId); |
54 | } |
55 | |
56 | void b2BroadPhase::MoveProxy(int32 proxyId, const b2AABB& aabb, const b2Vec2& displacement) |
57 | { |
58 | bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement); |
59 | if (buffer) |
60 | { |
61 | BufferMove(proxyId); |
62 | } |
63 | } |
64 | |
65 | void b2BroadPhase::TouchProxy(int32 proxyId) |
66 | { |
67 | BufferMove(proxyId); |
68 | } |
69 | |
70 | void b2BroadPhase::BufferMove(int32 proxyId) |
71 | { |
72 | if (m_moveCount == m_moveCapacity) |
73 | { |
74 | int32* oldBuffer = m_moveBuffer; |
75 | m_moveCapacity *= 2; |
76 | m_moveBuffer = (int32*)b2Alloc(m_moveCapacity * sizeof(int32)); |
77 | memcpy(m_moveBuffer, oldBuffer, m_moveCount * sizeof(int32)); |
78 | b2Free(oldBuffer); |
79 | } |
80 | |
81 | m_moveBuffer[m_moveCount] = proxyId; |
82 | ++m_moveCount; |
83 | } |
84 | |
85 | void b2BroadPhase::UnBufferMove(int32 proxyId) |
86 | { |
87 | for (int32 i = 0; i < m_moveCount; ++i) |
88 | { |
89 | if (m_moveBuffer[i] == proxyId) |
90 | { |
91 | m_moveBuffer[i] = e_nullProxy; |
92 | } |
93 | } |
94 | } |
95 | |
96 | // This is called from b2DynamicTree::Query when we are gathering pairs. |
97 | bool b2BroadPhase::QueryCallback(int32 proxyId) |
98 | { |
99 | // A proxy cannot form a pair with itself. |
100 | if (proxyId == m_queryProxyId) |
101 | { |
102 | return true; |
103 | } |
104 | |
105 | // Grow the pair buffer as needed. |
106 | if (m_pairCount == m_pairCapacity) |
107 | { |
108 | b2Pair* oldBuffer = m_pairBuffer; |
109 | m_pairCapacity *= 2; |
110 | m_pairBuffer = (b2Pair*)b2Alloc(m_pairCapacity * sizeof(b2Pair)); |
111 | memcpy(m_pairBuffer, oldBuffer, m_pairCount * sizeof(b2Pair)); |
112 | b2Free(oldBuffer); |
113 | } |
114 | |
115 | m_pairBuffer[m_pairCount].proxyIdA = b2Min(proxyId, m_queryProxyId); |
116 | m_pairBuffer[m_pairCount].proxyIdB = b2Max(proxyId, m_queryProxyId); |
117 | ++m_pairCount; |
118 | |
119 | return true; |
120 | } |
121 | |