Пример #1
0
	void	OnTriggerEnter(Collider other)
	{
		if(other.gameObject.layer == LayerMask.NameToLayer("Enemy")) {

			CollisionResult	result = new CollisionResult();

			result.object0 = this.gameObject;
			result.object1 = other.gameObject;
			result.is_trigger = false;

			this.collision_results.Add(result);

		} else if(other.gameObject.layer == LayerMask.NameToLayer("EnemyLair")) {

			CollisionResult	result = new CollisionResult();

			result.object0 = this.gameObject;
			result.object1 = other.gameObject;
			result.is_trigger = false;

			this.collision_results.Add(result);

		} else if(other.gameObject.layer == LayerMask.NameToLayer("Wall")) {

			CollisionResult	result = new CollisionResult();

			result.object0 = this.gameObject;
			result.object1 = other.gameObject;
			result.is_trigger = false;

			this.collision_results.Add(result);
		}
	}
Пример #2
0
		public static bool circleToCircle( Circle first, Circle second, out CollisionResult result )
		{
			result = new CollisionResult();

			// avoid the square root until we actually need it
			var distanceSquared = Vector2.DistanceSquared( first.position, second.position );
			var sumOfRadii = first.radius + second.radius;
			var collided = distanceSquared < sumOfRadii * sumOfRadii;
			if( collided )
			{
				result.normal = Vector2.Normalize( first.position - second.position );
				var depth = sumOfRadii - Mathf.sqrt( distanceSquared );
				result.minimumTranslationVector = -depth * result.normal;
				result.point = second.position + result.normal * second.radius;

				// this gets the actual point of collision which may or may not be useful so we'll leave it here for now
				//var collisionPointX = ( ( first.position.X * second.radius ) + ( second.position.X * first.radius ) ) / sumOfRadii;
				//var collisionPointY = ( ( first.position.Y * second.radius ) + ( second.position.Y * first.radius ) ) / sumOfRadii;
				//result.point = new Vector2( collisionPointX, collisionPointY );

				return true;
			}

			return false;
		}
            /// <summary>
            /// Determines if two objects have collided using Axis-Aligned Bounding Box
            /// </summary>
            /// <param name="first">The first object to check.</param>
            /// <param name="second">The second object to check.</param>
            /// <returns>True if a collision was detected, false otherwise.</returns>
            /// <remarks>
            /// https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection
            ///
            ///    Ax,Ay                    Bx,By
            ///      ---------------          ---------------
            ///      -             -          -             -
            ///      -             -          -             -
            ///      -             -          -             -
            ///      -             -          -             -
            ///      ---------------          ---------------
            ///                  AX,AY                     BX,BY
            ///
            /// They are seperate if any of these statements are true:
            ///
            ///  AX is less than Bx
            ///  BX is less than Ax
            ///  AY is less than By
            ///  BY is less than Ay
            ///
            /// </remarks>
            public static CollisionResult CheckForCollision(ICollidable first, ICollidable second, Vector2 velocity)
            {
                if (first == null)
                                {
                                        throw new ArgumentNullException("first");
                                }

                                if (second == null)
                                {
                                        throw new ArgumentNullException("second");
                                }

                                Rectangle a = first.BoundingBox;
                                Rectangle b = second.BoundingBox;

                                //bool haveCollided = !(a.Right < b.X
                                //         || b.Right < a.X
                                //         || a.Bottom < b.Y
                                //         || b.Bottom < a.Y);

                                bool haveCollided = (a.Right > b.X && b.Right > a.X && a.Bottom > b.Y && b.Bottom > a.Y);

                                a.Offset(Convert.ToInt32(velocity.X), Convert.ToInt32(velocity.Y));
                                bool willCollided = (a.Right > b.X && b.Right > a.X && a.Bottom > b.Y && b.Bottom > a.Y);

                                CollisionResult collisionResult = new CollisionResult();
                                collisionResult.HaveCollided = haveCollided;
                                collisionResult.WillCollide = willCollided;
                                collisionResult.CorrectionVector = null;
                                return collisionResult;
            }
Пример #4
0
        public override bool collidesWithShape( Shape other, out CollisionResult result )
        {
            // special, high-performance cases. otherwise we fall back to Polygon.
            if( other is Box )
                return ShapeCollisions.boxToBox( this, other as Box, out result );

            // TODO: get Minkowski working for circle to box
            //if( other is Circle )

            // fallthrough to standard cases
            return base.collidesWithShape( other, out result );
        }
Пример #5
0
        public override bool collidesWithShape( Shape other, out CollisionResult result )
        {
            if( other is Box )
                return ShapeCollisions.circleToBox( this, other as Box, out result );

            if( other is Circle )
                return ShapeCollisions.circleToCircle( this, other as Circle, out result );

            if( other is Polygon )
                return ShapeCollisions.circleToPolygon( this, other as Polygon, out result );

            throw new NotImplementedException( string.Format( "Collisions of Circle to {0} are not supported", other ) );
        }
Пример #6
0
		public static bool pointToBox( Vector2 point, Box box, out CollisionResult result )
		{
			result = new CollisionResult();

			if( box.containsPoint( point ) )
			{
				// get the point in the space of the Box
				result.point = box.bounds.getClosestPointOnRectangleBorderToPoint( point, out result.normal );
				result.minimumTranslationVector = point - result.point;

				return true;
			}

			return false;
		}
        /// <summary>
        /// Crear inicializado
        /// </summary>
        public ElipsoidCollisionManager()
        {
            gravityEnabled = true;
            gravityForce = new Vector3(0, -10, 0);
            slideFactor = 1.3f;
            movementSphere = new TgcBoundingSphere();
            eSphere = new TgcBoundingSphere();
            objetosCandidatos = new List<Collider>();
            onGroundMinDotValue = 0.72f;

            result = new CollisionResult();
            result.collisionFound = false;
            result.collisionNormal = Vector3.Empty;
            result.collisionPoint = Vector3.Empty;
            result.realMovmentVector = Vector3.Empty;
        }
Пример #8
0
        public override bool collidesWithShape( Shape other, out CollisionResult result )
        {
            if( other is Polygon )
                return ShapeCollisions.polygonToPolygon( this, other as Polygon, out result );

            if( other is Circle )
            {
                if( ShapeCollisions.circleToPolygon( other as Circle, this, out result ) )
                {
                    result.invertResult();
                    return true;
                }
                return false;
            }

            throw new NotImplementedException( string.Format( "overlaps of Polygon to {0} are not supported", other ) );
        }
Пример #9
0
		public static bool pointToPoly( Vector2 point, Polygon poly, out CollisionResult result )
		{
			result = new CollisionResult();

			if( poly.containsPoint( point ) )
			{
				float distanceSquared;
				var closestPoint = Polygon.getClosestPointOnPolygonToPoint( poly.points, point - poly.position, out distanceSquared, out result.normal );

				result.minimumTranslationVector = result.normal * Mathf.sqrt( distanceSquared );
				result.point = closestPoint + poly.position;

				return true;
			}

			return false;
		}
Пример #10
0
	// 컬리전에 히트하는 동안 호출되는 메소드.
	void 	OnCollisionStay(Collision other)
	{
		switch(other.gameObject.tag) {

			case "Item":
			case "Enemy":
			case "Boss":
			{
				CollisionResult	result = new CollisionResult();
		
				result.object0    = this.gameObject;
				result.object1    = other.gameObject;
				result.is_trigger = false;

				CollisionManager.getInstance().results.Add(result);
			}
			break;
		}
	}
Пример #11
0
		public static bool pointToCircle( Vector2 point, Circle circle, out CollisionResult result )
		{
			result = new CollisionResult();

			// avoid the square root until we actually need it
			var distanceSquared = Vector2.DistanceSquared( point, circle.position );
			var sumOfRadii = 1 + circle.radius;
			var collided = distanceSquared < sumOfRadii * sumOfRadii;
			if( collided )
			{
				result.normal = Vector2.Normalize( point - circle.position );
				var depth = sumOfRadii - Mathf.sqrt( distanceSquared );
				result.minimumTranslationVector = -depth * result.normal;
				result.point = circle.position + result.normal * circle.radius;

				return true;
			}

			return false;
		}
Пример #12
0
        public static bool pointToPoly(Vector2 point, Polygon poly, out CollisionResult result)
        {
            result = new CollisionResult();

            if (poly.containsPoint(point))
            {
                float distanceSquared;
                var   closestPoint = Polygon.getClosestPointOnPolygonToPoint(
                    poly.points,
                    point - poly.position,
                    out distanceSquared,
                    out result.normal);

                result.minimumTranslationVector = result.normal * Mathf.sqrt(distanceSquared);
                result.point = closestPoint + poly.position;

                return(true);
            }

            return(false);
        }
Пример #13
0
        public static bool PointToCircle(Vector2 point, Circle circle, out CollisionResult result)
        {
            result = new CollisionResult();

            // avoid the square root until we actually need it
            var distanceSquared = Vector2.DistanceSquared(point, circle.position);
            var sumOfRadii      = 1 + circle.Radius;
            var collided        = distanceSquared < sumOfRadii * sumOfRadii;

            if (collided)
            {
                result.Normal = Vector2.Normalize(point - circle.position);
                var depth = sumOfRadii - Mathf.Sqrt(distanceSquared);
                result.MinimumTranslationVector = -depth * result.Normal;
                result.Point = circle.position + result.Normal * circle.Radius;

                return(true);
            }

            return(false);
        }
Пример #14
0
        public static bool boxToBox( Box first, Box second, out CollisionResult result )
        {
            result = new CollisionResult();

            var minkowskiDiff = minkowskiDifference( first, second );
            if( minkowskiDiff.contains( 0f, 0f ) )
            {
                // calculate the MTV. if it is zero then we can just call this a non-collision
                result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();

                if( result.minimumTranslationVector == Vector2.Zero )
                    return false;

                result.normal = -result.minimumTranslationVector;
                result.normal.Normalize();

                return true;
            }

            return false;
        }
