Пример #1
0
 public void GetAABB(out AABB aabb, int childIndex)
 {
     Debug.Assert(0 <= childIndex && childIndex < this.ProxyCount);
     aabb = this.Proxies[childIndex].AABB;
 }
Пример #2
0
 /// <summary>
 /// Given a transform, compute the associated axis aligned bounding box for a child shape.
 /// </summary>
 /// <param name="aabb">The aabb results.</param>
 /// <param name="transform">The world transform of the shape.</param>
 /// <param name="childIndex">The child shape index.</param>
 public abstract void ComputeAABB(out AABB aabb, ref Transform transform, int childIndex);
Пример #3
0
        public void RebuildBottomUp()
        {
            int[] array = new int[this._nodeCount];
            int   i     = 0;

            for (int j = 0; j < this._nodeCapacity; j++)
            {
                bool flag = this._nodes[j].Height < 0;
                if (!flag)
                {
                    bool flag2 = this._nodes[j].IsLeaf();
                    if (flag2)
                    {
                        this._nodes[j].ParentOrNext = -1;
                        array[i] = j;
                        i++;
                    }
                    else
                    {
                        this.FreeNode(j);
                    }
                }
            }
            while (i > 1)
            {
                FP  y    = Settings.MaxFP;
                int num  = -1;
                int num2 = -1;
                for (int k = 0; k < i; k++)
                {
                    AABB aABB = this._nodes[array[k]].AABB;
                    for (int l = k + 1; l < i; l++)
                    {
                        AABB aABB2 = this._nodes[array[l]].AABB;
                        AABB aABB3 = default(AABB);
                        aABB3.Combine(ref aABB, ref aABB2);
                        FP   perimeter = aABB3.Perimeter;
                        bool flag3     = perimeter < y;
                        if (flag3)
                        {
                            num  = k;
                            num2 = l;
                            y    = perimeter;
                        }
                    }
                }
                int          num3      = array[num];
                int          num4      = array[num2];
                TreeNode <T> treeNode  = this._nodes[num3];
                TreeNode <T> treeNode2 = this._nodes[num4];
                int          num5      = this.AllocateNode();
                TreeNode <T> treeNode3 = this._nodes[num5];
                treeNode3.Child1 = num3;
                treeNode3.Child2 = num4;
                treeNode3.Height = 1 + Math.Max(treeNode.Height, treeNode2.Height);
                treeNode3.AABB.Combine(ref treeNode.AABB, ref treeNode2.AABB);
                treeNode3.ParentOrNext = -1;
                treeNode.ParentOrNext  = num5;
                treeNode2.ParentOrNext = num5;
                array[num2]            = array[i - 1];
                array[num]             = num5;
                i--;
            }
            this._root = array[0];
            this.Validate();
        }
Пример #4
0
        private void InsertLeaf(int leaf)
        {
            bool flag = this._root == -1;

            if (flag)
            {
                this._root = leaf;
                this._nodes[this._root].ParentOrNext = -1;
            }
            else
            {
                AABB aABB = this._nodes[leaf].AABB;
                int  num  = this._root;
                while (!this._nodes[num].IsLeaf())
                {
                    int  child     = this._nodes[num].Child1;
                    int  child2    = this._nodes[num].Child2;
                    FP   perimeter = this._nodes[num].AABB.Perimeter;
                    AABB aABB2     = default(AABB);
                    aABB2.Combine(ref this._nodes[num].AABB, ref aABB);
                    FP   perimeter2 = aABB2.Perimeter;
                    FP   x          = 2f * perimeter2;
                    FP   y          = 2f * (perimeter2 - perimeter);
                    bool flag2      = this._nodes[child].IsLeaf();
                    FP   fP;
                    if (flag2)
                    {
                        AABB aABB3 = default(AABB);
                        aABB3.Combine(ref aABB, ref this._nodes[child].AABB);
                        fP = aABB3.Perimeter + y;
                    }
                    else
                    {
                        AABB aABB4 = default(AABB);
                        aABB4.Combine(ref aABB, ref this._nodes[child].AABB);
                        FP perimeter3 = this._nodes[child].AABB.Perimeter;
                        FP perimeter4 = aABB4.Perimeter;
                        fP = perimeter4 - perimeter3 + y;
                    }
                    bool flag3 = this._nodes[child2].IsLeaf();
                    FP   y2;
                    if (flag3)
                    {
                        AABB aABB5 = default(AABB);
                        aABB5.Combine(ref aABB, ref this._nodes[child2].AABB);
                        y2 = aABB5.Perimeter + y;
                    }
                    else
                    {
                        AABB aABB6 = default(AABB);
                        aABB6.Combine(ref aABB, ref this._nodes[child2].AABB);
                        FP perimeter5 = this._nodes[child2].AABB.Perimeter;
                        FP perimeter6 = aABB6.Perimeter;
                        y2 = perimeter6 - perimeter5 + y;
                    }
                    bool flag4 = x < fP && fP < y2;
                    if (flag4)
                    {
                        break;
                    }
                    bool flag5 = fP < y2;
                    if (flag5)
                    {
                        num = child;
                    }
                    else
                    {
                        num = child2;
                    }
                }
                int num2         = num;
                int parentOrNext = this._nodes[num2].ParentOrNext;
                int num3         = this.AllocateNode();
                this._nodes[num3].ParentOrNext = parentOrNext;
                this._nodes[num3].UserData     = default(T);
                this._nodes[num3].AABB.Combine(ref aABB, ref this._nodes[num2].AABB);
                this._nodes[num3].Height = this._nodes[num2].Height + 1;
                bool flag6 = parentOrNext != -1;
                if (flag6)
                {
                    bool flag7 = this._nodes[parentOrNext].Child1 == num2;
                    if (flag7)
                    {
                        this._nodes[parentOrNext].Child1 = num3;
                    }
                    else
                    {
                        this._nodes[parentOrNext].Child2 = num3;
                    }
                    this._nodes[num3].Child1       = num2;
                    this._nodes[num3].Child2       = leaf;
                    this._nodes[num2].ParentOrNext = num3;
                    this._nodes[leaf].ParentOrNext = num3;
                }
                else
                {
                    this._nodes[num3].Child1       = num2;
                    this._nodes[num3].Child2       = leaf;
                    this._nodes[num2].ParentOrNext = num3;
                    this._nodes[leaf].ParentOrNext = num3;
                    this._root = num3;
                }
                for (num = this._nodes[leaf].ParentOrNext; num != -1; num = this._nodes[num].ParentOrNext)
                {
                    num = this.Balance(num);
                    int child3 = this._nodes[num].Child1;
                    int child4 = this._nodes[num].Child2;
                    Debug.Assert(child3 != -1);
                    Debug.Assert(child4 != -1);
                    this._nodes[num].Height = 1 + Math.Max(this._nodes[child3].Height, this._nodes[child4].Height);
                    this._nodes[num].AABB.Combine(ref this._nodes[child3].AABB, ref this._nodes[child4].AABB);
                }
            }
        }
