예제 #1
0
        private void OnArucoPose(MarkerPose pose)
        {
            var markerOffset = CalibrationOffsets[pose.Id];

            if (markerOffset == null)
            {
                markerOffset = new MarkerOffset
                {
                    ArMarkerId = pose.Id
                };
                CalibrationOffsets[pose.Id] = markerOffset;
            }

            // pose is marker's pose -> inverted we get camera pose
            var markerMatrix = Matrix4x4.TRS(pose.Position, pose.Rotation, Vector3.one);
            var cameraMatrix = markerMatrix.inverse;

            markerOffset.HasArPose           = true;
            markerOffset.ArPoseDetectionTime = Time.unscaledTime;
            markerOffset.ArMarkerPosition    = pose.Position;
            markerOffset.ArMarkerRotation    = pose.Rotation;
            markerOffset.ArCameraPosition    = cameraMatrix.GetPosition();
            markerOffset.ArCameraRotation    = cameraMatrix.GetRotation();
        }
        void OnEnable()
        {
            CalibrationOffsets = new MarkerOffset[MarkersPerRow * MarkersPerColumn];
            for (int i = 0; i < CalibrationOffsets.Length; i++) CalibrationOffsets[i] = new MarkerOffset { ArMarkerId = i };

            ArucoListener.Instance.NewPoseDetected += OnArucoPose;
            OptitrackListener.Instance.PosesReceived += OnOptitrackPose;
            SteamVR_Utils.Event.Listen("new_poses", OnSteamVrPose);
        }
        void OnDrawGizmos()
        {
            if (!Application.isPlaying)
            {
                return;
            }

            // Draw OpenVR rotation
            {
                Gizmos.color = Color.green;
                var start = SceneCameraTracker.Instance.transform.position;
                var end = start + (_ovrRot * Vector3.forward);
                var up = start + (_ovrRot * Vector3.up * 0.1f);
                var right = start + (_ovrRot * Vector3.right * 0.1f);
                Gizmos.DrawLine(start, end);
                Gizmos.DrawLine(start, up);
                Gizmos.DrawLine(start, right);
            }

            // this only works if we have optitrack coordinates for all markers
            if (FixedDisplays.Has(DisplayName))
            {
                var display = FixedDisplays.Get(DisplayName);
                var tableRotation = display.Rotation;
                var tableCenter = display.Position;

                // draw table's orientation in center of table
                Gizmos.color = Color.green;
                Gizmos.DrawLine(tableCenter, tableCenter + tableRotation * Vector3.up * 0.1f);
                Gizmos.color = Color.blue;
                Gizmos.DrawLine(tableCenter, tableCenter + tableRotation * Vector3.forward * 0.1f);
                Gizmos.color = Color.red;
                Gizmos.DrawLine(tableCenter, tableCenter + tableRotation * Vector3.right * 0.1f);

                for (int i = 0; i < CalibrationOffsets.Length; i++)
                {
                    if (CalibrationOffsets[i] == null)
                    {
                        CalibrationOffsets[i] = new MarkerOffset();
                    }

                    var marker = CalibrationOffsets[i];

                    // draw virtual position of calibrated markers, based on optitrack + measurements
                    Gizmos.color = Color.cyan;
                    var markerPosWorld = GetMarkerWorldPosition(i, tableRotation);
                    var markerSize = ArucoListener.Instance.MarkerSizeInMeter;
                    Gizmos.DrawWireSphere(markerPosWorld, 0.01f);
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, markerSize / 2), markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, markerSize / 2));
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, markerSize / 2), markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, -markerSize / 2));
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, -markerSize / 2), markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, -markerSize / 2));
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, -markerSize / 2), markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, markerSize / 2));

                    // if available, draw world position of camera based on marker
                    if (marker.HasArPose && (Time.unscaledTime - marker.ArPoseDetectionTime) < ArCutoffTime)
                    {
                        var localPos = marker.ArCameraPosition;
                        var worldPos = markerPosWorld + tableRotation * localPos;

                        var localRot = marker.ArCameraRotation;
                        var localForward = localRot * Vector3.forward;
                        var localRight = localRot * Vector3.right;
                        var localUp = localRot * Vector3.up;

                        var worldForward = tableRotation * localForward;
                        var worldRight = tableRotation * localRight;
                        var worldUp = tableRotation * localUp;

                        bool isOutlier = (worldPos - _optitrackCameraPose.Position).sqrMagnitude > 0.025f;

                        Gizmos.color = Color.white;
                        Gizmos.DrawWireSphere(worldPos, 0.01f);

                        Gizmos.color = isOutlier ? Color.grey : Color.green;
                        Gizmos.DrawLine(worldPos, worldPos + worldUp * 0.1f);
                        Gizmos.color = isOutlier ? Color.grey : Color.blue;
                        Gizmos.DrawLine(worldPos, worldPos + worldForward * 0.5f);
                        Gizmos.color = isOutlier ? Color.grey : Color.red;
                        Gizmos.DrawLine(worldPos, worldPos + worldRight * 0.1f);
                    }
                }

                {
                    Gizmos.color = Color.red;
                    Gizmos.DrawSphere(_debugAvgPosition, 0.01f);

                    Gizmos.color = Color.green;
                    Gizmos.DrawLine(_debugAvgPosition, _debugAvgPosition + _debugAvgRotation * Vector3.up * 0.1f);
                    Gizmos.color = Color.blue;
                    Gizmos.DrawLine(_debugAvgPosition, _debugAvgPosition + _debugAvgRotation * Vector3.forward);
                    Gizmos.color = Color.red;
                    Gizmos.DrawLine(_debugAvgPosition, _debugAvgPosition + _debugAvgRotation * Vector3.right * 0.1f);
                }

                if (CalibMethod == CalibrationMethod.LineExtension)
                {
                    Gizmos.color = Color.yellow;
                    foreach (var ray in _debugRays)
                    {
                        Gizmos.DrawLine(ray.origin, ray.origin + ray.direction);
                    }

                    Gizmos.color = Color.black;
                    foreach (var pos in _debugClosestPoints)
                    {
                        Gizmos.DrawSphere(pos, 0.001f);
                    }
                }
            }
        }
        private void OnArucoPose(MarkerPose pose)
        {
            var markerOffset = CalibrationOffsets[pose.Id];

            if (markerOffset == null)
            {
                markerOffset = new MarkerOffset
                {
                    ArMarkerId = pose.Id
                };
                CalibrationOffsets[pose.Id] = markerOffset;
            }

            // pose is marker's pose -> inverted we get camera pose
            var markerMatrix = Matrix4x4.TRS(pose.Position, pose.Rotation, Vector3.one);
            var cameraMatrix = markerMatrix.inverse;

            markerOffset.HasArPose = true;
            markerOffset.ArPoseDetectionTime = Time.unscaledTime;
            markerOffset.ArMarkerPosition = pose.Position;
            markerOffset.ArMarkerRotation = pose.Rotation;
            markerOffset.ArCameraPosition = cameraMatrix.GetPosition();
            markerOffset.ArCameraRotation = cameraMatrix.GetRotation();
        }
