示例#1
0
		// This one is only used for validation.
		internal bool TestOverlap(Proxy p1, Proxy p2)
		{
			for (int axis = 0; axis < 2; ++axis)
			{
				Bound[] bounds = _bounds[axis];

				Box2DXDebug.Assert(p1.LowerBounds[axis] < 2 * _proxyCount);
				Box2DXDebug.Assert(p1.UpperBounds[axis] < 2 * _proxyCount);
				Box2DXDebug.Assert(p2.LowerBounds[axis] < 2 * _proxyCount);
				Box2DXDebug.Assert(p2.UpperBounds[axis] < 2 * _proxyCount);

				if (bounds[p1.LowerBounds[axis]].Value > bounds[p2.UpperBounds[axis]].Value)
					return false;

				if (bounds[p1.UpperBounds[axis]].Value < bounds[p2.LowerBounds[axis]].Value)
					return false;
			}

			return true;
		}
示例#2
0
		internal bool TestOverlap(BoundValues b, Proxy p)
		{
			for (int axis = 0; axis < 2; ++axis)
			{
				Bound[] bounds = _bounds[axis];

				Box2DXDebug.Assert(p.LowerBounds[axis] < 2 * _proxyCount);
				Box2DXDebug.Assert(p.UpperBounds[axis] < 2 * _proxyCount);

				if (b.LowerValues[axis] > bounds[p.UpperBounds[axis]].Value)
					return false;

				if (b.UpperValues[axis] < bounds[p.LowerBounds[axis]].Value)
					return false;
			}

			return true;
		}
示例#3
0
		public void AddProxyResult(ushort proxyId, Proxy proxy, int maxCount, SortKeyFunc sortKey)
		{
			float key = sortKey(proxy.UserData);
			//Filter proxies on positive keys
			if (key < 0)
				return;
			//Merge the new key into the sorted list.
			//float32* p = std::lower_bound(m_querySortKeys,m_querySortKeys+m_queryResultCount,key);
			float[] querySortKeysPtr = _querySortKeys;

			int ip = 0;
			float p = querySortKeysPtr[ip];
			while (p < key && ip < _queryResultCount)
			{
				p = querySortKeysPtr[ip];
				ip++;
			}
			int i = ip;
			if (maxCount == _queryResultCount && i == _queryResultCount)
				return;
			if (maxCount == _queryResultCount)
				_queryResultCount--;
			//std::copy_backward
			for (int j = _queryResultCount + 1; j > i; --j)
			{
				_querySortKeys[j] = _querySortKeys[j - 1];
				_queryResults[j] = _queryResults[j - 1];
			}
			_querySortKeys[i] = key;
			_queryResults[i] = proxyId;
			_queryResultCount++;
		}
示例#4
0
		public BroadPhase(AABB worldAABB, PairCallback callback)
		{
			_pairManager = new PairManager();
			_pairManager.Initialize(this, callback);

			Box2DXDebug.Assert(worldAABB.IsValid);
			_worldAABB = worldAABB;
			_proxyCount = 0;

			Vec2 d = worldAABB.UpperBound - worldAABB.LowerBound;
			_quantizationFactor.X = (float)BROADPHASE_MAX / d.X;
			_quantizationFactor.Y = (float)BROADPHASE_MAX / d.Y;

			for (ushort i = 0; i < Settings.MaxProxies - 1; ++i)
			{
				_proxyPool[i] = new Proxy();
				_proxyPool[i].Next = (ushort)(i + 1);
				_proxyPool[i].TimeStamp = 0;
				_proxyPool[i].OverlapCount = BroadPhase.Invalid;
				_proxyPool[i].UserData = null;
			}
			_proxyPool[Settings.MaxProxies - 1] = new Proxy();
			_proxyPool[Settings.MaxProxies - 1].Next = PairManager.NullProxy;
			_proxyPool[Settings.MaxProxies - 1].TimeStamp = 0;
			_proxyPool[Settings.MaxProxies - 1].OverlapCount = BroadPhase.Invalid;
			_proxyPool[Settings.MaxProxies - 1].UserData = null;
			_freeProxy = 0;

			_timeStamp = 1;
			_queryResultCount = 0;

			for (int i = 0; i < 2; i++)
			{
				_bounds[i] = new Bound[(2 * Settings.MaxProxies)];
			}

			int bCount = 2 * Settings.MaxProxies;
			for (int j = 0; j < 2; j++)
				for (int k = 0; k < bCount; k++)
					_bounds[j][k] = new Bound();
		}
