// // 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); }
// // Check if the car is colliding with an obstacle or is outside of map // public static bool HasCarInvalidPosition(Vector3 carRearWheelPos, float heading, CarData carData, Map map) { bool hasInvalidPosition = false; //Step 1. Check if the car's rear wheel center is inside of the map IntVector2 rearWheelCellPos = map.ConvertWorldToCell(carRearWheelPos); if (!map.IsCellWithinGrid(rearWheelCellPos)) { //This is not a valid position hasInvalidPosition = true; return(hasInvalidPosition); } //Step 2. Check if any of the car's corner is outside of the map //Make the car bigger than it is to be on the safe side float carLength = carData.CarLength + Parameters.marginOfSafety; float carWidth = carData.carWidth + Parameters.marginOfSafety; Vector3 carCenterPos = carData.GetCenterPos(carRearWheelPos, heading); //Find all corners of the car Rectangle corners = CarData.GetCornerPositions(carCenterPos, heading, carWidth, carLength); //Detect if any of the corners is outside of the map = is the cell the corner is a part of the map HashSet <IntVector2> carCellPositions = new HashSet <IntVector2>(); carCellPositions.Add(map.ConvertWorldToCell(corners.FL)); carCellPositions.Add(map.ConvertWorldToCell(corners.FR)); carCellPositions.Add(map.ConvertWorldToCell(corners.BL)); carCellPositions.Add(map.ConvertWorldToCell(corners.BR)); foreach (IntVector2 cellPos in carCellPositions) { if (!map.IsCellWithinGrid(cellPos)) { //At least one of the corners is outside of the map hasInvalidPosition = true; return(hasInvalidPosition); } } //Step 3. Check if some of the car's known positions are far away from an obstacle //The car is not colliding with anything if the steps to an obstacle from center of car is greater than the length of the car IntVector2 carCenterCellPos = map.ConvertWorldToCell(carCenterPos); if (map.cellData[carCenterCellPos.x, carCenterCellPos.z].distanceToClosestObstacle > carData.CarLength * 0.7f) { //This is a valid position hasInvalidPosition = false; return(hasInvalidPosition); } //Step 4. Check if the car is hitting an obstacle //Use the car's corners and then rectangle-rectangle-intersection with the obstacles hasInvalidPosition = IsCarIntersectingWithObstacles(corners, carCenterCellPos, map); return(hasInvalidPosition); }