Пример #15
0
        /// <summary>
        /// tank's A.I. function.
        /// moves to the position and stops when collides with others.
        /// </summary>
        /// <param name="aiBase">current A.I.</param>
        /// <param name="gameTime"></param>
        public override void OnAIMoveEvent(AIBase aiBase, GameTime gameTime)
        {
            if (aiBase.IsActive)
            {
                Vector3 vMoveVelocity = new Vector3(0.0f, 0.0f, SpecData.MoveSpeed);

                CollisionResult result = MoveHitTest(gameTime, vMoveVelocity);
                if (result != null)
                {
                    if (GameSound.IsPlaying(soundMove))
                    {
                        GameSound.Stop(soundMove);
                    }

                    MoveStop();     //  Cannot move
                }
                else
                {
                    Move(vMoveVelocity);

                    if (!GameSound.IsPlaying(soundMove))
                    {
                        soundMove = GameSound.Play3D(SoundTrack.TankMove, this);
                    }
                }
            }
            else
            {
                if (GameSound.IsPlaying(soundMove))
                {
                    GameSound.Stop(soundMove);
                }

                MoveStop();

                turretAngleSpeed = 0.0f;

                SetNextAI(AIType.Search, HelperMath.RandomNormal());
            }
        }
Пример #16
0
    public static bool SphereOverlapSingle(EntityManager entityManager, Entity entity, int tick, sphere sphere,
                                           ref CollisionResult result)
    {
        var collData = entityManager.GetComponentData <HitCollisionData>(entity);

        var histIndex       = collData.GetHistoryIndex(tick);
        var transformBuffer = entityManager.GetBuffer <TransformHistory>(entity);

        var sphereArray  = entityManager.GetBuffer <Sphere>(entity);
        var capsuleArray = entityManager.GetBuffer <Capsule>(entity);
        var boxArray     = entityManager.GetBuffer <Box>(entity);
        var resultArray  = new NativeArray <CollisionResult>(1, Allocator.TempJob);

        var job = new SphereOverlapJob
        {
            transformBuffer = new NativeSlice <TransformHistory>(transformBuffer.ToNativeArray(Allocator.TempJob), histIndex * k_maxColliderCount),
            sphereArray     = sphereArray.ToNativeArray(Allocator.TempJob),
            capsuleArray    = capsuleArray.ToNativeArray(Allocator.TempJob),
            boxArray        = boxArray.ToNativeArray(Allocator.TempJob),
            sphere          = sphere,
            result          = resultArray,
        };

        var handle = job.Schedule();

        handle.Complete();
        result = resultArray[0];

        //if(math.length(result.box.size) > 0)
        //    DebugDraw.Prim(result.box, Color.red, 1);
        //if(result.capsule.radius > 0)
        //    DebugDraw.Prim(result.capsule, Color.red, 1);
        //if(result.sphere.radius > 0)
        //    DebugDraw.Prim(result.sphere, Color.red, 1);


        resultArray.Dispose();

        return(result.hit == 1);
    }
Пример #17
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 = System.Numerics.Vector2.DistanceSquared(closestPointOnBounds, circle.position);

            // 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);
        }
Пример #18
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;
		}
Пример #19
0
        private SceneIntersectResult SceneIntersect(RayEntity rayEntity, float?distanceMax = null)
        {
            CollisionResult collisionRef = null;
            float?          distanceMin  = null;
            IEssence        essenceRef   = null;

            foreach (var essence in essences)
            {
                var collision = essence.CheckCollision(rayEntity);

                if (collision == null)
                {
                    continue;
                }

                var distance = (rayEntity.Origin - collision.Point).Length();
                if (distanceMax != null && distanceMax < distance)
                {
                    continue;
                }

                if (distanceMin == null ^ distanceMin > distance)
                {
                    distanceMin  = distance;
                    essenceRef   = essence;
                    collisionRef = collision;
                }
            }

            if (essenceRef == null)
            {
                return(null);
            }

            return(new SceneIntersectResult()
            {
                Essence = essenceRef,
                Collision = collisionRef
            });
        }
Пример #20
0
        /// <summary>
        /// Checks wheter the cannon collides with an object horizontally and bounces it when it does.
        /// </summary>
        /// <param name="other"></param>
        public void CheckBounce(SpriteGameObject other)
        {
            if (!carriage.CollidesWith(other))
            {
                return;
            }

            CollisionResult side = carriage.CollisionSide(other);

            switch (side)
            {
            case CollisionResult.LEFT:
                position.X = other.Position.X + other.Width + carriage.Center.X;
                break;

            case CollisionResult.RIGHT:
                position.X = other.Position.X - carriage.Center.X;
                break;
            }
            // flip and decrease velocity by 70%
            velocity.X = velocity.X * -0.30f;
        }
Пример #21
0
 public void Collide(float s, PhysicsGroupType groupType, ICollide other)
 {
     if (groupType == PhysicsGroupType.Physical)
     {
         for (int i = bullets.Count - 1; i >= 0; i--)
         {
             Circle          bullet          = bullets[i];
             CollisionResult bulletCollision = other.Collide(s, groupType, bullet, bulletIdentity);
             if (bulletCollision)
             {
                 bullets.RemoveAt(i);
                 //bullet.Position = bulletCollision.PositionB;
                 //bullet.Velocity = bulletCollision.VelocityB;
             }
         }
         CollisionResult result = other.Collide(s, groupType, collision, null);
         if (result)
         {
             takeDamage(result.Identity);
         }
     }
 }
Пример #22
0
    void OnCollisionStay(Collision other)
    {
        switch (other.gameObject.tag)
        {
        case "Player":
        {
            chrBehaviorPlayer player = other.gameObject.GetComponent <chrBehaviorPlayer>();

            if (player != null)
            {
                CollisionResult result = new CollisionResult();

                result.object0    = this.gameObject;
                result.object1    = other.gameObject;
                result.is_trigger = false;

                this.collision_results.Add(result);
            }
        }
        break;
        }
    }
Пример #23
0
        public static bool circleToPolygon(Circle circle, Polygon polygon, out CollisionResult result)
        {
            result = new CollisionResult();

            // circle position in the polygons coordinates
            var poly2Circle = circle.position - polygon.position;

            // first, we need to find the closest distance from the circle to the polygon
            float distanceSquared;
            var   closestPoint = polygon.getClosestPointOnPolygonToPoint(poly2Circle, out distanceSquared, out result.normal);

            // make sure the squared distance is less than our radius squared else we are not colliding. Note that if the Circle is fully
            // contained in the Polygon the distance could be larger than the radius. Because of that we also  make sure the circle position
            // is not inside the poly.
            var circleCenterInsidePoly = polygon.containsPoint(circle.position);

            if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly)
            {
                return(false);
            }

            // figure out the mtv. We have to be careful to deal with circles fully contained in the polygon or with their center contained.
            Vector2 mtv;

            if (circleCenterInsidePoly)
            {
                mtv = result.normal * (Mathf.sqrt(distanceSquared) + circle.radius);
            }
            else
            {
                var distance = Mathf.sqrt(distanceSquared);
                mtv = (poly2Circle - closestPoint) * ((circle.radius - distance) / distance);
            }

            result.minimumTranslationVector = -mtv;
            result.point = closestPoint + polygon.position;

            return(true);
        }
Пример #24
0
        /// <summary>
        /// 检测与精灵对象是否冲突
        /// </summary>
        /// <param name="spriteChecker"></param>
        /// <returns></returns>
        public CollisionResult CheckCollisionWithSprites(SpriteColMethod spriteChecker)
        {
            foreach (Sprite sprite in spriteChecker.ColSprites)
            {
                CollisionResult result = sprite.CheckOutBorder(borderRect);
                if (result.IsCollided)
                {
                    float originX = result.NormalVector.X;
                    float originY = result.NormalVector.Y;

                    float x, y;

                    if (Math.Abs(originX) > 0.5)
                    {
                        x = 1;
                    }
                    else
                    {
                        x = 0;
                    }
                    if (Math.Abs(originY) > 0.5)
                    {
                        y = 1;
                    }
                    else
                    {
                        y = 0;
                    }

                    x *= Math.Sign(originX);
                    y *= Math.Sign(originY);


                    return(new CollisionResult(result.InterPos, new Vector2(x, y)));
                }
            }
            return(new CollisionResult(false));
        }
Пример #25
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);

            // 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;
                result.normal = Vector2.Normalize(closestPointOnBounds - circle.position);

                // 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 making sure the circle center is not in the box
            if (sqrDistance <= circle.radius * circle.radius)
            {
                var directionToCircle = circle.position - closestPointOnBounds;
                var depth             = directionToCircle.Length() - circle.radius;

                result.point  = closestPointOnBounds;
                result.normal = Vector2.Normalize(directionToCircle);
                result.minimumTranslationVector = depth * result.normal;

                return(true);
            }

            return(false);
        }
        public async Task <CollisionResult> DetectCollision(IPlayerActor player, ICollection <IPlayerActor> opponents)
        {
            var collissionChecks = await Task.WhenAll(opponents
                                                      .Select(opponent => IsCollidedWith(player, opponent)));

            var collided = collissionChecks
                           .Where(x => x.IsCollided)
                           .Select(x => x.Target);

            var sortedDictionary = new SortedDictionary <int, List <IPlayerActor> >();

            foreach (var grain in collided.Append(player))
            {
                var info = await grain.GetState();

                if (!sortedDictionary.ContainsKey(info.SpriteSize))
                {
                    sortedDictionary.Add(info.SpriteSize, new List <IPlayerActor>());
                }

                sortedDictionary[info.SpriteSize].Add(grain);
            }

            var loosers = sortedDictionary
                          .Take(sortedDictionary.Count - 1)
                          .SelectMany(k => k.Value)
                          .ToList();

            var winner = sortedDictionary.Count > 1 ? sortedDictionary.LastOrDefault().Value?.LastOrDefault() : null;

            var result = new CollisionResult
            {
                Loosers = loosers,
                Winner  = winner,
            };

            return(result);
        }
