/// <summary>
        /// Sets the default camera settings based on the current scene view camera
        /// </summary>
        /// <param name="sceneView">Scene view that we are getting the camera from</param>
        /// <param name="isSimView">Is the scene view a simulation view</param>
        public void SetDefaultEnvironmentCamera(SceneView sceneView, bool isSimView)
        {
            MARSSession.EnsureRuntimeState();
            var simCamera       = sceneView.camera;
            var cameraTransform = simCamera.transform;

            using (var undoBlock = new UndoBlock("Set Default Environment Camera"))
            {
                undoBlock.RecordObject(this);
                if (isSimView)
                {
                    var cameraScale = MARSSession.GetWorldScale();
                    var camPose     = new Pose(cameraTransform.position / cameraScale, cameraTransform.rotation);

                    m_EnvironmentInfo.DefaultCameraWorldPose = camPose;
                    m_EnvironmentInfo.DefaultCameraPivot     = sceneView.pivot / cameraScale;
                    m_EnvironmentInfo.DefaultCameraSize      = sceneView.size / cameraScale;
                }
                else
                {
                    m_EnvironmentInfo.DefaultCameraWorldPose = cameraTransform.GetWorldPose();
                    m_EnvironmentInfo.DefaultCameraPivot     = sceneView.pivot;
                    m_EnvironmentInfo.DefaultCameraSize      = sceneView.size;
                }
            }
        }
        internal static void ExtractPlanes(PlaneExtractionSettings settings)
        {
            using (var undoBlock = new UndoBlock("Extract Planes"))
            {
                var prefabRoot = settings.gameObject;
                undoBlock.RecordObject(prefabRoot);
                var voxelGenerationParams = settings.VoxelGenerationParams;
                var planeExtractionParams = settings.PlaneFindingParams;
                var voxelSize             = voxelGenerationParams.voxelSize;
                if ((int)(planeExtractionParams.minPointsPerSqMeter * (voxelSize * voxelSize)) <= 0)
                {
                    Debug.LogWarning("Minimum points per voxel is not greater than 0. " +
                                     "Increase either the voxel size or the minimum points per square meter.");
                    return;
                }

                if (!PlaneGenerationModule.TryDestroyPreviousPlanes(prefabRoot, "Extracting Planes", undoBlock))
                {
                    return;
                }

                GenerateVoxelGrids(prefabRoot, voxelGenerationParams, planeExtractionParams);
                FindPlanesInGrids(prefabRoot, undoBlock);
            }
        }
        internal static void SetChildrenVisible(bool visible, Transform instance)
        {
            using (var undoBlock = new UndoBlock("Setting visibility"))
            {
                foreach (Transform child in instance.transform)
                {
                    undoBlock.RecordObject(child);
                    child.gameObject.hideFlags = visible ? HideFlags.None : HideFlags.HideInHierarchy;
                }
            }

            EditorApplication.DirtyHierarchyWindowSorting(); // helps editor know to update

            s_LastSetChildrenVisible = visible;
        }
        /// <summary>
        /// Sets the simulated device starting pose based on the current scene view camera
        /// </summary>
        /// <param name="cameraPose">Camera pose we using</param>
        /// <param name="isSimView">Is this camera from a simulation view</param>
        public void SetSimulationStartingPose(Pose cameraPose, bool isSimView)
        {
            MARSSession.EnsureRuntimeState();
            using (var undoBlock = new UndoBlock("Set Simulation Starting Pose"))
            {
                undoBlock.RecordObject(this);
                if (isSimView)
                {
                    var cameraScale = MARSSession.GetWorldScale();
                    cameraPose.position /= cameraScale;
                }

                m_EnvironmentInfo.SimulationStartingPose = cameraPose;
            }
        }
        public void UpdatePrefabInfo()
        {
            var bounds = m_EnvironmentInfo.EnvironmentBounds;

            if (!m_EnvironmentInfo.EnvironmentBounds.Contains(m_EnvironmentInfo.SimulationStartingPose.position) ||
                !EnsureBoundsHasVolume(ref bounds, true))
            {
                using (var undoBlock = new UndoBlock("Update Environment Info"))
                {
                    undoBlock.RecordObject(this);
                    // See if we can grow the EnvironmentBounds to include the camera starting
                    // pose based on the gameObjects bounds.
                    var goBounds = BoundsUtils.GetBounds(gameObject.transform);
                    if (goBounds.Contains(m_EnvironmentInfo.SimulationStartingPose.position))
                    {
                        Debug.LogWarningFormat("Simulation starting pose for environment '{0}' is outside the bounds of " +
                                               "`EnvironmentInfo.EnvironmentBounds` but inside the bounds of {0}'s GameObject. Encapsulating " +
                                               "the GameObject's bounds", gameObject.name);
                        bounds.Encapsulate(goBounds);
                    }

                    // Make sure the EnvironmentBounds has volume
                    if (!EnsureBoundsHasVolume(ref bounds, false))
                    {
                        Debug.LogWarningFormat("`EnvironmentInfo.EnvironmentBounds` of {0} has no volume. Expanding the size " +
                                               "of sides with 0 size to 1.", gameObject.name);
                    }

                    // Move camera starting pose inside the EnvironmentBounds volume
                    if (!bounds.Contains(m_EnvironmentInfo.SimulationStartingPose.position))
                    {
                        var startingPose = m_EnvironmentInfo.SimulationStartingPose;
                        Debug.LogWarningFormat(
                            "Simulation starting pose for environment '{0}' is outside the total bounds of the environment. " +
                            "The starting pose will be moved to the closest point on the bounds.", gameObject.name);
                        startingPose.position = bounds.ClosestPoint(startingPose.position);
                        m_EnvironmentInfo.SimulationStartingPose = startingPose;
                    }

                    m_EnvironmentInfo.EnvironmentBounds = bounds;
                }
            }
        }
        public override void OnInspectorGUI()
        {
            var inspectedLightComponent = m_InspectedTarget.GetComponent <Light>();

            if (inspectedLightComponent != null && inspectedLightComponent.type != LightType.Directional)
            {
                EditorGUILayout.HelpBox(k_IncorrectLightTypeNextToVisualizerMsg, MessageType.Warning);

                if (GUILayout.Button("Change to Directional Light"))
                {
                    using (var undoBlock = new UndoBlock("Change light type"))
                    {
                        undoBlock.RecordObject(inspectedLightComponent);
                        inspectedLightComponent.type = LightType.Directional;
                    }
                }
            }

            //Show default UI from Monobehavior
            base.OnInspectorGUI();
        }