Пример #5
0
        public void RayCast(Func <RayCastInput, int, FP> callback, ref RayCastInput input)
        {
            TSVector2 point    = input.Point1;
            TSVector2 point2   = input.Point2;
            TSVector2 tSVector = point2 - point;

            Debug.Assert(tSVector.LengthSquared() > 0f);
            tSVector.Normalize();
            TSVector2 value     = MathUtils.Abs(new TSVector2(-tSVector.y, tSVector.x));
            FP        fP        = input.MaxFraction;
            AABB      aABB      = default(AABB);
            TSVector2 tSVector2 = point + fP * (point2 - point);

            TSVector2.Min(ref point, ref tSVector2, out aABB.LowerBound);
            TSVector2.Max(ref point, ref tSVector2, out aABB.UpperBound);
            this._raycastStack.Clear();
            this._raycastStack.Push(this._root);
            while (this._raycastStack.Count > 0)
            {
                int  num  = this._raycastStack.Pop();
                bool flag = num == -1;
                if (!flag)
                {
                    TreeNode <T> treeNode = this._nodes[num];
                    bool         flag2    = !AABB.TestOverlap(ref treeNode.AABB, ref aABB);
                    if (!flag2)
                    {
                        TSVector2 center  = treeNode.AABB.Center;
                        TSVector2 extents = treeNode.AABB.Extents;
                        FP        x       = FP.Abs(TSVector2.Dot(new TSVector2(-tSVector.y, tSVector.x), point - center)) - TSVector2.Dot(value, extents);
                        bool      flag3   = x > 0f;
                        if (!flag3)
                        {
                            bool flag4 = treeNode.IsLeaf();
                            if (flag4)
                            {
                                RayCastInput arg;
                                arg.Point1      = input.Point1;
                                arg.Point2      = input.Point2;
                                arg.MaxFraction = fP;
                                FP   fP2   = callback(arg, num);
                                bool flag5 = fP2 == 0f;
                                if (flag5)
                                {
                                    break;
                                }
                                bool flag6 = fP2 > 0f;
                                if (flag6)
                                {
                                    fP = fP2;
                                    TSVector2 value2 = point + fP * (point2 - point);
                                    aABB.LowerBound = TSVector2.Min(point, value2);
                                    aABB.UpperBound = TSVector2.Max(point, value2);
                                }
                            }
                            else
                            {
                                this._raycastStack.Push(treeNode.Child1);
                                this._raycastStack.Push(treeNode.Child2);
                            }
                        }
                    }
                }
            }
        }
Пример #6
0
 public void GetFatAABB(int proxyId, out AABB fatAABB)
 {
     Debug.Assert(0 <= proxyId && proxyId < this._nodeCapacity);
     fatAABB = this._nodes[proxyId].AABB;
 }