private AvatarTailor(ILoggerProvider loggerProvider, MainSettingsModelSO mainSettingsModel, PlayerDataModel playerDataModel, Settings settings, CalibrationData calibrationData, TrackedDeviceManager trackedDeviceManager) { _logger = loggerProvider.CreateLogger <AvatarTailor>(); _mainSettingsModel = mainSettingsModel; _playerDataModel = playerDataModel; _settings = settings; _calibrationData = calibrationData; _trackedDeviceManager = trackedDeviceManager; }
private void Inject(TrackedDeviceManager trackedDeviceManager, PlayerAvatarManager avatarManager, AvatarTailor avatarTailor, Settings settings, CalibrationData calibrationData, ShaderLoader shaderLoader, ILoggerProvider loggerProvider) { _trackedDeviceManager = trackedDeviceManager; _avatarManager = avatarManager; _avatarTailor = avatarTailor; _settings = settings; _calibrationData = calibrationData; _shaderLoader = shaderLoader; _logger = loggerProvider.CreateLogger <SettingsViewController>(); }
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); } }
public Pose GetRightSaberPose() { if (!calibrated || !this.rightController.isValid) { return(new Pose()); } Pose?rightControllerPose = this.GetBeatSaberDevicePosition(this.rightController); if (rightControllerPose == null) { return(new Pose()); } return(TrackedDeviceManager.GetTrackedObjectPose(this.savedRightSaber, this.savedRightController.Value, rightControllerPose.Value)); }
/// <summary> /// Save the initial saber positions relative to the VRControllers /// </summary> private void CalibrateSaberPositions() { calibrated = true; // Save current controller position this.savedLeftController = TrackedDeviceManager.GetDevicePose(this.leftController) ?? new Pose(); this.savedLeftController = this.AdjustForPlayerOrigin(this.savedLeftController); this.savedRightController = TrackedDeviceManager.GetDevicePose(this.rightController) ?? new Pose(); this.savedRightController = this.AdjustForPlayerOrigin(this.savedRightController); // Save current game saber positions this.savedLeftSaber.position = saberManager.leftSaber.transform.position; this.savedLeftSaber.rotation = saberManager.leftSaber.transform.rotation; this.savedRightSaber.position = saberManager.rightSaber.transform.position; this.savedRightSaber.rotation = saberManager.rightSaber.transform.rotation; }
/// <summary> /// Gets the position of the device but factors in the room rotation of Beat Saber into the return. /// It requires the <see cref="MainSettingsModelSO" /> which can be found by calling /// Resources.FindObjectsOfTypeAll<MainSettingsModelSO>().FirstOrDefault(); /// </summary> private Pose?GetBeatSaberDevicePosition(InputDevice device) { Pose?devicePose = TrackedDeviceManager.GetDevicePose(device); if (devicePose == null) { return(null); } var roomCenter = this.mainSettingsModel.roomCenter; var roomRotation = Quaternion.Euler(0, this.mainSettingsModel.roomRotation, 0); Pose newDevicePose = devicePose.Value; newDevicePose.position = roomRotation * devicePose.Value.position; newDevicePose.position += roomCenter; newDevicePose.rotation = roomRotation * devicePose.Value.rotation; return(newDevicePose); }
private void Update() { if (!this.showTrackers || this.trackerInstances == null || this.trackerInstances.Count == 0) { return; } foreach (var tracker in this.trackerInstances) { // Update all the tracker poses Pose trackerPose = TrackedDeviceManager.GetDevicePose(tracker.InputDevice) ?? new Pose(); trackerPose = this.AdjustForRoomRotation(trackerPose); tracker.Instance.transform.position = trackerPose.position; tracker.Instance.transform.rotation = trackerPose.rotation; } var selectedTrackerInstance = this.trackerInstances.Find(t => t.Serial == this.selectedTracker.Serial); if (this.selectedTracker == null || String.IsNullOrWhiteSpace(this.selectedTracker.Serial)) { // No selected tracker so disable the saber this.saberInstance.SetActive(false); return; } // Transform the Saber according to the Tracker Config Data Pose selectedTrackerPose = new Pose( selectedTrackerInstance.Instance.transform.position, selectedTrackerInstance.Instance.transform.rotation); Pose pose = Utilities.CalculatePoseFromTrackerData(this.selectedTracker, selectedTrackerPose); this.saberInstance.transform.position = pose.position; this.saberInstance.transform.rotation = pose.rotation; this.saberInstance.SetActive(true); }
/// <summary> /// Gets the pose for the given tracker config data or else it falls back to the /// right saber pose. This method accounts for Room Adjust and Noodle Extensions /// changing viewpoint functionality. /// </summary> public Pose GetRightSaberPose(TrackerConfigData configData) { Pose?trackerPose; if (!String.IsNullOrWhiteSpace(configData?.Serial) && (trackerPose = TrackedDeviceManager.instance.GetPoseFromSerial(configData.Serial)) != null) { // Return adjusted position from the tracker Pose adjustedPose = this.AdjustForPlayerOrigin(trackerPose.Value); return(Utilities.CalculatePoseFromTrackerData(configData, adjustedPose)); } else { if (!calibrated || !this.rightController.isValid) { return(new Pose()); } // Return adjusted position from the saber Pose controllerPose = TrackedDeviceManager.GetDevicePose(this.rightController) ?? new Pose(); Pose adjustedControllerPose = this.AdjustForPlayerOrigin(controllerPose); return(TrackedDeviceManager.GetTrackedObjectPose(this.savedRightSaber, this.savedRightController, adjustedControllerPose)); } }
//private void DrawBounds(Bounds b) //{ // var vectorArray = new Vector3[] // { // new Vector3(b.min.x, b.min.y, b.min.z), // new Vector3(b.max.x, b.min.y, b.min.z), // new Vector3(b.max.x, b.min.y, b.max.z), // new Vector3(b.min.x, b.min.y, b.max.z), // new Vector3(b.min.x, b.max.y, b.min.z), // new Vector3(b.max.x, b.max.y, b.min.z), // new Vector3(b.max.x, b.max.y, b.max.z), // new Vector3(b.min.x, b.max.y, b.max.z) // }; // this.lines.positionCount = 8; // this.lines.SetPositions(vectorArray); //} private void Update() { // If there is nothing to grab anywhere, do nothing if (!this.grabbableInstances.Any()) { return; } // Check for trigger clicks first as it's debounced and will override simply having the trigger down if (InputManager.instance.GetRightTriggerClicked()) { this.rightGrabbed = this.GrabInstance(InputManager.instance.RightController); return; } if (InputManager.instance.GetLeftTriggerClicked()) { this.leftGrabbed = this.GrabInstance(InputManager.instance.LeftController); return; } // If there is no grabbed instance or grabbed device then we are done if (this.leftGrabbed == null && this.rightGrabbed == null) { return; } // Check for trigger being held down on the device if (this.rightGrabbed != null) { if (InputManager.instance.GetRightTriggerDown()) { // Trigger held so track instance position with the device Pose?grabbedPose = TrackedDeviceManager.GetDevicePose(rightGrabbed.grabbedDevice); if (grabbedPose == null) { return; } this.rightGrabbed.grabbedInstance.Pose = TrackedDeviceManager.GetTrackedObjectPose(rightGrabbed.grabbedStartPose, rightGrabbed.grabbedDevicePose, grabbedPose.Value); this.rightGrabbed.grabbedInstance.Instance.transform.position = this.rightGrabbed.grabbedInstance.Pose.position; this.rightGrabbed.grabbedInstance.Instance.transform.rotation = this.rightGrabbed.grabbedInstance.Pose.rotation; this.rightGrabbed.grabbedInstance.ExpandedBounds = CalculateExpandedBounds(this.rightGrabbed.grabbedInstance.Instance); //DrawBounds(this.rightGrabbed.grabbedInstance.ExpandedBounds); } else { ReleaseInstance(ref this.rightGrabbed); } } if (this.leftGrabbed != null) { if (InputManager.instance.GetLeftTriggerDown()) { // Trigger held so track instance position with the device Pose?grabbedPose = TrackedDeviceManager.GetDevicePose(leftGrabbed.grabbedDevice); if (grabbedPose == null) { return; } this.leftGrabbed.grabbedInstance.Pose = TrackedDeviceManager.GetTrackedObjectPose(leftGrabbed.grabbedStartPose, leftGrabbed.grabbedDevicePose, grabbedPose.Value); this.leftGrabbed.grabbedInstance.Instance.transform.position = this.leftGrabbed.grabbedInstance.Pose.position; this.leftGrabbed.grabbedInstance.Instance.transform.rotation = this.leftGrabbed.grabbedInstance.Pose.rotation; this.leftGrabbed.grabbedInstance.ExpandedBounds = CalculateExpandedBounds(this.leftGrabbed.grabbedInstance.Instance); //DrawBounds(this.leftGrabbed.grabbedInstance.ExpandedBounds); } else { ReleaseInstance(ref this.leftGrabbed); } } }