Example #7
0
        /// <summary>
        /// Ensures that a MARS Scene has all required components and configuration
        /// </summary>
        public static void EnsureRuntimeState(Transform overrideUserRef = null)
        {
            // Make sure we have a MARS Session
            if (Instance == null)
            {
                Instance = GameObjectUtils.ExhaustiveComponentSearch <MARSSession>(null);
            }

            if (MARSSceneModule.instance.BlockEnsureSession)
            {
                return;
            }

            // Early out if nothing needs to change, otherwise we add an unnecessary undo group
            if (SessionConfigured(Instance))
            {
                return;
            }

            using (var undoBlock = new UndoBlock("Ensure MARS Runtime State"))
            {
                if (Instance == null)
                {
                    CreateSession(undoBlock);
                    DirtySimulatableSceneIfNeeded();
                }
                else
                {
                    undoBlock.RecordObject(Instance.gameObject);
                }

                if (!TestMode)
                {
                    EnsureSessionConfigured(Instance, undoBlock, overrideUserRef);
                }
            }
        }
Example #8
0
        static void EnsureSessionConfigured(MARSSession session, UndoBlock undoBlock, Transform overrideUserRef = null)
        {
            var sessionObject    = session.gameObject;
            var sessionTransform = session.transform;
            var changed          = false;

            // Make sure we have a properly configured MARS Camera
            if (!TestMode && session.m_CameraReference == null)
            {
                var marsCameraRef = GameObjectUtils.ExhaustiveComponentSearch <MARSCamera>(sessionObject);

                // If we can't find a MARS camera, get the main camera and create one on that
                if (marsCameraRef == null)
                {
                    LogRuntimeIssue("MARSCamera not present in the scene.  Adding one to the main camera.");

                    var createdNewCamera = false;
                    var cameraRef        = GameObjectUtils.ExhaustiveTaggedComponentSearch <Camera>(sessionObject, k_CameraTag);
                    if (cameraRef == null)
                    {
                        cameraRef        = CreateCamera(sessionTransform, undoBlock);
                        createdNewCamera = true;
                    }

                    marsCameraRef = undoBlock.AddComponent <MARSCamera>(cameraRef.gameObject);

                    if (!createdNewCamera)
                    {
                        var nearPlane    = cameraRef.nearClipPlane;
                        var cameraParent = cameraRef.transform.parent;
                        if (cameraParent == null)
                        {
                            cameraParent = sessionTransform;
                        }

                        var worldScale         = cameraParent.localScale.x;
                        var scaledMaxNearPlane = k_MaxNearPlane * worldScale;
                        if (nearPlane > scaledMaxNearPlane)
                        {
                            LogRuntimeIssue("Camera near clip plane is greater than the recommended distance. " +
                                            $"Setting near plane from {nearPlane} to {scaledMaxNearPlane}.");

                            undoBlock.RecordObject(cameraRef);
                            cameraRef.nearClipPlane = scaledMaxNearPlane;
                        }
                    }
                }

                session.m_CameraReference = marsCameraRef;
                changed = true;
            }

            const string correctBrokenSessionMessage = "If you have not customized the MARSSession game object, just delete " +
                                                       "the object and go to Create > MARS > Session.";

            var cameraTrans = session.m_CameraReference.transform;

            if (!TestMode && cameraTrans.GetComponentInParent <MARSSession>() == null)
            {
                const string cameraParentRequirementMessage = "MARSCamera must have a MARSSession object in its list of parents.";
                var          canReparent = true;
#if INCLUDE_AR_FOUNDATION
                if (cameraTrans.GetComponentInParent <ARSessionOrigin>() != null)
                {
                    canReparent = false;
                    Debug.LogError($"{cameraParentRequirementMessage} Please make sure the MARSSession component " +
                                   $"is on the same game object as the ARSessionOrigin. {correctBrokenSessionMessage}");
                }
#endif
                if (canReparent)
                {
                    LogRuntimeIssue($"{cameraParentRequirementMessage} Re-parenting.");
                    var cameraParent = cameraTrans.parent;
                    if (cameraParent)
                    {
                        sessionTransform.position   = cameraParent.position;
                        sessionTransform.rotation   = cameraParent.rotation;
                        sessionTransform.localScale = cameraParent.localScale;
                    }

                    undoBlock.SetTransformParent(cameraTrans, sessionTransform);
                    changed = true;
                }
            }

            // Look for the user object, if it's not in the scene, make a new one
            var userRef = session.m_UserReference;
            if (!TestMode && userRef == null)
            {
                userRef = session.m_CameraReference.transform.Find(k_UserName);
                if (userRef == null)
                {
                    if (overrideUserRef == null)
                    {
                        userRef = GameObjectUtils.Instantiate(MARSRuntimePrefabs.instance.UserPrefab).transform;
                    }
                    else
                    {
                        userRef = overrideUserRef;
                    }

                    userRef.name          = k_UserName;
                    userRef.parent        = session.m_CameraReference.transform;
                    userRef.localPosition = Vector3.zero;
                    userRef.localRotation = Quaternion.identity;
                    userRef.localScale    = Vector3.one;
                    undoBlock.RegisterCreatedObject(userRef.gameObject);
                }

                session.m_UserReference = userRef;
                changed = true;
            }

            // One more bizarre scenario to catch - the MARS Session and Camera being *one* object.
            // We can't just delete the MARS Session since the user might have other scripts there, so we just throw up a warning telling them to fix things manually
            if (!TestMode && session.m_CameraReference.transform == sessionTransform)
            {
                Debug.LogError("The MARS Session should be a parent of the MARSCamera, *NOT* the same object!  " +
                               $"Please correct this in your scene! {correctBrokenSessionMessage}");
            }

            if (sessionObject.activeInHierarchy == false)
            {
                LogRuntimeIssue("There is a MARS Session object in your scene that is *not* active.  Running your scene with an inactive MARS Session will cause problems.");
                sessionObject.SetActive(true);
                changed = true;
            }

            var cameraObject = session.cameraReference.gameObject;
            if (cameraObject.activeInHierarchy == false)
            {
                LogRuntimeIssue("There is a MARS Camera GameObject in your scene that is *not* active.  " +
                                "Re-enabling here, as running your scene with an inactive MARS Camera would cause problems.");

                cameraObject.SetActive(true);
                changed = true;
            }

            if (changed)
            {
                DirtySimulatableSceneIfNeeded();
            }
        }
