Skip to content

Commit 24766cf

Browse files
authored
Merge pull request #44 from HughPH/master
Performance improvement (at least in debug)
2 parents f2c6e3f + 7d37e8c commit 24766cf

File tree

3 files changed

+996
-1053
lines changed

3 files changed

+996
-1053
lines changed

src/box2dx/Box2D.NetStandard/Collision/BroadPhase.cs

Lines changed: 193 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -54,197 +54,197 @@ Collision Detection in Interactive 3D Environments by Gino van den Bergen
5454

5555
namespace Box2D.NetStandard.Collision
5656
{
57-
internal class BroadPhase
58-
{
59-
private readonly DynamicTree m_tree;
60-
private int[] m_moveBuffer;
61-
private int m_moveCapacity;
62-
private int m_moveCount;
63-
private Pair[] m_pairBuffer;
64-
private int m_pairCapacity;
65-
private int m_pairCount;
66-
67-
private int m_proxyCount;
68-
private int m_queryProxyId;
69-
70-
public BroadPhase()
71-
{
72-
m_proxyCount = 0;
73-
74-
m_pairCapacity = 16;
75-
m_pairCount = 0;
76-
m_pairBuffer = new Pair[m_pairCapacity];
77-
78-
m_moveCapacity = 16;
79-
m_moveCount = 0;
80-
m_moveBuffer = new int[m_moveCapacity];
81-
82-
m_tree = new DynamicTree();
83-
}
84-
85-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
86-
internal object GetUserData(int proxyId) => m_tree.GetUserData(proxyId);
87-
88-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
89-
public bool TestOverlap(int proxyIdA, int proxyIdB)
90-
{
91-
AABB aabbA = m_tree.GetFatAABB(proxyIdA);
92-
AABB aabbB = m_tree.GetFatAABB(proxyIdB);
93-
return Collision.TestOverlap(aabbA, aabbB);
94-
}
95-
96-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
97-
public AABB GetFatAABB(int proxyId) => m_tree.GetFatAABB(proxyId);
98-
99-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
100-
public int GetProxyCount() => m_proxyCount;
101-
102-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
103-
public int GetTreeHeight() => m_tree.Height;
104-
105-
public void UpdatePairs(Action<object, object> AddPair)
106-
{
107-
m_pairCount = 0;
108-
109-
for (var i = 0; i < m_moveCount; ++i)
110-
{
111-
m_queryProxyId = m_moveBuffer[i];
112-
if (m_queryProxyId == -1)
113-
{
114-
continue;
115-
}
116-
117-
AABB fatAABB = m_tree.GetFatAABB(m_queryProxyId);
118-
119-
m_tree.Query(QueryCallback, fatAABB);
120-
}
121-
122-
for (var i = 0; i < m_pairCount; ++i)
123-
{
124-
Pair primaryPair = m_pairBuffer[i];
125-
object userDataA = m_tree.GetUserData(primaryPair.proxyIdA);
126-
object userDataB = m_tree.GetUserData(primaryPair.proxyIdB);
127-
AddPair(userDataA, userDataB);
128-
}
129-
130-
for (var i = 0; i < m_moveCount; ++i)
131-
{
132-
int proxyId = m_moveBuffer[i];
133-
if (proxyId == -1)
134-
{
135-
continue;
136-
}
137-
138-
m_tree.ClearMoved(proxyId);
139-
}
140-
141-
m_moveCount = 0;
142-
}
143-
144-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
145-
public void Query(Func<int, bool> queryCallback, in AABB aabb)
146-
{
147-
m_tree.Query(queryCallback, in aabb);
148-
}
149-
150-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
151-
public void RayCast(Func<RayCastInput, int, float> RayCastCallback, in RayCastInput input)
152-
{
153-
m_tree.RayCast(RayCastCallback, in input);
154-
}
155-
156-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
157-
public void ShiftOrigin(in Vector2 newOrigin)
158-
{
159-
m_tree.ShiftOrigin(in newOrigin);
160-
}
161-
162-
public int CreateProxy(in AABB aabb, object userData)
163-
{
164-
int proxyId = m_tree.CreateProxy(aabb, userData);
165-
++m_proxyCount;
166-
BufferMove(proxyId);
167-
return proxyId;
168-
}
169-
170-
public void DestroyProxy(int proxyId)
171-
{
172-
UnBufferMove(proxyId);
173-
--m_proxyCount;
174-
m_tree.DestroyProxy(proxyId);
175-
}
176-
177-
// Call MoveProxy as many times as you like, then when you are done
178-
// call Commit to finalize the proxy pairs (for your time step).
179-
public void MoveProxy(int proxyId, in AABB aabb, in Vector2 displacement)
180-
{
181-
bool buffer = m_tree.MoveProxy((DynamicTree.Proxy)proxyId, aabb, displacement);
182-
if (buffer)
183-
{
184-
BufferMove(proxyId);
185-
}
186-
}
187-
188-
internal void TouchProxy(int proxyId)
189-
{
190-
BufferMove(proxyId);
191-
}
192-
193-
194-
private void BufferMove(int proxyId)
195-
{
196-
if (m_moveCount == m_moveCapacity)
197-
{
198-
int[] oldBuffer = m_moveBuffer;
199-
m_moveCapacity *= 2;
200-
m_moveBuffer = new int[m_moveCapacity];
201-
Array.Copy(oldBuffer, m_moveBuffer, m_moveCount);
202-
}
203-
204-
m_moveBuffer[m_moveCount] = proxyId;
205-
++m_moveCount;
206-
}
207-
208-
private void UnBufferMove(int proxyId)
209-
{
210-
for (var i = 0; i < m_moveCount; ++i)
211-
{
212-
if (m_moveBuffer[i] == proxyId)
213-
{
214-
m_moveBuffer[i] = -1;
215-
}
216-
}
217-
}
218-
219-
private bool QueryCallback(int proxyId)
220-
{
221-
// A proxy cannot form a pair with itself.
222-
if (proxyId == m_queryProxyId)
223-
{
224-
return true;
225-
}
226-
227-
bool moved = m_tree.WasMoved(proxyId);
228-
if (moved && proxyId > m_queryProxyId)
229-
// Both proxies are moving. Avoid duplicate pairs.
230-
{
231-
return true;
232-
}
233-
234-
// Grow the pair buffer as needed.
235-
if (m_pairCount == m_pairCapacity)
236-
{
237-
Pair[] oldBuffer = m_pairBuffer;
238-
m_pairCapacity = m_pairCapacity + (m_pairCapacity >> 1);
239-
m_pairBuffer = new Pair[m_pairCapacity];
240-
Array.Copy(oldBuffer, m_pairBuffer, m_pairCount);
241-
}
242-
243-
m_pairBuffer[m_pairCount].proxyIdA = Math.Min(proxyId, m_queryProxyId);
244-
m_pairBuffer[m_pairCount].proxyIdB = Math.Max(proxyId, m_queryProxyId);
245-
++m_pairCount;
246-
247-
return true;
248-
}
249-
}
57+
internal class BroadPhase
58+
{
59+
private readonly DynamicTree m_tree;
60+
private int[] m_moveBuffer;
61+
private int m_moveCapacity;
62+
private int m_moveCount;
63+
private Pair[] m_pairBuffer;
64+
private int m_pairCapacity;
65+
private int m_pairCount;
66+
67+
private int m_proxyCount;
68+
private int m_queryProxyId;
69+
70+
public BroadPhase()
71+
{
72+
m_proxyCount = 0;
73+
74+
m_pairCapacity = 16;
75+
m_pairCount = 0;
76+
m_pairBuffer = new Pair[m_pairCapacity];
77+
78+
m_moveCapacity = 16;
79+
m_moveCount = 0;
80+
m_moveBuffer = new int[m_moveCapacity];
81+
82+
m_tree = new DynamicTree();
83+
}
84+
85+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
86+
internal object GetUserData(int proxyId) => m_tree.GetUserData(proxyId);
87+
88+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
89+
public bool TestOverlap(int proxyIdA, int proxyIdB)
90+
{
91+
AABB aabbA = m_tree.GetFatAABB(proxyIdA);
92+
AABB aabbB = m_tree.GetFatAABB(proxyIdB);
93+
return Collision.TestOverlap(aabbA, aabbB);
94+
}
95+
96+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
97+
public AABB GetFatAABB(int proxyId) => m_tree.GetFatAABB(proxyId);
98+
99+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
100+
public int GetProxyCount() => m_proxyCount;
101+
102+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
103+
public int GetTreeHeight() => m_tree.Height;
104+
105+
public void UpdatePairs(Action<object, object> AddPair)
106+
{
107+
m_pairCount = 0;
108+
109+
for (var i = 0; i < m_moveCount; ++i)
110+
{
111+
m_queryProxyId = m_moveBuffer[i];
112+
if (m_queryProxyId == -1)
113+
{
114+
continue;
115+
}
116+
117+
AABB fatAABB = m_tree.GetFatAABB(m_queryProxyId);
118+
119+
m_tree.Query(QueryCallback, fatAABB);
120+
}
121+
122+
for (var i = 0; i < m_pairCount; ++i)
123+
{
124+
Pair primaryPair = m_pairBuffer[i];
125+
object userDataA = m_tree.GetUserData(primaryPair.proxyIdA);
126+
object userDataB = m_tree.GetUserData(primaryPair.proxyIdB);
127+
AddPair(userDataA, userDataB);
128+
}
129+
130+
for (var i = 0; i < m_moveCount; ++i)
131+
{
132+
int proxyId = m_moveBuffer[i];
133+
if (proxyId == -1)
134+
{
135+
continue;
136+
}
137+
138+
m_tree.ClearMoved(proxyId);
139+
}
140+
141+
m_moveCount = 0;
142+
}
143+
144+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
145+
public void Query(Func<int, bool> queryCallback, in AABB aabb)
146+
{
147+
m_tree.Query(queryCallback, in aabb);
148+
}
149+
150+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
151+
public void RayCast(Func<RayCastInput, int, float> RayCastCallback, in RayCastInput input)
152+
{
153+
m_tree.RayCast(RayCastCallback, in input);
154+
}
155+
156+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
157+
public void ShiftOrigin(in Vector2 newOrigin)
158+
{
159+
m_tree.ShiftOrigin(in newOrigin);
160+
}
161+
162+
public int CreateProxy(in AABB aabb, object userData)
163+
{
164+
int proxyId = m_tree.CreateProxy(aabb, userData);
165+
++m_proxyCount;
166+
BufferMove(proxyId);
167+
return proxyId;
168+
}
169+
170+
public void DestroyProxy(int proxyId)
171+
{
172+
UnBufferMove(proxyId);
173+
--m_proxyCount;
174+
m_tree.DestroyProxy(proxyId);
175+
}
176+
177+
// Call MoveProxy as many times as you like, then when you are done
178+
// call Commit to finalize the proxy pairs (for your time step).
179+
public void MoveProxy(int proxyId, in AABB aabb, in Vector2 displacement)
180+
{
181+
bool buffer = m_tree.MoveProxy(proxyId, aabb, displacement);
182+
if (buffer)
183+
{
184+
BufferMove(proxyId);
185+
}
186+
}
187+
188+
internal void TouchProxy(int proxyId)
189+
{
190+
BufferMove(proxyId);
191+
}
192+
193+
194+
private void BufferMove(int proxyId)
195+
{
196+
if (m_moveCount == m_moveCapacity)
197+
{
198+
int[] oldBuffer = m_moveBuffer;
199+
m_moveCapacity *= 2;
200+
m_moveBuffer = new int[m_moveCapacity];
201+
Array.Copy(oldBuffer, m_moveBuffer, m_moveCount);
202+
}
203+
204+
m_moveBuffer[m_moveCount] = proxyId;
205+
++m_moveCount;
206+
}
207+
208+
private void UnBufferMove(int proxyId)
209+
{
210+
for (var i = 0; i < m_moveCount; ++i)
211+
{
212+
if (m_moveBuffer[i] == proxyId)
213+
{
214+
m_moveBuffer[i] = -1;
215+
}
216+
}
217+
}
218+
219+
private bool QueryCallback(int proxyId)
220+
{
221+
// A proxy cannot form a pair with itself.
222+
if (proxyId == m_queryProxyId)
223+
{
224+
return true;
225+
}
226+
227+
bool moved = m_tree.WasMoved(proxyId);
228+
if (moved && proxyId > m_queryProxyId)
229+
// Both proxies are moving. Avoid duplicate pairs.
230+
{
231+
return true;
232+
}
233+
234+
// Grow the pair buffer as needed.
235+
if (m_pairCount == m_pairCapacity)
236+
{
237+
Pair[] oldBuffer = m_pairBuffer;
238+
m_pairCapacity = m_pairCapacity + (m_pairCapacity >> 1);
239+
m_pairBuffer = new Pair[m_pairCapacity];
240+
Array.Copy(oldBuffer, m_pairBuffer, m_pairCount);
241+
}
242+
243+
m_pairBuffer[m_pairCount].proxyIdA = Math.Min(proxyId, m_queryProxyId);
244+
m_pairBuffer[m_pairCount].proxyIdB = Math.Max(proxyId, m_queryProxyId);
245+
++m_pairCount;
246+
247+
return true;
248+
}
249+
}
250250
}

0 commit comments

Comments
 (0)