Example #1
0
 public override b2AABB ComputeAABB(b2Transform transform, int childIndex)
 {
     b2Vec2 p = transform.p + b2Math.b2Mul(transform.q, m_p);
     b2AABB aabb = new b2AABB();
     aabb.lowerBound.Set(p.x - m_radius, p.y - m_radius);
     aabb.upperBound.Set(p.x + m_radius, p.y + m_radius);
     return (aabb);
 }
Example #2
0
 /// Combine an AABB into this one.
 public void Combine(ref b2AABB aabb)
 {
     lowerBound = Utils.b2Min(lowerBound, aabb.lowerBound);
     upperBound = Utils.b2Max(upperBound, aabb.upperBound);
 }
Example #3
0
        public override void ComputeAABB(out b2AABB output, ref b2Transform xf, int childIndex)
        {
            b2Vec2 v1;
            v1.x = (xf.q.c * Vertex1.x - xf.q.s * Vertex1.y) + xf.p.x;
            v1.y = (xf.q.s * Vertex1.x + xf.q.c * Vertex1.y) + xf.p.y;

            b2Vec2 v2;
            v2.x = (xf.q.c * Vertex2.x - xf.q.s * Vertex2.y) + xf.p.x;
            v2.y = (xf.q.s * Vertex2.x + xf.q.c * Vertex2.y) + xf.p.y;

            b2Vec2 lower;
            lower.x = v1.x < v2.x ? v1.x : v2.x;
            lower.y = v1.y < v2.y ? v1.y : v2.y;
            
            //b2Math.b2Min(v1, v2);
            b2Vec2 upper;
            upper.x = v1.x > v2.x ? v1.x : v2.x;
            upper.y = v1.y > v2.y ? v1.y : v2.y; 
            // = b2Math.b2Max(v1, v2);

            output.LowerBound = lower;
            output.UpperBound = upper;
            output.Fatten(Radius);
        }
Example #4
0
	/**
	* Given a transform, compute the associated axis aligned bounding box for this shape.
	* @param aabb returns the axis aligned box.
	* @param xf the world transform of the shape.
	*/
	virtual public void ComputeAABB(b2AABB aabb, b2Transform xf) {}
Example #5
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2AABB obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
Example #6
0
        public override b2AABB ComputeAABB(b2Transform xf, int childIndex)
        {
            b2Vec2 v1 = b2Math.b2Mul(xf, m_vertex1);
            b2Vec2 v2 = b2Math.b2Mul(xf, m_vertex2);

            b2Vec2 lower = b2Math.b2Min(v1, v2);
            b2Vec2 upper = b2Math.b2Max(v1, v2);

            b2Vec2 r = new b2Vec2(m_radius, m_radius);
            b2AABB aabb = new b2AABB();
            aabb.lowerBound = lower - r;
            aabb.upperBound = upper + r;
            return(aabb);
        }
Example #7
0
        public override void ComputeAABB(out b2AABB output, ref b2Transform xf, int childIndex)
        {
#if false
            b2Vec2 lower = b2Math.b2Mul(ref xf, ref Vertices[0]);
            b2Vec2 upper = lower;

            for (int i = 1; i < m_vertexCount; ++i)
            {
                b2Vec2 v = b2Math.b2Mul(ref xf, ref Vertices[i]);
                lower = b2Math.b2Min(lower, v);
                upper = b2Math.b2Max(upper, v);
            }

            b2AABB aabb = b2AABB.Default;
            aabb.Set(lower, upper);
            aabb.Fatten(Radius);
            return(aabb);
#else
            var vert = Vertices[0];
            b2Vec2 lower;
            lower.x = (xf.q.c * vert.x - xf.q.s * vert.y) + xf.p.x;
            lower.y = (xf.q.s * vert.x + xf.q.c * vert.y) + xf.p.y;
            b2Vec2 upper = lower;

            for (int i = 1; i < m_vertexCount; ++i)
            {
                var vetr2 = Vertices[i];
                b2Vec2 v;
                v.x = (xf.q.c * vetr2.x - xf.q.s * vetr2.y) + xf.p.x;
                v.y = (xf.q.s * vetr2.x + xf.q.c * vetr2.y) + xf.p.y;

                lower.x = Math.Min(lower.x, v.x);
                lower.y = Math.Min(lower.y, v.y);
                upper.x = Math.Max(upper.x, v.x);
                upper.y = Math.Max(upper.y, v.y);
            }

            output.LowerBound = lower;
            output.UpperBound = upper;
            output.Fatten(Radius);
#endif
        }
