Пример #1
0
    private IEnumerator HostCloudAnchor()
    {
        // Wait until the anchor is fully uploaded to the cloud
        yield return(new WaitWhile(() => WorldAnchorCloud.cloudAnchorState == CloudAnchorState.None ||
                                   WorldAnchorCloud.cloudAnchorState == CloudAnchorState.TaskInProgress));

        if (WorldAnchorCloud.cloudAnchorState == CloudAnchorState.Success)
        {
            // save its ID to PlayerPrefs
            PlayerPrefs.SetString("cloud_anchor_id", WorldAnchorCloud.cloudAnchorId);
            PlayerPrefs.Save();

            // create new calibration cube representing cloud anchor and attach scene to it
            worldAnchorVis = Instantiate(WorldAnchorPrefab, Vector3.zero, Quaternion.identity);
            worldAnchorVis.transform.SetParent(WorldAnchorCloud.transform, false);
            AttachScene(WorldAnchorCloud.gameObject);

            // remove temporary local anchor
            RemoveLocalWorldAnchor();

            Notifications.Instance.ShowNotification("Cloud anchor created", WorldAnchorCloud.cloudAnchorState.ToString() + " ID: " + WorldAnchorCloud.cloudAnchorId);

            Calibrated        = true;
            UsingCloudAnchors = true;
            OnARCalibrated?.Invoke(this, new CalibrationEventArgs(true, WorldAnchorCloud.gameObject));
            Notifications.Instance.ShowNotification("Calibration successful", "");
            ActivateCalibrationElements((bool)MainSettingsMenu.Instance.CalibrationElements.GetValue());
            GameManager.Instance.SceneSetActive(true);
        }
        else
        {
            Notifications.Instance.ShowNotification("Cloud anchor error", WorldAnchorCloud.cloudAnchorState.ToString());
            Debug.LogError("Cloud anchor error: " + WorldAnchorCloud.cloudAnchorState);
        }
    }
Пример #2
0
    private void Start()
    {
#if UNITY_STANDALONE || !AR_ON
        Calibrated = true;
        OnARCalibrated?.Invoke(this, new CalibrationEventArgs(true, WorldAnchorLocal.gameObject));
#endif
    }
