//
        // Use the car's corners and then rectangle-rectangle-intersection with the obstacles to check if the car is intersecting with an obstacle
        //
        private static bool IsCarIntersectingWithObstacles(Rectangle carRectangle, IntVector2 carCenterCellPos, Map map)
        {
            bool hasInvalidPosition = false;

            ////Alternative 1. Find if one of the cells the car is intersecting is an obstacle
            ////This is slower because it requires a lot of triangle-triangle intersections to identify the cells
            ////which is the same as intersecting with the obstacles in the first place
            //bool isCellIntersectedByCarObstacle = FindIfCellBlockedByRectangleIsObstacle(carRectangle, carCenterCellPos, map);


            //if (isCellIntersectedByCarObstacle)
            //{
            //    hasInvalidPosition = true;

            //    return hasInvalidPosition;
            //}

            //return false;



            //But if we want more accurate collision detection we have to take into account that the obstacle
            //may not block the entire cell, so the can can maybe move into this position without colliding with an obstacle

            //Find all obstacles that are close to the car, so we dont have to check all obstacles
            //List<Obstacle> obstaclesThatAreClose = FindCloseObstaclesCell(carPos);
            //List<Obstacle> obstaclesThatAreClose = FindCloseObstaclesAABB(carCorners, map);

            //Maybe more efficient to instead of finding obstacles that are close, go through all obstacles
            //because the obstacle detection algorithm is using AABB anyway
            List <Obstacle> obstaclesThatAreClose = map.allObstacles;

            for (int i = 0; i < obstaclesThatAreClose.Count; i++)
            {
                Rectangle obstacleCorners = obstaclesThatAreClose[i].cornerPos;

                //Rectangle-rectangle intersection, which is here multiple triangle-triangle intersection tests
                if (Intersections.AreRectangleRectangleIntersecting(carRectangle, obstacleCorners))
                {
                    hasInvalidPosition = true;

                    return(hasInvalidPosition);
                }
            }

            return(hasInvalidPosition);
        }
        //
        // Methods that returns obstacles that are close to a car, because it's slow to check ALL obstacles
        //

        //Method 1 - Search through all obstacles to find which are close within a radius
        //private static List<Obstacle> FindCloseObstaclesWithinRadius(Vector3 pos, float radiusSqr)
        //{
        //    //The list with close obstacles
        //    List<Obstacle> closeObstacles = new List<Obstacle>();

        //    //Method 1 - Search through all obstacles to find which are close
        //    //The list with all obstacles in the map
        //    List<Obstacle> allObstacles = ObstaclesController.allObstacles;

        //    //Find close obstacles
        //    for (int i = 0; i < allObstacles.Count; i++)
        //    {
        //        float distSqr = (pos - allObstacles[i].centerPos).sqrMagnitude;

        //        //Add to the list of close obstacles if close enough
        //        if (distSqr < radiusSqr)
        //        {
        //            closeObstacles.Add(allObstacles[i]);
        //        }
        //    }

        //    return closeObstacles;
        //}



        //Method 2 - Find all obstacles the car might collide with by checking surrounding cells
        //might not be accurate because we dont alway knows how far from the car we should search
        //private static List<Obstacle> FindCloseObstaclesCell(Vector3 carPos)
        //{
        //    //The list with close obstacles
        //    List<Obstacle> closeObstacles = new List<Obstacle>();

        //    IntVector2 carCellPos = PathfindingController.ConvertCoordinateToCellPos(carPos);

        //    //Check an area of cells around the car's cell for obstacles
        //    //The car is 5 m long so search 3 m to each side?
        //    int searchArea = 3;

        //    for (int x = -searchArea; x <= searchArea; x++)
        //    {
        //        for (int z = -searchArea; z <= searchArea; z++)
        //        {
        //            IntVector2 cellPos = new IntVector2(carCellPos.x + x, carCellPos.z + z);

        //            //Is this cell within the map?
        //            if (PathfindingController.IsCellWithinGrid(cellPos))
        //            {
        //                //Add all obstacles from this list to the list of close obstacles
        //                List<Obstacle> obstaclesInCell = ObstaclesController.allObstaclesInEachCell[cellPos.x, cellPos.z];

        //                if (obstaclesInCell != null)
        //                {
        //                    for (int i = 0; i < obstaclesInCell.Count; i++)
        //                    {
        //                        //Might add the same obstacle more than one time, but maybe that's not a big problem?
        //                        closeObstacles.Add(obstaclesInCell[i]);
        //                    }
        //                }
        //            }
        //        }
        //    }


        //    return closeObstacles;
        //}



        //Method 3 - Find all obstacles the car might collide with by using AABB
        public static List <Obstacle> FindCloseObstaclesAABB(Rectangle carRect, Map map)
        {
            List <Obstacle> closeObstacles = new List <Obstacle>();

            //The list with all obstacles in the map
            List <Obstacle> allObstacles = map.allObstacles;

            //Find close obstacles
            for (int i = 0; i < allObstacles.Count; i++)
            {
                Rectangle obsRect = allObstacles[i].cornerPos;

                //Are the AABB intersecting?
                if (Intersections.AreIntersectingAABB(carRect, obsRect))
                {
                    closeObstacles.Add(allObstacles[i]);
                }
            }

            return(closeObstacles);
        }