Example #8
0
 /// Given a transform, compute the associated axis aligned bounding box for a child shape.
 /// @param aabb returns the axis aligned box.
 /// @param xf the world transform of the shape.
 /// @param childIndex the child shape
 public abstract void ComputeAABB(out b2AABB output, ref b2Transform xf, int childIndex);
Example #9
0
 /// Given a transform, compute the associated axis aligned bounding box for a child shape.
 /// @param aabb returns the axis aligned box.
 /// @param xf the world transform of the shape.
 /// @param childIndex the child shape
 public abstract void ComputeAABB(ref b2AABB aabb, b2Transform xf, int childIndex);
Example #10
0
    private void InsertLeaf(int leaf)
    {
        ++m_insertionCount;

        if (m_root == Settings.b2_nullNode)
        {
            m_root = leaf;
            m_nodes[m_root].parentOrNext = Settings.b2_nullNode;
            return;
        }

        // Find the best sibling for this node
        b2AABB leafAABB = m_nodes[leaf].aabb;
        int    index    = m_root;

        while (m_nodes[index].IsLeaf() == false)
        {
            int child1 = m_nodes[index].child1;
            int child2 = m_nodes[index].child2;

            float area = m_nodes[index].aabb.GetPerimeter();

            b2AABB combinedAABB = new b2AABB();
            combinedAABB.Combine(ref m_nodes[index].aabb, ref leafAABB);
            float combinedArea = combinedAABB.GetPerimeter();

            // Cost of creating a new parentOrNext for this node and the new leaf
            float cost = 2.0f * combinedArea;

            // Minimum cost of pushing the leaf further down the tree
            float inheritanceCost = 2.0f * (combinedArea - area);

            // Cost of descending into child1
            float cost1;
            if (m_nodes[child1].IsLeaf())
            {
                b2AABB aabb = new b2AABB();
                aabb.Combine(ref leafAABB, ref m_nodes[child1].aabb);
                cost1 = aabb.GetPerimeter() + inheritanceCost;
            }
            else
            {
                b2AABB aabb = new b2AABB();
                aabb.Combine(ref leafAABB, ref m_nodes[child1].aabb);
                float oldArea = m_nodes[child1].aabb.GetPerimeter();
                float newArea = aabb.GetPerimeter();
                cost1 = (newArea - oldArea) + inheritanceCost;
            }

            // Cost of descending into child2
            float cost2;
            if (m_nodes[child2].IsLeaf())
            {
                b2AABB aabb = new b2AABB();
                aabb.Combine(ref leafAABB, ref m_nodes[child2].aabb);
                cost2 = aabb.GetPerimeter() + inheritanceCost;
            }
            else
            {
                b2AABB aabb = new b2AABB();
                aabb.Combine(ref leafAABB, ref m_nodes[child2].aabb);
                float oldArea = m_nodes[child2].aabb.GetPerimeter();
                float newArea = aabb.GetPerimeter();
                cost2 = newArea - oldArea + inheritanceCost;
            }

            // Descend according to the minimum cost.
            if (cost < cost1 && cost < cost2)
            {
                break;
            }

            // Descend
            if (cost1 < cost2)
            {
                index = child1;
            }
            else
            {
                index = child2;
            }
        }

        int sibling = index;

        // Create a new parentOrNext.
        int oldParent = m_nodes[sibling].parentOrNext;
        int newParent = AllocateNode();

        m_nodes[newParent].parentOrNext = oldParent;
        m_nodes[newParent].userData     = null;
        m_nodes[newParent].aabb.Combine(ref leafAABB, ref m_nodes[sibling].aabb);
        m_nodes[newParent].height = m_nodes[sibling].height + 1;

        if (oldParent != Settings.b2_nullNode)
        {
            // The sibling was not the root.
            if (m_nodes[oldParent].child1 == sibling)
            {
                m_nodes[oldParent].child1 = newParent;
            }
            else
            {
                m_nodes[oldParent].child2 = newParent;
            }

            m_nodes[newParent].child1     = sibling;
            m_nodes[newParent].child2     = leaf;
            m_nodes[sibling].parentOrNext = newParent;
            m_nodes[leaf].parentOrNext    = newParent;
        }
        else
        {
            // The sibling was the root.
            m_nodes[newParent].child1     = sibling;
            m_nodes[newParent].child2     = leaf;
            m_nodes[sibling].parentOrNext = newParent;
            m_nodes[leaf].parentOrNext    = newParent;
            m_root = newParent;
        }

        // Walk back up the tree fixing heights and AABBs
        index = m_nodes[leaf].parentOrNext;
        while (index != Settings.b2_nullNode)
        {
            index = Balance(index);

            int child1 = m_nodes[index].child1;
            int child2 = m_nodes[index].child2;

            Debug.Assert(child1 != Settings.b2_nullNode);
            Debug.Assert(child2 != Settings.b2_nullNode);

            m_nodes[index].height = 1 + Utils.b2Max(m_nodes[child1].height, m_nodes[child2].height);
            m_nodes[index].aabb.Combine(ref m_nodes[child1].aabb, ref m_nodes[child2].aabb);

            index = m_nodes[index].parentOrNext;
        }

        //Validate();
    }
