public AbstractCar(AbstractCarPosition position, GameObject carGameObject) { this.position = position; this.carGameObject = carGameObject; this.carControl = carGameObject.GetComponent <TruckControl>(); this.speed = 0f; }
public void tick() { // check if there are cars waiting to go through the intersection if (currentlyOperatingCar == null) { if (carsAtThisIntersection.Count != 0) { currentlyOperatingCar = carsAtThisIntersection [0]; carsAtThisIntersection.RemoveAt(0); // remove the car from the road // TODO: Redesign the communication between road control and intersection control trafficManager.roadControlForRoad(currentlyOperatingCar.position.referenceRoad).RemoveCarFromRoad(currentlyOperatingCar); // calculate the final form after going through the intersection Road targetRoad = navigationManager.targetWayForAbstractCarAtIntersection(currentlyOperatingCar, referenceIntersection); // get target abstract position AbstractCarPosition targetAbstractPosition = new AbstractCarPosition(targetRoad, referenceIntersection, 0, currentlyOperatingCar.position.laneNumber); float startingDistance = trafficMath.startingDistanceForCurrentDrive(targetAbstractPosition); targetAbstractPosition.offset = startingDistance; // get current and target real location currentPosition = currentlyOperatingCar.carGameObject.transform.position; currentRotation = currentlyOperatingCar.carGameObject.transform.rotation; currentlyOperatingCar.position = targetAbstractPosition; currentlyOperatingCar.CalculatePositionAndOrientation(out targetPosition, out targetRotation); // calculate the pivot Math3d.LineLineIntersection(out pivot, currentPosition, Quaternion.Euler(0, 90, 0) * currentRotation * Vector3.right, targetPosition, Quaternion.Euler(0, 90, 0) * targetRotation * Vector3.right); startTime = Time.time; } } else { // animate // very little animation if it is just a curve float turningDuration = referenceIntersection.GetGraphicsType() == Intersection.IntersectionGraphicsType.TWO_WAY_SMOOTH ? 0.1f : 1f; // end if necessary if (Time.time - startTime > turningDuration) { // we end turning and proceed to the following route RoadTrafficControl roadControl = trafficManager.roadControlForRoad(currentlyOperatingCar.position.referenceRoad); roadControl.AddCar(currentlyOperatingCar); // remember intersections is updated after roads currentlyOperatingCar.updateCarPosition(); currentlyOperatingCar = null; return; } // Slerp between positions around pivot and lerp the Quaternion rotation currentlyOperatingCar.carGameObject.transform.position = pivot + Vector3.Slerp(currentPosition - pivot, targetPosition - pivot, (Time.time - startTime) / turningDuration); currentlyOperatingCar.carGameObject.transform.rotation = Quaternion.Slerp(currentRotation, targetRotation, (Time.time - startTime) / turningDuration); } }
// returns the maximum value of AbstractCarPosition.offset so that the car is not rushing into the intersection public float stoppingDistanceForCurrentDrive(AbstractCarPosition carPosition) { /** * * toIntersection ref intersection * * toLeftEdge * \===================================================| ^ * \|< STOPPING DISTANCE > | width(refIntersection) * \ ------------------------------------------------| x * \ | width(toIntersection) * \===============================================| v * toRightEdge * * * */ Intersection toIntersection = carPosition.referenceRoad.otherIntersection(carPosition.referenceIntersection); Vector3 toLeftEdge = builder.coordinateForRoadAtIntersection(toIntersection, carPosition.referenceRoad, IntersectionBuilder.RightOrLeft.LEFT); Vector3 toRightEdge = builder.coordinateForRoadAtIntersection(toIntersection, carPosition.referenceRoad, IntersectionBuilder.RightOrLeft.RIGHT); // get the proportion int totalNumberOfLanes = carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(toIntersection) + carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(carPosition .referenceIntersection); Vector3 stoppingLocation = Vector3.Lerp(toLeftEdge, toRightEdge, 1f / 2 - (1f / 2 + carPosition.laneNumber) / totalNumberOfLanes) * (1f / 2); // project the stopping location onto the outgoing vector Vector3 stoppingCompensation = Vector3.Project(stoppingLocation, IntersectionMath.getOutgoingVector(toIntersection, carPosition.referenceRoad)); float stoppingDistance = carPosition.referenceRoad.GetRoadLength() - stoppingCompensation.magnitude; return(stoppingDistance); }
public float startingDistanceForCurrentDrive(AbstractCarPosition carPosition) { /** * * refIntersection toIntersection * * fromLeftEdge * \===================================================| ^ * \ | width(toIntersection) * \ ------------------------------------------------| x * < >\ | width(refIntersection) * | \===============================================| v * | fromRightEdge * | * +--> startingDistance * */ Intersection toIntersection = carPosition.referenceRoad.otherIntersection(carPosition.referenceIntersection); Vector3 fromLeftEdge = builder.coordinateForRoadAtIntersection(carPosition.referenceIntersection, carPosition.referenceRoad, IntersectionBuilder.RightOrLeft.LEFT); Vector3 fromRightEdge = builder.coordinateForRoadAtIntersection(carPosition.referenceIntersection, carPosition.referenceRoad, IntersectionBuilder.RightOrLeft.RIGHT); // get the proportion int totalNumberOfLanes = carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(toIntersection) + carPosition.referenceRoad.GetNumberOfLanesInDirectionWithReferenceIntersection(carPosition .referenceIntersection); Vector3 startingLocation = Vector3.Lerp(fromLeftEdge, fromRightEdge, 1f / 2 + (1f / 2 + carPosition.laneNumber) / totalNumberOfLanes) * (1f / 2); // project the stopping location onto the outgoing vector Vector3 startignCompensation = Vector3.Project(startingLocation, IntersectionMath.getOutgoingVector(carPosition.referenceIntersection, carPosition.referenceRoad)); float startingDistance = startignCompensation.magnitude; return(startingDistance); }
void Update() { GameObject obj; Vector3 position = MouseCollisionDetection.getMousePositionOnPlane(out obj); laneNumberControl(); if (Input.GetMouseButtonDown(0)) { // if we click on a plane, add a car to it; if (obj.tag == GlobalTags.Intersection) { Intersection intersection = intersectionManager.intersectionForGameObject(obj); Road road = intersection.getConnectedRoads()[0]; AbstractCarPosition abstractPosition = new AbstractCarPosition(road, intersection, 0, laneNumber); AbstractCar car = new AbstractCar(abstractPosition, Instantiate(carPrefab, intersection.position, Quaternion.identity)); carTrafficManager.AddCar(car); } } }