Пример #3
0
    //public async void GetCameraPosition(CameraParameters cameraParams, string image, bool autoCalibrate = false) {
    //    try {
    //        // receive cameraPose from server
    //        IO.Swagger.Model.EstimatedPose cameraEstimatedPose = await WebsocketManager.Instance.GetCameraPose(cameraParams, image, inverse:false);
    //        IO.Swagger.Model.Pose cameraPose = cameraEstimatedPose.Pose;

    //        Vector3 cameraPositionReceived = new Vector3((float) cameraPose.Position.X, (float) cameraPose.Position.Y, (float) cameraPose.Position.Z);
    //        Quaternion cameraRotationReceived = new Quaternion((float) cameraPose.Orientation.X, (float) cameraPose.Orientation.Y,
    //                                                            (float) cameraPose.Orientation.Z, (float) cameraPose.Orientation.W);

    //        //Matrix4x4 cameraMatrix = AdjustMatrixByScreenOrientation(Matrix4x4.TRS(cameraPositionReceived, cameraRotationReceived, Vector3.one));
    //        Matrix4x4 cameraMatrix = Matrix4x4.TRS(cameraPositionReceived, cameraRotationReceived, Vector3.one);

    //        Vector3 cameraPosition = TransformConvertor.OpenCVToUnity(TransformConvertor.GetPositionFromMatrix(cameraMatrix));
    //        Quaternion cameraRotation = TransformConvertor.OpenCVToUnity(TransformConvertor.GetQuaternionFromMatrix(cameraMatrix));


    //        // Transformation Inversion to get Marker Position
    //        cameraMatrix = Matrix4x4.TRS(cameraPosition, cameraRotation, Vector3.one); // create translation, rotation and scaling matrix
    //        Matrix4x4 markerMatrix = cameraMatrix.inverse; // inverse to get marker rotation matrix
    //        markerMatrix.SetColumn(3, Vector4.zero); // set translation column to zeros
    //        Vector3 markerPos = markerMatrix.MultiplyPoint3x4(cameraPosition); // transform cameraPosition by marker matrix
    //        markerPos = -1 * markerPos;

    //        markerMatrix = AdjustMatrixByScreenOrientation(Matrix4x4.TRS(markerPos, TransformConvertor.GetQuaternionFromMatrix(markerMatrix), Vector3.one));

    //        // Marker Position
    //        GameObject marker = Instantiate(MarkerPositionGameObject); // create marker gameobject as child of the camera
    //        marker.transform.localPosition = ARCameraTransformMatrix.MultiplyPoint3x4(TransformConvertor.GetPositionFromMatrix(markerMatrix)); //ARCamera.TransformPoint(markerPos);
    //        marker.transform.localRotation = TransformConvertor.GetQuaternionFromMatrix(ARCameraTransformMatrix) * TransformConvertor.GetQuaternionFromMatrix(markerMatrix); //ARCamera.transform.rotation * Quaternion.LookRotation(markerMatrix.GetColumn(2), markerMatrix.GetColumn(1)); // get quaternion from rotation matrix
    //        marker.transform.localScale = new Vector3(1f, 1f, 1f);

    //        CreateLocalAnchor(marker);

    //        //if (WorldAnchorLocal != null) {
    //        //    // Camera Position
    //        //    GameObject camera = Instantiate(MarkerPositionGameObject, WorldAnchorLocal.transform);
    //        //    camera.transform.localPosition = cameraPosition;
    //        //    camera.transform.localRotation = cameraRotation;
    //        //    camera.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f);
    //        //}

    //        //Notifications.Instance.ShowNotification("Camera position", "GetCameraPose inverse false");

    //        markerDetectionState = MarkerDetectionState.Success;

    //    } catch (RequestFailedException ex) {
    //        markerDetectionState = MarkerDetectionState.Failure;
    //        Debug.Log("No markers visible");
    //        Notifications.Instance.ShowNotification("No markers visible", ex.Message);
    //    }
    //}

    public void CreateLocalAnchor(GameObject marker)
    {
#if (UNITY_ANDROID || UNITY_IOS) && AR_ON
        // remove all old local anchors, if there are some (in case we are recalibrating)
        RemoveLocalWorldAnchor();

        //FeatureMapQuality mapQuality = ARAnchorManager.EstimateFeatureMapQualityForHosting(new UnityEngine.Pose(marker.transform.position, marker.transform.rotation));
        //Debug.Log("FeatureMapQuality: " + mapQuality);
        //Notifications.Instance.ShowNotification("FeatureMapQuality", mapQuality.ToString());

        WorldAnchorLocal = marker.AddComponent <ARAnchor>();
        // immediately attach scene to local anchor (after cloud anchor is created, scene will be attached to it)
        AttachScene(WorldAnchorLocal.gameObject);
        GameManager.Instance.Scene.transform.localEulerAngles = new Vector3(0f, 90f, 90f);

        // Create cloud anchor
        if (Settings.Instance.UseCloudAnchors)
        {
            WorldAnchorCloud = ARAnchorManager.HostCloudAnchor(WorldAnchorLocal);
            StartCoroutine(HostCloudAnchor());
        }
        else
        {
            Calibrated        = true;
            UsingCloudAnchors = false;
            OnARCalibrated?.Invoke(this, new CalibrationEventArgs(true, WorldAnchorLocal.gameObject));
            //Notifications.Instance.ShowNotification("Calibration successful", "");
            worldAnchorVis = null;
            ActivateCalibrationElements((bool)MainSettingsMenu.Instance.CalibrationElements.GetValue());
        }

        GameManager.Instance.SceneSetActive(true);
        ActivateTrackableMarkers(false);
#endif
    }
Пример #4
0
    public void RecalibrateUsingARFoundation()
    {
#if (UNITY_ANDROID || UNITY_IOS) && AR_ON
        HideCurrentWorldAnchor();
        ActivateTrackableMarkers(true);
        Calibrated = false;
        OnARCalibrated?.Invoke(this, new CalibrationEventArgs(false, null));
        OnARRecalibrate?.Invoke(this, new EventArgs());
        GameManager.Instance.SceneSetActive(false);
#endif
    }