Пример #27
0
        public void CheckBounce(SpriteGameObject other)
        {
            if (!this.CollidesWith(other))
            {
                return;
            }

            CollisionResult side = this.CollisionSide(other);

            switch (side)
            {
            case CollisionResult.LEFT:
                position.X = other.Position.X + other.Width + this.Center.X;
                // decrease velocity by 70%
                velocity.X = velocity.X * Bounciness;
                break;

            case CollisionResult.RIGHT:
                position.X = other.Position.X - this.Center.X;
                // decrease velocity by 70%
                velocity.X = velocity.X * Bounciness;
                break;

            case CollisionResult.TOP:
                position.Y = other.Position.Y - this.Center.Y;
                // decrease velocity by 70%
                velocity.Y = velocity.Y * Bounciness;
                break;

            case CollisionResult.BOTTOM:
                position.Y = other.Position.Y - this.Center.Y + 1;
                // decrease velocity by 70%
                velocity.Y = velocity.Y * Bounciness;
                // add friction
                velocity = velocity * friction;
                break;
            }
        }
Пример #28
0
        public void Collide(float s, PhysicsGroupType groupType, ICollide other)
        {
            if (groupType == PhysicsGroupType.Physical)
            {
                Weapon.Collide(s, groupType, other);

                CollisionResult playerCollision = other.Collide(s, groupType, this.collision, null);
                if (playerCollision)
                {
                    if (collisionResult)
                    {
                        //Not sure if necessary, but if we have multiple collisions in a single frame, stop all movement.
                        collisionResult.PositionA = collision.Position;
                        collisionResult.VelocityA = Vector2.Zero;
                    }
                    else
                    {
                        collisionResult = playerCollision;
                    }
                    TakeDamage(playerCollision.Identity);
                }
            }
        }
Пример #29
0
    void    OnCollisionEnter(Collision other)
    {
        switch (other.gameObject.tag)
        {
        case "Player":
        case "Wall":
        {
            CollisionResult result = new CollisionResult();

            result.object0    = this.gameObject;
            result.object1    = other.gameObject;
            result.is_trigger = false;

            if (other.contacts.Length > 0)
            {
                result.option0 = (object)other.contacts[0];
            }

            this.control.collision_results.Add(result);
        }
        break;
        }
    }
Пример #30
0
        public override void Click(Entity entity, ItemStack item)
        {
            if (!(entity is PlayerEntity))
            {
                // TODO: non-player support
                return;
            }
            PlayerEntity player = (PlayerEntity)entity;

            if (player.LastClick + 0.2 > player.TheRegion.GlobalTickTime)
            {
                return;
            }
            Location        eye = player.ItemSource();
            Location        adj = player.ItemDir * 20f;
            CollisionResult cr  = player.TheRegion.Collision.CuboidLineTrace(new Location(0.1f), eye, eye + adj, player.IgnoreThis);

            if (!cr.Hit)
            {
                return;
            }
            ApplyHook(player, item, cr.Position, cr.HitEnt);
        }
Пример #31
0
    protected void    on_trigger_common(Collider other)
    {
        switch (other.gameObject.tag)
        {
        case "Item":
        {
            if (GameRoot.get().isNowCakeBiking())
            {
                CollisionResult result = new CollisionResult();

                result.object0    = this.gameObject;
                result.object1    = other.gameObject;
                result.is_trigger = true;

                this.control.collision_results.Add(result);
            }
            else
            {
                // 케이크 무한제공 이외(보통 게임 중)일 때는 리모트는.
                // 아이템을 주울 수 없다.
            }
        }
        break;

        case "Door":
        {
            CollisionResult result = new CollisionResult();

            result.object0    = this.gameObject;
            result.object1    = other.gameObject;
            result.is_trigger = true;

            CollisionManager.getInstance().results.Add(result);
        }
        break;
        }
    }
Пример #32
0
    protected void    on_trigger_common(Collider other)
    {
        switch (other.gameObject.tag)
        {
        case "Item":
        {
            if (GameRoot.get().isNowCakeBiking())
            {
                CollisionResult result = new CollisionResult();

                result.object0    = this.gameObject;
                result.object1    = other.gameObject;
                result.is_trigger = true;

                this.control.collision_results.Add(result);
            }
            else
            {
                // 耳€?댄겕 臾댄븳?쒓났 ?댁쇅(蹂댄넻 寃뚯엫 以????뚮뒗 由щえ?몃뒗.
                // ?꾩씠?쒖쓣 二쇱슱 ???녿떎.
            }
        }
        break;

        case "Door":
        {
            CollisionResult result = new CollisionResult();

            result.object0    = this.gameObject;
            result.object1    = other.gameObject;
            result.is_trigger = true;

            CollisionManager.getInstance().results.Add(result);
        }
        break;
        }
    }
Пример #33
0
        public CollisionResult Collide(float s, PhysicsGroupType groupType, PhysicsObject physicsObject, CollisionIdentity identity)
        {
            CollisionResult response = CollisionResult.None;

            if (groupType == PhysicsGroupType.Physical)
            {
                for (int i = bullets.Count - 1; i >= 0; i--)
                {
                    Circle          bullet          = bullets[i];
                    CollisionResult bulletCollision = physicsObject.Collide(s, bullet);
                    if (bulletCollision)
                    {
                        bullets.RemoveAt(i);
                        //bullet.Position = bulletCollision.PositionB;
                        //bullet.Velocity = bulletCollision.VelocityB;
                        bulletCollision.Identity = bulletIdentity;
                        response = bulletCollision;
                    }
                }
                CollisionResult result = physicsObject.Collide(s, collision);
                if (result)
                {
                    if (collisionResult)
                    {
                        collisionResult.PositionA = collision.Position;
                        collisionResult.VelocityA = Vector2.Zero;
                    }
                    else
                    {
                        collisionResult = result.Switch();
                    }
                    takeDamage(identity);
                    response = result;
                }
            }
            return(response);
        }
Пример #34
0
        public CollisionResult CollidePoint(Vector3 position, Vector3 impulse, QueryOptions options, float elasticity, Viewpoint viewpoint)
        {
            CollisionResult collisionResult = new CollisionResult();
            Vector3         vector3         = position + impulse;
            TrileInstance   instance        = (TrileInstance)null;

            if ((options & QueryOptions.Background) != QueryOptions.None)
            {
                instance = this.LevelManager.ActualInstanceAt(vector3);
            }
            if (instance == null)
            {
                NearestTriles nearestTriles = this.LevelManager.NearestTrile(vector3, options, new Viewpoint?(viewpoint));
                instance = nearestTriles.Deep ?? nearestTriles.Surface;
            }
            bool invertedGravity = (double)this.GravityFactor < 0.0;

            if (instance != null)
            {
                collisionResult = CollisionManager.CollideWithInstance(position, vector3, impulse, instance, options, elasticity, viewpoint, invertedGravity);
            }
            if (collisionResult.Collided && (invertedGravity ? ((double)impulse.Y > 0.0 ? 1 : 0) : ((double)impulse.Y < 0.0 ? 1 : 0)) != 0)
            {
                if ((double)vector3.X % 0.25 == 0.0)
                {
                    vector3.X += 1.0 / 1000.0;
                }
                if ((double)vector3.Z % 0.25 == 0.0)
                {
                    vector3.Z += 1.0 / 1000.0;
                }
                TrileInstance trileInstance = this.LevelManager.ActualInstanceAt(vector3);
                CollisionType rotatedFace;
                collisionResult.ShouldBeClamped = trileInstance == null || !trileInstance.Enabled || (rotatedFace = trileInstance.GetRotatedFace(this.CameraManager.VisibleOrientation)) == CollisionType.None || rotatedFace == CollisionType.Immaterial;
            }
            return(collisionResult);
        }
Пример #35
0
        private static CollisionResult CollideWithInstance(Vector3 origin, Vector3 destination, Vector3 impulse, TrileInstance instance, QueryOptions options, float elasticity, Viewpoint viewpoint, bool invertedGravity)
        {
            CollisionResult collisionResult = new CollisionResult();
            Vector3         normal          = -FezMath.Sign(impulse);
            FaceOrientation faceOrientation = FezMath.VisibleOrientation(viewpoint);

            if ((options & QueryOptions.Background) == QueryOptions.Background)
            {
                faceOrientation = FezMath.GetOpposite(faceOrientation);
            }
            CollisionType rotatedFace = instance.GetRotatedFace(faceOrientation);

            if (rotatedFace != CollisionType.None)
            {
                collisionResult.Destination     = instance;
                collisionResult.NearestDistance = instance.Center;
                collisionResult.Response        = CollisionManager.SolidCollision(normal, instance, origin, destination, impulse, elasticity);
                if (collisionResult.Response != Vector3.Zero)
                {
                    collisionResult.Collided = rotatedFace == CollisionType.AllSides || (rotatedFace == CollisionType.TopNoStraightLedge || rotatedFace == CollisionType.TopOnly) && (invertedGravity ? (double)normal.Y <0.0 : (double)normal.Y> 0.0);
                }
            }
            return(collisionResult);
        }
Пример #36
0
	void 	OnCollisionEnter(Collision other)
	{
		switch(other.gameObject.tag) {

			case "Player":
			case "Wall":
			{
				CollisionResult	result = new CollisionResult();
		
				result.object0    = this.gameObject;
				result.object1    = other.gameObject;
				result.is_trigger = false;

				if(other.contacts.Length > 0) {

					result.option0 = (object)other.contacts[0];
				}

				this.control.collision_results.Add(result);

			}
			break;
		}
	}
Пример #37
0
        public static bool boxToBox(Box first, Box second, out CollisionResult result)
        {
            result = new CollisionResult();

            var minkowskiDiff = minkowskiDifference(first, second);

            if (minkowskiDiff.contains(0f, 0f))
            {
                // calculate the MTV. if it is zero then we can just call this a non-collision
                result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();

                if (result.minimumTranslationVector == Vector2.Zero)
                {
                    return(false);
                }

                result.normal = -result.minimumTranslationVector;
                result.normal.Normalize();

                return(true);
            }

            return(false);
        }
