/// <summary> /// Generates a group of pedestrians inside the Unity scene. The position will be set /// randomly in a radious around the spawner. /// </summary> private void SpawnGroupOfPedestrians() { if (!pedGlobalParameters.flashPedestriansPaused || spawningInitialBatch) { // Create a new pedestrian profile FlashPedestriansProfile profile = new FlashPedestriansProfile(pedGlobalParameters.averageSpeed + Random.Range(-0.5f, 0.5f), true /*future use*/, true /*future use*/, Random.Range(0.0f, 1.0f), false /*future use*/, Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), pedGlobalParameters.sumoCarAwarenessEnabled, //percOfPedWillingToTakeTransport (Random.value < pedGlobalParameters.percOfPedWillingToChangeDestination) ? TravelPreference.time : TravelPreference.noPublicTransport); //Find a destination FlashPedestriansDestination destination = null; int destinationIndex = 0; float[] priorityPercentages = GetPrioritiesOfAllDestinations(); float rand = Random.Range(0.0f, 0.99f); for (int i = 0; i < priorityPercentages.Length; i++) { if (rand < priorityPercentages[i]) { destination = destinations[i]; //Get one of the destination points within the destination choosen destinationIndex = Random.Range(0, destination.numberOfdestinations); break; } } if (destination == null) { Debug.LogWarning("No destination could be found with the list of priorities, avoiding spawning..."); return; } //Find a new random spawning point inside the radious defined Vector3 spawningPoint = spawningPoints[Random.Range(0, numberOfSpawningPoints)]; //Vector3 spawningPoint = this.transform.position // + new Vector3(Random.Range(-spawningArea, spawningArea), // 0f, Random.Range(-spawningArea, spawningArea)); //Find the best itinerary using the travel preferences in the pedestrian profile. Itinerary itinerary = flashInformer.FindBestItinerary(spawningPoint, destination, stationsNearThisSpawner, profile.travelPreference, destinationIndex); if (showDebugInfo) { Debug.Log(itinerary.Print()); } //Calculate number of pedestrians to spawn in this iteration int pedToSpawn = Random.Range(minPedestriansPerSpawningIteration, maxPedestriansPerSpawningIteration); //Spawn pedestrians for (int i = 0; i < pedToSpawn; i++) { SpawnPedestrian(spawningPoint, profile, destination, itinerary, destinationIndex); } } }
/// <summary> /// Constructor of the class. /// </summary> /// <param name="destination"></param> /// <param name="itinerary"></param> public FlashPedestriansRouting(FlashPedestriansDestination destination, Itinerary itinerary, int destIndex = 0) { this.destination = destination; this.destinationIndex = destIndex; this.itinerary = itinerary; destinationTransform = destination.destinationTransform[destinationIndex]; }
/// <summary> /// Generates a group of pedestrians inside the Unity scene. The position will be set /// randomly in a radious around the spawner. /// </summary> private void SpawnGroupOfPedestrians() { if (!pedGlobalParameters.flashPedestriansPaused) { // Create a new pedestrian profile FlashPedestriansProfile profile = new FlashPedestriansProfile(pedGlobalParameters.averageSpeed + Random.Range(-0.5f, 0.5f), true /*future use*/, true /*future use*/, Random.Range(0.0f, 1.0f), false /*future use*/, Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), pedGlobalParameters.sumoCarAwarenessEnabled, TravelPreference.time); //Find a destination FlashPedestriansDestination destination = null; float[] priorityPercentages = getPrioritiesOfAllDestinations(); float rand = Random.Range(0.0f, 0.99f); for (int i = 0; i < priorityPercentages.Length; i++) { if (rand < priorityPercentages[i]) { destination = destinationPoints[i]; break; } } if (destination == null) { Debug.LogWarning("No destination could be found with the list of priorities, avoiding spawning..."); return; } //Find a new random spawning point inside the radious defined Vector3 spawningPoint = this.transform.position + new Vector3(Random.Range(-spawningArea, spawningArea), 0.0f, Random.Range(-spawningArea, spawningArea)); //Move the spawning point to the closest point in the walkable navmesh (is this an expensive operation?) //NavMeshHit hit; //if (NavMesh.SamplePosition(spawningPoint, out hit, 1000.0f, 1 << NavMesh.GetAreaFromName("footway"))) // spawningPoint = hit.position; //Find the best itinerary using the travel preferences in the pedestrian profile. Itinerary itinerary = flashInformer.FindBestItinerary(spawningPoint, destination, stationsNearThisSpawner, profile.travelPreference); //Calculate number of pedestrians to spawn in this iteration int pedToSpawn = Random.Range(minPedestriansPerSpawningIteration, maxPedestriansPerSpawningIteration); //Spawn pedestrians for (int i = 0; i < pedToSpawn; i++) { SpawnPedestrian(spawningPoint, profile, destination, itinerary); } } }
/// <summary> /// Bubble algorithm to find the best itinerary between the stations given and the stations close to the destination point. /// </summary> /// <param name="startingPoint">Point in the map where the pedestrian starts.</param> /// <param name="destination">Final destination of the pedestrian.</param> /// <param name="stationsNearby">Stations nearby considered by the pedestrian.</param> /// <param name="travelPreference">Travel preferences of the pedestrian.</param> /// <param name="destIndex">Index of the destination point within the destination object.</param> /// <returns>An Itinerary object with the best itinerary for the pedestrian (empty itinerary if anything better than walking has been found).</returns> public Itinerary FindBestItinerary(Vector3 startingPoint, FlashPedestriansDestination destination, StationController[] stationsNearby, TravelPreference travelPreference, int destIndex = 0) { Itinerary bestItineraryFound = new Itinerary(new List <StationController>()); // Return an empty itinerary if no public transport is the travel preference if (travelPreference == TravelPreference.noPublicTransport) { return(bestItineraryFound); } // The default travel time taken into account is the possibility of walking all the way float bestTravelTime = Vector3.Distance(startingPoint, destination.destinationTransform[destIndex].position) * secondsPerMeter; for (int i = 0; i < stationsNearby.Length; i++) { for (int j = 0; j < destination.stationsNearThisDestination[destIndex].Length; j++) { Itinerary nextItinerary = routingController.GetItinerary( stationsNearby[i], destination.stationsNearThisDestination[destIndex][j].GetComponent <StationController>(), travelPreference); if (nextItinerary != null) { // Check the total travel time considering walking times form the starting point to the first station and from th last station to the destination float timeWalkingToFirstStation = Vector3.Distance(startingPoint, nextItinerary.FirstStop.transform.position) * secondsPerMeter; float timeWalkingFromLastStation = Vector3.Distance(nextItinerary.LastStop.transform.position, destination.transform.position) * secondsPerMeter; float travelTime = nextItinerary.GetTotalTravelTime() + timeWalkingToFirstStation + timeWalkingFromLastStation; if (travelTime < bestTravelTime) { bestTravelTime = travelTime; bestItineraryFound = nextItinerary; } } } } if (bestItineraryFound == null) { Debug.Log("No itinerary found"); } return(bestItineraryFound); }
/// <summary> /// Constructor of the class. /// </summary> /// <param name="destinationPoint"></param> /// <param name="itinerary"></param> public FlashPedestriansRouting(FlashPedestriansDestination destinationPoint, Itinerary itinerary) { this.destinationPoint = destinationPoint; this.itinerary = itinerary; }
/// <summary> /// Spawns a Flash Pedestrian given its profile and its routing objects. /// </summary> /// <param name="profile">Profile object that will be used by the pedestrian.</param> /// <param name="routing">Routing object that will be used by the pedestrian.</param> /// <param name="routing">Index of the destination point within the destination.</param> private void SpawnPedestrian(Vector3 spawningPoint, FlashPedestriansProfile profile, FlashPedestriansDestination destination, Itinerary itinerary, int destIndex = 0) { GameObject newAgent; spawningPoint += new Vector3(Random.Range(-1.0f, 1.0f), 0.0f, Random.Range(-1.0f, 1.0f)); if (pedestrianCache.Count > 0) { newAgent = (GameObject)pedestrianCache.Dequeue(); newAgent.transform.position = spawningPoint; } else { //Random.Range(0, pedGlobalParameters.pedestrianObject.Length) newAgent = Instantiate(pedGlobalParameters.pedestrianObject, spawningPoint, Quaternion.identity) as GameObject; newAgent.transform.SetParent(this.transform, true); } if (pedGlobalParameters.rumoursEnabled || pedGlobalParameters.bikesEnabled) { BoxCollider col = newAgent.GetComponent <BoxCollider>(); if (col != null) { col.enabled = true; } else { newAgent.AddComponent <BoxCollider>(); } } FlashPedestriansController controller = newAgent.GetComponent <FlashPedestriansController>(); controller.uniqueId = nextIdForPedestrian++; controller.profile = profile; controller.routing = new FlashPedestriansRouting(destination, itinerary, destIndex); controller.flashInformer = flashInformer; // Subscribe pedestrian to the itinerary informer flashInformer.SubscribePedestrian(controller); newAgent.name = "flashPedestrian_" + this.name + "_" + "_" + controller.uniqueId; newAgent.SetActive(true); // Track the pedestrian in the heatmap if (trackPedestriansInHeatmap && heatmapCtrl != null) { heatmapCtrl.TrackNewElement(newAgent); } // Atomic increment of the KPI property Interlocked.Add(ref pedGlobalParameters.numberOfPedestriansOnScenario, pedGlobalParameters.numberOfPedestriansPerAgent); if (++numberOfPedestriansGenerated >= maxNumberOfPedestriansToSpawn && !spawnPedestriansInInfiniteLoop) { CancelInvoke(); } }