Пример #5
0
    /// <summary>
    /// Immediately creates local anchor after detected marker intersects detected plane beneath it.
    /// Cloud anchor is created afterwards, but it takes some time. When it is finished, scene will be attached to it.
    /// Called if user clicks on the calibration cube displayed over detected marker.
    /// </summary>
    /// <param name="tf"></param>
    public void CreateAnchor(Transform tf)
    {
#if (UNITY_ANDROID || UNITY_IOS) && AR_ON
        ARPlane          plane   = null;
        UnityEngine.Pose hitPose = new UnityEngine.Pose();

        // try to raycast straight down to intersect closest plane
        List <ARRaycastHit> raycastHits = new List <ARRaycastHit>();
        if (ARRaycastManager.Raycast(new Ray(tf.position, Vector3.down), raycastHits, TrackableType.PlaneWithinPolygon))
        {
            hitPose = raycastHits[0].pose;
            TrackableId hitPlaneId = raycastHits[0].trackableId;
            plane = ARPlaneManager.GetPlane(hitPlaneId);
        }

        // remove all old local anchors, if there are some (in case we are recalibrating)
        RemoveLocalWorldAnchor();
        RemoveCloudWorldAnchor();

        // set temporary world anchor
        //WorldAnchorLocal = ARAnchorManager.AttachAnchor(plane,
        //    new Pose(hitPose.position, Quaternion.FromToRotation(tf.up, plane.normal) * tf.rotation));

        //WorldAnchorLocal = ARAnchorManager.AddAnchor(new UnityEngine.Pose(hitPose != new UnityEngine.Pose() ? hitPose.position : tf.position,
        //    plane != null ? Quaternion.FromToRotation(tf.up, plane.normal) * tf.rotation : tf.rotation));

        WorldAnchorLocal = ARAnchorManager.AddAnchor(new UnityEngine.Pose(tf.position,
                                                                          plane != null ? Quaternion.FromToRotation(tf.up, plane.normal) * tf.rotation : tf.rotation));

        // immediately attach scene to local anchor (after cloud anchor is created, scene will be attached to it)
        AttachScene(WorldAnchorLocal.gameObject);

        // Create cloud anchor
        if (Settings.Instance.UseCloudAnchors)
        {
            WorldAnchorCloud = ARAnchorManager.HostCloudAnchor(WorldAnchorLocal);
            StartCoroutine(HostCloudAnchor());
        }
        else
        {
            Calibrated        = true;
            UsingCloudAnchors = false;
            OnARCalibrated?.Invoke(this, new CalibrationEventArgs(true, WorldAnchorLocal.gameObject));
            Notifications.Instance.ShowNotification("Calibration successful", "");
            worldAnchorVis = null;
            ActivateCalibrationElements((bool)MainSettingsMenu.Instance.CalibrationElements.GetValue());
        }

        GameManager.Instance.SceneSetActive(true);
        ActivateTrackableMarkers(false);
#endif
    }
Пример #6
0
    private void RunServerAutoCalibration()
    {
        #if (UNITY_ANDROID || UNITY_IOS) && AR_ON
        // If we used local calibration before, remove all local anchors and prepare for server calibration
        if (!UsingServerCalibration)
        {
            //Debug.Log("Server: Was using local calibration");
            Calibrated = false;
            OnARCalibrated?.Invoke(this, new CalibrationEventArgs(false, null));
            if (localCalibration != null)
            {
                //Debug.Log("Server: Stopping local calibration coroutine");
                StopCoroutine(localCalibration);
                localCalibration = null;
            }
            RemoveLocalWorldAnchor();
            GameManager.Instance.SceneSetActive(false);
        }

        ARTrackedImageManager.enabled = false;

        if (!Calibrated)
        {
            //Debug.Log("Server: not calibrated");
            // stop previously running calibration coroutine
            if (autoCalibration != null)
            {
                //Debug.Log("Server: Stopping autocalib");
                StopCoroutine(autoCalibration);
            }
            autoCalibration = StartCoroutine(AutoCalibrate());
        }

        UsingServerCalibration = true;
#endif
    }
Пример #7
0
    private IEnumerator AutoCalibrate()
    {
        // Do nothing while in the MainScreen (just track feature points, planes, etc. as user moves unintentionally with the device)
        yield return(new WaitUntil(() => GameManager.Instance.GetGameState() == GameManager.GameStateEnum.SceneEditor ||
                                   GameManager.Instance.GetGameState() == GameManager.GameStateEnum.ProjectEditor ||
                                   GameManager.Instance.GetGameState() == GameManager.GameStateEnum.PackageRunning));

        if (!Calibrated)
        {
            Notifications.Instance.ShowNotification("Calibrating", "Move the device around your workspace");
            TrackingLostAnimation.PlayVideo();
            //yield return new WaitForSeconds(10f);

            // Check how many features and planes the tracking has detected
            yield return(new WaitUntil(() => TrackingManager.Instance.GetTrackingQuality() == TrackingManager.TrackingQuality.GOOD_QUALITY));

            TrackingLostAnimation.StopVideo();

            Calibrated = false;
            OnARCalibrated?.Invoke(this, new CalibrationEventArgs(false, null));
            Notifications.Instance.ShowNotification("Locate as much markers as possible", "Calibration will be done automatically");
        }

        while (!Calibrated)
        {
            markerDetectionState = MarkerDetectionState.Processing;
            bool calibrated = false;
            yield return(CalibrateUsingServerAsync(success => {
                calibrated = success;
                markerDetectionState = success ? MarkerDetectionState.Success : MarkerDetectionState.Failure;
            }, inverse: true, force: true));

            Calibrated = calibrated;

            yield return(new WaitForSeconds(0.5f));
        }
        OnARCalibrated?.Invoke(this, new CalibrationEventArgs(true, WorldAnchorLocal.gameObject));

        // Main autocalibration loop
        while (Application.isFocused)
        {
            // Do nothing while in the MainScreen (just track feature points, planes, etc. as user moves unintentionally with the device)
            yield return(new WaitUntil(() => (GameManager.Instance.GetGameState() == GameManager.GameStateEnum.SceneEditor ||
                                              GameManager.Instance.GetGameState() == GameManager.GameStateEnum.ProjectEditor ||
                                              GameManager.Instance.GetGameState() == GameManager.GameStateEnum.PackageRunning) &&
                                       TrackingManager.Instance.IsDeviceTracking()));

            if (AutoRecalibration)
            {
                markerDetectionState = MarkerDetectionState.Processing;
                yield return(CalibrateUsingServerAsync(success => {
                    if (success)
                    {
                        markerDetectionState = MarkerDetectionState.Success;
                        recalibrateTime = 2f;
                    }
                    else
                    {
                        markerDetectionState = MarkerDetectionState.Failure;
                        if (anchorQuality > 0)
                        {
                            anchorQuality -= 0.05f;
                        }
                        //if (recalibrateTime > 1f) {
                        //    recalibrateTime -= 10f;
                        //}
                    }
                }, inverse: true, autoCalibrate: true));

                //Debug.Log("Current quality: " + anchorQuality);
            }

            yield return(new WaitForSeconds(AutoRecalibrateTime));
        }
    }