Пример #38
0
        // something isnt right here with this one
        static bool circleToPolygon2(Circle circle, Polygon polygon, out CollisionResult result)
        {
            result = new CollisionResult();

            var closestPointIndex     = -1;
            var poly2Circle           = circle.position - polygon.position;
            var poly2CircleNormalized = Vector2.Normalize(poly2Circle);
            var max = float.MinValue;

            for (var i = 0; i < polygon.points.Length; i++)
            {
                var projection = Vector2.Dot(polygon.points[i], poly2CircleNormalized);
                if (max < projection)
                {
                    closestPointIndex = i;
                    max = projection;
                }
            }

            var poly2CircleLength = poly2Circle.Length();

            if (poly2CircleLength - max - circle.radius > 0 && poly2CircleLength > 0)
            {
                return(false);
            }

            // we have a collision
            // find the closest point on the polygon. we know the closest index so we only have 2 edges to test
            var prePointIndex  = closestPointIndex - 1;
            var postPointIndex = closestPointIndex + 1;

            // handle wrapping the points
            if (prePointIndex < 0)
            {
                prePointIndex = polygon.points.Length - 1;
            }

            if (postPointIndex == polygon.points.Length)
            {
                postPointIndex = 0;
            }

            var   circleCenter = circle.position - polygon.position;
            var   closest1 = closestPointOnLine(polygon.points[prePointIndex], polygon.points[closestPointIndex], circleCenter);
            var   closest2 = closestPointOnLine(polygon.points[closestPointIndex], polygon.points[postPointIndex], circleCenter);
            float distance1, distance2;

            Vector2.DistanceSquared(ref circleCenter, ref closest1, out distance1);
            Vector2.DistanceSquared(ref circleCenter, ref closest2, out distance2);

            var radiusSquared = circle.radius * circle.radius;

            float seperationDistance;

            if (distance1 < distance2)
            {
                // make sure the squared distance is less than our radius squared else we are not colliding
                if (distance1 > radiusSquared)
                {
                    return(false);
                }

                seperationDistance = circle.radius - Mathf.sqrt(distance1);
                var edge = polygon.points[closestPointIndex] - polygon.points[prePointIndex];
                result.normal = new Vector2(edge.Y, -edge.X);
                result.point  = polygon.position + closest1;
            }
            else
            {
                // make sure the squared distance is less than our radius squared else we are not colliding
                if (distance2 > radiusSquared)
                {
                    return(false);
                }

                seperationDistance = circle.radius - Mathf.sqrt(distance2);
                var edge = polygon.points[postPointIndex] - polygon.points[closestPointIndex];
                result.normal = new Vector2(edge.Y, -edge.X);
                result.point  = polygon.position + closest2;
            }

            result.normal.Normalize();
            result.minimumTranslationVector = result.normal * -seperationDistance;

            return(true);
        }
Пример #39
0
	public void		removeResult(CollisionResult result)
	{
		this.results.Remove(result);
	}
Пример #40
0
        public void UpdateBrushHighLight(Vector3 Origin, Vector3 Direction, Vector4 Color, int ToolGroup, int Shape, float BrushRadius, float Radius)
        {
            if (FileManager.CurrentWorldFile == null || FileManager.MasteryFile == null)
            {
                return;
            }
            CollisionResults Results = new CollisionResults();

            switch (ToolGroup)
            {
            case 0:
                Results.AddRange(RayCastTerrain(Origin, Direction, Radius));
                break;

            case 1:

                Results.AddRange(RayCastWater(Origin, Direction, Radius));
                break;

            case 2:
                Results.AddRange(RayCastWater(Origin, Direction, Radius));
                Results.AddRange(RayCastTerrain(Origin, Direction, Radius));
                break;
            }
            if (Results.Count == 0)
            {
                return;
            }

            CollisionResult Result      = Results.GetClosest();
            int             SelectedLOD = FileManager.CurrentWorldFile.LODID;

            //Editing Bounds
            Vector2 A1 = new Vector2(Result.CollisionPoint.X - Radius, Result.CollisionPoint.Y - BrushRadius);
            Vector2 A2 = new Vector2(Result.CollisionPoint.X + Radius, Result.CollisionPoint.Y + BrushRadius);

            for (int i = 0; i < TerrainGeometries.Count; i++)
            {
                if (TerrainGeometries[i].WorldFile.LODID != SelectedLOD)
                {
                    continue;
                }
                Vector2 B1 = TerrainGeometries[i].WorldFile.GetA();
                Vector2 B2 = TerrainGeometries[i].WorldFile.GetB();

                if (A1.X < B2.X && A2.X > B1.X && A1.Y < B2.Y && A2.Y > B1.Y)
                {
                    if (Result.GeometryName.Contains("Water"))
                    {
                        WaterGeometries[i].SetHighLight(Result.CollisionPoint, Color, Shape, BrushRadius);
                    }
                    else if (Result.GeometryName.Contains("Terrain"))
                    {
                        TerrainGeometries[i].SetHighLight(Result.CollisionPoint, Color, Shape, BrushRadius);
                    }
                }
                else
                {
                    TerrainGeometries[i].SetHighLight(Result.CollisionPoint, new Vector4(), Shape, 0);
                    WaterGeometries[i].SetHighLight(Result.CollisionPoint, new Vector4(), Shape, 0);
                }
            }
        }