예제 #5
0
        void OnEnable()
        {
            CalibrationOffsets = new MarkerOffset[MarkersPerRow * MarkersPerColumn];
            for (int i = 0; i < CalibrationOffsets.Length; i++)
            {
                CalibrationOffsets[i] = new MarkerOffset {
                    ArMarkerId = i
                }
            }
            ;

            ArMarkerTracker.Instance.NewPoseDetected += OnArucoPose;
            OptitrackListener.PosesReceived          += OnOptitrackPose;
            SteamVR_Events.NewPoses.Listen(OnSteamVrPose);
        }

        void OnDisable()
        {
            ArMarkerTracker.Instance.NewPoseDetected -= OnArucoPose;
            OptitrackListener.PosesReceived          -= OnOptitrackPose;
            SteamVR_Events.NewPoses.Remove(OnSteamVrPose);
        }

        void Update()
        {
            if (SurfaceManager.Instance.Has(DisplayName) && (Time.unscaledTime - _optitrackCameraDetectionTime) < OptitrackCutoffTime)
            {
                var display       = SurfaceManager.Instance.Get(DisplayName);
                var tableRotation = display.Rotation;

                var lineRenderer = GetComponent <LineRenderer>();

                if (lineRenderer != null)
                {
                    lineRenderer.numPositions = 5;
                    lineRenderer.SetPosition(0, display.GetCornerPosition(Corner.TopLeft));
                    lineRenderer.SetPosition(1, display.GetCornerPosition(Corner.BottomLeft));
                    lineRenderer.SetPosition(2, display.GetCornerPosition(Corner.BottomRight));
                    lineRenderer.SetPosition(3, display.GetCornerPosition(Corner.TopRight));
                    lineRenderer.SetPosition(4, display.GetCornerPosition(Corner.TopLeft));
                }


                var markers = CalibrationOffsets.Where((m) => m.HasArPose && (Time.unscaledTime - m.ArPoseDetectionTime) < ArCutoffTime);

                if (markers == null)
                {
                    return;
                }

                if (!UseAverage)
                {
                    markers = new[] { markers.First() };
                }

                var rotations = new List <Quaternion>();
                var positions = new List <Vector3>();

                foreach (var marker in markers)
                {
                    var markerPosWorld = GetMarkerWorldPosition(marker.ArMarkerId, tableRotation);

                    var localPos = marker.ArCameraPosition;
                    var worldPos = markerPosWorld + tableRotation * localPos;

                    var localRot     = marker.ArCameraRotation;
                    var localForward = localRot * Vector3.forward;
                    var localUp      = localRot * Vector3.up;

                    var worldForward = tableRotation * localForward;
                    var worldUp      = tableRotation * localUp;
                    var worldRot     = Quaternion.LookRotation(worldForward, worldUp);

                    rotations.Add(worldRot);
                    positions.Add(worldPos);
                }

                CalibrationParams.PositionOffset = Quaternion.Inverse(_optitrackCameraPose.Rotation) * (MathUtility.Average(positions) - _optitrackCameraPose.Position);
                // c = b * inv(a)
                // => b = c * a?
                // from ovrRot to worldRot
                CalibrationParams.RotationOffset = MathUtility.Average(rotations) * Quaternion.Inverse(_ovrRot);
            }
        }