示例#5
0
		public unsafe void AddProxyResult(ushort proxyId, Proxy proxy, int maxCount, SortKeyFunc sortKey)
		{
			float key = sortKey(proxy.UserData);
			//Filter proxies on positive keys
			if (key < 0)
				return;
			//Merge the new key into the sorted list.
			//float32* p = std::lower_bound(m_querySortKeys,m_querySortKeys+m_queryResultCount,key);
			fixed (float* querySortKeysPtr = _querySortKeys)
			{
				float* p = querySortKeysPtr;
				while (*p < key && p < &querySortKeysPtr[_queryResultCount])
					p++;
				int i = (int)(p - &querySortKeysPtr[0]);
				if (maxCount == _queryResultCount && i == _queryResultCount)
					return;
				if (maxCount == _queryResultCount)
					_queryResultCount--;
				//std::copy_backward
				for (int j = _queryResultCount + 1; j > i; --j)
				{
					_querySortKeys[j] = _querySortKeys[j - 1];
					_queryResults[j] = _queryResults[j - 1];
				}
				_querySortKeys[i] = key;
				_queryResults[i] = proxyId;
				_queryResultCount++;
			}
		}
示例#6
0
        int QuerySegment(Segment segment, object[] userData, int maxCount, SortKeyFunc sortKey)
        {
            float maxLambda = 1;

            float dx = (segment.P2.X - segment.P1.X) * _quantizationFactor.X;
            float dy = (segment.P2.Y - segment.P1.Y) * _quantizationFactor.Y;

            int sx = dx < -Settings.FLT_EPSILON ? -1 : (dx > Settings.FLT_EPSILON ? 1 : 0);
            int sy = dy < -Settings.FLT_EPSILON ? -1 : (dy > Settings.FLT_EPSILON ? 1 : 0);

            Box2DXDebug.Assert(sx != 0 || sy != 0);

            float p1x = (segment.P1.X - _worldAABB.LowerBound.X) * _quantizationFactor.X;
            float p1y = (segment.P1.Y - _worldAABB.LowerBound.Y) * _quantizationFactor.Y;

#if ALLOWUNSAFE
            ushort *startValues  = stackalloc ushort[2];
            ushort *startValues2 = stackalloc ushort[2];
#else
            ushort[] startValues  = new ushort[2];
            ushort[] startValues2 = new ushort[2];
#endif

            int xIndex;
            int yIndex;

            ushort proxyId;
            Proxy  proxy;

            // TODO_ERIN implement fast float to ushort conversion.
            startValues[0]  = (ushort)((ushort)(p1x) & (BROADPHASE_MAX - 1));
            startValues2[0] = (ushort)((ushort)(p1x) | 1);

            startValues[1]  = (ushort)((ushort)(p1y) & (BROADPHASE_MAX - 1));
            startValues2[1] = (ushort)((ushort)(p1y) | 1);

            //First deal with all the proxies that contain segment.p1
            int lowerIndex;
            int upperIndex;
            Query(out lowerIndex, out upperIndex, startValues[0], startValues2[0], _bounds[0], 2 * _proxyCount, 0);
            if (sx >= 0)
            {
                xIndex = upperIndex - 1;
            }
            else
            {
                xIndex = lowerIndex;
            }
            Query(out lowerIndex, out upperIndex, startValues[1], startValues2[1], _bounds[1], 2 * _proxyCount, 1);
            if (sy >= 0)
            {
                yIndex = upperIndex - 1;
            }
            else
            {
                yIndex = lowerIndex;
            }

            //If we are using sortKey, then sort what we have so far, filtering negative keys
            if (sortKey != null)
            {
                //Fill keys
                for (int j = 0; j < _queryResultCount; j++)
                {
                    _querySortKeys[j] = sortKey(_proxyPool[_queryResults[j]].UserData);
                }
                //Bubble sort keys
                //Sorting negative values to the top, so we can easily remove them
                int i = 0;
                while (i < _queryResultCount - 1)
                {
                    float a = _querySortKeys[i];
                    float b = _querySortKeys[i + 1];
                    if ((a < 0) ? (b >= 0) : (a > b && b >= 0))
                    {
                        _querySortKeys[i + 1] = a;
                        _querySortKeys[i]     = b;
                        ushort tempValue = _queryResults[i + 1];
                        _queryResults[i + 1] = _queryResults[i];
                        _queryResults[i]     = tempValue;
                        i--;
                        if (i == -1)
                        {
                            i = 1;
                        }
                    }
                    else
                    {
                        i++;
                    }
                }
                //Skim off negative values
                while (_queryResultCount > 0 && _querySortKeys[_queryResultCount - 1] < 0)
                {
                    _queryResultCount--;
                }
            }

            //Now work through the rest of the segment
            for (; ;)
            {
                float xProgress = 0;
                float yProgress = 0;
                if (xIndex < 0 || xIndex >= _proxyCount * 2)
                {
                    break;
                }
                if (yIndex < 0 || yIndex >= _proxyCount * 2)
                {
                    break;
                }
                if (sx != 0)
                {
                    //Move on to the next bound
                    if (sx > 0)
                    {
                        xIndex++;
                        if (xIndex == _proxyCount * 2)
                        {
                            break;
                        }
                    }
                    else
                    {
                        xIndex--;
                        if (xIndex < 0)
                        {
                            break;
                        }
                    }
                    xProgress = (_bounds[0][xIndex].Value - p1x) / dx;
                }
                if (sy != 0)
                {
                    //Move on to the next bound
                    if (sy > 0)
                    {
                        yIndex++;
                        if (yIndex == _proxyCount * 2)
                        {
                            break;
                        }
                    }
                    else
                    {
                        yIndex--;
                        if (yIndex < 0)
                        {
                            break;
                        }
                    }
                    yProgress = (_bounds[1][yIndex].Value - p1y) / dy;
                }
                for (; ;)
                {
                    if (sy == 0 || (sx != 0 && xProgress < yProgress))
                    {
                        if (xProgress > maxLambda)
                        {
                            break;
                        }

                        //Check that we are entering a proxy, not leaving
                        if (sx > 0 ? _bounds[0][xIndex].IsLower : _bounds[0][xIndex].IsUpper)
                        {
                            //Check the other axis of the proxy
                            proxyId = _bounds[0][xIndex].ProxyId;
                            proxy   = _proxyPool[proxyId];
                            if (sy >= 0)
                            {
                                if (proxy.LowerBounds[1] <= yIndex - 1 && proxy.UpperBounds[1] >= yIndex)
                                {
                                    //Add the proxy
                                    if (sortKey != null)
                                    {
                                        AddProxyResult(proxyId, proxy, maxCount, sortKey);
                                    }
                                    else
                                    {
                                        _queryResults[_queryResultCount] = proxyId;
                                        ++_queryResultCount;
                                    }
                                }
                            }
                            else
                            {
                                if (proxy.LowerBounds[1] <= yIndex && proxy.UpperBounds[1] >= yIndex + 1)
                                {
                                    //Add the proxy
                                    if (sortKey != null)
                                    {
                                        AddProxyResult(proxyId, proxy, maxCount, sortKey);
                                    }
                                    else
                                    {
                                        _queryResults[_queryResultCount] = proxyId;
                                        ++_queryResultCount;
                                    }
                                }
                            }
                        }

                        //Early out
                        if (sortKey != null && _queryResultCount == maxCount && _queryResultCount > 0 && xProgress > _querySortKeys[_queryResultCount - 1])
                        {
                            break;
                        }

                        //Move on to the next bound
                        if (sx > 0)
                        {
                            xIndex++;
                            if (xIndex == _proxyCount * 2)
                            {
                                break;
                            }
                        }
                        else
                        {
                            xIndex--;
                            if (xIndex < 0)
                            {
                                break;
                            }
                        }
                        xProgress = (_bounds[0][xIndex].Value - p1x) / dx;
                    }
                    else
                    {
                        if (yProgress > maxLambda)
                        {
                            break;
                        }

                        //Check that we are entering a proxy, not leaving
                        if (sy > 0 ? _bounds[1][yIndex].IsLower : _bounds[1][yIndex].IsUpper)
                        {
                            //Check the other axis of the proxy
                            proxyId = _bounds[1][yIndex].ProxyId;
                            proxy   = _proxyPool[proxyId];
                            if (sx >= 0)
                            {
                                if (proxy.LowerBounds[0] <= xIndex - 1 && proxy.UpperBounds[0] >= xIndex)
                                {
                                    //Add the proxy
                                    if (sortKey != null)
                                    {
                                        AddProxyResult(proxyId, proxy, maxCount, sortKey);
                                    }
                                    else
                                    {
                                        _queryResults[_queryResultCount] = proxyId;
                                        ++_queryResultCount;
                                    }
                                }
                            }
                            else
                            {
                                if (proxy.LowerBounds[0] <= xIndex && proxy.UpperBounds[0] >= xIndex + 1)
                                {
                                    //Add the proxy
                                    if (sortKey != null)
                                    {
                                        AddProxyResult(proxyId, proxy, maxCount, sortKey);
                                    }
                                    else
                                    {
                                        _queryResults[_queryResultCount] = proxyId;
                                        ++_queryResultCount;
                                    }
                                }
                            }
                        }

                        //Early out
                        if (sortKey != null && _queryResultCount == maxCount && _queryResultCount > 0 && yProgress > _querySortKeys[_queryResultCount - 1])
                        {
                            break;
                        }

                        //Move on to the next bound
                        if (sy > 0)
                        {
                            yIndex++;
                            if (yIndex == _proxyCount * 2)
                            {
                                break;
                            }
                        }
                        else
                        {
                            yIndex--;
                            if (yIndex < 0)
                            {
                                break;
                            }
                        }
                        yProgress = (_bounds[1][yIndex].Value - p1y) / dy;
                    }
                }

                break;
            }

            int count = 0;
            for (int i = 0; i < _queryResultCount && count < maxCount; ++i, ++count)
            {
                Box2DXDebug.Assert(_queryResults[i] < Settings.MaxProxies);
                Proxy proxy_ = _proxyPool[_queryResults[i]];
                Box2DXDebug.Assert(proxy_.IsValid);
                userData[i] = proxy_.UserData;
            }

            // Prepare for next query.
            _queryResultCount = 0;
            IncrementTimeStamp();

            return(count);
        }