Example #11
0
    /// Build an optimal tree. Very expensive. For testing.
    public void RebuildBottomUp()
    {
        int[] nodes = new int[m_nodeCount];
        int   count = 0;

        // Build array of leaves. Free the rest.
        for (int i = 0; i < m_nodeCapacity; ++i)
        {
            if (m_nodes[i].height < 0)
            {
                // free node in pool
                continue;
            }

            if (m_nodes[i].IsLeaf())
            {
                m_nodes[i].parentOrNext = Settings.b2_nullNode;
                nodes[count]            = i;
                ++count;
            }
            else
            {
                FreeNode(i);
            }
        }

        while (count > 1)
        {
            float minCost = float.MaxValue;
            int   iMin    = -1;
            int   jMin    = -1;
            for (int i = 0; i < count; ++i)
            {
                b2AABB aabbi = m_nodes[nodes[i]].aabb;

                for (int j = i + 1; j < count; ++j)
                {
                    b2AABB aabbj = m_nodes[nodes[j]].aabb;
                    b2AABB b     = new b2AABB();
                    b.Combine(ref aabbi, ref aabbj);
                    float cost = b.GetPerimeter();
                    if (cost < minCost)
                    {
                        iMin    = i;
                        jMin    = j;
                        minCost = cost;
                    }
                }
            }

            int        index1 = nodes[iMin];
            int        index2 = nodes[jMin];
            b2TreeNode child1 = m_nodes[index1];
            b2TreeNode child2 = m_nodes[index2];

            int        parentIndex  = AllocateNode();
            b2TreeNode parentOrNext = m_nodes[parentIndex];
            parentOrNext.child1 = index1;
            parentOrNext.child2 = index2;
            parentOrNext.height = 1 + Utils.b2Max(child1.height, child2.height);
            parentOrNext.aabb.Combine(ref child1.aabb, ref child2.aabb);
            parentOrNext.parentOrNext = Settings.b2_nullNode;

            child1.parentOrNext = parentIndex;
            child2.parentOrNext = parentIndex;

            nodes[jMin] = nodes[count - 1];
            nodes[iMin] = parentIndex;
            --count;
        }

        m_root = nodes[0];
        nodes  = null;

        Validate();
    }
