예제 #1
0
    private void processCarsWithLaneNumberAndRefernceIntersection(int laneNumber, Intersection refIntersection)
    {
        //TODO: sort list first instead of doing it on the fly
        AbstractCar[] sortedCars = cars
                                   .Where(c => c.position.referenceIntersection == refIntersection)
                                   .Where(c => c.position.laneNumber == laneNumber)
                                   .OrderByDescending(c => c.position.offset)
                                   .ToArray();
        for (int j = 0; j < sortedCars.Length; j++)
        {
            AbstractCar car = sortedCars[j];
            // check if this is the first car
            // TODO: Reduce code copying
            if (j == 0)
            {
                // move the first car into the intersection if necessary
                float stoppingOffset = trafficMath.stoppingDistanceForCurrentDrive(car.position);
                if (car.position.offset < stoppingOffset)
                {
                    car.SmartAdjustSpeedAccordingToStoppingDistance(stoppingOffset - car.position.offset, 2f);
                    car.position.offset += car.GetSpeed() * Time.deltaTime;
                    //we should not exceed the stopping distance
                    // If the car is close enough to the intersection
                    if (stoppingOffset - car.position.offset < 0.05f)
                    {
                        car.position.offset = stoppingOffset;
                        car.DecreaseSpeed(100f);                        // force stop the car

                        moveCarToIntersection(car);
                    }
                }

                car.updateCarPosition();
            }
            else
            {
                // let the car follow the previous car
                int   MIN_DIST       = 2;
                float stoppingOffset = sortedCars[j - 1].position.offset - MIN_DIST;
                if (car.position.offset < stoppingOffset)
                {
                    car.SmartAdjustSpeedAccordingToStoppingDistance(stoppingOffset - car.position.offset, 2f);
                    car.position.offset += car.GetSpeed() * Time.deltaTime;
                }

                car.updateCarPosition();
            }
        }
    }
예제 #2
0
    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);
        }
    }