Exemple #1
0
        private static PosRot GetTrackerWorldPosRot(XRNodeState tracker)
        {
            Vector3    pos = new Vector3();
            Quaternion rot = new Quaternion();

            try
            {
                var notes = new List <XRNodeState>();
                InputTracking.GetNodeStates(notes);
                foreach (XRNodeState note in notes)
                {
                    if (note.uniqueID != tracker.uniqueID)
                    {
                        continue;
                    }
                    if (note.TryGetPosition(out pos) && note.TryGetRotation(out rot))
                    {
                        var roomCenter   = BeatSaberUtil.GetRoomCenter();
                        var roomRotation = BeatSaberUtil.GetRoomRotation();
                        pos  = roomRotation * pos;
                        pos += roomCenter;
                        rot  = roomRotation * rot;
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Log(e.Message + "\n" + e.StackTrace, Logger.LogLevel.Error);
            }
            return(new PosRot(pos, rot));
        }
        public void ResizeAvatar(SpawnedAvatar avatar)
        {
            if (!avatar.customAvatar.descriptor.allowHeightCalibration)
            {
                return;
            }

            // compute scale
            float            scale;
            AvatarResizeMode resizeMode = SettingsManager.settings.resizeMode;

            switch (resizeMode)
            {
            case AvatarResizeMode.ArmSpan:
                float playerArmLength = SettingsManager.settings.playerArmSpan;
                var   avatarArmLength = avatar.customAvatar.GetArmSpan();

                scale = playerArmLength / avatarArmLength;
                break;

            case AvatarResizeMode.Height:
                scale = BeatSaberUtil.GetPlayerEyeHeight() / avatar.customAvatar.eyeHeight;
                break;

            default:
                scale = 1.0f;
                break;
            }

            // apply scale
            avatar.behaviour.scale = scale;

            SharedCoroutineStarter.instance.StartCoroutine(FloorMendingWithDelay(avatar));
        }
Exemple #3
0
        public void ResizeAvatar(SpawnedAvatar avatar)
        {
            if (!avatar.customAvatar.descriptor.allowHeightCalibration || !avatar.customAvatar.isIKAvatar)
            {
                return;
            }

            // compute scale
            float            scale;
            AvatarResizeMode resizeMode = SettingsManager.settings.resizeMode;

            switch (resizeMode)
            {
            case AvatarResizeMode.ArmSpan:
                float avatarArmLength = avatar.customAvatar.GetArmSpan();

                if (avatarArmLength > 0)
                {
                    scale = SettingsManager.settings.playerArmSpan / avatarArmLength;
                }
                else
                {
                    scale = 1.0f;
                }

                break;

            case AvatarResizeMode.Height:
                float avatarEyeHeight = avatar.customAvatar.eyeHeight;

                if (avatarEyeHeight > 0)
                {
                    scale = BeatSaberUtil.GetPlayerEyeHeight() / avatarEyeHeight;
                }
                else
                {
                    scale = 1.0f;
                }

                break;

            default:
                scale = 1.0f;
                break;
            }

            if (scale <= 0)
            {
                Plugin.logger.Warn("Calculated scale is <= 0; reverting to 1");
                scale = 1.0f;
            }

            // apply scale
            avatar.tracking.scale = scale;

            SharedCoroutineStarter.instance.StartCoroutine(FloorMendingWithDelay(avatar));
        }
Exemple #4
0
        private static PosRot GetXRNodeWorldPosRot(XRNode node)
        {
            var pos = InputTracking.GetLocalPosition(node);
            var rot = InputTracking.GetLocalRotation(node);

            var roomCenter   = BeatSaberUtil.GetRoomCenter();
            var roomRotation = BeatSaberUtil.GetRoomRotation();

            pos  = roomRotation * pos;
            pos += roomCenter;
            rot  = roomRotation * rot;
            return(new PosRot(pos, rot));
        }
Exemple #5
0
        private IEnumerator FloorMendingWithDelay(SpawnedAvatar avatar)
        {
            yield return(new WaitForEndOfFrame()); // wait for CustomFloorPlugin:PlatformManager:Start to hide original platform

            float floorOffset = 0f;

            if (SettingsManager.settings.enableFloorAdjust && avatar.customAvatar.isIKAvatar)
            {
                float playerEyeHeight = BeatSaberUtil.GetPlayerEyeHeight();
                float avatarEyeHeight = avatar.customAvatar.eyeHeight;

                floorOffset = playerEyeHeight - avatarEyeHeight * avatar.tracking.scale;

                if (SettingsManager.settings.moveFloorWithRoomAdjust)
                {
                    floorOffset += BeatSaberUtil.GetRoomCenter().y;
                }
            }

            floorOffset = (float)Math.Round(floorOffset, 3);  // round to millimeter

            // apply offset
            avatar.tracking.verticalPosition = floorOffset;

            // ReSharper disable Unity.PerformanceCriticalCodeInvocation
            GameObject menuPlayersPlace = GameObject.Find("MenuPlayersPlace");
            GameObject originalFloor    = GameObject.Find("Environment/PlayersPlace");
            GameObject customFloor      = GameObject.Find("Platform Loader");

            // ReSharper disable restore Unity.PerformanceCriticalCodeInvocation

            if (menuPlayersPlace)
            {
                Plugin.logger.Info($"Moving MenuPlayersPlace floor {Math.Abs(floorOffset)} m {(floorOffset >= 0 ? "up" : "down")}");
                menuPlayersPlace.transform.position = new Vector3(0, floorOffset, 0);
            }

            if (originalFloor)
            {
                Plugin.logger.Info($"Moving PlayersPlace {Math.Abs(floorOffset)} m {(floorOffset >= 0 ? "up" : "down")}");
                originalFloor.transform.position = new Vector3(0, floorOffset, 0);
            }

            if (customFloor)
            {
                Plugin.logger.Info($"Moving Custom Platforms floor {Math.Abs(floorOffset)} m {(floorOffset >= 0 ? "up" : "down")}");

                _initialPlatformPosition       = _initialPlatformPosition ?? customFloor.transform.position;
                customFloor.transform.position = (Vector3.up * floorOffset) + _initialPlatformPosition ?? Vector3.zero;
            }
        }
        private void ResizePlayerAvatar()
        {
            if (_currentSpawnedPlayerAvatar?.GameObject == null)
            {
                return;
            }
            if (!_currentSpawnedPlayerAvatar.CustomAvatar.AllowHeightCalibration)
            {
                return;
            }

            var playerHeight = BeatSaberUtil.GetPlayerHeight();

            if (playerHeight == _prevPlayerHeight)
            {
                return;
            }
            _prevPlayerHeight = playerHeight;
            _currentSpawnedPlayerAvatar.GameObject.transform.localScale =
                _startAvatarLocalScale * (playerHeight / _currentSpawnedPlayerAvatar.CustomAvatar.Height);
            Plugin.Log("Resizing avatar to " + (playerHeight / _currentSpawnedPlayerAvatar.CustomAvatar.Height) +
                       "x scale");
        }
        private IEnumerator FloorMendingWithDelay(SpawnedAvatar avatar)
        {
            yield return(new WaitForEndOfFrame()); // wait for CustomFloorPlugin:PlatformManager:Start to hide original platform

            float floorOffset = 0f;

            if (SettingsManager.settings.enableFloorAdjust && avatar.customAvatar.isIKAvatar)
            {
                float playerViewPointHeight = BeatSaberUtil.GetPlayerEyeHeight();
                float avatarViewPointHeight = avatar.customAvatar.viewPoint.position.y;

                floorOffset = playerViewPointHeight - avatarViewPointHeight * avatar.behaviour.scale;
            }

            // apply offset
            avatar.behaviour.position = new Vector3(0, floorOffset, 0);

            // ReSharper disable Unity.PerformanceCriticalCodeInvocation
            var originalFloor = GameObject.Find("MenuPlayersPlace") ?? GameObject.Find("Static/PlayersPlace");
            var customFloor   = GameObject.Find("Platform Loader");

            // ReSharper disable restore Unity.PerformanceCriticalCodeInvocation

            if (originalFloor)
            {
                Plugin.logger.Info($"Moving original floor {Math.Abs(floorOffset)} m {(floorOffset >= 0 ? "up" : "down")}");
                originalFloor.transform.position = new Vector3(0, floorOffset, 0);
            }

            if (customFloor)
            {
                Plugin.logger.Info($"Moving Custom Platforms floor {Math.Abs(floorOffset)} m {(floorOffset >= 0 ? "up" : "down")}");

                _initialPlatformPosition       = _initialPlatformPosition ?? customFloor.transform.position;
                customFloor.transform.position = (Vector3.up * floorOffset) + _initialPlatformPosition ?? Vector3.zero;
            }
        }
Exemple #8
0
        public void CalibrateFullBodyTracking()
        {
            Plugin.logger.Info("Calibrating full body tracking");

            TrackedDeviceManager input = PersistentSingleton <TrackedDeviceManager> .instance;

            TrackedDeviceState head      = input.head;
            TrackedDeviceState leftFoot  = input.leftFoot;
            TrackedDeviceState rightFoot = input.rightFoot;
            TrackedDeviceState pelvis    = input.waist;

            Vector3 floorNormal   = Vector3.up;
            float   floorPosition = SettingsManager.settings.moveFloorWithRoomAdjust ? BeatSaberUtil.GetRoomCenter().y : 0;

            if (leftFoot.found)
            {
                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
                SettingsManager.settings.fullBodyCalibration.leftLeg = new Pose((leftFoot.position.y - floorPosition) * Vector3.down, leftRotationCorrection);
                Plugin.logger.Info("Saved left foot pose correction " + SettingsManager.settings.fullBodyCalibration.leftLeg);
            }

            if (rightFoot.found)
            {
                Vector3    rightFootForward         = rightFoot.rotation * Vector3.up;
                Vector3    rightFootStraightForward = Vector3.ProjectOnPlane(rightFootForward, floorNormal);
                Quaternion rightRotationCorrection  = Quaternion.Inverse(rightFoot.rotation) * Quaternion.LookRotation(Vector3.up, rightFootStraightForward);
                SettingsManager.settings.fullBodyCalibration.rightLeg = new Pose((rightFoot.position.y - floorPosition) * Vector3.down, rightRotationCorrection);
                Plugin.logger.Info("Saved right foot pose correction " + SettingsManager.settings.fullBodyCalibration.rightLeg);
            }

            if (head.found && pelvis.found)
            {
                // 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 / 15f * 10f, 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);

                SettingsManager.settings.fullBodyCalibration.pelvis = new Pose(pelvisPositionCorrection, pelvisRotationCorrection);
                Plugin.logger.Info("Saved pelvis pose correction " + SettingsManager.settings.fullBodyCalibration.pelvis);
            }
        }