Esempio n. 1
0
        static bool CollideCircles(CircleShape circleA, ref FSTransform firstTransform, CircleShape circleB, ref FSTransform secondTransform, out FSCollisionResult result)
        {
            result = new FSCollisionResult();
            Collision.CollideCircles(ref _manifold, circleA, ref firstTransform, circleB, ref secondTransform);
            if (_manifold.PointCount > 0)
            {
                // this is essentically directly from ContactSolver.WorldManifold.Initialize. To avoid doing the extra math twice we duplicate this code
                // here because it doesnt return some values we need to calculate separation
                var pointA = MathUtils.Mul(ref firstTransform, _manifold.LocalPoint);
                var pointB = MathUtils.Mul(ref secondTransform, _manifold.Points[0].LocalPoint);

                result.Normal = pointA - pointB;
                Vector2Ext.Normalize(ref result.Normal);

                var cA = pointA - circleA.Radius * result.Normal;
                var cB = pointB + circleB.Radius * result.Normal;
                result.Point  = 0.5f * (cA + cB);
                result.Point *= FSConvert.SimToDisplay;

                var separation = Vector2.Dot(pointA - pointB, result.Normal) - circleA.Radius - circleB.Radius;
                result.MinimumTranslationVector = result.Normal * Math.Abs(separation);

                                #if DEBUG_FSCOLLISIONS
                Debug.drawPixel(result.point, 5, Color.Red, 0.2f);
                Debug.drawLine(result.point, result.point + result.normal * 20, Color.Yellow, 0.2f);
                                #endif

                return(true);
            }

            return(false);
        }
Esempio n. 2
0
        /// <summary>
        /// builds the Polygon edge normals. These are lazily created and updated only by the edgeNormals getter
        /// </summary>
        void BuildEdgeNormals()
        {
            // for boxes we only require 2 edges since the other 2 are parallel
            var totalEdges = isBox ? 2 : Points.Length;

            if (_edgeNormals == null || _edgeNormals.Length != totalEdges)
            {
                _edgeNormals = new Vector2[totalEdges];
            }

            Vector2 p2;

            for (var i = 0; i < totalEdges; i++)
            {
                var p1 = Points[i];
                if (i + 1 >= Points.Length)
                {
                    p2 = Points[0];
                }
                else
                {
                    p2 = Points[i + 1];
                }

                var perp = Vector2Ext.Perpendicular(ref p1, ref p2);
                Vector2Ext.Normalize(ref perp);
                _edgeNormals[i] = perp;
            }

            return;
        }
Esempio n. 3
0
        /// <summary>
        /// iterates all the edges of the polygon and gets the closest point on any edge to point. Returns via out the squared distance
        /// to the closest point and the normal of the edge it is on. point should be in the space of the Polygon (point - poly.position)
        /// </summary>
        /// <returns>The closest point on polygon to point.</returns>
        /// <param name="point">Point.</param>
        /// <param name="distanceSquared">Distance squared.</param>
        /// <param name="edgeNormal">Edge normal.</param>
        public static Vector2 GetClosestPointOnPolygonToPoint(Vector2[] points, Vector2 point, out float distanceSquared, out Vector2 edgeNormal)
        {
            distanceSquared = float.MaxValue;
            edgeNormal      = Vector2.Zero;
            var closestPoint = Vector2.Zero;

            float tempDistanceSquared;

            for (var i = 0; i < points.Length; i++)
            {
                var j = i + 1;
                if (j == points.Length)
                {
                    j = 0;
                }

                var closest = ShapeCollisions.ClosestPointOnLine(points[i], points[j], point);
                Vector2.DistanceSquared(ref point, ref closest, out tempDistanceSquared);

                if (tempDistanceSquared < distanceSquared)
                {
                    distanceSquared = tempDistanceSquared;
                    closestPoint    = closest;

                    // get the normal of the line
                    var line = points[j] - points[i];
                    edgeNormal.X = -line.Y;
                    edgeNormal.Y = line.X;
                }
            }

            Vector2Ext.Normalize(ref edgeNormal);

            return(closestPoint);
        }