예제 #6
0
        void OnDrawGizmos()
        {
            if (!Application.isPlaying)
            {
                return;
            }

            // Draw OpenVR rotation
            {
                Gizmos.color = Color.green;
                var start = SceneCameraTracker.Instance.transform.position;
                var end   = start + (_ovrRot * Vector3.forward);
                var up    = start + (_ovrRot * Vector3.up * 0.1f);
                var right = start + (_ovrRot * Vector3.right * 0.1f);
                Gizmos.DrawLine(start, end);
                Gizmos.DrawLine(start, up);
                Gizmos.DrawLine(start, right);
            }

            // this only works if we have optitrack coordinates for all markers
            if (SurfaceManager.Instance.Has(DisplayName))
            {
                var display       = SurfaceManager.Instance.Get(DisplayName);
                var tableRotation = display.Rotation;

                // draw table's orientation in center of table
                {
                    var tableCenter = display.Position;
                    Gizmos.color = Color.green;
                    Gizmos.DrawLine(tableCenter, tableCenter + tableRotation * Vector3.up * 0.1f);
                    Gizmos.color = Color.blue;
                    Gizmos.DrawLine(tableCenter, tableCenter + tableRotation * Vector3.forward * 0.1f);
                    Gizmos.color = Color.red;
                    Gizmos.DrawLine(tableCenter, tableCenter + tableRotation * Vector3.right * 0.1f);
                }

                for (int i = 0; i < CalibrationOffsets.Length; i++)
                {
                    if (CalibrationOffsets[i] == null)
                    {
                        CalibrationOffsets[i] = new MarkerOffset();
                    }

                    var marker = CalibrationOffsets[i];

                    // draw virtual position of calibrated markers, based on optitrack + measurements
                    Gizmos.color = Color.cyan;
                    var markerPosWorld = GetMarkerWorldPosition(i, tableRotation);
                    var markerSize     = ArMarkerTracker.Instance.MarkerSizeInMeter;
                    Gizmos.DrawWireSphere(markerPosWorld, 0.01f);
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, markerSize / 2), markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, markerSize / 2));
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, markerSize / 2), markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, -markerSize / 2));
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(-markerSize / 2, 0, -markerSize / 2), markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, -markerSize / 2));
                    Gizmos.DrawLine(markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, -markerSize / 2), markerPosWorld + tableRotation * new Vector3(markerSize / 2, 0, markerSize / 2));


                    // if available, draw world position of camera based on marker
                    if (marker.HasArPose && (Time.unscaledTime - marker.ArPoseDetectionTime) < ArCutoffTime)
                    {
                        var localPos = marker.ArCameraPosition;
                        var worldPos = markerPosWorld + tableRotation * localPos;

                        var localRot     = marker.ArCameraRotation;
                        var localForward = localRot * Vector3.forward;
                        var localRight   = localRot * Vector3.right;
                        var localUp      = localRot * Vector3.up;

                        var worldForward = tableRotation * localForward;
                        var worldRight   = tableRotation * localRight;
                        var worldUp      = tableRotation * localUp;

                        bool isOutlier = (worldPos - _optitrackCameraPose.Position).sqrMagnitude > 0.025f;

                        Gizmos.color = Color.white;
                        Gizmos.DrawWireSphere(worldPos, 0.01f);

                        Gizmos.color = isOutlier ? Color.grey : Color.green;
                        Gizmos.DrawLine(worldPos, worldPos + worldUp * 0.1f);
                        Gizmos.color = isOutlier ? Color.grey : Color.blue;
                        Gizmos.DrawLine(worldPos, worldPos + worldForward * 0.5f);
                        Gizmos.color = isOutlier ? Color.grey : Color.red;
                        Gizmos.DrawLine(worldPos, worldPos + worldRight * 0.1f);
                    }
                }

                {
                    Gizmos.color = Color.red;
                    Gizmos.DrawSphere(_debugAvgPosition, 0.01f);

                    Gizmos.color = Color.green;
                    Gizmos.DrawLine(_debugAvgPosition, _debugAvgPosition + _debugAvgRotation * Vector3.up * 0.1f);
                    Gizmos.color = Color.blue;
                    Gizmos.DrawLine(_debugAvgPosition, _debugAvgPosition + _debugAvgRotation * Vector3.forward);
                    Gizmos.color = Color.red;
                    Gizmos.DrawLine(_debugAvgPosition, _debugAvgPosition + _debugAvgRotation * Vector3.right * 0.1f);
                }
            }
        }
