/// <summary> /// Update the pairs. This results in pair callbacks. This can only add pairs. /// </summary> /// <param name="callback">The callback.</param> public void UpdatePairs(BroadphaseDelegate <TProxy> callback) { // Reset pair buffer _pairCount = 0; // Perform tree queries for all moving proxies. for (int j = 0; j < _moveCount; ++j) { _queryProxyId = _moveBuffer[j]; if (_queryProxyId == NullProxy) { continue; } // We have to query the tree with the fat AABB so that // we don't fail to create a pair that may touch later. AABB fatAABB = _tree.GetFatAABB(_queryProxyId); // Query tree, create pairs and add them pair buffer. _tree.Query(_queryCallback, ref fatAABB, out _, null); } // Reset move buffer _moveCount = 0; // Sort the pair buffer to expose duplicates. Array.Sort(_pairBuffer, 0, _pairCount); // Send the pairs back to the client. int i = 0; while (i < _pairCount) { Pair primaryPair = _pairBuffer[i]; TProxy userDataA = _tree.GetUserData(primaryPair.ProxyIdA); TProxy userDataB = _tree.GetUserData(primaryPair.ProxyIdB); callback(ref userDataA, ref userDataB); ++i; // Skip any duplicate pairs. while (i < _pairCount) { Pair pair = _pairBuffer[i]; if (pair.ProxyIdA != primaryPair.ProxyIdA || pair.ProxyIdB != primaryPair.ProxyIdB) { break; } ++i; } } // Try to keep the tree balanced. //_tree.Rebalance(4); }
/// <summary> /// Finds all of the overlapping pairs between this DynamicTree and the specified other DynamicTree. /// </summary> public void QueryPairsWith(DynamicTree <T> other, Transform t1, Transform t2, Vector2 displacement, Action <T, T> callback) { if (_nodeCount > other._nodeCount) { other.QueryPairsWith(this, t2, t1, -displacement, callback); return; } _queryPairsCurOtherTree = other; _queryPairsCurCallback = callback; Stack <int> stack = _queryStack.Value; if (_root != NullNode) { stack.Push(_root); } while (stack.Count > 0) { TreeNode <T> node = _nodes[stack.Pop()]; if (node.IsLeaf()) { AABB aabb = node.AABB; // Transform into other coordinate system and predict displacement. AABB.Transform(ref t1, ref aabb); aabb.Displace(displacement); AABB.InvTransform(ref t2, ref aabb); _queryPairsCurUserData = node.UserData; Debug.Assert(((FixtureProxy)(object)_queryPairsCurUserData).Fixture != null); other.Query(_queryPairsOtherQueryCallback, ref aabb, out _, null); } else { if (node.Child1 != NullNode) { stack.Push(node.Child1); } if (node.Child2 != NullNode) { stack.Push(node.Child2); } } } _queryPairsCurOtherTree = null; _queryPairsCurCallback = null; _queryPairsCurUserData = default(T); }