示例#7
0
        // Call MoveProxy as many times as you like, then when you are done
        // call Commit to finalized the proxy pairs (for your time step).
        public void MoveProxy(int proxyId, AABB aabb)
        {
            if (proxyId == PairManager.NullProxy || Settings.MaxProxies <= proxyId)
            {
                Box2DXDebug.Assert(false);
                return;
            }

            if (aabb.IsValid == false)
            {
                Box2DXDebug.Assert(false);
                return;
            }

            int boundCount = 2 * _proxyCount;

            Proxy proxy = _proxyPool[proxyId];

            // Get new bound values
            BoundValues newValues = new BoundValues();;

            ComputeBounds(out newValues.LowerValues, out newValues.UpperValues, aabb);

            // Get old bound values
            BoundValues oldValues = new BoundValues();

            for (int axis = 0; axis < 2; ++axis)
            {
                oldValues.LowerValues[axis] = _bounds[axis][proxy.LowerBounds[axis]].Value;
                oldValues.UpperValues[axis] = _bounds[axis][proxy.UpperBounds[axis]].Value;
            }

            for (int axis = 0; axis < 2; ++axis)
            {
                Bound[] bounds = _bounds[axis];

                int lowerIndex = proxy.LowerBounds[axis];
                int upperIndex = proxy.UpperBounds[axis];

                ushort lowerValue = newValues.LowerValues[axis];
                ushort upperValue = newValues.UpperValues[axis];

                int deltaLower = lowerValue - bounds[lowerIndex].Value;
                int deltaUpper = upperValue - bounds[upperIndex].Value;

                bounds[lowerIndex].Value = lowerValue;
                bounds[upperIndex].Value = upperValue;

                //
                // Expanding adds overlaps
                //

                // Should we move the lower bound down?
                if (deltaLower < 0)
                {
                    int index = lowerIndex;
                    while (index > 0 && lowerValue < bounds[index - 1].Value)
                    {
                        Bound bound     = bounds[index];
                        Bound prevBound = bounds[index - 1];

                        int   prevProxyId = prevBound.ProxyId;
                        Proxy prevProxy   = _proxyPool[prevBound.ProxyId];

                        ++prevBound.StabbingCount;

                        if (prevBound.IsUpper == true)
                        {
                            if (TestOverlap(newValues, prevProxy))
                            {
                                _pairManager.AddBufferedPair(proxyId, prevProxyId);
                            }

                            ++prevProxy.UpperBounds[axis];
                            ++bound.StabbingCount;
                        }
                        else
                        {
                            ++prevProxy.LowerBounds[axis];
                            --bound.StabbingCount;
                        }

                        --proxy.LowerBounds[axis];
                        Common.Math.Swap <Bound>(ref bounds[index], ref bounds[index - 1]);
                        --index;
                    }
                }

                // Should we move the upper bound up?
                if (deltaUpper > 0)
                {
                    int index = upperIndex;
                    while (index < boundCount - 1 && bounds[index + 1].Value <= upperValue)
                    {
                        Bound bound       = bounds[index];
                        Bound nextBound   = bounds[index + 1];
                        int   nextProxyId = nextBound.ProxyId;
                        Proxy nextProxy   = _proxyPool[nextProxyId];

                        ++nextBound.StabbingCount;

                        if (nextBound.IsLower == true)
                        {
                            if (TestOverlap(newValues, nextProxy))
                            {
                                _pairManager.AddBufferedPair(proxyId, nextProxyId);
                            }

                            --nextProxy.LowerBounds[axis];
                            ++bound.StabbingCount;
                        }
                        else
                        {
                            --nextProxy.UpperBounds[axis];
                            --bound.StabbingCount;
                        }

                        ++proxy.UpperBounds[axis];
                        Common.Math.Swap <Bound>(ref bounds[index], ref bounds[index + 1]);
                        ++index;
                    }
                }

                //
                // Shrinking removes overlaps
                //

                // Should we move the lower bound up?
                if (deltaLower > 0)
                {
                    int index = lowerIndex;
                    while (index < boundCount - 1 && bounds[index + 1].Value <= lowerValue)
                    {
                        Bound bound     = bounds[index];
                        Bound nextBound = bounds[index + 1];

                        int   nextProxyId = nextBound.ProxyId;
                        Proxy nextProxy   = _proxyPool[nextProxyId];

                        --nextBound.StabbingCount;

                        if (nextBound.IsUpper)
                        {
                            if (TestOverlap(oldValues, nextProxy))
                            {
                                _pairManager.RemoveBufferedPair(proxyId, nextProxyId);
                            }

                            --nextProxy.UpperBounds[axis];
                            --bound.StabbingCount;
                        }
                        else
                        {
                            --nextProxy.LowerBounds[axis];
                            ++bound.StabbingCount;
                        }

                        ++proxy.LowerBounds[axis];
                        Common.Math.Swap <Bound>(ref bounds[index], ref bounds[index + 1]);
                        ++index;
                    }
                }

                // Should we move the upper bound down?
                if (deltaUpper < 0)
                {
                    int index = upperIndex;
                    while (index > 0 && upperValue < bounds[index - 1].Value)
                    {
                        Bound bound     = bounds[index];
                        Bound prevBound = bounds[index - 1];

                        int   prevProxyId = prevBound.ProxyId;
                        Proxy prevProxy   = _proxyPool[prevProxyId];

                        --prevBound.StabbingCount;

                        if (prevBound.IsLower == true)
                        {
                            if (TestOverlap(oldValues, prevProxy))
                            {
                                _pairManager.RemoveBufferedPair(proxyId, prevProxyId);
                            }

                            ++prevProxy.LowerBounds[axis];
                            --bound.StabbingCount;
                        }
                        else
                        {
                            ++prevProxy.UpperBounds[axis];
                            ++bound.StabbingCount;
                        }

                        --proxy.UpperBounds[axis];
                        Common.Math.Swap <Bound>(ref bounds[index], ref bounds[index - 1]);
                        --index;
                    }
                }
            }

            if (IsValidate)
            {
                Validate();
            }
        }