예제 #7
0
        void OnEnable()
        {
            CalibrationOffsets = new MarkerOffset[MarkersPerRow * MarkersPerColumn];
            for (int i = 0; i < CalibrationOffsets.Length; i++)
            {
                CalibrationOffsets[i] = new MarkerOffset {
                    ArMarkerId = i
                }
            }
            ;

            ArMarkerTracker.Instance.NewPoseDetected += OnArucoPose;
            OptitrackListener.PosesReceived          += OnOptitrackPose;
            SteamVR_Events.NewPoses.Listen(OnSteamVrPose);
        }

        void OnDisable()
        {
            ArMarkerTracker.Instance.NewPoseDetected -= OnArucoPose;
            OptitrackListener.PosesReceived          -= OnOptitrackPose;
            SteamVR_Events.NewPoses.Remove(OnSteamVrPose);
        }

        void Update()
        {
            if (SurfaceManager.Instance.Has(DisplayName))
            {
                var display      = SurfaceManager.Instance.Get(DisplayName);
                var lineRenderer = GetComponent <LineRenderer>();

                if (lineRenderer != null)
                {
                    lineRenderer.numPositions = 5;
                    lineRenderer.SetPosition(0, display.GetCornerPosition(Corner.TopLeft));
                    lineRenderer.SetPosition(1, display.GetCornerPosition(Corner.BottomLeft));
                    lineRenderer.SetPosition(2, display.GetCornerPosition(Corner.BottomRight));
                    lineRenderer.SetPosition(3, display.GetCornerPosition(Corner.TopRight));
                    lineRenderer.SetPosition(4, display.GetCornerPosition(Corner.TopLeft));
                }


                if (TestCamera != null && CalibrationOffsets != null)
                {
                    var markers       = CalibrationOffsets.Where((m) => m.HasArPose && (Time.unscaledTime - m.ArPoseDetectionTime) < ArCutoffTime && m.ArMarkerId == 212);
                    var tableRotation = display.Rotation;

                    if (markers == null || markers.Count() != 1)
                    {
                        return;
                    }

                    var marker = markers.First();

                    var markerPosWorld = GetMarkerWorldPosition(marker.ArMarkerId, tableRotation);

                    var localPos = marker.ArCameraPosition;
                    var worldPos = markerPosWorld + tableRotation * localPos;

                    var localRot     = marker.ArCameraRotation;
                    var localForward = localRot * Vector3.forward;
                    var localUp      = localRot * Vector3.up;

                    var worldForward = tableRotation * localForward;
                    var worldUp      = tableRotation * localUp;
                    var worldRot     = Quaternion.LookRotation(worldForward, worldUp);

                    TestCamera.transform.position = worldPos;
                    TestCamera.transform.rotation = worldRot;

                    if (Input.GetKeyDown(KeyCode.Space))
                    {
                        Debug.Log("Calibrating...");
                        CalibrationParams.PositionOffset = Quaternion.Inverse(_optitrackCameraPose.Rotation) * (_optitrackCameraPose.Position - worldPos);
                        // c = b * inv(a)
                        // => b = c * a?
                        // from ovrRot to worldRot
                        CalibrationParams.RotationOffset = worldRot * Quaternion.Inverse(_ovrRot);
                    }
                }
            }
        }