Example #9
0
        static MARSSession CreateSession(UndoBlock undoBlock, bool marsBehaviorsInScene = true)
        {
            const string sessionNotPresentMessage = "MARS Session not present in the scene - creating one now.";

            if (marsBehaviorsInScene)
            {
                LogRuntimeIssue(sessionNotPresentMessage);
            }
            else if (!TestMode)
            {
                Debug.Log(sessionNotPresentMessage);
            }

            GameObject sessionObject = null;
            Camera     cameraRef     = null;

            k_Cameras.Clear();
            GameObjectUtils.GetComponentsInActiveScene(k_Cameras);
            if (k_Cameras.Count > 0)
            {
                cameraRef = k_Cameras[0];
                foreach (var camera in k_Cameras)
                {
                    if (camera.CompareTag(k_CameraTag))
                    {
                        cameraRef = camera;
                        break;
                    }
                }
            }

            if (cameraRef != null && cameraRef.transform.parent != null)
            {
                sessionObject = cameraRef.transform.parent.gameObject;
                var addToParentMessage = "Adding MARS Session component to immediate parent of main camera.";
#if INCLUDE_AR_FOUNDATION
                var arSessionOrigin = cameraRef.GetComponentInParent <ARSessionOrigin>();
                if (arSessionOrigin != null)
                {
                    sessionObject      = arSessionOrigin.gameObject;
                    addToParentMessage = "Adding MARS Session component to AR Session Origin game object.";
                }
#endif

                Debug.Log(addToParentMessage);
                undoBlock.RecordObject(sessionObject);
#if UNITY_EDITOR
                EditorGUIUtility.PingObject(sessionObject);
#endif
            }

            if (sessionObject == null)
            {
                sessionObject = new GameObject(k_ObjectName);
                sessionObject.transform.SetAsFirstSibling();
                undoBlock.RegisterCreatedObject(sessionObject);
            }

            var sessionTrans = sessionObject.transform;
            if (cameraRef == null)
            {
                cameraRef = CreateCamera(sessionTrans, undoBlock);
            }

            var cameraObj     = cameraRef.gameObject;
            var marsCameraRef = cameraObj.GetComponent <MARSCamera>();
            if (!marsCameraRef)
            {
                Debug.Log("Adding MARS Camera component to main camera.");

                // TODO: configure near plane
                marsCameraRef = undoBlock.AddComponent <MARSCamera>(cameraObj);
            }

            var session = undoBlock.AddComponent <MARSSession>(sessionObject);
            Instance = session;
            session.m_CameraReference = marsCameraRef;

            return(session);
        }