Example #12
0
    /// Ray-cast against the proxies in the tree. This relies on the callback
    /// to perform a exact ray-cast in the case were the proxy contains a shape.
    /// The callback also performs the any collision filtering. This has performance
    /// roughly equal to k * log(n), where k is the number of collisions and n is the
    /// number of proxies in the tree.
    /// @param input the ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
    /// @param callback a callback class that is called for each proxy that is hit by the ray.
    public void RayCast(b2BroadphaseRayCastCallback callback, b2RayCastInput input)
    {
        b2Vec2 p1 = new b2Vec2(input.p1);
        b2Vec2 p2 = new b2Vec2(input.p2);
        b2Vec2 r  = p2 - p1;

        Debug.Assert(r.LengthSquared() > 0.0f);
        r.Normalize();

        // v is perpendicular to the segment.
        b2Vec2 v     = Utils.b2Cross(1.0f, r);
        b2Vec2 abs_v = Utils.b2Abs(v);

        // Separating axis for segment (Gino, p80).
        // |dot(v, p1 - c)| > dot(|v|, h)

        float maxFraction = input.maxFraction;

        // Build a bounding box for the segment.
        b2AABB segmentAABB = new b2AABB();
        {
            b2Vec2 t = p1 + maxFraction * (p2 - p1);
            segmentAABB.lowerBound = Utils.b2Min(p1, t);
            segmentAABB.upperBound = Utils.b2Max(p1, t);
        }

        Stack <int> stack = new Stack <int>(256);

        stack.Push(m_root);

        while (stack.Count > 0)
        {
            int nodeId = stack.Pop();
            if (nodeId == Settings.b2_nullNode)
            {
                continue;
            }

            b2TreeNode node = m_nodes[nodeId];

            if (Utils.b2TestOverlap(ref node.aabb, ref segmentAABB) == false)
            {
                continue;
            }

            // Separating axis for segment (Gino, p80).
            // |dot(v, p1 - c)| > dot(|v|, h)
            b2Vec2 c          = node.aabb.GetCenter();
            b2Vec2 h          = node.aabb.GetExtents();
            float  separation = Utils.b2Abs(Utils.b2Dot(v, p1 - c)) - Utils.b2Dot(abs_v, h);
            if (separation > 0.0f)
            {
                continue;
            }

            if (node.IsLeaf())
            {
                b2RayCastInput subInput = new b2RayCastInput();
                subInput.p1          = input.p1;
                subInput.p2          = input.p2;
                subInput.maxFraction = maxFraction;

                float value = callback(subInput, nodeId);

                if (value == 0.0f)
                {
                    // The client has terminated the ray cast.
                    return;
                }

                if (value > 0.0f)
                {
                    // Update segment bounding box.
                    maxFraction = value;
                    b2Vec2 t = p1 + maxFraction * (p2 - p1);
                    segmentAABB.lowerBound = Utils.b2Min(p1, t);
                    segmentAABB.upperBound = Utils.b2Max(p1, t);
                }
            }
            else
            {
                stack.Push(node.child1);
                stack.Push(node.child2);
            }
        }
    }
Example #13
0
        public b2AABB GetAABB(int childIndex)
        {
            b2AABB ret = new b2AABB(Box2dPINVOKE.b2Fixture_GetAABB(swigCPtr, childIndex), false);

            return(ret);
        }
 public OverlapShapeInputNative()
 {
     transform = Physics2DNative.GetNewTransform(Vector2.Zero, 0f);
     aabb      = new b2AABB();
 }
Example #15
0
 /// Combine two AABBs into this one.
 public void Combine(ref b2AABB aabb1, ref b2AABB aabb2)
 {
     lowerBound = Utils.b2Min(aabb1.lowerBound, aabb2.lowerBound);
     upperBound = Utils.b2Max(aabb1.upperBound, aabb2.upperBound);
 }
