private void ValidateTable() { #if DEBUG for (int i = 0; i < PairManager.TableCapacity; ++i) { ushort index = _hashTable[i]; while (index != PairManager.NullPair) { Pair pair = _pairs[index]; Box2DXDebug.Assert(pair.IsBuffered() == false); Box2DXDebug.Assert(pair.IsFinal() == true); Box2DXDebug.Assert(pair.IsRemoved() == false); Box2DXDebug.Assert(pair.ProxyId1 != pair.ProxyId2); Box2DXDebug.Assert(pair.ProxyId1 < Settings.MaxProxies); Box2DXDebug.Assert(pair.ProxyId2 < Settings.MaxProxies); Proxy proxy1 = _broadPhase._proxyPool[pair.ProxyId1]; Proxy proxy2 = _broadPhase._proxyPool[pair.ProxyId2]; Box2DXDebug.Assert(proxy1.IsValid == true); Box2DXDebug.Assert(proxy2.IsValid == true); Box2DXDebug.Assert(_broadPhase.TestOverlap(proxy1, proxy2) == true); index = pair.Next; } } #endif }
private void ValidateBuffer() { #if DEBUG Box2DXDebug.Assert(_pairBufferCount <= _pairCount); //std::sort(m_pairBuffer, m_pairBuffer + m_pairBufferCount); BufferedPair[] tmp = new BufferedPair[_pairBufferCount]; Array.Copy(_pairBuffer, 0, tmp, 0, _pairBufferCount); Array.Sort <BufferedPair>(tmp, BufferedPairSortPredicate); Array.Copy(tmp, 0, _pairBuffer, 0, _pairBufferCount); for (int i = 0; i < _pairBufferCount; ++i) { if (i > 0) { Box2DXDebug.Assert(Equals(_pairBuffer[i], _pairBuffer[i - 1]) == false); } Pair pair = Find(_pairBuffer[i].ProxyId1, _pairBuffer[i].ProxyId2); Box2DXDebug.Assert(pair.IsBuffered()); Box2DXDebug.Assert(pair.ProxyId1 != pair.ProxyId2); Box2DXDebug.Assert(pair.ProxyId1 < Settings.MaxProxies); Box2DXDebug.Assert(pair.ProxyId2 < Settings.MaxProxies); Proxy proxy1 = _broadPhase._proxyPool[pair.ProxyId1]; Proxy proxy2 = _broadPhase._proxyPool[pair.ProxyId2]; Box2DXDebug.Assert(proxy1.IsValid == true); Box2DXDebug.Assert(proxy2.IsValid == true); } #endif }
// Buffer a pair for removal. public void RemoveBufferedPair(int id1, int id2) { Box2DXDebug.Assert(id1 != PairManager.NullProxy && id2 != PairManager.NullProxy); Box2DXDebug.Assert(_pairBufferCount < Settings.MaxPairs); Pair pair = Find(id1, id2); if (pair == null) { // The pair never existed. This is legal (due to collision filtering). return; } // If this pair is not in the pair buffer ... if (pair.IsBuffered() == false) { // This must be an old pair. Box2DXDebug.Assert(pair.IsFinal() == true); pair.SetBuffered(); _pairBuffer[_pairBufferCount].ProxyId1 = pair.ProxyId1; _pairBuffer[_pairBufferCount].ProxyId2 = pair.ProxyId2; ++_pairBufferCount; Box2DXDebug.Assert(_pairBufferCount <= _pairCount); } pair.SetRemoved(); if (BroadPhase.IsValidate) { ValidateBuffer(); } }
/* * As proxies are created and moved, many pairs are created and destroyed. Even worse, the same * pair may be added and removed multiple times in a single time step of the physics engine. To reduce * traffic in the pair manager, we try to avoid destroying pairs in the pair manager until the * end of the physics step. This is done by buffering all the RemovePair requests. AddPair * requests are processed immediately because we need the hash table entry for quick lookup. * * All user user callbacks are delayed until the buffered pairs are confirmed in Commit. * This is very important because the user callbacks may be very expensive and client logic * may be harmed if pairs are added and removed within the same time step. * * Buffer a pair for addition. * We may add a pair that is not in the pair manager or pair buffer. * We may add a pair that is already in the pair manager and pair buffer. * If the added pair is not a new pair, then it must be in the pair buffer (because RemovePair was called). */ public void AddBufferedPair(int id1, int id2) { Box2DXDebug.Assert(id1 != PairManager.NullProxy && id2 != PairManager.NullProxy); Box2DXDebug.Assert(_pairBufferCount < Settings.MaxPairs); Pair pair = AddPair(id1, id2); // If this pair is not in the pair buffer ... if (pair.IsBuffered() == false) { // This must be a newly added pair. Box2DXDebug.Assert(pair.IsFinal() == false); // Add it to the pair buffer. pair.SetBuffered(); _pairBuffer[_pairBufferCount].ProxyId1 = pair.ProxyId1; _pairBuffer[_pairBufferCount].ProxyId2 = pair.ProxyId2; ++_pairBufferCount; Box2DXDebug.Assert(_pairBufferCount <= _pairCount); } // Confirm this pair for the subsequent call to Commit. pair.ClearRemoved(); if (BroadPhase.IsValidate) { ValidateBuffer(); } }
public void Commit() { int removeCount = 0; Proxy[] proxies = _broadPhase._proxyPool; for (int i = 0; i < _pairBufferCount; ++i) { Pair pair = Find(_pairBuffer[i].ProxyId1, _pairBuffer[i].ProxyId2); Box2DXDebug.Assert(pair.IsBuffered()); pair.ClearBuffered(); Box2DXDebug.Assert(pair.ProxyId1 < Settings.MaxProxies && pair.ProxyId2 < Settings.MaxProxies); Proxy proxy1 = proxies[pair.ProxyId1]; Proxy proxy2 = proxies[pair.ProxyId2]; Box2DXDebug.Assert(proxy1.IsValid); Box2DXDebug.Assert(proxy2.IsValid); if (pair.IsRemoved()) { // It is possible a pair was added then removed before a commit. Therefore, // we should be careful not to tell the user the pair was removed when the // the user didn't receive a matching add. if (pair.IsFinal() == true) { _callback.PairRemoved(proxy1.UserData, proxy2.UserData, pair.UserData); } // Store the ids so we can actually remove the pair below. _pairBuffer[removeCount].ProxyId1 = pair.ProxyId1; _pairBuffer[removeCount].ProxyId2 = pair.ProxyId2; ++removeCount; } else { Box2DXDebug.Assert(_broadPhase.TestOverlap(proxy1, proxy2) == true); if (pair.IsFinal() == false) { pair.UserData = _callback.PairAdded(proxy1.UserData, proxy2.UserData); pair.SetFinal(); } } } for (int i = 0; i < removeCount; ++i) { RemovePair(_pairBuffer[i].ProxyId1, _pairBuffer[i].ProxyId2); } _pairBufferCount = 0; if (BroadPhase.IsValidate) { ValidateTable(); } }
public void Commit() { int num = 0; Proxy[] proxyPool = this._broadPhase._proxyPool; for (int i = 0; i < this._pairBufferCount; i++) { Pair pair = this.Find((int)this._pairBuffer[i].ProxyId1, (int)this._pairBuffer[i].ProxyId2); Box2DXDebug.Assert(pair.IsBuffered()); pair.ClearBuffered(); Box2DXDebug.Assert((int)pair.ProxyId1 < Settings.MaxProxies && (int)pair.ProxyId2 < Settings.MaxProxies); Proxy proxy = proxyPool[(int)pair.ProxyId1]; Proxy proxy2 = proxyPool[(int)pair.ProxyId2]; Box2DXDebug.Assert(proxy.IsValid); Box2DXDebug.Assert(proxy2.IsValid); if (pair.IsRemoved()) { if (pair.IsFinal()) { this._callback.PairRemoved(proxy.UserData, proxy2.UserData, pair.UserData); } this._pairBuffer[num].ProxyId1 = pair.ProxyId1; this._pairBuffer[num].ProxyId2 = pair.ProxyId2; num++; } else { Box2DXDebug.Assert(this._broadPhase.TestOverlap(proxy, proxy2)); if (!pair.IsFinal()) { pair.UserData = this._callback.PairAdded(proxy.UserData, proxy2.UserData); pair.SetFinal(); } } } for (int i = 0; i < num; i++) { this.RemovePair((int)this._pairBuffer[i].ProxyId1, (int)this._pairBuffer[i].ProxyId2); } this._pairBufferCount = 0; if (BroadPhase.IsValidate) { this.ValidateTable(); } }
public void AddBufferedPair(int id1, int id2) { Box2DXDebug.Assert(id1 != (int)PairManager.NullProxy && id2 != (int)PairManager.NullProxy); Box2DXDebug.Assert(this._pairBufferCount < Settings.MaxPairs); Pair pair = this.AddPair(id1, id2); if (!pair.IsBuffered()) { Box2DXDebug.Assert(!pair.IsFinal()); pair.SetBuffered(); this._pairBuffer[this._pairBufferCount].ProxyId1 = pair.ProxyId1; this._pairBuffer[this._pairBufferCount].ProxyId2 = pair.ProxyId2; this._pairBufferCount++; Box2DXDebug.Assert(this._pairBufferCount <= this._pairCount); } pair.ClearRemoved(); if (BroadPhase.IsValidate) { this.ValidateBuffer(); } }
private void ValidateBuffer() { Box2DXDebug.Assert(this._pairBufferCount <= this._pairCount); BufferedPair[] array = new BufferedPair[this._pairBufferCount]; Array.Copy(this._pairBuffer, 0, array, 0, this._pairBufferCount); Array.Sort <BufferedPair>(array, new Comparison <BufferedPair>(PairManager.BufferedPairSortPredicate)); Array.Copy(array, 0, this._pairBuffer, 0, this._pairBufferCount); for (int i = 0; i < this._pairBufferCount; i++) { if (i > 0) { Box2DXDebug.Assert(!object.Equals(this._pairBuffer[i], this._pairBuffer[i - 1])); } Pair pair = this.Find((int)this._pairBuffer[i].ProxyId1, (int)this._pairBuffer[i].ProxyId2); Box2DXDebug.Assert(pair.IsBuffered()); Box2DXDebug.Assert(pair.ProxyId1 != pair.ProxyId2); Box2DXDebug.Assert((int)pair.ProxyId1 < Settings.MaxProxies); Box2DXDebug.Assert((int)pair.ProxyId2 < Settings.MaxProxies); Proxy proxy = this._broadPhase._proxyPool[(int)pair.ProxyId1]; Proxy proxy2 = this._broadPhase._proxyPool[(int)pair.ProxyId2]; Box2DXDebug.Assert(proxy.IsValid); Box2DXDebug.Assert(proxy2.IsValid); } }