Exemplo n.º 1
0
        /// <summary>
        /// It checks for the collision between a collision ray and a collision sphere.
        /// </summary>
        /// <param name="sourceCollide">Source collision ray</param>
        /// <param name="targetCollide">Target collision sphere</param>
        /// <param name="result">A result report</param>
        /// <returns>True if there is a collision</returns>
        public bool TestRayintersectSphere(CollideRay sourceCollide,
                                           CollideSphere targetCollide,
                                           ref CollisionResult result)
        {
            totalCollidingCount++;

            // Test ray with the sphere
            float?distance = sourceCollide.Ray.Intersects(targetCollide.BoundingSphere);

            if (distance != null)
            {
                if (result != null)
                {
                    Vector3 dir = Vector3.Normalize(sourceCollide.Ray.Position -
                                                    targetCollide.BoundingSphere.Center);

                    Vector3 length = dir * targetCollide.Radius;

                    result.distance        = (float)distance;
                    result.detectedCollide = targetCollide;
                    result.intersect       = targetCollide.BoundingSphere.Center + length;
                    result.normal          = null;
                    result.collideCount++;
                }

                return(true);
            }

            return(false);
        }
Exemplo n.º 2
0
        /// <summary>
        /// It checks for the collision between a collision ray and a collision box.
        /// </summary>
        /// <param name="sourceCollide">Source collision ray</param>
        /// <param name="targetCollide">Target collision box</param>
        /// <param name="result">A result report</param>
        /// <returns>True if there is a collision</returns>
        public bool TestRayintersectBox(CollideRay sourceCollide,
                                        CollideBox targetCollide,
                                        ref CollisionResult result)
        {
            totalCollidingCount++;

            // Test ray with the box
            float?distance = sourceCollide.Ray.Intersects(targetCollide.BoundingBox);

            if (distance != null)
            {
                if (result != null)
                {
                    result.distance        = (float)distance;
                    result.detectedCollide = targetCollide;
                    result.intersect       = null;
                    result.normal          = null;
                    result.collideCount++;
                }

                return(true);
            }

            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// It checks for the collision between a collision ray and a collision model.
        /// </summary>
        /// <param name="sourceCollide">Source collision ray</param>
        /// <param name="targetCollide">Target collision model</param>
        /// <param name="result">A result report</param>
        /// <returns>True if there is a collision</returns>
        public bool TestRayintersectModel(CollideRay sourceCollide,
                                          CollideModel targetCollide,
                                          ref CollisionResult result)
        {
            Vector3 intersect;
            Vector3 normal;
            float   distance;

            //  use quad tree.
            if (targetCollide.QuadTree != null)
            {
                if (TestUsingQuadTree((CollideElement)sourceCollide,
                                      targetCollide.QuadTree.RootNode,
                                      out intersect,
                                      out normal,
                                      out distance))
                {
                    result.detectedCollide = targetCollide;
                    result.intersect       = intersect;
                    result.normal          = normal;
                    result.distance        = distance;
                    result.collideCount++;

                    return(true);
                }
            }
            // Test ray with the model
            else
            {
                if (TestRayintersectModel(sourceCollide.Ray, targetCollide.Vertices,
                                          targetCollide.TransformMatrix,
                                          out intersect,
                                          out normal,
                                          out distance))
                {
                    result.distance        = distance;
                    result.detectedCollide = targetCollide;
                    result.intersect       = intersect;
                    result.normal          = normal;
                    result.collideCount++;
                }
            }

            return(false);
        }
Exemplo n.º 4
0
        /// <summary>
        /// checks contaning.
        /// </summary>
        public bool Contains(ref CollideElement bounds)
        {
            if (bounds is CollideBox)
            {
                CollideBox target = bounds as CollideBox;

                return(containBox.Intersects(target.BoundingBox));
            }
            else if (bounds is CollideSphere)
            {
                CollideSphere target = bounds as CollideSphere;

                return(containBox.Intersects(target.BoundingSphere));
            }
            else if (bounds is CollideRay)
            {
                CollideRay target = bounds as CollideRay;

                return(containBox.Intersects(target.Ray) != null);
            }

            return(false);
        }
Exemplo n.º 5
0
        protected bool TestUsingQuadTree(CollideElement sourceCollide,
                                         QuadNode quadNode,
                                         out Vector3 intersect,
                                         out Vector3 normal,
                                         out float distance)
        {
            bool result = false;

            float   tempDistance  = 0.0f;
            Vector3 tempIntersect = Vector3.Zero;
            Vector3 tempNormal    = Vector3.Zero;

            float   closestDistance     = float.MaxValue;
            Vector3 closestIntersection = Vector3.Zero;
            Vector3 closestNormal       = Vector3.Zero;

            distance  = 0.0f;
            intersect = Vector3.Zero;
            normal    = Vector3.Zero;

            //  checks upper left node.
            if (quadNode.UpperLeftNode != null)
            {
                if (TestUsingQuadTree(sourceCollide, quadNode.UpperLeftNode,
                                      out tempIntersect, out tempNormal,
                                      out tempDistance))
                {
                    result = true;

                    //  checks closest
                    if (closestDistance > tempDistance)
                    {
                        closestDistance     = tempDistance;
                        closestIntersection = tempIntersect;
                        closestNormal       = tempNormal;
                    }
                }
            }

            //  checks upper right node.
            if (quadNode.UpperRightNode != null)
            {
                if (TestUsingQuadTree(sourceCollide, quadNode.UpperRightNode,
                                      out tempIntersect, out tempNormal,
                                      out tempDistance))
                {
                    result = true;

                    //  checks closest
                    if (closestDistance > tempDistance)
                    {
                        closestDistance     = tempDistance;
                        closestIntersection = tempIntersect;
                        closestNormal       = tempNormal;
                    }
                }
            }

            //  checks lower left node.
            if (quadNode.LowerLeftNode != null)
            {
                if (TestUsingQuadTree(sourceCollide, quadNode.LowerLeftNode,
                                      out tempIntersect, out tempNormal,
                                      out tempDistance))
                {
                    result = true;

                    //  checks closest
                    if (closestDistance > tempDistance)
                    {
                        closestDistance     = tempDistance;
                        closestIntersection = tempIntersect;
                        closestNormal       = tempNormal;
                    }
                }
            }

            //  checks lower right node.
            if (quadNode.LowerRightNode != null)
            {
                if (TestUsingQuadTree(sourceCollide, quadNode.LowerRightNode,
                                      out tempIntersect, out tempNormal,
                                      out tempDistance))
                {
                    result = true;

                    //  checks closest
                    if (closestDistance > tempDistance)
                    {
                        closestDistance     = tempDistance;
                        closestIntersection = tempIntersect;
                        closestNormal       = tempNormal;
                    }
                }
            }
            //  checks vertices in quad node.
            if (quadNode.Contains(ref sourceCollide))
            {
                //  checks vertices with bounding sphere.
                if (sourceCollide is CollideSphere)
                {
                    CollideSphere collide = sourceCollide as CollideSphere;

                    // Hit test sphere with the model
                    BoundingSphere sphere = collide.BoundingSphere;

                    if (quadNode.Vertices != null)
                    {
                        if (TestSphereintersectModel(sphere, quadNode.Vertices,
                                                     Matrix.Identity,
                                                     out tempIntersect, out tempNormal,
                                                     out tempDistance))
                        {
                            result = true;

                            //  checks closest
                            if (closestDistance > tempDistance)
                            {
                                closestDistance     = tempDistance;
                                closestIntersection = tempIntersect;
                                closestNormal       = tempNormal;
                            }
                        }
                    }
                }
                //  checks vertices with ray.
                else if (sourceCollide is CollideRay)
                {
                    CollideRay collide = sourceCollide as CollideRay;

                    if (quadNode.Vertices != null)
                    {
                        if (TestRayintersectModel(collide.Ray, quadNode.Vertices,
                                                  Matrix.Identity,
                                                  out tempIntersect, out tempNormal,
                                                  out tempDistance))
                        {
                            result = true;

                            //  checks closest
                            if (closestDistance > tempDistance)
                            {
                                closestDistance     = tempDistance;
                                closestIntersection = tempIntersect;
                                closestNormal       = tempNormal;
                            }
                        }
                    }
                }
            }

            //  resolve final result.
            if (result)
            {
                distance  = closestDistance;
                intersect = closestIntersection;
                normal    = closestNormal;
            }

            return(result);
        }
Exemplo n.º 6
0
        /// <summary>
        /// It tests for collision among the collision elements which
        /// have been registered to the collision layer and returns the result.
        /// </summary>
        /// <param name="collide">Source collsion element</param>
        /// <param name="targetLayer">Target collison layer</param>
        /// <param name="resultType">type of result</param>
        /// <returns>A result report</returns>
        public CollisionResult HitTest(CollideElement collide,
                                       ref CollisionLayer targetLayer,
                                       ResultType resultType)
        {
            CollisionResult result = null;

            tempResult.Clear();
            totalCollidingCount = 0;

            if (activeOn == false)
            {
                return(null);
            }

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

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

            //  checking all collisions in current collision layer
            for (int i = 0; i < targetLayer.CollideCount; i++)
            {
                CollideElement targetCollide = targetLayer.GetCollide(i);

                //  Skip ifself
                if (collide.Equals(targetCollide))
                {
                    continue;
                }
                else if (collide.Id != 0 && targetCollide.Id != 0)
                {
                    if (collide.Id == targetCollide.Id)
                    {
                        continue;
                    }
                }

                //   If source collision is BoundingSphere
                if (collide is CollideSphere)
                {
                    CollideSphere sourceCollideSphere = collide as CollideSphere;

                    //  Test with target sphere
                    if (targetCollide is CollideSphere)
                    {
                        CollideSphere targetCollideSphere =
                            targetCollide as CollideSphere;

                        TestSphereintersectSphere(sourceCollideSphere,
                                                  targetCollideSphere, ref tempResult);
                    }
                    //  Test with target model
                    else if (targetCollide is CollideModel)
                    {
                        CollideModel targetCollideModel =
                            targetCollide as CollideModel;

                        TestSphereintersectModel(sourceCollideSphere,
                                                 targetCollideModel, ref tempResult);
                    }
                    //  Test with target box
                    else if (targetCollide is CollideBox)
                    {
                        CollideBox targetCollideBox = targetCollide as CollideBox;

                        TestSphereintersectBox(sourceCollideSphere,
                                               targetCollideBox, ref tempResult);
                    }
                    //  Test with target ray
                    if (targetCollide is CollideRay)
                    {
                        CollideRay targetCollideRay =
                            targetCollide as CollideRay;

                        TestRayintersectSphere(targetCollideRay,
                                               sourceCollideSphere, ref tempResult);
                    }
                }
                //   If source collision is Ray
                else if (collide is CollideRay)
                {
                    CollideRay sourceCollideRay = collide as CollideRay;

                    //  Test with target model
                    if (targetCollide is CollideModel)
                    {
                        CollideModel targetCollideModel =
                            targetCollide as CollideModel;

                        TestRayintersectModel(sourceCollideRay,
                                              targetCollideModel, ref tempResult);
                    }
                    //  Test with target sphere
                    else if (targetCollide is CollideSphere)
                    {
                        CollideSphere targetCollideSphere =
                            targetCollide as CollideSphere;

                        TestRayintersectSphere(sourceCollideRay,
                                               targetCollideSphere, ref tempResult);
                    }
                    //  Test with target box
                    else if (targetCollide is CollideBox)
                    {
                        CollideBox targetCollideBox = targetCollide as CollideBox;

                        TestRayintersectBox(sourceCollideRay,
                                            targetCollideBox, ref tempResult);
                    }
                }
                //   If source collision is Ray
                else if (collide is CollideBox)
                {
                    CollideBox sourceCollideBox = collide as CollideBox;

                    //  Test with target sphere
                    if (targetCollide is CollideSphere)
                    {
                        CollideSphere targetCollideSphere =
                            targetCollide as CollideSphere;

                        TestSphereintersectBox(targetCollideSphere,
                                               sourceCollideBox, ref tempResult);
                    }
                    //  Test with target box
                    else if (targetCollide is CollideBox)
                    {
                        CollideBox targetCollideBox = targetCollide as CollideBox;

                        TestBoxintersectBox(sourceCollideBox,
                                            targetCollideBox, ref tempResult);
                    }
                    //  Test with target ray
                    else if (targetCollide is CollideRay)
                    {
                        CollideRay targetCollideRay = targetCollide as CollideRay;

                        TestRayintersectBox(targetCollideRay,
                                            sourceCollideBox, ref tempResult);
                    }
                }

                //  To find the nearest detected collision.
                if (resultType == ResultType.NearestOne)
                {
                    if (tempResult.collideCount > 0)
                    {
                        if (result == null)
                        {
                            result          = new CollisionResult();
                            result.distance = float.MaxValue;
                        }

                        if (result.distance > tempResult.distance)
                        {
                            tempResult.CopyTo(ref result);
                        }
                    }
                }
            }

            return(result);
        }
Exemplo n.º 7
0
        /// <summary>
        /// It checks for the collision between a collision ray and a collision sphere.
        /// </summary>
        /// <param name="sourceCollide">Source collision ray</param>
        /// <param name="targetCollide">Target collision sphere</param>
        /// <param name="result">A result report</param>
        /// <returns>True if there is a collision</returns>
        public bool TestRayintersectSphere(CollideRay sourceCollide, 
                                            CollideSphere targetCollide, 
                                            ref CollisionResult result)
        {
            totalCollidingCount++;

            // Test ray with the sphere
            float? distance = sourceCollide.Ray.Intersects(targetCollide.BoundingSphere);
            if (distance != null)
            {
                if (result != null)
                {
                    Vector3 dir = Vector3.Normalize(sourceCollide.Ray.Position - 
                                                    targetCollide.BoundingSphere.Center);

                    Vector3 length = dir * targetCollide.Radius;

                    result.distance = (float)distance;
                    result.detectedCollide = targetCollide;                    
                    result.intersect = targetCollide.BoundingSphere.Center + length;
                    result.normal = null;
                    result.collideCount++;
                }

                return true;
            }

            return false;
        }
Exemplo n.º 8
0
        /// <summary>
        /// It checks for the collision between a collision ray and a collision box.
        /// </summary>
        /// <param name="sourceCollide">Source collision ray</param>
        /// <param name="targetCollide">Target collision box</param>
        /// <param name="result">A result report</param>
        /// <returns>True if there is a collision</returns>
        public  bool TestRayintersectBox(CollideRay sourceCollide, 
                                                CollideBox targetCollide, 
                                                ref CollisionResult result)
        {
            totalCollidingCount++;

            // Test ray with the box
            float? distance = sourceCollide.Ray.Intersects(targetCollide.BoundingBox);
            if (distance != null)
            {
                if (result != null)
                {
                    result.distance = (float)distance;
                    result.detectedCollide = targetCollide;
                    result.intersect = null;
                    result.normal = null;
                    result.collideCount++;
                }

                return true;
            }

            return false;
        }
Exemplo n.º 9
0
        /// <summary>
        /// It checks for the collision between a collision ray and a collision model.
        /// </summary>
        /// <param name="sourceCollide">Source collision ray</param>
        /// <param name="targetCollide">Target collision model</param>
        /// <param name="result">A result report</param>
        /// <returns>True if there is a collision</returns>
        public bool TestRayintersectModel(CollideRay sourceCollide, 
                                                CollideModel targetCollide, 
                                                ref CollisionResult result)
        {
            Vector3 intersect;
            Vector3 normal;
            float distance;

            //  use quad tree.
            if (targetCollide.QuadTree != null)
            {
                if( TestUsingQuadTree((CollideElement)sourceCollide, 
                                        targetCollide.QuadTree.RootNode,
                                        out intersect,
                                        out normal,
                                        out distance))
                {
                    result.detectedCollide = targetCollide;
                    result.intersect = intersect;
                    result.normal = normal;
                    result.distance = distance;
                    result.collideCount++;

                    return true;
                }
            }
            // Test ray with the model
            else
            {
                if( TestRayintersectModel(sourceCollide.Ray, targetCollide.Vertices,
                                            targetCollide.TransformMatrix,
                                            out intersect,
                                            out normal,
                                            out distance))
                {
                    result.distance = distance;
                    result.detectedCollide = targetCollide;
                    result.intersect = intersect;
                    result.normal = normal;
                    result.collideCount++;
                }
                                        
            }

            return false;
        }
Exemplo n.º 10
0
        /// <summary>
        /// checks for collision between the 3rd view camera, 
        /// which follows the player moving, and the world.
        /// </summary>
        public void CheckCollisionCamera()
        {
            CollideSphere playerSphere = Collide as CollideSphere;

            if ((FrameworkCore.CurrentCamera.FirstCamera is FollowCamera) == false)
                return;

            // Check collison of the follow camera
            ViewCamera viewCamera = FrameworkCore.CurrentCamera;
            FollowCamera camera = null;

            switch (this.PlayerIndex)
            {
                case PlayerIndex.One:
                    camera = viewCamera.GetCamera(0) as FollowCamera;
                    break;
                case PlayerIndex.Two:
                    camera = viewCamera.GetCamera(1) as FollowCamera;
                    break;
                case PlayerIndex.Three:
                    camera = viewCamera.GetCamera(2) as FollowCamera;
                    break;
                case PlayerIndex.Four:
                    camera = viewCamera.GetCamera(3) as FollowCamera;
                    break;
            }

            //  Default setting offset
            Vector3 followCameraOffset = SpecData.CameraPositionOffset;

            float distanceBetweenCamera =
                        Math.Abs(Vector3.Distance(Vector3.Zero, followCameraOffset));

            CollisionResult finalResult, leftResult, rightResult;
            finalResult = leftResult = rightResult = null;

            //  Booster camera
            if (this.isActiveBooster && this.isDelayBooster == false)
            {
                followCameraOffset.Z *= 1.5f;
            }

            Vector3 start = camera.Target;
            Vector3 dir = camera.Position - start;
            dir.Normalize();

            //  check to left side of camera
            {

                CollideRay simulateRay =
                    new CollideRay(start - camera.Right, dir);

                //  check collison with world
                leftResult = FrameworkCore.CollisionContext.HitTest(
                                                                simulateRay,
                                                                ref colLayerMoveWorld,
                                                                ResultType.NearestOne);
            }

            //  check to right side of camera
            {
                CollideRay simulateRay =
                    new CollideRay(start + camera.Right, dir);

                //  check collison with world
                rightResult = FrameworkCore.CollisionContext.HitTest(
                                                                simulateRay,
                                                                ref colLayerMoveWorld,
                                                                ResultType.NearestOne);
            }

            if (leftResult != null && rightResult != null)
            {
                if( leftResult.distance < rightResult.distance)
                    finalResult = leftResult;
                else
                    finalResult = rightResult;
            }
            else if (leftResult != null)
            {
                finalResult = leftResult;
            }
            else if (rightResult != null)
            {
                finalResult = rightResult;
            }

            if (finalResult != null)
            {
                //  The camera collided behind player with world
                if (finalResult.distance < distanceBetweenCamera)
                {
                    float distance = finalResult.distance;

                    if (finalResult.distance < playerSphere.Radius)
                        distance = playerSphere.Radius;

                    // Change camera position
                    camera.PositionOffset = new Vector3(
                                0.0f,
                                followCameraOffset.Y * 
                                    (distance / distanceBetweenCamera),
                                -distance);
                }
                else
                {
                    camera.PositionOffset = followCameraOffset;
                }
            }
            else
            {
                camera.PositionOffset = followCameraOffset;
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// checks for the weapon firing collision.
        /// When collision check succeeds, returns a result report.  
        /// If not, returns null.
        /// </summary>
        /// <param name="position">the start position of firing</param>
        /// <param name="direction">the direction of firing</param>
        /// <param name="distance">the range of firing</param>
        /// <param name="targetCollisionLayer">target collision layer</param>
        /// <param name="worldCollisionLayer">world collision layer</param>
        /// <returns>result report</returns>
        protected static CollisionResult FireHitTest(Vector3 position,
                                              Vector3 direction,
                                              float distance,
                                              ref CollisionLayer targetCollisionLayer,
                                              ref CollisionLayer worldCollisionLayer)
        {
            bool doHit = false;

            CollideRay collideRay = new CollideRay(position, direction);

            //  checks with enemies.
            CollisionResult fireResult = FrameworkCore.CollisionContext.HitTest(
                                                    collideRay,
                                                    ref targetCollisionLayer,
                                                    ResultType.NearestOne);

            if (fireResult != null)
            {
                if (fireResult.distance <= distance)
                {
                    //  Hit unit
                    doHit = true;
                }
            }

            //  checks with world.
            CollisionResult worldResult = FrameworkCore.CollisionContext.HitTest(
                                                            collideRay,
                                                            ref worldCollisionLayer,
                                                            ResultType.NearestOne);

            if (worldResult != null)
            {
                //  Hit world
                if (worldResult.distance <= distance)
                {
                    if (doHit)
                    {
                        //  closer world
                        if (worldResult.distance < fireResult.distance)
                        {
                            return worldResult;
                        }
                    }
                    else
                    {
                        return worldResult;
                    }
                }
            }

            if (doHit)
            {
                return fireResult;
            }

            return null;
        }
Exemplo n.º 12
0
        public CollisionResult HitTestWithWorld(Vector3 start, Vector3 direction)
        {
            CollideRay simulateRay = new CollideRay(start, direction);
            simulateRay.Id = Collide.Id;

            //  Test collision
            CollisionResult result =
                    FrameworkCore.CollisionContext.HitTest(simulateRay,
                                                            ref colLayerMoveWorld,
                                                            ResultType.NearestOne);
            return result;
        }
Exemplo n.º 13
0
        public CollisionResult MoveHitTestWithWorld(Vector3 velocityAmount)
        {
            CollideSphere playerSphere = Collide as CollideSphere;
            float radius = playerSphere.Radius;

            //  calculate simulated position for collision.
            Matrix transformSimulate = TransformedMatrix *
                                       Matrix.CreateTranslation(velocityAmount);

            // first, check using sphere.
            {
                CollideSphere simulateSphere =
                                new CollideSphere(playerSphere.LocalCenter, radius);

                simulateSphere.Transform(transformSimulate);
                simulateSphere.Id = playerSphere.Id;

                CollisionResult result = FrameworkCore.CollisionContext.HitTest(
                                                                simulateSphere,
                                                                ref colLayerMoveWorld,
                                                                ResultType.NearestOne);

                if (result != null)
                {
                    return result;
                }
            }

            //  second, check using ray.
            {
                Vector3 direction = velocityAmount;
                direction.Normalize();

                CollideRay simulateRay =
                        new CollideRay(playerSphere.BoundingSphere.Center, direction);

                simulateRay.Id = playerSphere.Id;

                CollisionResult result = FrameworkCore.CollisionContext.HitTest(
                                                                simulateRay,
                                                                ref colLayerMoveWorld,
                                                                ResultType.NearestOne);

                if (result != null)
                {
                    if (result.distance <= radius)
                        return result;
                }
            }

            return null;
        }