Пример #8
0
    private IEnumerator Calibrate()
    {
#if (UNITY_ANDROID || UNITY_IOS) && AR_ON
        // Do nothing while in the MainScreen (just track feature points, planes, etc. as user moves unintentionally with the device)
        yield return(new WaitUntil(() => GameManager.Instance.GetGameState() == GameManager.GameStateEnum.SceneEditor ||
                                   GameManager.Instance.GetGameState() == GameManager.GameStateEnum.ProjectEditor ||
                                   GameManager.Instance.GetGameState() == GameManager.GameStateEnum.PackageRunning));

        Notifications.Instance.ShowNotification("Calibrating", "Move the device around your workspace");
        TrackingLostAnimation.PlayVideo();
        //yield return new WaitForSeconds(10f);

        // Check how many features and planes the tracking has detected
        yield return(new WaitUntil(() => TrackingManager.Instance.GetTrackingQuality() == TrackingManager.TrackingQuality.GOOD_QUALITY));

        TrackingLostAnimation.StopVideo();

        if (Settings.Instance.UseCloudAnchors)
        {
            // Try to load cloud anchor defined by ID saved in PlayerPrefs
            if (LoadCloudAnchor())
            {
                // if anchor exist in the cloud, wait for it to be fully loaded
                yield return(new WaitUntil(() => WorldAnchorCloud.cloudAnchorState == CloudAnchorState.Success));

                worldAnchorVis = Instantiate(WorldAnchorPrefab, Vector3.zero, Quaternion.identity);
                worldAnchorVis.transform.SetParent(WorldAnchorCloud.transform, false);
                AttachScene(WorldAnchorCloud.gameObject);

                // disactivate marker tracking, because anchor is loaded from the cloud
                ActivateTrackableMarkers(false);

                Notifications.Instance.ShowNotification("Cloud anchor loaded", "Cloud anchor loaded sucessfully");

                Calibrated        = true;
                UsingCloudAnchors = true;
                OnARCalibrated?.Invoke(this, new CalibrationEventArgs(true, WorldAnchorCloud.gameObject));
                Notifications.Instance.ShowNotification("Calibration successful", "");
                GameManager.Instance.SceneSetActive(true);
            }
            //TODO If anchor is not present in the system, play animation to manually calibrate by clicking on marker
            else
            {
                Calibrated = false;
                OnARCalibrated?.Invoke(this, new CalibrationEventArgs(false, null));
                Notifications.Instance.ShowNotification("Calibrate by clicking on the Calibration cube", "Cloud anchor does not exist. Please calibrate manually by clicking on the cube displayed on your marker");

                //AttachScene(null, initLocalAnchor: true);

                ActivateTrackableMarkers(true);
            }
        }
        else
        {
            Calibrated = false;
            OnARCalibrated?.Invoke(this, new CalibrationEventArgs(false, null));
            Notifications.Instance.ShowNotification("Calibrate by clicking on the Calibration cube", "Please calibrate manually by clicking on the cube displayed on your marker");

            //AttachScene(null, initLocalAnchor: true);

            ActivateTrackableMarkers(true);
        }
#endif
        yield return(null);
    }