Exemplo n.º 1
0
        internal void CalibrateFullBodyTrackingManual(SpawnedAvatar spawnedAvatar)
        {
            _logger.Info("Running manual full body tracking calibration");

            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.GetAvatarManualCalibration(spawnedAvatar.avatar.fileName);

            if (TryGetUncalibratedPoseForAvatar(DeviceUse.Waist, spawnedAvatar, out Pose waist))
            {
                Vector3    positionOffset = Quaternion.Inverse(waist.rotation) * (spawnedAvatar.pelvis.position - waist.position);
                Quaternion rotationOffset = Quaternion.Inverse(waist.rotation) * spawnedAvatar.pelvis.rotation;

                fullBodyCalibration.waist = new Pose(positionOffset, rotationOffset);
                _logger.Info("Set waist pose correction " + fullBodyCalibration.waist);
            }

            if (TryGetUncalibratedPoseForAvatar(DeviceUse.LeftFoot, spawnedAvatar, out Pose leftFoot))
            {
                Vector3    positionOffset = Quaternion.Inverse(leftFoot.rotation) * (spawnedAvatar.leftLeg.position - leftFoot.position);
                Quaternion rotationOffset = Quaternion.Inverse(leftFoot.rotation) * spawnedAvatar.leftLeg.rotation;

                fullBodyCalibration.leftFoot = new Pose(positionOffset, rotationOffset);
                _logger.Info("Set left foot pose correction " + fullBodyCalibration.leftFoot);
            }

            if (TryGetUncalibratedPoseForAvatar(DeviceUse.RightFoot, spawnedAvatar, out Pose rightFoot))
            {
                Vector3    positionOffset = Quaternion.Inverse(rightFoot.rotation) * (spawnedAvatar.rightLeg.position - rightFoot.position);
                Quaternion rotationOffset = Quaternion.Inverse(rightFoot.rotation) * spawnedAvatar.rightLeg.rotation;

                fullBodyCalibration.rightFoot = new Pose(positionOffset, rotationOffset);
                _logger.Info("Set right foot pose correction " + fullBodyCalibration.rightFoot);
            }

            inputChanged?.Invoke();
        }
        private void UpdateUI(LoadedAvatar avatar)
        {
            DisableCalibrationMode(false);

            if (avatar == null)
            {
                _clearButton.interactable     = false;
                _calibrateButton.interactable = false;
                _automaticCalibrationSetting.checkbox.interactable = false;
                _automaticCalibrationHoverHint.text = "No avatar selected";

                return;
            }

            _currentAvatarSettings          = _settings.GetAvatarSettings(avatar.fileName);
            _currentAvatarManualCalibration = _calibrationData.GetAvatarManualCalibration(avatar.fileName);

            UpdateCalibrationButtons(avatar);

            _ignoreExclusionsSetting.CheckboxValue = _currentAvatarSettings.ignoreExclusions;

            _bypassCalibration.CheckboxValue         = _currentAvatarSettings.bypassCalibration;
            _bypassCalibration.checkbox.interactable = avatar.supportsFullBodyTracking;
            _bypassCalibrationHoverHint.text         = avatar.supportsFullBodyTracking ? "Disable the need for calibration before full body tracking is applied." : "Not supported by current avatar";

            _automaticCalibrationSetting.CheckboxValue         = _currentAvatarSettings.useAutomaticCalibration;
            _automaticCalibrationSetting.checkbox.interactable = avatar.descriptor.supportsAutomaticCalibration;
            _automaticCalibrationHoverHint.text = avatar.descriptor.supportsAutomaticCalibration ? "Use automatic calibration instead of manual calibration." : "Not supported by current avatar";
        }
        private void UpdateUI(LoadedAvatar avatar)
        {
            SetInteractableRecursively(avatar != null);
            UpdateCalibrationButtons(avatar);

            if (avatar == null)
            {
                _clearButton.interactable                 = false;
                _calibrateButton.interactable             = false;
                _automaticCalibrationSetting.interactable = false;
                _automaticCalibrationHoverHint.text       = "No avatar selected";

                return;
            }

            _currentAvatarSettings          = _settings.GetAvatarSettings(avatar.fileName);
            _currentAvatarManualCalibration = _calibrationData.GetAvatarManualCalibration(avatar.fileName);

            _ignoreExclusionsSetting.Value = _currentAvatarSettings.ignoreExclusions;

            _bypassCalibration.Value = _currentAvatarSettings.bypassCalibration;

            _automaticCalibrationSetting.Value        = _currentAvatarSettings.useAutomaticCalibration;
            _automaticCalibrationSetting.interactable = avatar.descriptor.supportsAutomaticCalibration;
            _automaticCalibrationHoverHint.text       = avatar.descriptor.supportsAutomaticCalibration ? "Use automatic calibration instead of manual calibration." : "Not supported by current avatar";
        }