示例#8
0
        public void DestroyProxy(int proxyId)
        {
            Box2DXDebug.Assert(0 < _proxyCount && _proxyCount <= Settings.MaxProxies);
            Proxy proxy = _proxyPool[proxyId];

            Box2DXDebug.Assert(proxy.IsValid);

            int boundCount = 2 * _proxyCount;

            for (int axis = 0; axis < 2; ++axis)
            {
                Bound[] bounds = _bounds[axis];

                int    lowerIndex = proxy.LowerBounds[axis];
                int    upperIndex = proxy.UpperBounds[axis];
                ushort lowerValue = bounds[lowerIndex].Value;
                ushort upperValue = bounds[upperIndex].Value;

#warning "Check this"
                //memmove(bounds + lowerIndex, bounds + lowerIndex + 1, (upperIndex - lowerIndex - 1) * sizeof(b2Bound));
                Bound[] tmp = new Bound[upperIndex - lowerIndex - 1];
                for (int i = 0; i < (upperIndex - lowerIndex - 1); i++)
                {
                    tmp[i] = bounds[lowerIndex + 1 + i].Clone();
                }
                for (int i = 0; i < (upperIndex - lowerIndex - 1); i++)
                {
                    bounds[lowerIndex + i] = tmp[i];
                }

                //memmove(bounds + upperIndex - 1, bounds + upperIndex + 1, (boundCount - upperIndex - 1) * sizeof(b2Bound));
                tmp = new Bound[boundCount - upperIndex - 1];
                for (int i = 0; i < (boundCount - upperIndex - 1); i++)
                {
                    tmp[i] = bounds[upperIndex + 1 + i].Clone();
                }
                for (int i = 0; i < (boundCount - upperIndex - 1); i++)
                {
                    bounds[upperIndex - 1 + i] = tmp[i];
                }

                // Fix bound indices.
                for (int index = lowerIndex; index < boundCount - 2; ++index)
                {
                    Proxy proxy_ = _proxyPool[bounds[index].ProxyId];
                    if (bounds[index].IsLower)
                    {
                        proxy_.LowerBounds[axis] = (ushort)index;
                    }
                    else
                    {
                        proxy_.UpperBounds[axis] = (ushort)index;
                    }
                }

                // Fix stabbing count.
                for (int index = lowerIndex; index < upperIndex - 1; ++index)
                {
                    --bounds[index].StabbingCount;
                }

                // Query for pairs to be removed. lowerIndex and upperIndex are not needed.
                Query(out lowerIndex, out upperIndex, lowerValue, upperValue, bounds, boundCount - 2, axis);
            }

            Box2DXDebug.Assert(_queryResultCount < Settings.MaxProxies);

            for (int i = 0; i < _queryResultCount; ++i)
            {
                Box2DXDebug.Assert(_proxyPool[_queryResults[i]].IsValid);
                _pairManager.RemoveBufferedPair(proxyId, _queryResults[i]);
            }

            _pairManager.Commit();

            // Prepare for next query.
            _queryResultCount = 0;
            IncrementTimeStamp();

            // Return the proxy to the pool.
            proxy.UserData       = null;
            proxy.OverlapCount   = BroadPhase.Invalid;
            proxy.LowerBounds[0] = BroadPhase.Invalid;
            proxy.LowerBounds[1] = BroadPhase.Invalid;
            proxy.UpperBounds[0] = BroadPhase.Invalid;
            proxy.UpperBounds[1] = BroadPhase.Invalid;

            proxy.Next = _freeProxy;
            _freeProxy = (ushort)proxyId;
            --_proxyCount;

            if (IsValidate)
            {
                Validate();
            }
        }
