Example #1
0
        public override void TryCollide(SegmentCollider other)
        {
            if (other == this || !other.GameObject.Enabled)
            {
                return;
            }
            if (other.Segment.Far <= Segment.Close || Segment.Far <= other.Segment.Close)
            {
                return;
            }

            var rotation      = GameObject.Transform.Rotation;
            var otherRotation = other.GameObject.Transform.Rotation;

            if (Math.Abs(rotation.Y - otherRotation.Y) + MathUtils.Epsilon > (Segment.AngleSize + other.Segment.AngleSize) / 2)
            {
                return;
            }

            var position      = GameObject.Transform.Position;
            var otherPosition = other.GameObject.Transform.Position;
            var heightDif     = position.Y - otherPosition.Y;

            if (heightDif > other.Segment.Height || heightDif < 0)
            {
                return;
            }

            GameObject.Transform.Position = GameObject.Transform.Position.WithY(otherPosition.Y + other.Segment.Height);
            if (GameObject.RigidBody != null)
            {
                GameObject.RigidBody.Velocity = Vec3.Zero;
            }
            OnCollision(other, position, Vec3.Up);
        }
Example #2
0
 private void OnCollision(SegmentCollider collider, Vec3 normal)
 {
     if (collider == lastCollider)
     {
         GameObject.RigidBody.Move();
         return;
     }
     GameObject.RigidBody !.Velocity = Vec3.Reflect(GameObject.RigidBody.Velocity, normal);
     GameObject.RigidBody.Move();
     lastCollider = collider;
     OnCollision(collider, GameObject.Transform.Position - normal.Normalized * Radius, normal);
 }
Example #3
0
        public override void TryCollide(SegmentCollider other)
        {
            if (!other.GameObject.Enabled)
            {
                return;
            }

            var realCenter = (Center + GameObject.Transform.Position);

            if (realCenter.Dot(other.GameObject.Transform.Position) < 0)
            {
                return;
            }
            if (other.GameObject.Transform.Position.Y > realCenter.Y)
            {
                return;
            }

            var otherRotation  = other.GameObject.Transform.Rotation;
            var centerDistance = realCenter.Magnitude;
            var frontNormal    = realCenter.WithY(0).Normalized;

            var rotMat     = Mat3.Rotation(Vec3.Up * -otherRotation.Y);
            var closeLeft  = rotMat * other.CloseLeft;
            var farLeft    = rotMat * other.FarLeft;
            var closeRight = rotMat * other.CloseRight;
            var farRight   = rotMat * other.FarRight;

            var leftVec     = farLeft - closeLeft;
            var rightVec    = farRight - closeRight;
            var leftNormal  = Vec3.Up.Cross(leftVec).Normalized;
            var rightNormal = rightVec.Cross(Vec3.Up).Normalized;

            var inCloseOffset = other.Segment.Close - Radius < centerDistance;
            var inFarOffset   = other.Segment.Far + Radius > centerDistance;
            var inLeftOffset  = Vec3.CheckLeftRight(
                realCenter, closeLeft + leftNormal * Radius, farLeft) < 0;
            var inRightOffset = Vec3.CheckLeftRight(
                realCenter, closeRight + rightNormal * Radius, farRight) > 0;

            // Check if in offset boundary
            if (inCloseOffset && inFarOffset && inLeftOffset && inRightOffset)
            {
                // Check if close / far side hit
                var inLeft  = Vec3.CheckLeftRight(realCenter, closeLeft, farLeft) < 0;
                var inRight = Vec3.CheckLeftRight(realCenter, closeRight, farRight) > 0;
                if (inCloseOffset && inFarOffset && inLeft && inRight)
                {
                    var normal = frontNormal;
                    if (Math.Abs(centerDistance - other.Segment.Close) < Math.Abs(centerDistance - other.Segment.Far))
                    {
                        normal = -frontNormal;
                    }
                    OnCollision(other, normal);
                    return;
                }

                // Check if left / right side hit
                var inClose = other.Segment.Close < centerDistance;
                var inFar   = other.Segment.Far > centerDistance;
                if (inClose && inFar && inLeftOffset && inRightOffset)
                {
                    var normal = rightNormal;
                    if (farLeft.DistanceTo(realCenter) < farRight.DistanceTo(realCenter))
                    {
                        normal = leftNormal;
                    }
                    OnCollision(other, normal);
                    return;
                }

                // Check if corner hit
                var corners = new List <Vec3> {
                    closeLeft, farLeft, closeRight, farRight
                };
                foreach (var corner in corners)
                {
                    if (corner.DistanceTo(realCenter) > Radius)
                    {
                        continue;
                    }
                    var normal = realCenter - corner;
                    OnCollision(other, normal);
                    return;
                }
            }

            lastCollider = null;
        }
Example #4
0
 public virtual void TryCollide(SegmentCollider plane)
 {
 }