Exemplo n.º 4
0
        public void UpdateUI(SpawnedAvatar avatar)
        {
            if (_currentAvatarSettings != null)
            {
                _currentAvatarSettings.useAutomaticCalibration.changed -= OnUseAutomaticCalibrationChanged;
            }

            UpdateCalibrationButtons(avatar);

            if (!avatar)
            {
                _clearButton.interactable                 = false;
                _calibrateButton.interactable             = false;
                _automaticCalibrationSetting.interactable = false;
                _automaticCalibrationHoverHint.text       = "No avatar selected";

                return;
            }

            _currentAvatarSettings          = _settings.GetAvatarSettings(avatar.prefab.fileName);
            _currentAvatarManualCalibration = _calibrationData.GetAvatarManualCalibration(avatar.prefab.fileName);

            _currentAvatarSettings.useAutomaticCalibration.changed += OnUseAutomaticCalibrationChanged;

            _ignoreExclusionsSetting.Value = _currentAvatarSettings.ignoreExclusions;

            _bypassCalibration.Value = _currentAvatarSettings.bypassCalibration;

            _automaticCalibrationSetting.Value        = _currentAvatarSettings.useAutomaticCalibration;
            _automaticCalibrationSetting.interactable = avatar.prefab.descriptor.supportsAutomaticCalibration;
            _automaticCalibrationHoverHint.text       = avatar.prefab.descriptor.supportsAutomaticCalibration ? "Use automatic calibration instead of manual calibration." : "Not supported by current avatar";
        }
Exemplo n.º 5
0
        public void ClearAutomaticFullBodyTrackingData()
        {
            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.automaticCalibration;

            fullBodyCalibration.leftFoot  = Pose.identity;
            fullBodyCalibration.rightFoot = Pose.identity;
            fullBodyCalibration.waist     = Pose.identity;
        }
Exemplo n.º 6
0
        public void ClearManualFullBodyTrackingData(SpawnedAvatar spawnedAvatar)
        {
            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.GetAvatarManualCalibration(spawnedAvatar.avatar.fileName);

            fullBodyCalibration.leftFoot  = Pose.identity;
            fullBodyCalibration.rightFoot = Pose.identity;
            fullBodyCalibration.waist     = Pose.identity;
        }
Exemplo n.º 7
0
        internal void ClearAutomaticFullBodyTrackingData()
        {
            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.automaticCalibration;

            fullBodyCalibration.leftFoot  = Pose.identity;
            fullBodyCalibration.rightFoot = Pose.identity;
            fullBodyCalibration.waist     = Pose.identity;

            inputChanged?.Invoke();
        }
Exemplo n.º 8
0
        internal void ClearManualFullBodyTrackingData(SpawnedAvatar spawnedAvatar)
        {
            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.GetAvatarManualCalibration(spawnedAvatar.avatar.fileName);

            fullBodyCalibration.leftFoot  = Pose.identity;
            fullBodyCalibration.rightFoot = Pose.identity;
            fullBodyCalibration.waist     = Pose.identity;

            inputChanged?.Invoke();
        }
