Esempio n. 1
0
        /// <summary>
        ///     Describes whether this instance test overlap
        /// </summary>
        /// <param name="b">The </param>
        /// <param name="p">The </param>
        /// <returns>The bool</returns>
        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);
        }
Esempio n. 2
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).
        /// <summary>
        ///     Moves the proxy using the specified proxy id
        /// </summary>
        /// <param name="proxyId">The proxy id</param>
        /// <param name="aabb">The aabb</param>
        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 proxy1 = 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][proxy1.LowerBounds[axis]].Value;
                oldValues.UpperValues[axis] = Bounds[axis][proxy1.UpperBounds[axis]].Value;
            }

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

                int lowerIndex = proxy1.LowerBounds[axis];
                int upperIndex = proxy1.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)
                        {
                            if (TestOverlap(newValues, prevProxy))
                            {
                                PairManager.AddBufferedPair(proxyId, prevProxyId);
                            }

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

                        --proxy1.LowerBounds[axis];
                        Math.Swap(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)
                        {
                            if (TestOverlap(newValues, nextProxy))
                            {
                                PairManager.AddBufferedPair(proxyId, nextProxyId);
                            }

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

                        ++proxy1.UpperBounds[axis];
                        Math.Swap(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;
                        }

                        ++proxy1.LowerBounds[axis];
                        Math.Swap(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)
                        {
                            if (TestOverlap(oldValues, prevProxy))
                            {
                                PairManager.RemoveBufferedPair(proxyId, prevProxyId);
                            }

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

                        --proxy1.UpperBounds[axis];
                        Math.Swap(ref bounds[index], ref bounds[index - 1]);
                        --index;
                    }
                }
            }

            if (IsValidate)
            {
                Validate();
            }
        }