diff --git a/Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalEyeDriver.cs b/Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalEyeDriver.cs index ed4cdc642..a3e6c2095 100644 --- a/Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalEyeDriver.cs +++ b/Basis/Packages/com.basis.framework/Drivers/Local/BasisLocalEyeDriver.cs @@ -42,8 +42,8 @@ public class BasisLocalEyeDriver public static Transform leftEyeTransform, rightEyeTransform; private static Transform _headRef; // used for calibration reference - private static EyeCalibration _calLeft; - private static EyeCalibration _calRight; + public static EyeCalibration calLeft; + public static EyeCalibration calRight; private static NativeArray _state; @@ -51,8 +51,6 @@ public class BasisLocalEyeDriver public static bool Override = false; public static bool IsEnabled = false; - public static Quaternion leftEyeInitialRotation; - public static quaternion rightEyeInitialRotation; public static void Initalize() { Dispose(); @@ -70,8 +68,6 @@ public static void Initalize() _state = new NativeArray(1, Allocator.Persistent); _state[0] = EyeState.Create((uint)UnityEngine.Random.Range(1, int.MaxValue)); - leftEyeInitialRotation = leftEyeTransform.rotation; - rightEyeInitialRotation = rightEyeTransform.rotation; CalibrateEyes(); IsEnabled = true; @@ -107,10 +103,10 @@ public void Simulate(float dt) perEyeVarRad = perEyeVarianceDeg, occasionalCenterReturn = occasionalCenterReturn, - calLeftBasis = _calLeft.basis, - calLeftInvBasis = _calLeft.invBasis, - calRightBasis = _calRight.basis, - calRightInvBasis = _calRight.invBasis, + calLeftBasis = calLeft.basis, + calLeftInvBasis = calLeft.invBasis, + calRightBasis = calRight.basis, + calRightInvBasis = calRight.invBasis, rightBase = rightEyeTransform.localRotation, leftBase = leftEyeTransform.localRotation, @@ -138,8 +134,8 @@ public void Apply() private static void CalibrateEyes() { // Per-eye calibration against head reference directions - _calLeft = CalibrateOneEye(leftEyeTransform, _headRef); - _calRight = CalibrateOneEye(rightEyeTransform, _headRef); + calLeft = CalibrateOneEye(leftEyeTransform, _headRef); + calRight = CalibrateOneEye(rightEyeTransform, _headRef); } [System.Serializable] @@ -149,6 +145,7 @@ public struct EyeCalibration // canonical: +Z forward, +Y up, +X right public quaternion basis; public quaternion invBasis; + public quaternion initialRotation; } private static float3[] axes = new float3[] { @@ -211,7 +208,7 @@ private static EyeCalibration CalibrateOneEye(Transform eye, Transform refHead) quaternion basis = new quaternion(m); quaternion inv = math.inverse(basis); - return new EyeCalibration { basis = basis, invBasis = inv }; + return new EyeCalibration { basis = basis, invBasis = inv, initialRotation = eye.localRotation }; } [BurstCompile] diff --git a/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/Components/Actuation/EyeTrackingBoneActuation.cs b/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/Components/Actuation/EyeTrackingBoneActuation.cs index 5f5230edc..c484f2fef 100644 --- a/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/Components/Actuation/EyeTrackingBoneActuation.cs +++ b/Basis/Packages/dev.hai-vr.basis.comms/Scripts/Systems/Runtime/Components/Actuation/EyeTrackingBoneActuation.cs @@ -161,7 +161,7 @@ private void OnDestroy() private void Update() { - if (!IsLocal || !_trackingActive || !_eyeTrackingParametersActive) + if (!_eyeFollowDriverApplicable || !_trackingActive || !_eyeTrackingParametersActive) { return; } @@ -200,7 +200,7 @@ private void OnAddressUpdated(int address, float value) return; } - if (IsLocal) + if (_eyeFollowDriverApplicable) { _lastEyeParameterSampleTime = Time.unscaledTime; if (!_eyeTrackingParametersActive) @@ -225,20 +225,20 @@ private void OnTrackingActivityUpdated(int address, float value) } _trackingActive = isTrackingActive; - if (IsLocal && !_trackingActive) + if (_eyeFollowDriverApplicable && !_trackingActive) { SetLocalEyeParameterState(false); } bool shouldApplyEyeTracking = ShouldApplyEyeTracking(); - if (IsLocal) + if (_eyeFollowDriverApplicable) { SetBuiltInEyeFollowDriverOverriden(shouldApplyEyeTracking); } if (_trackingActive) { - if (IsLocal) + if (_eyeFollowDriverApplicable) { if (shouldApplyEyeTracking) { @@ -259,7 +259,7 @@ private void OnTrackingActivityUpdated(int address, float value) ResetEyeValuesToZero(); _eyeTrackingParametersActive = false; - if (IsLocal) + if (_eyeFollowDriverApplicable) { SubmitNeutralEyesToNetwork(); } @@ -288,19 +288,34 @@ private void SetEyeRotation(float x, float y, EyeSide side) if (_eyeFollowDriverApplicable) { - var xDeg = Mathf.Asin(x) * Mathf.Rad2Deg * multiplyX; - var yDeg = Mathf.Asin(-y) * Mathf.Rad2Deg * multiplyY; - Quaternion Euler = Quaternion.Euler(yDeg, xDeg, 0); + + // Uses EyeCalibration from BasisLocalEyeDriver to handle arbitrary eye bone orientations for local player. + // Retaining Hai's original FIXME: This could/should be replaced by a WIP normalized muscle system + + float xRad = Mathf.Asin(x) * multiplyX; + float yRad = Mathf.Asin(-y) * multiplyY; + quaternion yaw = quaternion.AxisAngle(new float3(0, 1, 0), xRad); + quaternion pitch = quaternion.AxisAngle(new float3(1, 0, 0), yRad); + quaternion canonical = math.mul(yaw, pitch); + switch (side) { - // FIXME: This wrongly assumes that eye bone transforms are oriented the same. - // This needs to be fixed later by using the work-in-progress normalized muscle system instead. case EyeSide.Left: - BasisLocalEyeDriver.leftEyeTransform.localRotation = math.mul(BasisLocalEyeDriver.leftEyeInitialRotation, Euler); + { + var cal = BasisLocalEyeDriver.calLeft; + quaternion rigOffset = math.mul(math.mul(cal.basis, canonical), cal.invBasis); + BasisLocalEyeDriver.leftEyeTransform.localRotation = + math.mul(cal.initialRotation, rigOffset); break; + } case EyeSide.Right: - BasisLocalEyeDriver.rightEyeTransform.localRotation = math.mul(BasisLocalEyeDriver.rightEyeInitialRotation, Euler); + { + var cal = BasisLocalEyeDriver.calRight; + quaternion rigOffset = math.mul(math.mul(cal.basis, canonical), cal.invBasis); + BasisLocalEyeDriver.rightEyeTransform.localRotation = + math.mul(cal.initialRotation, rigOffset); break; + } default: throw new ArgumentOutOfRangeException(nameof(side), side, null); }