public async void GetMarkerPosition(CameraParameters cameraParams, string image, bool autoCalibrate = false, bool force = false, bool showNotification = false) { try { // receive cameraPose from server IO.Swagger.Model.EstimatedPose markerEstimatedPose = await WebsocketManager.Instance.GetCameraPose(cameraParams, image, inverse : true); if ((float)markerEstimatedPose.Quality > anchorQuality || force) { anchorQuality = (float)markerEstimatedPose.Quality; //Notifications.Instance.ShowNotification("Marker quality", markerEstimatedPose.Quality.ToString()); IO.Swagger.Model.Pose markerPose = markerEstimatedPose.Pose; Vector3 markerPositionReceived = new Vector3((float)markerPose.Position.X, (float)markerPose.Position.Y, (float)markerPose.Position.Z); Quaternion markerRotationReceived = new Quaternion((float)markerPose.Orientation.X, (float)markerPose.Orientation.Y, (float)markerPose.Orientation.Z, (float)markerPose.Orientation.W); Matrix4x4 markerMatrix = AdjustMatrixByScreenOrientation(Matrix4x4.TRS(markerPositionReceived, markerRotationReceived, Vector3.one)); Vector3 markerPosition = TransformConvertor.OpenCVToUnity(TransformConvertor.GetPositionFromMatrix(markerMatrix)); Quaternion markerRotation = TransformConvertor.OpenCVToUnity(TransformConvertor.GetQuaternionFromMatrix(markerMatrix)); // Marker Position GameObject marker = Instantiate(MarkerPositionGameObject); marker.transform.localPosition = ARCameraTransformMatrix.MultiplyPoint3x4(markerPosition); //ARCamera.TransformPoint(markerPosition); marker.transform.localRotation = TransformConvertor.GetQuaternionFromMatrix(ARCameraTransformMatrix) * markerRotation; //ARCamera.transform.rotation * markerRotation; marker.transform.localScale = new Vector3(1f, 1f, 1f); CreateLocalAnchor(marker); //System.IO.File.WriteAllBytes(Application.persistentDataPath + "/image" + imageNum + ".jpg", m_Texture.EncodeToJPG()); //imageNum++; // Transformation Inversion to get Camera Position //markerMatrix = Matrix4x4.TRS(markerPosition, markerRotation, Vector3.one); // create translation, rotation and scaling matrix //Matrix4x4 cameraMatrix = markerMatrix.inverse; // inverse to get marker rotation matrix //cameraMatrix.SetColumn(3, Vector4.zero); // set translation column to zeros //Vector3 cameraPos = cameraMatrix.MultiplyPoint3x4(markerPosition); // transform cameraPosition by marker matrix //cameraPos = -1 * cameraPos; //if (WorldAnchorLocal != null) { // // Camera Position // GameObject camera = Instantiate(MarkerPositionGameObject, WorldAnchorLocal.transform); // camera.transform.localPosition = cameraPos; // camera.transform.localRotation = Quaternion.LookRotation(cameraMatrix.GetColumn(2), cameraMatrix.GetColumn(1)); // camera.transform.localScale = new Vector3(0.05f, 0.05f, 0.05f); //} //Notifications.Instance.ShowNotification("Marker position", "GetCameraPose inverse true"); markerDetectionState = MarkerDetectionState.Success; if (showNotification) { Notifications.Instance.ShowNotification("Calibration successful", ""); } } else { markerDetectionState = MarkerDetectionState.Failure; if (showNotification) { Notifications.Instance.ShowNotification("No markers visible", "Find some markers and try again."); } } } catch (RequestFailedException ex) { markerDetectionState = MarkerDetectionState.Failure; Debug.Log("No markers visible"); if (showNotification) { Notifications.Instance.ShowNotification("No markers visible", "Find some markers and try again."); } } }
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)); } }