Esempio n. 4
0
        public override Vector2 getPosition()
        {
            // we need a position that's far enough away to be safe
            // calculate the vector from them to us, then make sure it's at least the approach distance
            // 1. get dir to me
            var dirToMe = Vector2Ext.Normalize(nt.Position - mind.state.me.body.pos);
            // 2. scale to minimum range, find resultant (away)
            var targetAway = approachRange * -dirToMe;

            return(targetAway);
        }
Esempio n. 5
0
        static bool CollideEdgeAndCircle(EdgeShape edge, ref FSTransform edgeTransform, CircleShape circle,
                                         ref FSTransform circleTransform, out FSCollisionResult result)
        {
            result = new FSCollisionResult();
            Collision.CollideEdgeAndCircle(ref _manifold, edge, ref edgeTransform, circle, ref circleTransform);
            if (_manifold.PointCount > 0)
            {
                // code adapted from PositionSolverManifold.Initialize
                if (_manifold.Type == ManifoldType.Circles)
                {
                    // this is essentically directly from ContactSolver.WorldManifold.Initialize. To avoid doing the extra math twice we duplicate this code
                    // here because it doesnt return some values we need to calculate separation
                    var pointA = MathUtils.Mul(ref edgeTransform, _manifold.LocalPoint);
                    var pointB = MathUtils.Mul(ref circleTransform, _manifold.Points[0].LocalPoint);

                    result.Normal = pointA - pointB;
                    Vector2Ext.Normalize(ref result.Normal);

                    var cA = pointA - edge.Radius * result.Normal;
                    var cB = pointB + circle.Radius * result.Normal;
                    result.Point  = 0.5f * (cA + cB);
                    result.Point *= FSConvert.SimToDisplay;

                    var separation = Vector2.Dot(pointA - pointB, result.Normal) - edge.Radius - circle.Radius;

                    // Ensure normal points from A to B
                    Vector2.Negate(ref result.Normal, out result.Normal);
                    result.MinimumTranslationVector = result.Normal * Math.Abs(separation);
                }
                else                 // FaceA
                {
                    result.Normal = MathUtils.Mul(edgeTransform.Q, _manifold.LocalNormal);
                    var planePoint = MathUtils.Mul(ref edgeTransform, _manifold.LocalPoint);

                    var clipPoint  = MathUtils.Mul(ref circleTransform, _manifold.Points[0].LocalPoint);
                    var separation = Vector2.Dot(clipPoint - planePoint, result.Normal) - edge.Radius - circle.Radius;
                    result.Point = (clipPoint - result.Normal * circle.Radius) * FSConvert.SimToDisplay;

                    result.MinimumTranslationVector = result.Normal * -separation;
                }

#if DEBUG_FSCOLLISIONS
                Debug.drawPixel(result.point, 5, Color.Red, 0.2f);
                Debug.drawLine(result.point, result.point + result.normal * 20, Color.Yellow, 0.2f);
#endif

                return(true);
            }

            return(false);
        }
Esempio n. 6
0
        public void Update()
        {
            if (CanAccelearte)
            {
                CurrentSpeed += Acceleration * Time.DeltaTime;

                if (CurrentSpeed > MaxSpeed)
                {
                    CurrentSpeed  = MaxSpeed;
                    CanAccelearte = false;
                }
            }

            var motion = Vector2Ext.Normalize(player.Position - Entity.Position) * CurrentSpeed * Time.DeltaTime;

            mover.ApplyMovement(motion);
        }