Example #16
0
 /// Given a transform, compute the associated axis aligned bounding box for a child shape.
 /// @param aabb returns the axis aligned box.
 /// @param xf the world transform of the shape.
 /// @param childIndex the child shape
 public abstract void ComputeAABB(out b2AABB output, ref b2Transform xf, int childIndex);
Example #17
0
        public override b2AABB ComputeAABB(b2Transform xf, int childIndex)
        {
            b2Vec2 lower = b2Math.b2Mul(xf, m_vertices[0]);
            b2Vec2 upper = lower;

            for (int i = 1; i < m_vertexCount; ++i)
            {
                b2Vec2 v = b2Math.b2Mul(xf, m_vertices[i]);
                lower = b2Math.b2Min(lower, v);
                upper = b2Math.b2Max(upper, v);
            }

            b2Vec2 r = new b2Vec2(m_radius, m_radius);
            b2AABB aabb = new b2AABB();
            aabb.m_lowerBound = lower - r;
            aabb.m_upperBound = upper + r;
            return(aabb);
        }
Example #18
0
        public b2AABB GetFatAABB(int proxyId)
        {
            b2AABB ret = new b2AABB(Box2DPINVOKE.b2DynamicTree_GetFatAABB(swigCPtr, proxyId), false);

            return(ret);
        }
Example #19
0
 public override void ComputeAABB(out b2AABB output, ref b2Transform transform, int childIndex)
 {
     b2Vec2 p;
     p.x = transform.p.x + transform.q.c * Position.x - transform.q.s * Position.y;
     p.y = transform.p.y + transform.q.s * Position.x + transform.q.c * Position.y;
     
     output.LowerBound.x = p.x - Radius;
     output.LowerBound.y = p.y - Radius;
     output.UpperBound.x = p.x + Radius;
     output.UpperBound.y = p.y + Radius;
 }
Example #20
0
        public override void ComputeAABB(out b2AABB output, ref b2Transform xf, int childIndex)
        {
            int i1 = childIndex;
            int i2 = childIndex + 1;
            if (i2 == Count)
            {
                i2 = 0;
            }

            b2Vec2 v1 = b2Math.b2Mul(ref xf, ref Vertices[i1]);
            b2Vec2 v2 = b2Math.b2Mul(ref xf, ref Vertices[i2]);

            b2Math.b2Min(ref v1, ref v2, out output.LowerBound);
            b2Math.b2Max(ref v1, ref v2, out output.UpperBound);
        }
Example #21
0
 public void DrawAABB(b2AABB aabb, b2Color c)
 {
     Gl.glColor3f(c.r, c.g, c.b);
     Gl.glBegin(Gl.GL_LINE_LOOP);
     Gl.glVertex2f(aabb.lowerBound.x, aabb.lowerBound.y);
     Gl.glVertex2f(aabb.upperBound.x, aabb.lowerBound.y);
     Gl.glVertex2f(aabb.upperBound.x, aabb.upperBound.y);
     Gl.glVertex2f(aabb.lowerBound.x, aabb.upperBound.y);
     Gl.glEnd();
 }
Example #22
0
        public override b2AABB ComputeAABB(b2Transform xf, int childIndex)
        {
            int i1 = childIndex;
            int i2 = childIndex + 1;
            if (i2 == m_count)
            {
                i2 = 0;
            }

            b2Vec2 v1 = b2Math.b2Mul(xf, m_vertices[i1]);
            b2Vec2 v2 = b2Math.b2Mul(xf, m_vertices[i2]);

            b2AABB aabb = new b2AABB();
            aabb.lowerBound = b2Math.b2Min(v1, v2);
            aabb.upperBound = b2Math.b2Max(v1, v2);
            return (aabb);
        }
Example #23
0
 /// Query an AABB for overlapping proxies. The callback class
 /// is called for each proxy that overlaps the supplied AABB.
 public void Query(b2BroadphaseQueryCallback callback, b2AABB aabb)
 {
     m_tree.Query(callback, aabb);
 }