示例#9
0
        // Create and destroy proxies. These call Flush first.
        public ushort CreateProxy(AABB aabb, object userData)
        {
            Box2DXDebug.Assert(_proxyCount < Settings.MaxProxies);
            Box2DXDebug.Assert(_freeProxy != PairManager.NullProxy);

            ushort proxyId = _freeProxy;
            Proxy  proxy   = _proxyPool[proxyId];

            _freeProxy = proxy.Next;

            proxy.OverlapCount = 0;
            proxy.UserData     = userData;

            int boundCount = 2 * _proxyCount;

            ushort[] lowerValues = new ushort[2], upperValues = new ushort[2];
            ComputeBounds(out lowerValues, out upperValues, aabb);

            for (int axis = 0; axis < 2; ++axis)
            {
                Bound[] bounds = _bounds[axis];
                int     lowerIndex, upperIndex;
                Query(out lowerIndex, out upperIndex, lowerValues[axis], upperValues[axis], bounds, boundCount, axis);

#warning "Check this"
                //memmove(bounds + upperIndex + 2, bounds + upperIndex, (boundCount - upperIndex) * sizeof(b2Bound));
                Bound[] tmp = new Bound[boundCount - upperIndex];
                for (int i = 0; i < (boundCount - upperIndex); i++)
                {
                    tmp[i] = bounds[upperIndex + i].Clone();
                }
                for (int i = 0; i < (boundCount - upperIndex); i++)
                {
                    bounds[upperIndex + 2 + i] = tmp[i];
                }

                //memmove(bounds + lowerIndex + 1, bounds + lowerIndex, (upperIndex - lowerIndex) * sizeof(b2Bound));
                tmp = new Bound[upperIndex - lowerIndex];
                for (int i = 0; i < (upperIndex - lowerIndex); i++)
                {
                    tmp[i] = bounds[lowerIndex + i].Clone();
                }
                for (int i = 0; i < (upperIndex - lowerIndex); i++)
                {
                    bounds[lowerIndex + 1 + i] = tmp[i];
                }

                // The upper index has increased because of the lower bound insertion.
                ++upperIndex;

                // Copy in the new bounds.
                bounds[lowerIndex].Value   = lowerValues[axis];
                bounds[lowerIndex].ProxyId = proxyId;
                bounds[upperIndex].Value   = upperValues[axis];
                bounds[upperIndex].ProxyId = proxyId;

                bounds[lowerIndex].StabbingCount = lowerIndex == 0 ? (ushort)0 : bounds[lowerIndex - 1].StabbingCount;
                bounds[upperIndex].StabbingCount = bounds[upperIndex - 1].StabbingCount;

                // Adjust the stabbing count between the new bounds.
                for (int index = lowerIndex; index < upperIndex; ++index)
                {
                    ++bounds[index].StabbingCount;
                }

                // Adjust the all the affected bound indices.
                for (int index = lowerIndex; index < boundCount + 2; ++index)
                {
                    Proxy proxy_ = _proxyPool[bounds[index].ProxyId];
                    if (bounds[index].IsLower)
                    {
                        proxy_.LowerBounds[axis] = (ushort)index;
                    }
                    else
                    {
                        proxy_.UpperBounds[axis] = (ushort)index;
                    }
                }
            }

            ++_proxyCount;

            Box2DXDebug.Assert(_queryResultCount < Settings.MaxProxies);

            // Create pairs if the AABB is in range.
            for (int i = 0; i < _queryResultCount; ++i)
            {
                Box2DXDebug.Assert(_queryResults[i] < Settings.MaxProxies);
                Box2DXDebug.Assert(_proxyPool[_queryResults[i]].IsValid);

                _pairManager.AddBufferedPair(proxyId, _queryResults[i]);
            }

            _pairManager.Commit();

            if (IsValidate)
            {
                Validate();
            }

            // Prepare for next query.
            _queryResultCount = 0;
            IncrementTimeStamp();

            return(proxyId);
        }