public virtual void LoadProvider() { if (SuppressWarnings) { return; } #if UNITY_EDITOR // Suppress warnings in one-shot simulation var temporalSim = EditorOnlyDelegates.IsSimulatingTemporal != null && EditorOnlyDelegates.IsSimulatingTemporal(); if (!temporalSim && !Application.isPlaying) { return; } #endif foreach (var providerInterface in GetType().GetInterfaces()) { if (providerInterface == typeof(IFunctionalityProvider)) { continue; } if (!typeof(IFunctionalityProvider).IsAssignableFrom(providerInterface)) { continue; } Debug.LogWarning($"Using stub provider for {providerInterface} - no other providers found"); } }
/// <summary> /// Gather trackable objects in the simulated environment and do any other initialization that depends on the environment /// </summary> protected virtual void SetupTrackingForEnvironment() { // Once the environment is set up we can gather its synthesized trackables. To simulate discovery of these // trackables we can check how visible they are to the camera - this includes frustum checking, occlusion checking, // and other heuristics. m_EnvironmentScene = EditorOnlyDelegates.GetSimulatedEnvironmentScene(); if (!m_EnvironmentScene.IsValid()) { return; } // Get the environment physics scene to check if trackable objects are occluded by other objects in the environment m_EnvironmentPhysicsScene = m_EnvironmentScene.GetPhysicsScene(); m_SimulatedTrackableObjects.Clear(); k_SimulatedObjects.Clear(); GameObjectUtils.GetComponentsInScene(m_EnvironmentScene, k_SimulatedObjects); foreach (var simulatedObject in k_SimulatedObjects) { var synthTrackable = simulatedObject.GetComponent <TSynthTrackable>(); if (synthTrackable == null) { continue; } synthTrackable.Initialize(); m_SimulatedTrackableObjects[synthTrackable] = simulatedObject; this.InjectFunctionalitySingle(simulatedObject); simulatedObject.StartRunInEditMode(); } k_SimulatedObjects.Clear(); }
void SetupTrackingForEnvironment() { m_EnvironmentScene = EditorOnlyDelegates.GetSimulatedEnvironmentScene(); if (!m_EnvironmentScene.IsValid()) { return; } m_EnvironmentPhysicsScene = m_EnvironmentScene.GetPhysicsScene(); m_SynthMarkers.Clear(); k_SimulatedObjects.Clear(); GameObjectUtils.GetComponentsInScene(m_EnvironmentScene, k_SimulatedObjects); foreach (var simulatedObject in k_SimulatedObjects) { var synthesizedMarker = simulatedObject.GetComponent <SynthesizedMarker>(); if (synthesizedMarker == null || !synthesizedMarker.isActiveAndEnabled) { continue; } synthesizedMarker.Initialize(); m_SynthMarkers.Add(synthesizedMarker); this.InjectFunctionalitySingle(simulatedObject); simulatedObject.StartRunInEditMode(); } k_SimulatedObjects.Clear(); }
void OnEnable() { #if UNITY_EDITOR if (Application.isPlaying && !EditorOnlyDelegates.IsEntitled(false)) { Debug.LogWarning(EntitlementsFailedMessage); } #endif ModuleLoaderCore.instance.OnBehaviorEnable(); }
// combine all marker tracking heuristics into one result static SimulatedMarkerTrackingResult GetMarsCameraTrackingQuality(SynthesizedMarker marker, Camera cam) { var markerTrans = marker.transform; var markerPos = markerTrans.position; var markerUp = markerTrans.up; // tolerance > 1 allows tracking loss to happen when most of the marker goes out, not just the center const float relaxedTolerance = 1.1f; // if the marker is outside the camera frustum, the device can't see/track it anymore if (!SimulatedTrackingUtils.PointInFrustum(cam, markerPos, relaxedTolerance)) { return(new SimulatedMarkerTrackingResult(0f, TrackingFailureCause.OutOfFrustum)); } var camTrans = cam.transform; var camPos = camTrans.position; var camForward = camTrans.forward; var distance = Vector3.Distance(camPos, markerPos); var distanceQuality = GetDistanceQuality(marker.Extents, distance); // markers that are too far away can't be tracked if (distanceQuality <= 0f) { return(new SimulatedMarkerTrackingResult(0f, TrackingFailureCause.OutOfRange)); } // assume marker isn't occluded by environment in the case where the physics scene is not available var occluded = false; var hitCount = 0; #if UNITY_EDITOR var simScene = EditorOnlyDelegates.GetSimulatedEnvironmentScene(); if (simScene.IsValid()) { var physicScene = simScene.GetPhysicsScene(); if (physicScene.IsValid()) { occluded = TestPointOcclusion(physicScene, camPos, markerPos, out hitCount); } } #endif if (occluded) { return(new SimulatedMarkerTrackingResult(0f, TrackingFailureCause.Occluded, k_RayHits[0].point, hitCount)); } var alignmentQuality = GetImageAlignmentQuality(markerUp, camForward); // this is important to consider in combination with the surface viewing angle test, // because the camera's forward can be aligned with the marker's normal without actually looking at the marker var lookDirQuality = GetLookDirectionQuality(markerPos, camPos, camForward); return(new SimulatedMarkerTrackingResult(alignmentQuality * lookDirQuality * distanceQuality)); }
internal void SimulationRaycastHits() { var cameraTransform = m_Camera.transform; var origin = cameraTransform.position; var fov = m_Camera.fieldOfView * 0.5f; var rotation = cameraTransform.rotation; var mask = SimulationConstants.SimulatedEnvironmentLayerMask; var horizontalFOV = m_Camera.GetHorizontalFOV(); var scaledMaxHitDistance = m_MaxHitDistance * m_DistanceScale; if (m_RaycastHits.Length != m_RaysPerCast) { m_RaycastHits = new RaycastHit[m_RaysPerCast]; } if (m_Raycasts.Length != m_RaysPerCast) { m_Raycasts = new Ray[m_RaysPerCast]; } var simScene = EditorOnlyDelegates.GetSimulatedEnvironmentScene(); if (!simScene.IsValid()) { return; } var physicScene = simScene.GetPhysicsScene(); if (!physicScene.IsValid()) { return; } for (var i = 0; i < m_RaysPerCast; i++) { var direction = FrustumRay(fov, horizontalFOV, rotation); RaycastHit hit; m_Raycasts[i] = new Ray(origin, direction); physicScene.Raycast(m_Raycasts[i].origin, m_Raycasts[i].direction, out hit, scaledMaxHitDistance, mask); m_RaycastHits[i] = hit; } m_LastCastTime = MarsTime.Time; }
public static double?TryGetAppendedDataTimestamp() { // Subtracting some fraction of time step is a way to accommodate a quirk of recording while a recording is playing. // Recordings are played back at increments of MarsTime.TimeStep. So when we append data to a recording // we have to make sure the timestamps are not on exact increments, otherwise the data could get played back // at the wrong frame in MarsTime due to rounding errors. #if UNITY_EDITOR var recordingDirector = EditorOnlyDelegates.GetCurrentRecordingDirector(); if (recordingDirector != null) { return(Math.Max(recordingDirector.CurrentTime - MarsTime.TimeStep * k_TimeStepOffsetFactor, 0d)); } #endif return(null); }
IEnumerator StartWebCamCoroutine() { #if UNITY_EDITOR || !PLATFORM_LUMIN var devices = WebCamTexture.devices; if (m_WebCamDeviceIndex >= devices.Length) { Debug.LogWarning("Selected web cam device is not available. Resync simulation to refresh available devices."); yield break; } #if UNITY_EDITOR var isTemporal = EditorOnlyDelegates.IsSimulatingTemporal(); if (!EditorOnlyDelegates.PerformCameraPermissionCheck(isTemporal)) yield break; #endif var device = devices[m_WebCamDeviceIndex]; var requestedWidth = k_DefaultRequestedWidth; var requestedHeight = k_DefaultRequestedHeight; var requestedFPS = k_DefaultRequestedFPS; var availableResolutions = device.availableResolutions; if (availableResolutions != null && availableResolutions.Length > 0) { var resolution = availableResolutions[0]; requestedWidth = resolution.width; requestedHeight = resolution.height; requestedFPS = resolution.refreshRate; } m_LiveVideoTexture = new WebCamTexture(device.name, requestedWidth, requestedHeight, requestedFPS); VideoFacingDirection = device.isFrontFacing ? CameraFacingDirection.User : CameraFacingDirection.World; VideoFocalLength = SimulationVideoContextSettings.instance.SimulatedFocalLength; m_LiveVideoTexture.Play(); while (m_LiveVideoTexture != null && m_LiveVideoTexture.width <= k_InvalidWidth) yield return null; if (m_LiveVideoTexture == null) yield break; if (m_BackgroundRenderer != null && VideoFeedTexture != m_LiveVideoTexture) ChangeVideoFeedTexture(m_LiveVideoTexture); #else Debug.LogWarning("Webcam API not available on Lumin platform"); yield break; #endif }
void OnEnable() { m_LastGrowthTime = MarsTime.Time; MarsTime.MarsUpdate += OnMarsUpdate; m_PreviousExtentsDebug = MarsDebugSettings.SimDiscoveryModulePlaneExtentsDebug; m_PreviousVerticesDebug = MarsDebugSettings.SimDiscoveryModulePlaneVerticesDebug; m_PointCloudProvider = GetComponent <SimulatedDiscoveryPointCloudProvider>(); m_PointCloudProvider.PointCloudUpdated += OnPointCloudUpdated; EditorOnlyEvents.onEnvironmentSetup += SetupFromEnvironment; if (EditorOnlyDelegates.IsEnvironmentSetup != null && EditorOnlyDelegates.IsEnvironmentSetup()) { SetupFromEnvironment(); } m_ProvidesSessionControl = m_SessionProvider; }
public void AddOrUpdateTrait(int dataID, string traitName, T value) { #if UNITY_EDITOR if (!EditorOnlyDelegates.IsEntitled(true)) { return; } #endif Dictionary <int, T> collection; if (!m_Dictionary.TryGetValue(traitName, out collection)) { collection = new Dictionary <int, T>(); m_Dictionary.Add(traitName, collection); } collection[dataID] = value; }
void UpdateForCamera(Camera viewCamera) { if (viewCamera == null) { return; } #if UNITY_EDITOR var spriteColor = m_SpriteRenderer.color; if (EditorOnlyDelegates.IsGizmosCamera != null && EditorOnlyDelegates.IsGizmosCamera(viewCamera)) { spriteColor.a = m_SpriteAlpha; } else { spriteColor.a = 0f; } m_SpriteRenderer.color = spriteColor; #endif var cameraTransform = viewCamera.transform; var forward = cameraTransform.forward; transform.rotation = Quaternion.LookRotation(forward, cameraTransform.up); // Set world scale of transform based on view distance for constant screen-space size var delta = cameraTransform.position - transform.position; var distanceScale = delta.magnitude; var newScale = distanceScale * k_ScaleByDistance * Vector3.one; if (transform.parent != null) { var parentScale = transform.parent.localScale; var inverseParentScale = new Vector3(1.0f / parentScale.x, 1.0f / parentScale.y, 1.0f / parentScale.z); newScale.Scale(inverseParentScale); } transform.localScale = newScale; }
void Update() { if (Application.isPlaying) { return; } if (!m_PlayableDirector.playableGraph.IsValid()) { return; } var paused = !m_PlayableDirector.playableGraph.IsPlaying(); var temporal = EditorOnlyDelegates.IsSimulatingTemporal(); if (temporal && paused) { m_PlayableDirector.Resume(); } else if (!temporal && !paused) { m_PlayableDirector.Pause(); } }
void IModuleBehaviorCallbacks.OnBehaviorAwake() { if (!Application.isPlaying) { return; } var session = MARSSession.Instance; if (session == null) { return; } GetAllMonoBehaviors(); var subscriberCount = 0; var sceneObjects = k_MonoBehaviourObjects; sceneObjects.AddRange(m_CustomRuntimeSceneObjects); var providers = new List <IFunctionalityProvider>(); var providerTypes = new HashSet <Type>(); var subscriberTypes = new HashSet <Type>(); subscriberTypes.Add(typeof(MARSSceneModule)); foreach (var behavior in sceneObjects) { // Exclude modules as they have already been set up for FI if (behavior is IModule) { continue; } var functionalityProvider = behavior as IFunctionalityProvider; if (functionalityProvider != null) { providers.Add(functionalityProvider); providerTypes.Add(functionalityProvider.GetType()); } var subscriber = behavior as IFunctionalitySubscriber; if (subscriber != null) { subscriberCount++; subscriberTypes.Add(subscriber.GetType()); } } if (MarsDebugSettings.SceneModuleLogging) { Debug.Log(string.Format("Scene Module found {0} providers with types: {1}", providers.Count, string.Join(",", providerTypes.Select(type => type.Name).ToArray()))); Debug.Log(string.Format("Scene Module found {0} subscribers with types: {1}", subscriberCount, string.Join(",", subscriberTypes.Select(type => type.Name).ToArray()))); } // TODO: notify other modules (i.e. backend) that the active island has changed #if UNITY_EDITOR var useSimulationIsland = Application.isPlaying && simulateInPlaymode; if (useSimulationIsland) { var simulationIsland = m_SimulateDiscovery ? m_SimulatedDiscoveryIsland : m_SimulationIsland; if (simulationIsland != null) { m_FIModule.SetActiveIsland(simulationIsland); } } else { var island = session.island; if (island != null) { m_FIModule.SetActiveIsland(island); } } #else var island = session.island; if (island) { m_FIModule.SetActiveIsland(island); } #endif var activeIsland = m_FIModule.activeIsland; activeIsland.AddProviders(providers); var newProviders = new List <IFunctionalityProvider>(); if (BeforeSetupDefaultProviders != null) { BeforeSetupDefaultProviders(newProviders); activeIsland.AddProviders(newProviders); } activeIsland.SetupDefaultProviders(subscriberTypes, newProviders); var definitions = new HashSet <TraitDefinition>(); foreach (var requirement in session.requirements.TraitRequirements) { definitions.Add(requirement); } activeIsland.InjectFunctionality(sceneObjects); activeIsland.RequireProvidersWithDefaultProviders(definitions, newProviders); sceneObjects.Clear(); sceneObjects.AddRange(newProviders); activeIsland.InjectFunctionality(sceneObjects); activeIsland.InjectFunctionalitySingle(this); #if UNITY_EDITOR if (EditorOnlyDelegates.CullEnvironmentFromSceneLights != null) { for (var i = 0; i < SceneManager.sceneCount; i++) { EditorOnlyDelegates.CullEnvironmentFromSceneLights(SceneManager.GetSceneAt(i)); } } #endif // Update the scale provider to the scene's session scale in case it needs to cache this value this.SetCameraScale(session.transform.localScale.x); subscriberTypes.Clear(); }
void OnEnable() { var isSimulatingTemporal = EditorOnlyDelegates.IsSimulatingTemporal != null && EditorOnlyDelegates.IsSimulatingTemporal(); if (Application.isPlaying || !isSimulatingTemporal) { return; } m_PlayableDirector.Pause(); }