Exemple #3
0
        //Instantiate one cube and add its position to the array
        void AddObstacle(Map map, Rectangle avoidRect)
        {
            //Generate random coordinates in the map
            float posX = Random.Range(1f, map.MapWidth - 1f);
            float posZ = Random.Range(1f, map.MapWidth - 1f);
            //Rotation
            float rotY = Random.Range(0f, 360f);
            //Size
            float sizeX = Random.Range(Parameters.minObstacleSize, Parameters.maxObstacleSize);
            float sizeZ = Random.Range(Parameters.minObstacleSize, Parameters.maxObstacleSize);

            Vector3 pos = new Vector3(posX, 0.5f, posZ);

            Quaternion rot = Quaternion.Euler(0f, rotY, 0f);

            Vector3 scale = new Vector3(sizeX, 1f, sizeZ);

            //Update the prefab with the new data
            obstaclePrefabObj.transform.position   = pos;
            obstaclePrefabObj.transform.rotation   = rot;
            obstaclePrefabObj.transform.localScale = scale;

            Obstacle newObstacle = new Obstacle(obstaclePrefabObj.transform);


            //The obstacle shouldnt intersect with the start area
            if (Intersections.AreRectangleRectangleIntersecting(avoidRect, newObstacle.cornerPos))
            {
                return;
            }


            //Add a new obstacle object at this position
            Instantiate(obstaclePrefabObj, obstaclesParent);

            map.allObstacles.Add(newObstacle);
        }
        //
        // Check if the trailer is colliding with the drag vehicle
        //
        public static bool IsTrailerCollidingWithDragVehicle(
            Vector3 semiRearWheelPos, float semiHeading, CarData semiData,
            Vector3 trailerRearWheelPos, float trailerHeading, CarData trailerData)
        {
            bool isColliding = false;

            //Use triangle-traingle intersection so we need the rectangles
            Vector3 trailerCenter = trailerData.GetCenterPos(trailerRearWheelPos, trailerHeading);

            Rectangle trailerRect = CarData.GetCornerPositions(trailerCenter, trailerHeading, trailerData.carWidth * 0.9f, trailerData.CarLength);

            //The semi's cabin rectangle
            Vector3 cabinCenter = semiData.GetSemiCabinCenter(semiRearWheelPos, semiHeading);

            //Make it slightly shorter or too many false collisions
            Rectangle semiRect = CarData.GetCornerPositions(cabinCenter, semiHeading, semiData.carWidth, semiData.cabinLength * 0.95f);

            if (Intersections.AreRectangleRectangleIntersecting(trailerRect, semiRect))
            {
                return(true);
            }

            return(isColliding);
        }