Exemplo n.º 9
0
        public void CalibrateFullBodyTrackingAuto()
        {
            _logger.Info("Calibrating full body tracking");

            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.automaticCalibration;

            Vector3 floorNormal   = Vector3.up;
            float   floorPosition = _settings.moveFloorWithRoomAdjust ? _roomCenter.y : 0;

            if (_trackedDeviceManager.leftFoot.tracked)
            {
                TrackedDeviceState leftFoot = _trackedDeviceManager.leftFoot;

                Vector3    leftFootForward         = leftFoot.rotation * Vector3.up;                                                                       // forward on feet trackers is y (up)
                Vector3    leftFootStraightForward = Vector3.ProjectOnPlane(leftFootForward, floorNormal);                                                 // get projection of forward vector on xz plane (floor)
                Quaternion leftRotationCorrection  = Quaternion.Inverse(leftFoot.rotation) * Quaternion.LookRotation(Vector3.up, leftFootStraightForward); // get difference between world rotation and flat forward rotation
                fullBodyCalibration.leftFoot = new Pose((leftFoot.position.y - floorPosition) * Vector3.back, leftRotationCorrection);
                _logger.Info("Set left foot pose correction " + fullBodyCalibration.leftFoot);
            }

            if (_trackedDeviceManager.rightFoot.tracked)
            {
                TrackedDeviceState rightFoot = _trackedDeviceManager.rightFoot;

                Vector3    rightFootForward         = rightFoot.rotation * Vector3.up;
                Vector3    rightFootStraightForward = Vector3.ProjectOnPlane(rightFootForward, floorNormal);
                Quaternion rightRotationCorrection  = Quaternion.Inverse(rightFoot.rotation) * Quaternion.LookRotation(Vector3.up, rightFootStraightForward);
                fullBodyCalibration.rightFoot = new Pose((rightFoot.position.y - floorPosition) * Vector3.back, rightRotationCorrection);
                _logger.Info("Set right foot pose correction " + fullBodyCalibration.rightFoot);
            }

            if (_trackedDeviceManager.head.tracked && _trackedDeviceManager.waist.tracked)
            {
                TrackedDeviceState head   = _trackedDeviceManager.head;
                TrackedDeviceState pelvis = _trackedDeviceManager.waist;

                // using "standard" 8 head high body proportions w/ eyes at 1/2 head height
                // reference: https://miro.medium.com/max/3200/1*cqTRyEGl26l4CImEmWz68Q.jpeg
                float eyeHeight = head.position.y - floorPosition;

                Vector3 wantedPelvisPosition     = new Vector3(0, eyeHeight / 22.5f * 14f, 0);
                Vector3 pelvisPositionCorrection = wantedPelvisPosition - Vector3.up * (pelvis.position.y - floorPosition);

                Vector3    pelvisForward            = pelvis.rotation * Vector3.forward;
                Vector3    pelvisStraightForward    = Vector3.ProjectOnPlane(pelvisForward, floorNormal);
                Quaternion pelvisRotationCorrection = Quaternion.Inverse(pelvis.rotation) * Quaternion.LookRotation(pelvisStraightForward, Vector3.up);

                fullBodyCalibration.waist = new Pose(pelvisPositionCorrection, pelvisRotationCorrection);
                _logger.Info("Set waist pose correction " + fullBodyCalibration.waist);
            }
        }
Exemplo n.º 10
0
        internal VRPlayerInput(TrackedDeviceManager trackedDeviceManager, LoadedAvatar avatar, Settings settings, CalibrationData calibrationData)
        {
            _deviceManager     = trackedDeviceManager;
            _settings          = settings;
            _avatarSettings    = settings.GetAvatarSettings(avatar.fileName);
            _calibrationData   = calibrationData;
            _manualCalibration = calibrationData.GetAvatarManualCalibration(avatar.fileName);

            _deviceManager.deviceAdded            += OnDevicesUpdated;
            _deviceManager.deviceRemoved          += OnDevicesUpdated;
            _deviceManager.deviceTrackingAcquired += OnDevicesUpdated;
            _deviceManager.deviceTrackingLost     += OnDevicesUpdated;

            _leftHandAnimAction  = new SkeletalInput("/actions/customavatars/in/lefthandanim");
            _rightHandAnimAction = new SkeletalInput("/actions/customavatars/in/righthandanim");
        }
Exemplo n.º 11
0
        internal void CalibrateFullBodyTrackingAuto()
        {
            _logger.Info("Running automatic full body tracking calibration");

            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.automaticCalibration;

            Vector3 floorNormal = Vector3.up;

            if (TryGetUncalibratedPose(DeviceUse.LeftFoot, out Pose leftFoot))
            {
                Vector3    leftFootForward         = leftFoot.rotation * Vector3.up;                                                                       // forward on feet trackers is y (up)
                Vector3    leftFootStraightForward = Vector3.ProjectOnPlane(leftFootForward, floorNormal);                                                 // get projection of forward vector on xz plane (floor)
                Quaternion leftRotationCorrection  = Quaternion.Inverse(leftFoot.rotation) * Quaternion.LookRotation(Vector3.up, leftFootStraightForward); // get difference between world rotation and flat forward rotation
                fullBodyCalibration.leftFoot = new Pose(leftFoot.position.y * Vector3.back, leftRotationCorrection);
                _logger.Info("Set left foot pose correction " + fullBodyCalibration.leftFoot);
            }

            if (TryGetUncalibratedPose(DeviceUse.RightFoot, out Pose rightFoot))
            {
                Vector3    rightFootForward         = rightFoot.rotation * Vector3.up;
                Vector3    rightFootStraightForward = Vector3.ProjectOnPlane(rightFootForward, floorNormal);
                Quaternion rightRotationCorrection  = Quaternion.Inverse(rightFoot.rotation) * Quaternion.LookRotation(Vector3.up, rightFootStraightForward);
                fullBodyCalibration.rightFoot = new Pose(rightFoot.position.y * Vector3.back, rightRotationCorrection);
                _logger.Info("Set right foot pose correction " + fullBodyCalibration.rightFoot);
            }

            if (TryGetUncalibratedPose(DeviceUse.Head, out Pose head) && TryGetUncalibratedPose(DeviceUse.Waist, out Pose waist))
            {
                // using "standard" 8 head high body proportions w/ eyes at 1/2 head height
                // reference: https://miro.medium.com/max/3200/1*cqTRyEGl26l4CImEmWz68Q.jpeg
                float eyeHeight = head.position.y;

                Vector3 wantedWaistPosition     = new Vector3(0, eyeHeight / 22.5f * 14f, 0);
                Vector3 waistPositionCorrection = wantedWaistPosition - Vector3.up * waist.position.y;

                Vector3    waistForward            = waist.rotation * Vector3.forward;
                Vector3    waistStraightForward    = Vector3.ProjectOnPlane(waistForward, floorNormal);
                Quaternion waistRotationCorrection = Quaternion.Inverse(waist.rotation) * Quaternion.LookRotation(waistStraightForward, Vector3.up);

                fullBodyCalibration.waist = new Pose(waistPositionCorrection, waistRotationCorrection);
                _logger.Info("Set waist pose correction " + fullBodyCalibration.waist);

                _beatSaberUtilities.SetPlayerHeight(eyeHeight + MainSettingsModelSO.kHeadPosToPlayerHeightOffset);
            }

            inputChanged?.Invoke();
        }
