static void TriggerOnTemporalSimulationStart() { #if UNITY_EDITOR EditorOnlyEvents.OnTemporalSimulationStart(); #endif if (onTemporalSimulationStart != null) { onTemporalSimulationStart(); } }
bool TryStartSimulation() { if (!TraitCodeGenerator.HasGenerated || EditorApplication.isPlayingOrWillChangePlaymode) { return(false); } var useExistingData = KeepDataBetweenSimulations; KeepDataBetweenSimulations = false; m_SimulationRestartNeeded = false; NextSimModeSelection = SimulationModeSelection.NoModePreference; // Make sure the watchdog is up-to-date before we check if the scene has entities or subscribers m_SceneWatchdogModule.ExecutePollingTask(); if (!sceneIsSimulatable) { CleanupSimulation(); return(false); } if (!m_SimulationSceneModule.IsSimulationReady) { return(false); } // if this method is null, that means something has tried to start simulation when the database isn't setup if (IUsesQueryResultsMethods.RegisterQuery == null) { return(false); } var simulationSettings = SimulationSettings.instance; if (!simulationSettings.IsSpatialContextAvailable) { return(false); } var marsSession = MarsRuntimeUtils.GetMarsSessionInActiveScene(); if (marsSession == null) { return(false); } ProfilerMarkers.TryStartSimulation.Begin(); // only profile after safety checks if (MarsDebugSettings.QuerySimulationModuleLogging) { Debug.Log("Start simulation"); } // Cancel delay calls in case the previous simulation was one-shot. Otherwise we can end up stopping behaviors // in the middle of temporal simulation or doubling up on delay calls for one-shot simulation. EditorApplication.delayCall -= StopRunningOneShot; EditorApplication.delayCall -= DelayStopRunningOneShot; BeforeSimulationSetup?.Invoke(); m_SlowTaskModule.ClearTasks(); QueryObjectMapping.Map.Clear(); k_TraitRequirements.Clear(); k_FunctionalitySubscriberObjects.Clear(); EditorOnlyEvents.OnSimulationStart(k_FunctionalitySubscriberObjects, k_TraitRequirements); m_SimulatedObjectsManager.SetupSimulatables(k_FunctionalitySubscriberObjects); simulating = true; var providersPreserved = useExistingData; if (!useExistingData) { if (m_SimulationContext.Update(marsSession, k_FunctionalitySubscriberObjects, simulatingTemporal)) { if (MarsDebugSettings.QuerySimulationModuleLogging) { Debug.Log("Simulation context changed. Recreating providers."); } CleanupProviders(); functionalityIsland = simulationSettings.EnvironmentMode == EnvironmentMode.Synthetic && simulatingTemporal ? m_SimulatedDiscoveryIsland : m_SimulationIsland; providersRoot = new GameObject("Providers"); m_SimulationSceneModule.AddContentGameObject(providersRoot); GameObjectUtils.gameObjectInstantiated += OnProviderInstantiated; if (addCustomProviders != null) { addCustomProviders(m_Providers); functionalityIsland.AddProviders(m_Providers); } var subscriberTypes = m_SimulationContext.SceneSubscriberTypes; functionalityIsland.SetupDefaultProviders(subscriberTypes, m_Providers); var definitions = new HashSet <TraitDefinition>(); k_TraitRequirements.UnionWith(m_SimulationContext.SceneRequirements); m_ReasoningModule.ExtraTraitRequirements.Clear(); m_ReasoningModule.ExtraTraitRequirements.UnionWith(k_TraitRequirements); foreach (var requirement in k_TraitRequirements) { definitions.Add(requirement); } functionalityIsland.RequireProvidersWithDefaultProviders(definitions, m_Providers); functionalityIsland.PrepareFunctionalityForSubscriberTypes(subscriberTypes, m_Providers); ModuleLoaderCore.instance.InjectFunctionalityInModules(functionalityIsland); GameObjectUtils.gameObjectInstantiated -= OnProviderInstantiated; providersRoot.SetHideFlagsRecursively(SimulatedObjectsManager.SimulatedObjectHideFlags); foreach (var provider in m_Providers) { var providerBehaviour = provider as MonoBehaviour; if (providerBehaviour != null) { m_ProviderBehaviours.Add(providerBehaviour); } } foreach (var gameObject in m_ProviderGameObjects) { foreach (var simulatable in gameObject.GetComponentsInChildren <ISimulatable>()) { var providerBehaviour = simulatable as MonoBehaviour; if (providerBehaviour != null) { m_ProviderBehaviours.Add(providerBehaviour); } } } } else { providersPreserved = true; StopRunningProviders(); } } // When using providers from the last simulation, ensure they stay at the bottom of the hierarchy if (providersPreserved) { providersRoot.transform.SetAsLastSibling(); } this.SetCameraScale(MarsWorldScaleModule.GetWorldScale()); // Set active island now that providers have been setup m_FIModule.SetActiveIsland(functionalityIsland); functionalityIsland.InjectFunctionalitySingle(marsSession); marsSession.StartRunInEditMode(); if (!useExistingData) { // Clear the database and then run providers in edit mode so we start getting data. m_Database.Clear(); foreach (var providerBehaviour in m_ProviderBehaviours) { providerBehaviour.StartRunInEditMode(); } } m_ReasoningModule.ResetReasoningAPIs(); // We must also reset the backend's query management state each time, otherwise there is no guarantee that // the its collections will be ordered the same way each time, even if the ordering of clients in the scene // stays the same. This also ensures its slow tasks are registered using edit mode time rather than play mode time. m_QueryBackend.ResetQueryManagement(); GameObjectUtils.gameObjectInstantiated += m_SimulatedObjectsManager.AddSpawnedObjectToSimulation; m_QueryBackend.onQueryMatchFound += k_OnQueryMatchFound; m_QueryBackend.onSetQueryMatchFound += k_OnSetQueryMatchFound; if (simulationSettings.FindAllMatchingDataPerQuery) { m_QueryBackend.onQueryMatchesFound += k_OnQueryMatchesFound; } // inject functionality on all copied functionality subscribers functionalityIsland.InjectPreparedFunctionality(k_FunctionalitySubscriberObjects); GeoLocationModule.instance.AddOrUpdateLocationTrait(); m_SchedulerModule.ResetTime(); m_SimulatedObjectsManager.StartRunningSimulatables(); ProfilerMarkers.TryStartSimulation.End(); return(true); }
void CopySimulatablesToSimulationScene() { ProfilerMarkers.CopySimulatablesToSimulationScene.Begin(); // Destroy old copied objects and objects spawned by queries. DestroySimulatedObjectsRoot(); // If anything about the session changes in EnsureRuntimeState, it tries to dirty the simulatable scene // which would trigger another simulation. To prevent that we temporarily clear the delegate. EditorOnlyDelegates.DirtySimulatableScene = null; MARSSession.EnsureRuntimeState(); EditorOnlyDelegates.DirtySimulatableScene = DirtySimulatableScene; var session = MarsRuntimeUtils.GetMarsSessionInActiveScene(); // Find all the root game objects in the active scene and move them under a root transform. var activeScene = SceneManager.GetActiveScene(); k_RootGameObjects.Clear(); activeScene.GetRootGameObjects(k_RootGameObjects); SimulatedContentRoot = new GameObject(k_TemporaryRootName); SimulatedContentRoot.SetActive(false); foreach (var gameObject in k_RootGameObjects) { gameObject.transform.SetParent(SimulatedContentRoot.transform, true); } k_OriginalSimulatables.Clear(); SimulatedContentRoot.GetComponentsInChildren(k_OriginalSimulatables); k_OriginalTransforms.Clear(); SimulatedContentRoot.GetComponentsInChildren(k_OriginalTransforms); k_OriginalTransforms.RemoveAt(0); // Ignore the root // Copy the root transform to the simulated content scene. The reason we copy simulatables this way rather than // copying them individually is so that their references to other simulatables stay intact. var copiedSimulatedContentRoot = GameObjectUtils.CloneWithHideFlags(SimulatedContentRoot); copiedSimulatedContentRoot.name = k_SimulatedContentRootName; // After copying, we need to move original gameobjects back to the scene root. foreach (var gameObject in k_RootGameObjects) { gameObject.transform.SetParent(null, true); } UnityObjectUtils.Destroy(SimulatedContentRoot); SimulatedContentRoot = copiedSimulatedContentRoot; // Remove the copied MARS Session to avoid conflicts var copiedSession = SimulatedContentRoot.GetComponentInChildren(typeof(MARSSession)); UnityObjectUtils.Destroy(copiedSession); m_SimulationSceneModule.AddContentGameObject(SimulatedContentRoot); k_CopiedTransforms.Clear(); SimulatedContentRoot.GetComponentsInChildren(k_CopiedTransforms); k_CopiedTransforms.RemoveAt(0); // Ignore the root var copiedTransformsCount = k_CopiedTransforms.Count; Debug.Assert(k_OriginalTransforms.Count == copiedTransformsCount, "Copied Transforms in the simulation scene do not map 1:1 with original Transforms in the query scene."); m_OriginalToCopiedTransforms.Clear(); m_CopiedToOriginalTransforms.Clear(); for (var i = 0; i < copiedTransformsCount; ++i) { AddTransformCopy(k_CopiedTransforms[i], k_OriginalTransforms[i]); } m_SimulatableBehaviours.Clear(); k_CopiedSimulatables.Clear(); SimulatedContentRoot.GetComponentsInChildren(k_CopiedSimulatables); var copiedSimulatablesCount = k_CopiedSimulatables.Count; Debug.Assert(k_OriginalSimulatables.Count == copiedSimulatablesCount, "Copied ISimulatables in the simulation scene do not map 1:1 with original ISimulatables in the query scene."); m_CopiedToOriginalSimulatables.Clear(); m_OriginalToCopiedSimulatables.Clear(); m_LandmarkControllers.Clear(); for (var i = 0; i < copiedSimulatablesCount; i++) { var originalSimulatable = k_OriginalSimulatables[i]; var copiedSimulatable = k_CopiedSimulatables[i]; var behaviour = copiedSimulatable as MonoBehaviour; if (behaviour != null) { m_SimulatableBehaviours.Add(behaviour); } var landmarkController = originalSimulatable as LandmarkController; if (landmarkController) { m_LandmarkControllers[landmarkController] = (LandmarkController)copiedSimulatable; } AddSimulatedCopy(copiedSimulatable, originalSimulatable); } AddSyntheticEnvironmentSimulatedObjects(); EditorOnlyEvents.OnSetupSimulatables(m_SimulatableBehaviours); k_CopiedLights.Clear(); SimulatedContentRoot.GetComponentsInChildren(k_CopiedLights); // Content scene lights on shouldn't cast on the simulated environment foreach (var light in k_CopiedLights) { light.cullingMask &= ~(SimulationConstants.SimulatedEnvironmentLayerMask); } // Set up simulation camera at the device starting position // with the correct settings for rendering the sim scene var cameraReference = session.cameraReference; if (cameraReference == null) { cameraReference = session.GetComponentInChildren <MARSCamera>(true); if (cameraReference == null) { Debug.LogError("MARSSession does not have a MARSCamera"); return; } } var originalCamera = cameraReference.gameObject; var copiedCameraTrans = GetCopiedTransform(originalCamera.transform); var startingPose = m_EnvironmentManager.DeviceStartingPose; copiedCameraTrans.SetLocalPose(startingPose); SimulatedCamera = copiedCameraTrans.GetComponent <Camera>(); SimulatedCamera.cameraType = CameraType.SceneView; SimulatedCamera.tag = "Untagged"; // Copied camera should not be marked as the main camera SimulationSceneModule.instance.AssignCameraToSimulation(SimulatedCamera); // Disallow MSAA on copied camera to avoid tiled GPU perf warning // https://issuetracker.unity3d.com/issues/tiled-gpu-perf-warning-appears-when-multiple-cameras-with-allow-msaa-are-present-in-the-scene-and-viewport-rect-is-not-default SimulatedCamera.allowMSAA = false; SimulatedContentRoot.AddToHideFlagsRecursively(SimulatedObjectHideFlags); EntityVisualsModule.instance.simEntitiesRoot = SimulatedContentRoot.transform; SimulatedContentRoot.SetActive(true); foreach (var contentHierarchy in Resources.FindObjectsOfTypeAll <ContentHierarchyPanel>()) { contentHierarchy.RestoreState(); } ProfilerMarkers.CopySimulatablesToSimulationScene.End(); }