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");
            }
        }
Пример #2
0
        /// <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();
        }
Пример #3
0
        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();
        }
Пример #4
0
        void OnEnable()
        {
#if UNITY_EDITOR
            if (Application.isPlaying && !EditorOnlyDelegates.IsEntitled(false))
            {
                Debug.LogWarning(EntitlementsFailedMessage);
            }
#endif
            ModuleLoaderCore.instance.OnBehaviorEnable();
        }
Пример #5
0
        // 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;
        }
Пример #7
0
        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();
            }
        }
Пример #13
0
        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();
        }