Exemplo n.º 12
0
        private void OnAvatarChanged(SpawnedAvatar spawnedAvatar)
        {
            if (_avatarSettings != null)
            {
                _avatarSettings.useAutomaticCalibration.changed -= OnUseAutomaticCalibrationChanged;
                _avatarSettings.bypassCalibration.changed       -= OnBypassCalibrationChanged;
            }

            if (!spawnedAvatar)
            {
                _avatarSettings    = null;
                _manualCalibration = null;

                return;
            }

            _avatarSettings    = _settings.GetAvatarSettings(spawnedAvatar.avatar.fileName);
            _manualCalibration = _calibrationData.GetAvatarManualCalibration(spawnedAvatar.avatar.fileName);

            _avatarSettings.useAutomaticCalibration.changed += OnUseAutomaticCalibrationChanged;
            _avatarSettings.bypassCalibration.changed       += OnBypassCalibrationChanged;
        }
Exemplo n.º 13
0
        public void CalibrateFullBodyTrackingManual(SpawnedAvatar spawnedAvatar)
        {
            CalibrationData.FullBodyCalibration fullBodyCalibration = _calibrationData.GetAvatarManualCalibration(spawnedAvatar.avatar.fileName);

            if (_trackedDeviceManager.waist.tracked)
            {
                TrackedDeviceState pelvis = _trackedDeviceManager.waist;

                Vector3    positionOffset = Quaternion.Inverse(spawnedAvatar.pelvis.rotation) * (spawnedAvatar.pelvis.position - ApplyTrackedPointFloorOffset(spawnedAvatar, pelvis.position));
                Quaternion rotationOffset = Quaternion.Inverse(pelvis.rotation) * spawnedAvatar.pelvis.rotation;

                fullBodyCalibration.waist = new Pose(positionOffset, rotationOffset);
                _logger.Info("Set waist pose correction " + fullBodyCalibration.waist);
            }

            if (_trackedDeviceManager.leftFoot.tracked)
            {
                TrackedDeviceState leftFoot = _trackedDeviceManager.leftFoot;

                Vector3    positionOffset = Quaternion.Inverse(spawnedAvatar.leftLeg.rotation) * (spawnedAvatar.leftLeg.position - ApplyTrackedPointFloorOffset(spawnedAvatar, leftFoot.position));
                Quaternion rotationOffset = Quaternion.Inverse(leftFoot.rotation) * spawnedAvatar.leftLeg.rotation;

                fullBodyCalibration.leftFoot = new Pose(positionOffset, rotationOffset);
                _logger.Info("Set left foot pose correction " + fullBodyCalibration.leftFoot);
            }

            if (_trackedDeviceManager.rightFoot.tracked)
            {
                TrackedDeviceState rightFoot = _trackedDeviceManager.rightFoot;

                Vector3    positionOffset = Quaternion.Inverse(spawnedAvatar.rightLeg.rotation) * (spawnedAvatar.rightLeg.position - ApplyTrackedPointFloorOffset(spawnedAvatar, rightFoot.position));
                Quaternion rotationOffset = Quaternion.Inverse(rightFoot.rotation) * spawnedAvatar.rightLeg.rotation;

                fullBodyCalibration.rightFoot = new Pose(positionOffset, rotationOffset);
                _logger.Info("Set right foot pose correction " + fullBodyCalibration.rightFoot);
            }
        }