void Awake()
    {
        // add our one-way platforms to our normal platform mask so that we can land on them from above
        platformMask |= oneWayPlatformMask;

        // cache some components
        tfTransform = GetComponent <TFTransform>();
        boxCollider = GetComponent <TFPolygonCollider>();
        rigidBody2D = GetComponent <TFRigidbody>();

        if (rigidBody2D)
        {
            rigidBody2D.OnTriggerEnter += TFOnTriggerEnter;
            rigidBody2D.OnTriggerStay  += TFOnTriggerStay;
            rigidBody2D.OnTriggerExit  += TFOnTriggerExit;
        }

        // here, we trigger our properties that have setters with bodies
        skinWidth = _skinWidth;

        // we want to set our CC2D to ignore all collision layers except what is in our triggerMask
        for (var i = 0; i < 32; i++)
        {
            // see if our triggerMask contains this layer and if not ignore it
            if ((triggerMask.mask & 1 << i) == 0)
            {
                Physics2D.IgnoreLayerCollision(gameObject.layer, i);
            }
        }
    }
Example #2
0
        internal TFRaycastHit2D Raycast(ITreeRaycastCallback callback, FixVec2 pointA, FixVec2 pointB, TFLayerMask mask)
        {
            TFRaycastHit2D hit = new TFRaycastHit2D();
            FixVec2        r   = pointB - pointA;

            if (r.GetMagnitudeSquared() <= Fix.zero)
            {
                return(hit);
            }
            r.Normalize();

            // v is perpendicular to the segment.
            FixVec2 v     = FixVec2.Cross(Fix.one, r);
            FixVec2 abs_v = FixVec2.Abs(v);

            // Separating axis for segment (Gino, p80).
            // |dot(v, p1 - c)| > dot(|v|, h)
            Fix maxFraction = Fix.one;

            // Build a bounding box for the segment.
            AABB    segmentAABB = new AABB();
            FixVec2 t           = pointA + maxFraction * (pointB - pointA);

            segmentAABB.min = FixVec2.Min(pointA, t);
            segmentAABB.max = FixVec2.Max(pointA, t);

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

            stack.Push(rootIndex);

            List <TFRaycastOutput> hitNodes = new List <TFRaycastOutput>(2);

            while (stack.Count > 0)
            {
                var nodeId = stack.Pop();
                if (nodeId == nullNode)
                {
                    continue;
                }

                var node = nodes[nodeId];

                if (!node.aabb.Overlaps(segmentAABB))
                {
                    continue;
                }

                // Separating axis for segment (Gino, p80).
                // |dot(v, p1 - c)| > dot(|v|, h)
                var c          = node.aabb.GetCenter();
                var h          = node.aabb.GetExtents();
                var separation = FixMath.Abs(FixVec2.Dot(v, pointA - c)) - FixVec2.Dot(abs_v, h);
                if (separation > Fix.zero)
                {
                    continue;
                }

                if (node.IsLeaf())
                {
                    // If value is >= 0, then we hit the node.
                    TFRaycastHit2D rHit;
                    Fix            value = callback.RayCastCallback(pointA, pointB, maxFraction, nodeId, out rHit, mask);

                    if (value == Fix.zero)
                    {
                        // The client has terminated the ray cast.
                        if (rHit)
                        {
                            // We actually hit the node, add it to the list.
                            hitNodes.Add(new TFRaycastOutput(nodeId, rHit));
                        }
                        break;
                    }

                    if (value == maxFraction)
                    {
                        if (rHit)
                        {
                            // We actually hit the node, add it to the list.
                            hitNodes.Add(new TFRaycastOutput(nodeId, rHit));
                        }
                    }
                    else if (value > Fix.zero)
                    {
                        if (rHit)
                        {
                            // We actually hit the node, add it to the list.
                            hitNodes.Add(new TFRaycastOutput(nodeId, rHit));
                        }
                        // Update segment bounding box.
                        maxFraction = value;
                        FixVec2 g = pointA + maxFraction * (pointB - pointA);
                        segmentAABB.min = FixVec2.Min(pointA, g);
                        segmentAABB.max = FixVec2.Max(pointA, g);
                    }
                }
                else
                {
                    stack.Push(node.leftChildIndex);
                    stack.Push(node.rightChildIndex);
                }
            }

            // Decide which node was the closest to the starting point.
            Fix closestNode = maxFraction;

            for (int i = 0; i < hitNodes.Count; i++)
            {
                if (hitNodes[i].hit.fraction < closestNode)
                {
                    closestNode = hitNodes[i].hit.fraction;
                    hit         = hitNodes[i].hit;
                }
            }
            return(hit);
        }
Example #3
0
        public Fix RayCastCallback(FixVec2 pointA, FixVec2 pointB, Fix maxFraction, int proxyID, out TFRaycastHit2D hit, TFLayerMask mask)
        {
            TFRigidbody rigid = bodies[dynamicTree.nodes[proxyID].bodyIndex];


            if (!(mask == (mask | (1 << rigid.layer))))
            {
                // This object is not in the mask, ignore it.
                hit = new TFRaycastHit2D();
                return(maxFraction);
            }

            rigid.coll.Raycast(out hit, pointA, pointB, maxFraction);

            if (!hit)
            {
                // We did not hit the body, ignore it and use our max ray length.
                return(maxFraction);
            }

            Fix     fraction = hit.fraction;
            FixVec2 point    = (Fix.one - fraction) * pointA + fraction * pointB;

            hit.point    = point;
            hit.distance = (point - pointA).GetMagnitude();
            return(RayCastCallback(rigid, hit.point, hit.normal, hit.fraction));
        }
Example #4
0
        public TFRaycastHit2D Raycast(FixVec2 origin, FixVec2 direction, Fix distance, TFLayerMask mask)
        {
            TFRaycastHit2D hit = dynamicTree.Raycast(this, origin, origin + direction * distance, mask);

            return(hit);
        }
Example #5
0
        public static TFRaycastHit2D Raycast(FixVec2 origin, FixVec2 direction, Fix distance, TFLayerMask mask)
        {
            TFRaycastHit2D hit = physicsScene.Raycast(origin, direction, distance, mask);

            return(hit);
        }