Пример #41
0
        public CollisionResults RayCastWater(Vector3 Origin, Vector3 Direction, float Range, bool HasCurrentChunkLock)
        {
            if (FileManager.MasteryFile == null)
            {
                return(new CollisionResults());
            }

            int LOD = FileManager.CurrentWorldFile.LODID;

            SettingsContainer Settings         = FileManager.MasteryFile.Settings;
            List <WorldFile>  ActiveWorldFiles = FileManager.MasteryFile.ActiveWorldFiles;

            CollisionResults Results = new CollisionResults();

            List <Vector2> QuadCheck = new List <Vector2>();

            if (HasCurrentChunkLock)
            {
                if (FileManager.CurrentWorldFile != null)
                {
                    float TerrainScale = FileManager.CurrentWorldFile.TerrainScale;
                    float HeightScale  = FileManager.CurrentWorldFile.HeightScale;
                    int[,] HeightMap      = FileManager.CurrentWorldFile.HeightMap;
                    int[,] WaterHeightMap = FileManager.CurrentWorldFile.WaterHeightMap;

                    float Precision = TerrainScale * 0.5f;

                    for (float j = 0; j < Range; j += Precision)
                    {
                        Vector3 CurrentPosition       = Origin + (Direction * j);
                        Vector3 CurrentVertexPosition = (CurrentPosition - FileManager.CurrentWorldFile.GetPosition()) / TerrainScale;

                        int VX = (int)Math.Floor(CurrentVertexPosition.X);
                        int VY = (int)Math.Floor(CurrentVertexPosition.Y);

                        if (VX < 0 || VY < 0 || VX >= HeightMap.GetLength(0) - 1 || VY >= HeightMap.GetLength(1) - 1)
                        {
                            continue;
                        }

                        float MidPoint =
                            (HeightMap[VX, VY] + HeightMap[VX + 1, VY] + HeightMap[VX, VY + 1] + HeightMap[VX + 1, VY + 1] +
                             WaterHeightMap[VX, VY] + WaterHeightMap[VX + 1, VY] + WaterHeightMap[VX, VY + 1] + WaterHeightMap[VX + 1, VY + 1]) / 4;

                        Vector3[] QuadVertices =
                        {
                            new Vector3(0,                       0, (WaterHeightMap[VX,     VY] + HeightMap[VX,         VY]) * HeightScale),
                            new Vector3(TerrainScale,            0, (WaterHeightMap[VX + 1, VY] + HeightMap[VX + 1,     VY]) * HeightScale),
                            new Vector3(0,            TerrainScale, (WaterHeightMap[VX,     VY + 1] + HeightMap[VX,     VY + 1]) * HeightScale),
                            new Vector3(TerrainScale, TerrainScale, (WaterHeightMap[VX + 1, VY + 1] + HeightMap[VX + 1, VY + 1]) * HeightScale)
                        };

                        if (!QuadCheck.Contains(new Vector2(VX, VY)))
                        {
                            QuadCheck.Add(new Vector2(VX, VY));

                            Vector3 VertexWorldPosition = FileManager.CurrentWorldFile.GetPosition() + new Vector3(VX * TerrainScale, VY * TerrainScale, 0);

                            for (int k = 0; k < Indices.Length; k += 3)
                            {
                                Vector3 V0 = VertexWorldPosition + QuadVertices[Indices[k]];
                                Vector3 V1 = VertexWorldPosition + QuadVertices[Indices[k + 1]];
                                Vector3 V2 = VertexWorldPosition + QuadVertices[Indices[k + 2]];

                                if (CollisionUtil.Intersect(V0, V1, V2, Origin, Direction))
                                {
                                    TerrainWaterContainer WaterGeom = WaterGeometries.Where(x => x.WorldFile.FileName == FileManager.CurrentWorldFile.FileName).First();

                                    Vector3         CollisionPoint = CollisionUtil.GetCollisionPoint(V0, V1, V2, Origin, Direction);
                                    CollisionResult Result         = new CollisionResult(
                                        V0,
                                        V1,
                                        V2,
                                        Origin,
                                        CollisionPoint,
                                        WaterGeom.Geom);
                                    Results.Add(Result);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                int PX = (int)Math.Floor(Origin.X / Settings.ChunkSize);
                int PY = (int)Math.Floor(Origin.Y / Settings.ChunkSize);

                for (int i = 0; i < ActiveWorldFiles.Count; i++)
                {
                    int ValidLOD = LOD == -1 ? ActiveWorldFiles[i].LODID : LOD;
                    if (Math.Abs(ActiveWorldFiles[i].IDX - PX) <= Settings.ChunkSelectionRadius && Math.Abs(ActiveWorldFiles[i].IDY - PY) < Settings.ChunkSelectionRadius && ActiveWorldFiles[i].LODID == ValidLOD)
                    {
                        float TerrainScale = ActiveWorldFiles[i].TerrainScale;
                        float HeightScale  = ActiveWorldFiles[i].HeightScale;
                        int[,] HeightMap      = ActiveWorldFiles[i].HeightMap;
                        int[,] WaterHeightMap = FileManager.CurrentWorldFile.WaterHeightMap;

                        float Precision = TerrainScale * 0.5f;

                        for (float j = 0; j < Range; j += Precision)
                        {
                            Vector3 CurrentPosition       = Origin + (Direction * j);
                            Vector3 CurrentVertexPosition = (CurrentPosition - ActiveWorldFiles[i].GetPosition()) / TerrainScale;

                            int VX = (int)Math.Floor(CurrentVertexPosition.X);
                            int VY = (int)Math.Floor(CurrentVertexPosition.Y);

                            if (VX < 0 || VY < 0 || VX >= HeightMap.GetLength(0) - 1 || VY >= HeightMap.GetLength(1) - 1)
                            {
                                continue;
                            }
                            float MidPoint =
                                (HeightMap[VX, VY] + HeightMap[VX + 1, VY] + HeightMap[VX, VY + 1] + HeightMap[VX + 1, VY + 1] +
                                 WaterHeightMap[VX, VY] + WaterHeightMap[VX + 1, VY] + WaterHeightMap[VX, VY + 1] + WaterHeightMap[VX + 1, VY + 1]) / 4;

                            Vector3[] QuadVertices =
                            {
                                new Vector3(0,                       0, (WaterHeightMap[VX,     VY] + HeightMap[VX,         VY]) * HeightScale),
                                new Vector3(TerrainScale,            0, (WaterHeightMap[VX + 1, VY] + HeightMap[VX + 1,     VY]) * HeightScale),
                                new Vector3(0,            TerrainScale, (WaterHeightMap[VX,     VY + 1] + HeightMap[VX,     VY + 1]) * HeightScale),
                                new Vector3(TerrainScale, TerrainScale, (WaterHeightMap[VX + 1, VY + 1] + HeightMap[VX + 1, VY + 1]) * HeightScale)
                            };

                            if (!QuadCheck.Contains(new Vector2(VX, VY)))
                            {
                                QuadCheck.Add(new Vector2(VX, VY));

                                Vector3 VertexWorldPosition = ActiveWorldFiles[i].GetPosition() + new Vector3(VX * TerrainScale, VY * TerrainScale, 0);

                                for (int k = 0; k < Indices.Length; k += 3)
                                {
                                    Vector3 V0 = VertexWorldPosition + QuadVertices[Indices[k]];
                                    Vector3 V1 = VertexWorldPosition + QuadVertices[Indices[k + 1]];
                                    Vector3 V2 = VertexWorldPosition + QuadVertices[Indices[k + 2]];

                                    if (CollisionUtil.Intersect(V0, V1, V2, Origin, Direction))
                                    {
                                        Vector3 CollisionPoint = CollisionUtil.GetCollisionPoint(V0, V1, V2, Origin, Direction);

                                        TerrainWaterContainer WaterGeom = WaterGeometries.Where(x => x.WorldFile.FileName == FileManager.CurrentWorldFile.FileName).First();

                                        CollisionResult Result = new CollisionResult(
                                            V0,
                                            V1,
                                            V2,
                                            Origin,
                                            CollisionPoint,
                                            WaterGeom.Geom);
                                        Results.Add(Result);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(Results);
        }
Пример #42
0
		/// <summary>
		/// checks for a collision between two Polygons
		/// </summary>
		/// <returns>The collision.</returns>
		/// <param name="first">Polygon a.</param>
		/// <param name="second">Polygon b.</param>
		public static bool polygonToPolygon( Polygon first, Polygon second, out CollisionResult result )
		{
			result = new CollisionResult();
			var isIntersecting = true;

			var firstEdges = first.edgeNormals;
			var secondEdges = second.edgeNormals;
			var minIntervalDistance = float.PositiveInfinity;
			var translationAxis = new Vector2();
			var polygonOffset = first.position - second.position;
			Vector2 axis;

			// Loop through all the edges of both polygons
			for( var edgeIndex = 0; edgeIndex < firstEdges.Length + secondEdges.Length; edgeIndex++ )
			{
				// 1. Find if the polygons are currently intersecting
				// Polygons have the normalized axis perpendicular to the current edge cached for us
				if( edgeIndex < firstEdges.Length )
					axis = firstEdges[edgeIndex];
				else
					axis = secondEdges[edgeIndex - firstEdges.Length];

				// Find the projection of the polygon on the current axis
				float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
				var intervalDist = 0f;
				getInterval( axis, first, ref minA, ref maxA );
				getInterval( axis, second, ref minB, ref maxB );

				// get our interval to be space of the second Polygon. Offset by the difference in position projected on the axis.
				float relativeIntervalOffset;
				Vector2.Dot( ref polygonOffset, ref axis, out relativeIntervalOffset );
				minA += relativeIntervalOffset;
				maxA += relativeIntervalOffset;

				// check if the polygon projections are currentlty intersecting
				intervalDist = intervalDistance( minA, maxA, minB, maxB );
				if( intervalDist > 0 )
					isIntersecting = false;


				// for Poly-to-Poly casts add a Vector2? parameter called deltaMovement. In the interest of speed we do not use it here
				// 2. Now find if the polygons *will* intersect. only bother checking if we have some velocity
				//if( deltaMovement.HasValue )
				//{
				//	// Project the velocity on the current axis
				//	var velocityProjection = Vector2.Dot( axis, deltaMovement.Value );

				//	// Get the projection of polygon A during the movement
				//	if( velocityProjection < 0 )
				//		minA += velocityProjection;
				//	else
				//		maxA += velocityProjection;

				//	// Do the same test as above for the new projection
				//	intervalDist = intervalDistance( minA, maxA, minB, maxB );
				//	if( intervalDist > 0 )
				//		willIntersect = false;
				//}


				// If the polygons are not intersecting and won't intersect, exit the loop
				if( !isIntersecting )
					return false;

				// Check if the current interval distance is the minimum one. If so store the interval distance and the current distance.
				// This will be used to calculate the minimum translation vector
				intervalDist = Math.Abs( intervalDist );
				if( intervalDist < minIntervalDistance )
				{
					minIntervalDistance = intervalDist;
					translationAxis = axis;

					if( Vector2.Dot( translationAxis, polygonOffset ) < 0 )
						translationAxis = -translationAxis;
				}
			}

			// The minimum translation vector can be used to push the polygons appart.
			result.normal = translationAxis;
			result.minimumTranslationVector = -translationAxis * minIntervalDistance;

			return true;
		}
Пример #43
0
 /// <summary>
 /// 处理碰撞,空函数
 /// </summary>
 /// <param name="result"></param>
 /// <param name="objB"></param>
 public void HandleCollision(CollisionResult result, ICollideObj objA, ICollideObj objB)
 {
 }
        /// <summary>
        /// Mover Elipsoide con detección de colisiones, sliding y gravedad.
        /// Se actualiza la posición del centro del Elipsoide
        /// </summary>
        /// <param name="characterElipsoid">Elipsoide del cuerpo a mover</param>
        /// <param name="movementVector">Movimiento a realizar</param>
        /// <param name="colliders">Obstáculos contra los cuales se puede colisionar</param>
        /// <returns>Desplazamiento relativo final efecutado al Elipsoide</returns> 
        public Vector3 moveCharacter(TgcElipsoid characterElipsoid, Vector3 movementVector, List<Collider> colliders)
        {
            //Guardar posicion original del Elipsoide
            Vector3 originalElipsoidCenter = characterElipsoid.Center;

            //Pasar elipsoid space
            Vector3 eCenter = TgcVectorUtils.div(characterElipsoid.Center, characterElipsoid.Radius);
            Vector3 eMovementVector = TgcVectorUtils.div(movementVector, characterElipsoid.Radius);
            eSphere.setValues(eCenter, 1);
            Vector3 eOrigCenter = eSphere.Center;


            //Ver si la distancia a recorrer es para tener en cuenta
            float distanceToTravelSq = movementVector.LengthSq();
            if (distanceToTravelSq >= EPSILON)
            {
                //Mover la distancia pedida
                selectPotentialColliders(characterElipsoid, movementVector, colliders);
                this.result = doCollideWithWorld(eSphere, eMovementVector, characterElipsoid.Radius, objetosCandidatos, 0, movementSphere, 1);
            }

            //Aplicar gravedad
            if (gravityEnabled)
            {
                //Mover con gravedad
                Vector3 eGravity = TgcVectorUtils.div(gravityForce, characterElipsoid.Radius);
                selectPotentialColliders(characterElipsoid, eGravity, colliders);
                this.result = doCollideWithWorld(eSphere, eGravity, characterElipsoid.Radius, objetosCandidatos, 0, movementSphere, onGroundMinDotValue);
            }

            //Mover Elipsoid pasando valores de colision a R3
            Vector3 movement = TgcVectorUtils.mul(eSphere.Center - eOrigCenter, characterElipsoid.Radius);
            characterElipsoid.moveCenter(movement);

            //Ajustar resultados
            result.realMovmentVector = TgcVectorUtils.mul(result.realMovmentVector, characterElipsoid.Radius);
            result.collisionPoint = TgcVectorUtils.mul(result.collisionPoint, characterElipsoid.Radius);


            return movement;
        }
Пример #45
0
        /// <summary>
        /// Verifica si este poligono esta colisionando o va a colisionar
        /// con otro poligono dado.
        /// Esta verificación se realiza utilizando SAT (Separating Axis Theorem) la cual explica
        /// que, si existe una linea en el plano que pueda separar dos distintas figuras en diferentes
        /// lados por completo, entonces estas figuras no están colisionando.
        /// Nota: Este teorema solo debería aplicarse ante poligonos concavos, de otra forma el algoritmo
        /// no daria una respuesta correcta ante poligonos convexos.
        /// </summary>
        /// <param name="polygon2">Segundo poligono con el cual se hará la verificacion</param>
        /// <param name="distance">Distancia por la cual se movera el poligono principal (this)</param>
        /// <param name="result">Referencia del objeto que contendrá la información necesaria sobre 
        /// si se esta intersectando, si se intersectará y la distancia necesaria 
        /// para evitar una intersección</param>
        protected override CollisionResult IntersectWithPolygon(Polygon polygon2, ref Vector2 distance)
        {
            CollisionResult result = new CollisionResult();
            result.triggeringBody = this;
            result.affectedBody = polygon2;
            // Se asume que ambos poligonos intersectan hasta que
            // se pueda demostrar lo contrario
            result.intersect = true;
            result.willIntersect = true;
            // Se obtiene la cantidad de lados del poligono principal
            // y del segundo poligono
            int sideCountA = this.sides.Count;
            int sideCountB = polygon2.Sides.Count;
            float minIntervalDistance = float.PositiveInfinity;
            Vector2 translationAxis = new Vector2();
            // Lado actual a analizar
            Line currentSide;

            // Se realiza una verificacion por cada uno de los lados de ambos poligonos
            // hasta que pueda encontrarse alguna separación entre ambos o hasta que se hayan
            // verificado todos los lados
            for (int sideIndex = 0; sideIndex < sideCountA + sideCountB; sideIndex++)
            {
                if (sideIndex < sideCountA)
                {
                    currentSide = this.sides[sideIndex];
                }
                else
                {
                    currentSide = polygon2.Sides[sideIndex - sideCountA];
                }
                // Se obtiene un Vector perpendicular al lado actual con valores unitarios,
                // esto servira para obtener el eje sobre el cual deben hacerse las proyecciones
                Vector2 axis = new Vector2(-currentSide.Edge.Y, currentSide.Edge.X);
                axis.Normalize();

                // Se proyectan ambos poligonos sobre el mismo eje
                float minA = 0; float minB = 0; float maxA = 0; float maxB = 0;
                this.Project(ref axis, out minA, out maxA);
                polygon2.Project(ref axis, out minB, out maxB);

                // Se obtiene el intervalo entre ambos poligonos sobre el eje,
                // si el intervalo (separación) es mayor a 0 entonces los poligonos
                // no están intersectando
                float intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.intersect = false;

                // Luego se realizan los mismos calculos pero sumando el vector
                // de velocidad al poligono en (posible) movimiento
                float velocityProjection = Vector2.Dot(axis, distance);

                //if (velocityProjection < 0)
                //{
                    minA += velocityProjection;
                //}
                //else
                //{
                    maxA += velocityProjection;
                //}

                // Si el intervalo de distancia es menor a 0 con el poligono en movimiento,
                // entonces los poligonos tambien intersectaran al moverse
                intervalDistance = IntervalDistance(minA, maxA, minB, maxB);
                if (intervalDistance > 0) result.willIntersect = false;

                // Si ya sabemos que los poligonos estan intersectando y van a intersectar,
                // no hay mucho mas que hacer aquí asi que terminamos las verificaciones
                if (result.intersect == false && result.willIntersect == false)
                {
                    break;
                }

                // Si el intervalo de distancia es el minimo, se guarda
                // junto con el eje donde fue encontrado para asi poder separar
                // a los poligonos en esa dirección
                intervalDistance = Math.Abs(intervalDistance);
                if (intervalDistance < minIntervalDistance)
                {
                    minIntervalDistance = intervalDistance;
                    translationAxis = axis;

                    Vector2 d = this.Center - polygon2.Center;
                    if (Vector2.Dot(d, translationAxis) < 0)
                    {
                        translationAxis = -translationAxis;
                    }
                }
            }

            // El vector minimo de transición
            // servira para separar ambos poligonos en caso de que colisionen.
            if (result.willIntersect)
            {
                result.minimumTranslationVector =
                       translationAxis * minIntervalDistance;
            }

            result.translationAxis = translationAxis;
            return result;
        }
Пример #46
0
	protected	void	on_trigger_common(Collider other)
	{
		switch(other.gameObject.tag) {

			case "Door":
			{
				CollisionResult	result = new CollisionResult();
		
				result.object0    = this.gameObject;
				result.object1    = other.gameObject;
				result.is_trigger = false;

				CollisionManager.getInstance().results.Add(result);
			}
			break;
		}
	}
Пример #47
0
        /// <summary>
        /// Verifica si este poligono esta colisionando o va a colisionar
        /// con una esféra dada.
        /// Para esto se ubica el punto centro de la esfera en la región de voronoi
        /// que le corresponde según el poligono, de forma que obtenemos el punto
        /// mas cercano de la esfera al poligono junto al respectivo eje.
        /// </summary>
        /// <param name="sphere">Esféra con la cual se hará la verificacion</param>
        /// <param name="distance">Distancia por la cual se movera este poligono</param>
        /// <param name="result">Referencia del objeto que contendrá la información necesaria sobre 
        /// si se esta intersectando, si se intersectará y la distancia necesaria 
        /// para evitar una intersección</param>
        protected override CollisionResult IntersectWithSphere(Sphere sphere, ref Vector2 distance)
        {
            CollisionResult result = new CollisionResult();
            result.triggeringBody = this;
            result.affectedBody = sphere;
            // Empezamos asumiendo que las dos figuras no
            // se encuentran intersectando
            result.intersect = false;
            result.willIntersect = false;
            // Se toman tanto la cantidad de puntos
            // como la cantidad de lados del poligono
            int sideCountPolygon = this.sides.Count;
            int pointCountPolygon = this.vertices.Count;
            // Dos valores distintos para guardar
            float minIntervalDistanceAfterMove = float.PositiveInfinity;
            float minIntervalDistance = float.PositiveInfinity;
            Vector2 translationAxis = new Vector2();

            // Ahora se estudia cada lado del poligono para verificar si el centro
            // de la esfera se encuentra perpendicular a algun punto de ese lado
            for (int sideIndex = 0; sideIndex < sideCountPolygon; sideIndex++)
            {
                Line currentSide = this.sides[sideIndex];

                // Se crea un vector paralelo al lado donde puedan proyectase
                // ambos puntos del lado actual mas el centro de la esfera
                Vector2 axis = new Vector2(currentSide.Edge.X, currentSide.Edge.Y);
                axis.Normalize();

                float minA = Vector2.Dot(axis, currentSide.StartPoint);
                float maxA = Vector2.Dot(axis, currentSide.EndPoint);
                float centerB = Vector2.Dot(axis, sphere.Center);

                float velocityProjection = Vector2.Dot(axis, distance);

                // Se realiza un chequeo preliminar antes de sumar el vector
                // de distancia
                #region Verificaciones de intersección actual

                // Si el punto centro se encuentra perpendicular a algun
                // punto del lado actual, entonces la esfera puede encontrarse en esa region
                if (minA <= centerB && maxA >= centerB)
                {
                    // Creamos un eje perpendicular a la linea para obtener la distancia
                    // entre un punto de la linea y el centro de la esfera
                    axis = new Vector2(-currentSide.Edge.Y, currentSide.Edge.X);
                    axis.Normalize();

                    // Ya que el eje es perpendicular, tanto el punto inicial de la linea
                    // como el final terminan en la misma posicion al ser proyectados
                    float pointA = Vector2.Dot(axis, currentSide.EndPoint);
                    float pointB = Vector2.Dot(axis, sphere.Center);

                    // Se obtiene el intervalo y se guarda en caso de que sea menor
                    // al intervalo anterior (La esfera se encontrara en la region de voronoi
                    // que tenga el punto mas cercano desde la esfera hacia el poligono)
                    float intervalDistance = Math.Abs(pointA - pointB);
                    if (intervalDistance < minIntervalDistance)
                    {
                        minIntervalDistance = intervalDistance;
                    }
                }
                #endregion

                // Aplicamos la proyeccion de velocidad a el lado actual
                if (velocityProjection < 0)
                {
                    minA += velocityProjection;
                }
                else
                {
                    maxA += velocityProjection;
                }

                // Si el punto centro se encuentra perpendicular a algun
                // punto del lado actual, entonces la esfera puede encontrarse en esa region
                if (minA <= centerB && maxA >= centerB)
                {
                    // Creamos un eje perpendicular a la linea para obtener la distancia
                    // entre un punto de la linea y el centro de la esfera
                    axis = new Vector2(-currentSide.Edge.Y, currentSide.Edge.X);
                    axis.Normalize();

                    // Volvemos a aplicar la proyeccion de velocidad puesto que
                    // esta vez estamos proyectando en un diferente eje
                    velocityProjection = Vector2.Dot(axis, distance);
                    // Ya que el eje es perpendicular, tanto el punto inicial de la linea
                    // como el final terminan en la misma posicion al ser proyectados
                    float pointA = Vector2.Dot(axis, currentSide.EndPoint) + velocityProjection;
                    float pointB = Vector2.Dot(axis, sphere.Center);

                    // Se obtiene el intervalo y se guarda en caso de que sea menor
                    // al intervalo anterior (La esfera se encontrara en la region de voronoi
                    // que tenga el punto mas cercano desde la esfera hacia el poligono)
                    float intervalDistance = Math.Abs(pointA - pointB);
                    if (intervalDistance < minIntervalDistanceAfterMove)
                    {
                        minIntervalDistanceAfterMove = intervalDistance;
                        translationAxis = axis;

                        Vector2 d = this.Center - sphere.Center;
                        if (Vector2.Dot(d, translationAxis) < 0)
                        {
                            translationAxis = -translationAxis;
                        }
                    }
                }
            }

            // Luego se estudia la distancia entre cada vertice del poligono
            // contra el centro de la esfera, si se encuentra alguna distancia
            // menor que las ya guardadas entonces se guarda
            for (int pointIndex = 0; pointIndex < pointCountPolygon; pointIndex++)
            {
                Vector2 currentPoint = this.vertices[pointIndex];
                // Creamos una linea que vaya desde el vertice hasta el centro
                // de la esfera, sumandole el vector de distancia al vertice
                Line line = new Line(currentPoint + distance, sphere.Center);

                Vector2 axis = new Vector2(line.Edge.X, line.Edge.Y);
                axis.Normalize();

                if (line.Lenght < minIntervalDistanceAfterMove)
                {
                    minIntervalDistanceAfterMove = line.Lenght;
                    translationAxis = axis;

                    Vector2 d = this.Center - sphere.Center;
                    if (Vector2.Dot(d, translationAxis) < 0)
                    {
                        translationAxis = -translationAxis;
                    }
                }

                // Misma verificacion sin sumar el vector de distancia
                #region Verificaciones de intersección actual
                line = new Line(currentPoint, sphere.Center);

                axis = new Vector2(line.Edge.X, line.Edge.Y);
                axis.Normalize();

                if (line.Lenght < minIntervalDistance)
                {
                    minIntervalDistance = line.Lenght;
                }
                #endregion
            }

            // Se verifica si el poligono intersecta
            bool isInside = this.PointInBody(sphere.Center);
            if (isInside || minIntervalDistance < sphere.Radius)
            {
                result.intersect = true;
            }

            // Se verifica si intersectaran y aplica un vector de transicion
            // diferente dependiendo de si el centro de la esfera se encuentra
            // dentro o fuera del poligono
            isInside = this.PointInBody(sphere.Center - distance);
            if (isInside)
            {
                result.minimumTranslationVector =
                       translationAxis * (sphere.Radius + minIntervalDistanceAfterMove);
                result.willIntersect = true;
            }
            else if (minIntervalDistanceAfterMove < sphere.Radius)
            {
                result.minimumTranslationVector =
                       translationAxis * Math.Abs(sphere.Radius - minIntervalDistanceAfterMove);
                result.willIntersect = true;
            }

            result.translationAxis = translationAxis;
            return result;
        }
Пример #48
0
Файл: Box.cs Проект: prime31/Nez
		public override bool pointCollidesWithShape( Vector2 point, out CollisionResult result )
		{
			if( isUnrotated )
				return ShapeCollisions.pointToBox( point, this, out result );

			return base.pointCollidesWithShape( point, out result );
		}
Пример #49
0
        /// <summary>
        /// note: if circle center lies in the box the collision result will be incorrect!
        /// </summary>
        /// <returns><c>true</c>, if to box was circled, <c>false</c> otherwise.</returns>
        /// <param name="first">First.</param>
        /// <param name="second">Second.</param>
        /// <param name="result">Result.</param>
        public static bool circleToBox( Circle first, Box second, out CollisionResult result )
        {
            result = new CollisionResult();

            var closestPointOnBounds = second.bounds.getClosestPointOnRectangleBorderToPoint( first.position );

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

            // see if the point on the box is less than radius from the circle
            if( sqrDistance <= first.radius * first.radius )
            {
                var distanceToCircle = first.position - closestPointOnBounds;
                var depth = distanceToCircle.Length() - first.radius;

                result.point = closestPointOnBounds;
                result.normal = Vector2.Normalize( distanceToCircle );
                result.minimumTranslationVector = depth * result.normal;

                return true;
            }

            return false;
        }
Пример #50
0
        // something isnt right here with this one
        static bool circleToPolygon2( Circle circle, Polygon polygon, out CollisionResult result )
        {
            result = new CollisionResult();

            var closestPointIndex = -1;
            var poly2Circle = circle.position - polygon.position;
            var poly2CircleNormalized = Vector2.Normalize( poly2Circle );
            var max = float.MinValue;

            for( var i = 0; i < polygon.points.Length; i++ )
            {
                var projection = Vector2.Dot( polygon.points[i], poly2CircleNormalized );
                if( max < projection )
                {
                    closestPointIndex = i;
                    max = projection;
                }
            }

            var poly2CircleLength = poly2Circle.Length();
            if( poly2CircleLength - max - circle.radius > 0 && poly2CircleLength > 0 )
                return false;

            // we have a collision
            // find the closest point on the polygon. we know the closest index so we only have 2 edges to test
            var prePointIndex = closestPointIndex - 1;
            var postPointIndex = closestPointIndex + 1;

            // handle wrapping the points
            if( prePointIndex < 0 )
                prePointIndex = polygon.points.Length - 1;

            if( postPointIndex == polygon.points.Length )
                postPointIndex = 0;

            var circleCenter = circle.position - polygon.position;
            var closest1 = closestPointOnLine( polygon.points[prePointIndex], polygon.points[closestPointIndex], circleCenter );
            var closest2 = closestPointOnLine( polygon.points[closestPointIndex], polygon.points[postPointIndex], circleCenter );
            float distance1, distance2;
            Vector2.DistanceSquared( ref circleCenter, ref closest1, out distance1 );
            Vector2.DistanceSquared( ref circleCenter, ref closest2, out distance2 );

            var radiusSquared = circle.radius * circle.radius;

            float seperationDistance;
            if( distance1 < distance2 )
            {
                // make sure the squared distance is less than our radius squared else we are not colliding
                if( distance1 > radiusSquared )
                    return false;

                seperationDistance = circle.radius - Mathf.sqrt( distance1 );
                var edge = polygon.points[closestPointIndex] - polygon.points[prePointIndex];
                result.normal = new Vector2( edge.Y, -edge.X );
                result.point = polygon.position + closest1;
            }
            else
            {
                // make sure the squared distance is less than our radius squared else we are not colliding
                if( distance2 > radiusSquared )
                    return false;

                seperationDistance = circle.radius - Mathf.sqrt( distance2 );
                var edge = polygon.points[postPointIndex] - polygon.points[closestPointIndex];
                result.normal = new Vector2( edge.Y, -edge.X );
                result.point = polygon.position + closest2;
            }

            result.normal.Normalize();
            result.minimumTranslationVector = result.normal * -seperationDistance;

            return true;
        }
Пример #51
0
        /// <summary>
        /// does an overlap check of first vs second. ShapeCollisionResult retuns the data for moving first so it isn't colliding with second.
        /// </summary>
        /// <returns><c>true</c>, if to polygon was polygoned, <c>false</c> otherwise.</returns>
        /// <param name="first">First.</param>
        /// <param name="second">Second.</param>
        /// <param name="result">Result.</param>
        public static bool polygonToPolygon( Polygon first, Polygon second, out CollisionResult result )
        {
            result = new CollisionResult();
            float timeOfCollision;

            if( polygonToPolygon( first, second, null, out result.normal, out timeOfCollision ) )
            {
                result.minimumTranslationVector = result.normal * ( timeOfCollision );
                return true;
            }

            return false;
        }
Пример #52
0
	void 	OnTriggerEnter(Collider other)
	{
		// 여분의 것과 맞지 않는 설정이므로 일단 쌓아 버린다.
		CollisionResult	result = new CollisionResult();
		
		result.object0 = this.gameObject;
		result.object1 = other.gameObject;
		result.is_trigger = false;
		
		this.collision_results.Add(result);
	}
Пример #53
0
 public void SetResult(CollisionResult result)
 => this.result = result;
Пример #54
0
		public static bool circleToPolygon( Circle circle, Polygon polygon, out CollisionResult result )
		{
			result = new CollisionResult();

			// circle position in the polygons coordinates
			var poly2Circle = circle.position - polygon.position;

			// first, we need to find the closest distance from the circle to the polygon
			float distanceSquared;
			var closestPoint = Polygon.getClosestPointOnPolygonToPoint( polygon.points, poly2Circle, out distanceSquared, out result.normal );

			// make sure the squared distance is less than our radius squared else we are not colliding. Note that if the Circle is fully
			// contained in the Polygon the distance could be larger than the radius. Because of that we also  make sure the circle position
			// is not inside the poly.
			var circleCenterInsidePoly = polygon.containsPoint( circle.position );
			if( distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly )
				return false;

			// figure out the mtv. We have to be careful to deal with circles fully contained in the polygon or with their center contained.
			Vector2 mtv;
			if( circleCenterInsidePoly )
			{
				mtv = result.normal * ( Mathf.sqrt( distanceSquared ) - circle.radius );
			}
			else
			{
				// if we have no distance that means the circle center is on the polygon edge. Move it only by its radius
				if( distanceSquared == 0 )
				{
					mtv = result.normal * circle.radius;
				}
				else
				{
					var distance = Mathf.sqrt( distanceSquared );
					mtv = -( poly2Circle - closestPoint ) * ( ( circle.radius - distance ) / distance );
				}
			}

			result.minimumTranslationVector = mtv;
			result.point = closestPoint + polygon.position;

			return true;
		}
        /// <summary>
        /// Detección de colisiones recursiva
        /// </summary>
        /// <param name="eSphere">Sphere de radio 1 pasada a Elipsoid space</param>
        /// <param name="eMovementVector">Movimiento pasado a Elipsoid space</param>
        /// <param name="eRadius">Radio de la elipsoide</param>
        /// <param name="colliders">Objetos contra los cuales colisionar</param>
        /// <param name="recursionDepth">Nivel de recursividad</param>
        /// <param name="movementSphere">Esfera real que representa el movimiento abarcado</param>
        /// <param name="slidingMinY">Minimo valor de normal Y de colision para hacer sliding</param>
        /// <returns>Resultado de colision</returns>
        public CollisionResult doCollideWithWorld(TgcBoundingSphere eSphere, Vector3 eMovementVector, Vector3 eRadius, List<Collider> colliders, int recursionDepth, TgcBoundingSphere movementSphere, float slidingMinY)
        {
            CollisionResult result = new CollisionResult();
            result.collisionFound = false;

            //Limitar recursividad
            if (recursionDepth > 5)
            {
                return result;
            }

            //Posicion deseada
            Vector3 nextSphereCenter = eSphere.Center + eMovementVector;

            //Buscar el punto de colision mas cercano de todos los objetos candidatos
            Vector3 q;
            float t;
            Vector3 n;
            float minT = float.MaxValue;
            foreach (Collider collider in colliders)
            {
                //Colisionar Sphere en movimiento contra Collider (cada Collider resuelve la colision)
                if (collider.intersectMovingElipsoid(eSphere, eMovementVector, eRadius, movementSphere, out t, out q, out n))
                {
                    //Quedarse con el menor instante de colision
                    if(t < minT)
                    {
                        minT = t;
                        result.collisionFound = true;
                        result.collisionPoint = q;
                        result.collisionNormal = n;
                        result.collider = collider;
                    }
                }
            }

            //Si nunca hubo colisión, avanzar todo lo requerido
            if (!result.collisionFound)
            {
                //Avanzar todo lo pedido
                eSphere.moveCenter(eMovementVector);
                result.realMovmentVector = eMovementVector;
                result.collisionNormal = Vector3.Empty;
                result.collisionPoint = Vector3.Empty;
                result.collider = null;
                return result;
            }


            //Solo movernos si ya no estamos muy cerca
            if (minT >= EPSILON)
            {
                //Restar un poco al instante de colision, para movernos hasta casi esa distancia
                minT -= EPSILON;
                result.realMovmentVector = eMovementVector * minT;
                eSphere.moveCenter(result.realMovmentVector);

                //Quitarle al punto de colision el EPSILON restado al movimiento, para no afectar al plano de sliding
                Vector3 v = Vector3.Normalize(result.realMovmentVector);
                result.collisionPoint -= v * EPSILON;
            }


            //Calcular plano de Sliding, como un plano tangete al punto de colision con la esfera, apuntando hacia el centro de la esfera
            Vector3 slidePlaneOrigin = result.collisionPoint;
            Vector3 slidePlaneNormal = eSphere.Center - result.collisionPoint;
            slidePlaneNormal.Normalize();
            Plane slidePlane = Plane.FromPointNormal(slidePlaneOrigin, slidePlaneNormal);

            //Calcular vector de movimiento para sliding, proyectando el punto de destino original sobre el plano de sliding
            float distance = TgcCollisionUtils.distPointPlane(nextSphereCenter, slidePlane);
            Vector3 newDestinationPoint = nextSphereCenter - distance * slidePlaneNormal;
            Vector3 slideMovementVector = newDestinationPoint - result.collisionPoint;

            //No hacer recursividad si es muy pequeño
            slideMovementVector.Scale(slideFactor);
            if (slideMovementVector.Length() < EPSILON)
            {
                return result;
            }

            //Ver si posee la suficiente pendiente en Y para hacer sliding
            if (result.collisionNormal.Y <= slidingMinY)
            {
                //Recursividad para aplicar sliding
                doCollideWithWorld(eSphere, slideMovementVector, eRadius, colliders, recursionDepth + 1, movementSphere, slidingMinY);
            }

            
            return result;
        }
Пример #56
0
        public CollisionResults RayCastTerrain(Vector3 Origin, Vector3 Direction, float Range, WorldFile File)
        {
            if (FileManager.MasteryFile == null)
            {
                return(new CollisionResults());
            }

            SettingsContainer Settings         = FileManager.MasteryFile.Settings;
            List <WorldFile>  ActiveWorldFiles = FileManager.MasteryFile.ActiveWorldFiles;

            List <Vector2>   QuadCheck = new List <Vector2>();
            CollisionResults Results   = new CollisionResults();

            float TerrainScale = File.TerrainScale;
            float HeighScale   = File.HeightScale;

            int[,] HeightMap = File.HeightMap;

            float Precision = TerrainScale * 0.5f;

            for (float j = 0; j < Range; j += Precision)
            {
                Vector3 CurrentPosition       = Origin + (Direction * j);
                Vector3 CurrentVertexPosition = (CurrentPosition - File.GetPosition()) / TerrainScale;

                int VX = (int)Math.Floor(CurrentVertexPosition.X);
                int VY = (int)Math.Floor(CurrentVertexPosition.Y);

                if (VX < 0 || VY < 0 || VX >= HeightMap.GetLength(0) - 1 || VY >= HeightMap.GetLength(1) - 1)
                {
                    continue;
                }

                Vector3[] QuadVertices =
                {
                    new Vector3(0,                       0, HeightMap[VX,     VY] * HeighScale),
                    new Vector3(TerrainScale,            0, HeightMap[VX + 1, VY] * HeighScale),
                    new Vector3(0,            TerrainScale, HeightMap[VX,     VY + 1] * HeighScale),
                    new Vector3(TerrainScale, TerrainScale, HeightMap[VX + 1, VY + 1] * HeighScale)
                };

                if (!QuadCheck.Contains(new Vector2(VX, VY)))
                {
                    QuadCheck.Add(new Vector2(VX, VY));

                    Vector3 VertexWorldPosition = File.GetPosition() + new Vector3(VX * TerrainScale, VY * TerrainScale, 0);
                    for (int k = 0; k < Indices.Length; k += 3)
                    {
                        Vector3 V0 = VertexWorldPosition + QuadVertices[Indices[k]];
                        Vector3 V1 = VertexWorldPosition + QuadVertices[Indices[k + 1]];
                        Vector3 V2 = VertexWorldPosition + QuadVertices[Indices[k + 2]];

                        if (CollisionUtil.Intersect(V0, V1, V2, Origin, Direction))
                        {
                            TerrainGeometryContainer TerrainGeom = TerrainGeometries.Where(x => x.WorldFile.FileName == FileManager.CurrentWorldFile.FileName).First();

                            Vector3         CollisionPoint = CollisionUtil.GetCollisionPoint(V0, V1, V2, Origin, Direction);
                            CollisionResult Result         = new CollisionResult(
                                V0,
                                V1,
                                V2,
                                Origin,
                                CollisionPoint,
                                TerrainGeom.TerrainGeometry);
                            Results.Add(Result);
                        }
                    }
                }
            }
            return(Results);
        }
Пример #57
0
 /// <summary>
 /// 处理重叠,空函数
 /// </summary>
 /// <param name="result"></param>
 /// <param name="objB"></param>
 public void HandleOverlap(CollisionResult result, ICollideObj objA, ICollideObj objB)
 {
 }
Пример #58
0
	void	Update()
	{
		this.resolve_collision();

		float	explode_time = 0.5f;

		// ---------------------------------------------------------------- //
		// 다음 상태로 전환할지 체크한다.

		switch(this.step.do_transition()) {

			case STEP.FLYING:
			{
				if(this.trigger_damage) {

					this.step.set_next(STEP.EXPLODE);
				}
			}
			break;

			case STEP.EXPLODE:
			{
				//if(this.explode_effect == null) {
				if(this.step.get_time() > explode_time) {

					this.step.set_next(STEP.END);
				}
			}
			break;
		}

		// ---------------------------------------------------------------- //
		// 상태 전환 시 초기화.

		while(this.step.get_next() != STEP.NONE) {

			switch(this.step.do_initialize()) {
	
				case STEP.FLYING:
				{
				}
				break;

				case STEP.EXPLODE:
				{
					this.model_node.GetComponent<Renderer>().enabled = false;
					this.explode_effect = EffectRoot.get().createYuzuExplode(this.gameObject.getPosition().Y(0.5f));

					this.coli_node.setLocalScale(Vector3.one*this.max_radius*0.0f);
				}
				break;

				case STEP.END:
				{
					this.gameObject.destroy();
				}
				break;
			}
		}

		// ---------------------------------------------------------------- //
		// 각 상태에서의 실행 처리.

		switch(this.step.do_execution(Time.deltaTime)) {

			case STEP.FLYING:
			{
				// 이동.
				this.velocity += Physics.gravity*Time.deltaTime;
				this.transform.position += this.velocity*Time.deltaTime;
			}
			break;

			case STEP.EXPLODE:
			{
				float	rate = this.step.get_time()/explode_time;

				float	scale = rate*this.max_radius;

				this.coli_node.setLocalScale(Vector3.one*scale);

				// 폭풍과의 충돌.
				// 콜라이더가 바닥에 충돌하면 그 다음 폭풍이 충돌해도 OnTriggerEnter가.
				// 호출되지 않으므로 직접 조사한다.

				RaycastHit	hit;

				if(Physics.SphereCast(this.transform.position, scale*this.coli_sphere_radius, Vector3.up, out hit, float.MinValue, LayerMask.GetMask("Enemy", "EnemyLair"))) {

					CollisionResult	result = new CollisionResult();
		
					result.object0 = this.gameObject;
					result.object1 = hit.collider.gameObject;
					result.is_trigger = true;
		
					this.collision_results.Add(result);
				}

			}
			break;
		}
	}
Пример #59
0
	void OnCollisionStay(Collision other)
	{
		switch(other.gameObject.tag) {

			case "Player":
			{
				chrBehaviorPlayer	player = other.gameObject.GetComponent<chrBehaviorPlayer>();

				if(player != null) {

					CollisionResult	result = new CollisionResult();
			
					result.object0    = this.gameObject;
					result.object1    = other.gameObject;
					result.is_trigger = false;
	
					this.collision_results.Add(result);
				}
			}
			break;
		}
	}
Пример #60
0
        public static bool circleToPolygon( Circle circle, Polygon polygon, out CollisionResult result )
        {
            result = new CollisionResult();

            // circle position in the polygons coordinates
            var poly2Circle = circle.position - polygon.position;

            // first, we need to find the closest distance from the circle to the polygon
            float distanceSquared;
            var closestPoint = polygon.getClosestPointOnPolygonToPoint( poly2Circle, out distanceSquared, out result.normal );

            // make sure the squared distance is less than our radius squared else we are not colliding
            if( distanceSquared > circle.radius * circle.radius )
                return false;

            // figure out the mtd
            var distance = Mathf.sqrt( distanceSquared );
            var mtv = ( poly2Circle - closestPoint ) * ( ( circle.radius - distance ) / distance );

            result.minimumTranslationVector = -mtv;
            result.normal.Normalize();

            return true;
        }