Esempio n. 7
0
        /// <summary>
        /// works for circles whos center is in the box as well as just overlapping with the center out of the box.
        /// </summary>
        /// <returns><c>true</c>, if to box was circled, <c>false</c> otherwise.</returns>
        /// <param name="circle">First.</param>
        /// <param name="box">Second.</param>
        /// <param name="result">Result.</param>
        public static bool CircleToBox(Circle circle, Box box, out CollisionResult result)
        {
            result = new CollisionResult();

            var closestPointOnBounds =
                box.bounds.GetClosestPointOnRectangleBorderToPoint(circle.position, out result.Normal);

            // deal with circles whos center is in the box first since its cheaper to see if we are contained
            if (box.ContainsPoint(circle.position))
            {
                result.Point = closestPointOnBounds;

                // calculate mtv. Find the safe, non-collided position and get the mtv from that.
                var safePlace = closestPointOnBounds + result.Normal * circle.Radius;
                result.MinimumTranslationVector = circle.position - safePlace;

                return(true);
            }

            float sqrDistance;

            Vector2.DistanceSquared(ref closestPointOnBounds, ref circle.position, out sqrDistance);

            // see if the point on the box is less than radius from the circle
            if (sqrDistance == 0)
            {
                result.MinimumTranslationVector = result.Normal * circle.Radius;
            }
            else if (sqrDistance <= circle.Radius * circle.Radius)
            {
                result.Normal = circle.position - closestPointOnBounds;
                var depth = result.Normal.Length() - circle.Radius;

                result.Point = closestPointOnBounds;
                Vector2Ext.Normalize(ref result.Normal);
                result.MinimumTranslationVector = depth * result.Normal;

                return(true);
            }

            return(false);
        }
Esempio n. 8
0
        public float getTargetAngle()
        {
            var dirToTarget = Vector2Ext.Normalize(getPosition() - mind.state.me.body.pos);

            return(dirToTarget.ScreenSpaceAngle());
        }
Esempio n. 9
0
        public void OnTriggerEnter(Collider other, Collider local)
        {
            var hitEntity = other.Entity;

            switch (other.Tag)
            {
            case Constants.Colliders.THING: {
                if (hitEntity.HasComponent <Capsule>())
                {
                    var capsule = hitEntity.GetComponent <Capsule>();
                    if (!capsule.acquired && Time.TotalTime > capsule.firstAvailableAt)
                    {
                        // apply the capsule
                        var gotEnergy = capsule.energy;
                        me.core.energy += gotEnergy;
                        capsule.acquire();     // blow it up
                        // send signal to mind
                        if (me.mind.control)
                        {
                            me.mind.signal(new ItemSignals.CapsuleAcquiredSignal(capsule, gotEnergy));
                        }
                    }
                }

                break;
            }

            case Constants.Colliders.SHOOT: {
                if (hitEntity.HasComponent <Shooter>())
                {
                    var shooter = hitEntity.GetComponent <Shooter>();
                    if (shooter.firing)
                    {
                        // ouch
                        me.core.energy -= Constants.Mechanics.SHOOT_DRAIN;
                        me.core.clamp();
                        // send signal to mind
                        if (me.mind.control)
                        {
                            me.mind.signal(new PhysicalSignals.ShotSignal(shooter));
                        }
                    }
                }

                break;
            }
            }

            if (other.Tag == Constants.Colliders.LANE)
            {
                // lanes multiply velocity
                velocity *= laneFactor;
                drag      = Vector2.Zero;
            }

            if (other.Tag == Constants.Mechanics.TRIGGER_GRAVITY)
            {
                var gravThing = other.Entity;
                var succ      = true;
                if (gravThing.HasComponent <Capsule>())
                {
                    var cap = gravThing.GetComponent <Capsule>();
                    if (Time.TotalTime < cap.firstAvailableAt)
                    {
                        succ = false;
                    }
                }

                if (succ)
                {
                    var thingBody    = gravThing.GetComponent <KinBody>();
                    var toMe         = Entity.Position - gravThing.Position;
                    var toMeDir      = Vector2Ext.Normalize(toMe);
                    var dist         = toMe.Length();
                    var velInfluence = Mathf.Clamp(velocity.Length(), 1f, 10f);
                    var gravForce    = (gravityFactor * mass * velInfluence) / (dist * dist);
                    thingBody.velocity += gravForce * toMeDir;
                }
            }
        }