Skip to content

Commit fd19203

Browse files
committed
Support combined and sepatate eye tracking
1 parent 253a7b9 commit fd19203

File tree

2 files changed

+69
-13
lines changed

2 files changed

+69
-13
lines changed

ALVRModule/ALVRModule.cs

+66-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Text;
66
using VRCFaceTracking;
77
using VRCFaceTracking.Core.Params.Expressions;
8+
using VRCFaceTracking.Core.Types;
89
using static VRCFaceTracking.Core.Params.Expressions.UnifiedExpressions;
910

1011
namespace ALVRModule
@@ -111,6 +112,65 @@ private static float[] GetParams(byte[] packet, ref int cursor, int param_count)
111112
return data;
112113
}
113114

115+
// Code taken from VRCFaceTracking-QuestProOpenXR
116+
private static void SetEyesQuatParams(float[] p)
117+
{
118+
Debug.Assert(p.Length == 8);
119+
120+
var eye = UnifiedTracking.Data.Eye;
121+
122+
var q_x = p[0];
123+
var q_y = p[1];
124+
var q_z = p[2];
125+
var q_w = p[3];
126+
127+
double yaw = Math.Atan2(2.0 * (q_y * q_z + q_w * q_x), q_w * q_w - q_x * q_x - q_y * q_y + q_z * q_z);
128+
double pitch = Math.Asin(-2.0 * (q_x * q_z - q_w * q_y));
129+
130+
double pitch_L = (180.0 / Math.PI) * pitch;
131+
double yaw_L = (180.0 / Math.PI) * yaw;
132+
133+
q_x = p[4];
134+
q_y = p[5];
135+
q_z = p[6];
136+
q_w = p[7];
137+
yaw = Math.Atan2(2.0 * (q_y * q_z + q_w * q_x), q_w * q_w - q_x * q_x - q_y * q_y + q_z * q_z);
138+
pitch = Math.Asin(-2.0 * (q_x * q_z - q_w * q_y));
139+
140+
double pitch_R = (180.0 / Math.PI) * pitch;
141+
double yaw_R = (180.0 / Math.PI) * yaw;
142+
143+
var radianConst = 0.0174533f;
144+
145+
var pitch_R_mod = (float)(Math.Abs(pitch_R) + 4f * Math.Pow(Math.Abs(pitch_R) / 30f, 30f));
146+
var pitch_L_mod = (float)(Math.Abs(pitch_L) + 4f * Math.Pow(Math.Abs(pitch_L) / 30f, 30f));
147+
var yaw_R_mod = (float)(Math.Abs(yaw_R) + 6f * Math.Pow(Math.Abs(yaw_R) / 27f, 18f));
148+
var yaw_L_mod = (float)(Math.Abs(yaw_L) + 6f * Math.Pow(Math.Abs(yaw_L) / 27f, 18f));
149+
150+
eye.Right.Gaze = new Vector2(
151+
pitch_R < 0 ? pitch_R_mod * radianConst : -1 * pitch_R_mod * radianConst,
152+
yaw_R < 0 ? -1 * yaw_R_mod * radianConst : (float)yaw_R * radianConst);
153+
eye.Left.Gaze = new Vector2(
154+
pitch_L < 0 ? pitch_L_mod * radianConst : -1 * pitch_L_mod * radianConst,
155+
yaw_L < 0 ? -1 * yaw_L_mod * radianConst : (float)yaw_L * radianConst);
156+
157+
eye.Left.PupilDiameter_MM = 5f;
158+
eye.Right.PupilDiameter_MM = 5f;
159+
160+
eye._minDilation = 0;
161+
eye._maxDilation = 10;
162+
}
163+
private static void SetCombEyesQuatParams(float[] p)
164+
{
165+
Debug.Assert(p.Length == 4);
166+
167+
var array = new float[8];
168+
p.CopyTo(array, 0);
169+
p.CopyTo(array, 4);
170+
171+
SetEyesQuatParams(array);
172+
}
173+
114174
private static void SetFaceFbParams(float[] p)
115175
{
116176
Debug.Assert(p.Length == (int)FaceFbMax);
@@ -121,16 +181,6 @@ private static void SetFaceFbParams(float[] p)
121181
eye.Left.Openness = 1.0f - (float)Math.Max(0, Math.Min(1, p[(int)EyesClosedL] + p[(int)EyesClosedL] * p[(int)LidTightenerL]));
122182
eye.Right.Openness = 1.0f - (float)Math.Max(0, Math.Min(1, p[(int)EyesClosedR] + p[(int)EyesClosedR] * p[(int)LidTightenerR]));
123183

124-
eye.Left.Gaze.x = (p[(int)EyesLookRightL] - p[(int)EyesLookLeftL]) * 0.5f;
125-
eye.Left.Gaze.y = (p[(int)EyesLookUpL] - p[(int)EyesLookDownL]) * 0.5f;
126-
eye.Right.Gaze.x = (p[(int)EyesLookRightR] - p[(int)EyesLookLeftR]) * 0.5f;
127-
eye.Right.Gaze.y = (p[(int)EyesLookUpR] - p[(int)EyesLookDownR]) * 0.5f;
128-
129-
eye._minDilation = 0.0f;
130-
eye._maxDilation = 1.0f;
131-
eye.Left.PupilDiameter_MM = 0.5f;
132-
eye.Right.PupilDiameter_MM = 0.5f;
133-
134184
static void SetParam(float[] data, FaceFb input, UnifiedExpressions outputType)
135185
{
136186
UnifiedTracking.Data.Shapes[(int)outputType].Weight = data[(int)input];
@@ -246,6 +296,12 @@ public override void Update()
246296

247297
switch (str)
248298
{
299+
case "EyesQuat":
300+
SetFaceFbParams(GetParams(packet, ref cursor, 8));
301+
break;
302+
case "CombQuat":
303+
SetFaceFbParams(GetParams(packet, ref cursor, 4));
304+
break;
249305
case "FaceFb\0\0":
250306
SetFaceFbParams(GetParams(packet, ref cursor, (int)FaceFbMax));
251307
break;

metadata.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
"AuthorName": "zarik5",
44
"DllFileName": "ALVRModule.dll",
55
"Downloads": 0,
6-
"DownloadUrl": "https://github.com/alvr-org/VRCFT-ALVR/releases/download/v1.1.0/ALVRModule.zip",
7-
"LastUpdated": "2023-08-18T16:19:33Z",
6+
"DownloadUrl": "https://github.com/alvr-org/VRCFT-ALVR/releases/download/v1.2.0/ALVRModule.zip",
7+
"LastUpdated": "2023-11-08T07:36:37Z",
88
"ModuleDescription": "VRCFaceTracking module for ALVR support",
99
"ModuleName": "ALVR Module",
1010
"ModulePageUrl": "https://github.com/alvr-org/VRCFT-ALVR",
1111
"Rating": 0,
1212
"Ratings": 0,
1313
"RatingSum": 0,
1414
"UsageInstructions": "Set `Eye and face tracking` to `VRCFaceTracking`. Reconnect the client if necessary.",
15-
"Version": "1.1.0"
15+
"Version": "1.2.0"
1616
}

0 commit comments

Comments
 (0)