diff --git a/src/Baballonia/Assets/Icons.axaml b/src/Baballonia/Assets/Icons.axaml
index 2b8c2c94..bb9dd674 100644
--- a/src/Baballonia/Assets/Icons.axaml
+++ b/src/Baballonia/Assets/Icons.axaml
@@ -42,6 +42,7 @@
M16.9510797,2.50304787 C17.7274884,2.50304787 18.4490393,2.9033378 18.8600157,3.56205529 L20.3810589,6 L22.75,6 C24.5449254,6 26,7.45507456 26,9.25 L26,21.75 C26,23.5449254 24.5449254,25 22.75,25 L5.25,25 C3.45507456,25 2,23.5449254 2,21.75 L2,9.25 C2,7.45507456 3.45507456,6 5.25,6 L7.81851226,6 L9.2010861,3.62210494 C9.60389995,2.92930357 10.3448058,2.50304787 11.1462,2.50304787 L16.9510797,2.50304787 Z M16.9510797,4.00304787 L11.1462,4.00304787 C10.9172302,4.00304787 10.7030739,4.10743702 10.5620036,4.28269019 L10.4978287,4.3760669 L8.8983713,7.12698098 C8.76410002,7.35791477 8.51713142,7.5 8.25,7.5 L5.25,7.5 C4.28350169,7.5 3.5,8.28350169 3.5,9.25 L3.5,21.75 C3.5,22.7164983 4.28350169,23.5 5.25,23.5 L22.75,23.5 C23.7164983,23.5 24.5,22.7164983 24.5,21.75 L24.5,9.25 C24.5,8.28350169 23.7164983,7.5 22.75,7.5 L19.9649865,7.5 C19.7061837,7.5 19.4656667,7.36657003 19.3286745,7.14699753 L17.5873917,4.35605034 C17.4503996,4.13647785 17.2098826,4.00304787 16.9510797,4.00304787 Z M14,9.5009905 C17.0375661,9.5009905 19.5,11.9634244 19.5,15.0009905 C19.5,18.0385566 17.0375661,20.5009905 14,20.5009905 C10.9624339,20.5009905 8.5,18.0385566 8.5,15.0009905 C8.5,11.9634244 10.9624339,9.5009905 14,9.5009905 Z M14,11.0009905 C11.790861,11.0009905 10,12.7918515 10,15.0009905 C10,17.2101295 11.790861,19.0009905 14,19.0009905 C16.209139,19.0009905 18,17.2101295 18,15.0009905 C18,12.7918515 16.209139,11.0009905 14,11.0009905 Z
M10.0492532,15.4208574 L16.3060077,6.94493547 C16.5131405,6.66433611 16.8962754,6.58091825 17.2013158,6.75000494 C17.4758699,6.90219275 17.61052,7.21639422 17.5413028,7.51420559 L17.510592,7.61262428 L13.6405266,17.4116224 C13.2205308,18.475051 12.0179777,18.9966563 10.9545491,18.5766605 C10.8710782,18.543694 10.7898393,18.5053348 10.7113465,18.4618255 C9.71108052,17.9073691 9.34968053,16.6470175 9.904137,15.6467516 L9.97303013,15.5314501 L9.97303013,15.5314501 L10.0492532,15.4208574 L16.3060077,6.94493547 L10.0492532,15.4208574 Z M13.850015,12.7977214 L11.2560655,16.3117019 L11.2160666,16.373966 L11.2160666,16.373966 C11.0632395,16.6496733 11.1628536,16.9970689 11.4385609,17.149896 L11.5055502,17.1815268 L11.5055502,17.1815268 C11.769176,17.2856445 12.0638421,17.1796801 12.2044743,16.9439092 L12.2453929,16.8606213 L13.850015,12.7977214 Z M18.6095174,7.41397033 C19.364068,8.02528183 20.0469718,8.75083284 20.6317275,9.58595046 C21.1562296,10.3350171 21.6612578,11.2420254 21.9517027,11.9842912 C22.1026388,12.3700259 21.9122969,12.8050834 21.5265623,12.9560194 C21.1408277,13.1069554 20.7057702,12.9166136 20.5548341,12.530879 C20.4575421,12.2822379 20.3277108,12.0046594 20.1775548,11.7190679 L18.1280514,12.9023464 C17.769332,13.1094531 17.3106392,12.9865468 17.1035324,12.6278273 C16.9136845,12.2990011 17.0011393,11.8861696 17.2933389,11.6601229 L17.3780514,11.6033083 L19.3963044,10.4364308 L19.1658779,10.1227204 C18.8419948,9.70016342 18.4876665,9.31329453 18.1081562,8.96304177 L18.4883177,7.99876394 C18.5262055,7.90283222 18.5550318,7.80534515 18.5751558,7.70730436 L18.5988599,7.55995309 L18.6095174,7.41397033 Z M15.9809484,5.85271523 C15.8318986,5.9392755 15.694531,6.04936208 15.5743759,6.18134222 L15.4601633,6.32055973 L14.919203,7.05349635 C14.2174399,6.80955942 13.4886764,6.6517272 12.7502416,6.58305531 L12.75,9.25589923 C12.75,9.6701128 12.4142136,10.0058992 12,10.0058992 C11.6203042,10.0058992 11.306509,9.72374535 11.2568466,9.35766979 L11.25,9.25589923 L11.2496135,6.56662077 C9.65294084,6.68015443 8.06551588,7.21425939 6.65889532,8.19918572 C5.84294582,8.77051971 5.13152818,9.52142873 4.54015984,10.4038879 L6.62237477,11.6059717 C6.98109424,11.8130785 7.1040006,12.2717713 6.89689382,12.6304908 C6.70704594,12.959317 6.30579591,13.0899946 5.96393397,12.9499658 L5.87237477,12.9050099 L3.79818254,11.7080227 C3.6704134,11.9742424 3.55177265,12.248307 3.44255853,12.5292935 C3.29249811,12.9153696 2.8578736,13.1066981 2.47179751,12.9566377 C2.08572142,12.8065773 1.89439292,12.3719528 2.04445335,11.9858767 C2.85090303,9.91103954 4.12374054,8.14315832 5.79853067,6.97045765 C8.8904309,4.8054858 12.7328827,4.5119546 15.9809484,5.85271523 Z
M34.156-.088a4.1 4.1 0 0 1 .556 8.159l-.556.037H15.031c-3.537 0-6.445 2.688-6.795 6.132l-.035.698v19.138a4.1 4.1 0 0 1-8.159.556l-.037-.556V14.939A15.03 15.03 0 0 1 14.116-.06l.915-.027zM8.163 74.49a4.1 4.1 0 0 0-8.122 0l-.037.556v19.137l.03.952a15.03 15.03 0 0 0 14.082 14.047l.915.027h19.125l.556-.037a4.1 4.1 0 0 0 0-8.122l-.556-.038H15.031l-.698-.035c-3.215-.327-5.77-2.882-6.097-6.097l-.035-.698V75.046zM95.178-.06l-.915-.027H75.138l-.556.037a4.1 4.1 0 0 0 0 8.122l.556.037h19.125l.698.035a6.83 6.83 0 0 1 6.096 6.097l.036.698v19.138l.037.556a4.1 4.1 0 0 0 8.122 0l.038-.556V14.939l-.03-.952A15.03 15.03 0 0 0 95.178-.06zM22.981 53.265l.046-.112a15.1 15.1 0 0 1 .241-.544 26.14 26.14 0 0 1 1.125-2.137c1.057-1.811 2.729-4.246 5.164-6.681 4.806-4.806 12.679-9.728 25.106-9.728s20.301 4.922 25.107 9.728c2.434 2.434 4.107 4.869 5.164 6.681a26.1 26.1 0 0 1 1.125 2.137 20.6 20.6 0 0 1 .241.544l.046.113c.815 2.077 3.163 3.186 5.275 2.393a4.1 4.1 0 0 0 2.398-5.276l-.004-.009-.004-.011-.011-.028-.031-.081-.103-.253a24.01 24.01 0 0 0-.373-.843 34.39 34.39 0 0 0-1.479-2.815 41.38 41.38 0 0 0-6.448-8.346c-6.123-6.123-16.008-12.129-30.902-12.129s-24.779 6.006-30.902 12.129a41.38 41.38 0 0 0-6.448 8.346 34.22 34.22 0 0 0-1.479 2.815 23.92 23.92 0 0 0-.373.843l-.103.253-.032.081c-.012.031-.884 4.101 2.38 5.325a4.1 4.1 0 0 0 5.27-2.382zm31.682-9.639c-10.562 0-19.125 8.562-19.125 19.125S44.1 81.876 54.663 81.876s19.125-8.562 19.125-19.125-8.562-19.125-19.125-19.125zM43.734 62.751a10.93 10.93 0 0 1 10.928-10.928A10.93 10.93 0 0 1 65.59 62.751 10.93 10.93 0 0 1 54.663 73.68a10.93 10.93 0 0 1-10.928-10.928zm77.788 3.625a12.31 12.31 0 0 0-17.403 0l-43.528 43.531a9.31 9.31 0 0 0-2.52 4.633l-3.355 15.657c-.179.835.078 1.704.681 2.307s1.472.86 2.307.681l15.657-3.355a9.32 9.32 0 0 0 4.634-2.521l43.528-43.532a12.31 12.31 0 0 0-.001-17.403zm-13.844 3.56c2.84-2.84 7.444-2.84 10.284 0s2.84 7.444 0 10.284l-2.268 2.268-10.284-10.284zm-5.827 5.827l10.284 10.284-37.701 37.704a4.28 4.28 0 0 1-2.129 1.158l-11.853 2.54 2.54-11.854a4.28 4.28 0 0 1 1.158-2.128z
+ M12,9.0046246 C14.209139,9.0046246 16,10.7954856 16,13.0046246 C16,15.2137636 14.209139,17.0046246 12,17.0046246 C9.790861,17.0046246 8,15.2137636 8,13.0046246 C8,10.7954856 9.790861,9.0046246 12,9.0046246 Z M12,10.5046246 C10.6192881,10.5046246 9.5,11.6239127 9.5,13.0046246 C9.5,14.3853365 10.6192881,15.5046246 12,15.5046246 C13.3807119,15.5046246 14.5,14.3853365 14.5,13.0046246 C14.5,11.6239127 13.3807119,10.5046246 12,10.5046246 Z M12,5.5 C16.613512,5.5 20.5960869,8.65000641 21.7011157,13.0643865 C21.8017,13.4662019 21.557504,13.8734775 21.1556885,13.9740618 C20.7538731,14.0746462 20.3465976,13.8304502 20.2460132,13.4286347 C19.3071259,9.67795854 15.9213644,7 12,7 C8.07693257,7 4.69009765,9.68026417 3.75285786,13.4331499 C3.65249525,13.8350208 3.24535455,14.0794416 2.84348365,13.979079 C2.44161275,13.8787164 2.19719198,13.4715757 2.29755459,13.0697048 C3.4006459,8.65271806 7.38448293,5.5 12,5.5 Z
M121.522 66.376a12.31 12.31 0 0 0-17.403 0l-43.528 43.531c-1.269 1.269-2.144 2.878-2.52 4.633l-3.355 15.657c-.179.835.078 1.704.681 2.307s1.472.86 2.307.681l15.657-3.355c1.755-.376 3.364-1.252 4.634-2.521l43.528-43.532a12.31 12.31 0 0 0-.001-17.403zm-13.844 3.56c2.84-2.84 7.444-2.84 10.284 0s2.84 7.444 0 10.284l-2.268 2.268-10.284-10.284zm-5.827 5.827l10.284 10.284-37.701 37.704a4.28 4.28 0 0 1-2.129 1.158l-11.853 2.54 2.54-11.854c.173-.806.575-1.545 1.158-2.128z M24.442 51.356a3.8 3.8 0 0 0-3.784 4.145c1.42 15.57 12.918 28.785 30.384 28.785S80.007 71.07 81.427 55.5a3.8 3.8 0 0 0-3.784-4.145zm26.6 25.33c-11.435 0-19.613-7.495-22.127-17.731h44.253C70.656 69.19 62.477 76.686 51.043 76.686zm16.465-41.795c-2.069 0-3.598 1.455-3.841 3.089a3.8 3.8 0 0 1-4.315 3.202 3.8 3.8 0 0 1-3.202-4.315c.818-5.525 5.69-9.576 11.358-9.576s10.54 4.05 11.358 9.576a3.8 3.8 0 0 1-3.202 4.315 3.8 3.8 0 0 1-4.315-3.202c-.242-1.634-1.771-3.089-3.841-3.089zm-36.77 3.089c.242-1.634 1.771-3.089 3.84-3.089s3.599 1.455 3.84 3.089a3.8 3.8 0 0 0 4.315 3.202 3.8 3.8 0 0 0 3.202-4.315c-.818-5.525-5.69-9.576-11.358-9.576s-10.54 4.05-11.358 9.576a3.8 3.8 0 0 0 3.202 4.315 3.8 3.8 0 0 0 4.315-3.202zM51.043.695C23.064.695.382 23.377.382 51.356s22.681 50.66 50.66 50.66 50.66-22.682 50.66-50.66S79.021.695 51.043.695zM7.981 51.356c0-23.782 19.279-43.061 43.061-43.061s43.061 19.279 43.061 43.061-19.279 43.061-43.061 43.061S7.981 75.137 7.981 51.356z
M24,4 C35.045695,4 44,12.954305 44,24 C44,35.045695 35.045695,44 24,44 C12.954305,44 4,35.045695 4,24 C4,12.954305 12.954305,4 24,4 Z M24,6.5 C14.3350169,6.5 6.5,14.3350169 6.5,24 C6.5,33.6649831 14.3350169,41.5 24,41.5 C33.6649831,41.5 41.5,33.6649831 41.5,24 C41.5,14.3350169 33.6649831,6.5 24,6.5 Z M32.6338835,17.6161165 C33.1220388,18.1042719 33.1220388,18.8957281 32.6338835,19.3838835 L21.6338835,30.3838835 C21.1457281,30.8720388 20.3542719,30.8720388 19.8661165,30.3838835 L15.3661165,25.8838835 C14.8779612,25.3957281 14.8779612,24.6042719 15.3661165,24.1161165 C15.8542719,23.6279612 16.6457281,23.6279612 17.1338835,24.1161165 L20.75,27.732233 L30.8661165,17.6161165 C31.3542719,17.1279612 32.1457281,17.1279612 32.6338835,17.6161165 Z
M3,6.25 C3,4.45507 4.45507,3 6.25,3 L17.75,3 C19.5449,3 21,4.45507 21,6.25 L21,17.75 C21,19.5449 19.5449,21 17.75,21 L6.25,21 C4.45507,21 3,19.5449 3,17.75 L3,6.25 Z M6.25,4.5 C5.2835,4.5 4.5,5.2835 4.5,6.25 L4.5,17.75 C4.5,18.7165 5.2835,19.5 6.25,19.5 L9,19.5 L9,4.5 L6.25,4.5 Z M10.5,4.5 L10.5,14 L19.5,14 L19.5,6.25 C19.5,5.2835 18.7165,4.5 17.75,4.5 L10.5,4.5 Z M19.5,15.5 L10.5,15.5 L10.5,19.5 L17.75,19.5 C18.7165,19.5 19.5,18.7165 19.5,17.75 L19.5,15.5 Z
diff --git a/src/Baballonia/Assets/Resources.Designer.cs b/src/Baballonia/Assets/Resources.Designer.cs
index 73681c19..5c030174 100644
--- a/src/Baballonia/Assets/Resources.Designer.cs
+++ b/src/Baballonia/Assets/Resources.Designer.cs
@@ -177,6 +177,24 @@ public static string Calibration_Eye_Expressions_Stabilize_Eyes_Header {
}
}
+ ///
+ /// Looks up a localized string similar to No autocalibration (Eyes are tuned during VR calibrations).
+ ///
+ public static string Calibration_EyeCalibrationDisabled_Description {
+ get {
+ return ResourceManager.GetString("Calibration_EyeCalibrationDisabled_Description", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Eye Calibration.
+ ///
+ public static string Calibration_EyeCalibrationDisabled_Title {
+ get {
+ return ResourceManager.GetString("Calibration_EyeCalibrationDisabled_Title", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to • Raising the.
///
@@ -321,6 +339,24 @@ public static string Calibration_Tongue_Expressions_Header {
}
}
+ ///
+ /// Looks up a localized string similar to Enables automatic face calibration.
+ ///
+ public static string Calibration_UseAutocalibration_Description {
+ get {
+ return ResourceManager.GetString("Calibration_UseAutocalibration_Description", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Face Auto-Calibration.
+ ///
+ public static string Calibration_UseAutocalibration_Title {
+ get {
+ return ResourceManager.GetString("Calibration_UseAutocalibration_Title", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Start typing....
///
diff --git a/src/Baballonia/Assets/Resources.af-ZA.resx b/src/Baballonia/Assets/Resources.af-ZA.resx
index 73b898d1..e923ce6c 100644
--- a/src/Baballonia/Assets/Resources.af-ZA.resx
+++ b/src/Baballonia/Assets/Resources.af-ZA.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.ar-SA.resx b/src/Baballonia/Assets/Resources.ar-SA.resx
index 7cd1708b..36d4b70e 100644
--- a/src/Baballonia/Assets/Resources.ar-SA.resx
+++ b/src/Baballonia/Assets/Resources.ar-SA.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.ca-ES.resx b/src/Baballonia/Assets/Resources.ca-ES.resx
index 0a67058f..53d2bbbd 100644
--- a/src/Baballonia/Assets/Resources.ca-ES.resx
+++ b/src/Baballonia/Assets/Resources.ca-ES.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.cs-CZ.resx b/src/Baballonia/Assets/Resources.cs-CZ.resx
index ccd21fb1..11f40a0a 100644
--- a/src/Baballonia/Assets/Resources.cs-CZ.resx
+++ b/src/Baballonia/Assets/Resources.cs-CZ.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.da-DK.resx b/src/Baballonia/Assets/Resources.da-DK.resx
index 6de2b8a2..ae7f781f 100644
--- a/src/Baballonia/Assets/Resources.da-DK.resx
+++ b/src/Baballonia/Assets/Resources.da-DK.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.de-DE.resx b/src/Baballonia/Assets/Resources.de-DE.resx
index 291eaf6e..c772969c 100644
--- a/src/Baballonia/Assets/Resources.de-DE.resx
+++ b/src/Baballonia/Assets/Resources.de-DE.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.el-GR.resx b/src/Baballonia/Assets/Resources.el-GR.resx
index 4825fb2c..c9ddbc34 100644
--- a/src/Baballonia/Assets/Resources.el-GR.resx
+++ b/src/Baballonia/Assets/Resources.el-GR.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.en-US.resx b/src/Baballonia/Assets/Resources.en-US.resx
index 73b898d1..e923ce6c 100644
--- a/src/Baballonia/Assets/Resources.en-US.resx
+++ b/src/Baballonia/Assets/Resources.en-US.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.es-ES.resx b/src/Baballonia/Assets/Resources.es-ES.resx
index 62d8e0e7..40e4b967 100644
--- a/src/Baballonia/Assets/Resources.es-ES.resx
+++ b/src/Baballonia/Assets/Resources.es-ES.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.fi-FI.resx b/src/Baballonia/Assets/Resources.fi-FI.resx
index 9492e0ba..f48b17d5 100644
--- a/src/Baballonia/Assets/Resources.fi-FI.resx
+++ b/src/Baballonia/Assets/Resources.fi-FI.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.fr-FR.resx b/src/Baballonia/Assets/Resources.fr-FR.resx
index c027dfd0..f8875b90 100644
--- a/src/Baballonia/Assets/Resources.fr-FR.resx
+++ b/src/Baballonia/Assets/Resources.fr-FR.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.he-IL.resx b/src/Baballonia/Assets/Resources.he-IL.resx
index 73b898d1..e923ce6c 100644
--- a/src/Baballonia/Assets/Resources.he-IL.resx
+++ b/src/Baballonia/Assets/Resources.he-IL.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.hu-HU.resx b/src/Baballonia/Assets/Resources.hu-HU.resx
index 73b898d1..e923ce6c 100644
--- a/src/Baballonia/Assets/Resources.hu-HU.resx
+++ b/src/Baballonia/Assets/Resources.hu-HU.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.it-IT.resx b/src/Baballonia/Assets/Resources.it-IT.resx
index 4f895a11..07438cb7 100644
--- a/src/Baballonia/Assets/Resources.it-IT.resx
+++ b/src/Baballonia/Assets/Resources.it-IT.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.ja-JP.resx b/src/Baballonia/Assets/Resources.ja-JP.resx
index ee3b1d51..7325e034 100644
--- a/src/Baballonia/Assets/Resources.ja-JP.resx
+++ b/src/Baballonia/Assets/Resources.ja-JP.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.ko-KR.resx b/src/Baballonia/Assets/Resources.ko-KR.resx
index bb97129f..8e438658 100644
--- a/src/Baballonia/Assets/Resources.ko-KR.resx
+++ b/src/Baballonia/Assets/Resources.ko-KR.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.nl-NL.resx b/src/Baballonia/Assets/Resources.nl-NL.resx
index d12f70f0..b5398d47 100644
--- a/src/Baballonia/Assets/Resources.nl-NL.resx
+++ b/src/Baballonia/Assets/Resources.nl-NL.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.pl-PL.resx b/src/Baballonia/Assets/Resources.pl-PL.resx
index c615b2fa..b283676f 100644
--- a/src/Baballonia/Assets/Resources.pl-PL.resx
+++ b/src/Baballonia/Assets/Resources.pl-PL.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.pt-BR.resx b/src/Baballonia/Assets/Resources.pt-BR.resx
index 850ed7c8..35dc982c 100644
--- a/src/Baballonia/Assets/Resources.pt-BR.resx
+++ b/src/Baballonia/Assets/Resources.pt-BR.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.pt-PT.resx b/src/Baballonia/Assets/Resources.pt-PT.resx
index 17fa3154..60f0386c 100644
--- a/src/Baballonia/Assets/Resources.pt-PT.resx
+++ b/src/Baballonia/Assets/Resources.pt-PT.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.resx b/src/Baballonia/Assets/Resources.resx
index 174ac1da..fe3eeec2 100644
--- a/src/Baballonia/Assets/Resources.resx
+++ b/src/Baballonia/Assets/Resources.resx
@@ -726,4 +726,16 @@
If you are using Baballonia with VRCFaceTracking, there is no need to change these ports
+
+ Face Auto-Calibration
+
+
+ Enables automatic face calibration
+
+
+ Eye Calibration
+
+
+ No autocalibration (Eyes are tuned during VR calibrations)
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.ro-RO.resx b/src/Baballonia/Assets/Resources.ro-RO.resx
index bda22288..62c3af89 100644
--- a/src/Baballonia/Assets/Resources.ro-RO.resx
+++ b/src/Baballonia/Assets/Resources.ro-RO.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.ru-RU.resx b/src/Baballonia/Assets/Resources.ru-RU.resx
index c1792e40..f01a6b97 100644
--- a/src/Baballonia/Assets/Resources.ru-RU.resx
+++ b/src/Baballonia/Assets/Resources.ru-RU.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.sv-SE.resx b/src/Baballonia/Assets/Resources.sv-SE.resx
index 45e222a8..4385e580 100644
--- a/src/Baballonia/Assets/Resources.sv-SE.resx
+++ b/src/Baballonia/Assets/Resources.sv-SE.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.tr-TR.resx b/src/Baballonia/Assets/Resources.tr-TR.resx
index 019ffd40..941190fe 100644
--- a/src/Baballonia/Assets/Resources.tr-TR.resx
+++ b/src/Baballonia/Assets/Resources.tr-TR.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.uk-UA.resx b/src/Baballonia/Assets/Resources.uk-UA.resx
index 52d3b1e5..937e9daf 100644
--- a/src/Baballonia/Assets/Resources.uk-UA.resx
+++ b/src/Baballonia/Assets/Resources.uk-UA.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.vi-VN.resx b/src/Baballonia/Assets/Resources.vi-VN.resx
index a93ab205..024296cf 100644
--- a/src/Baballonia/Assets/Resources.vi-VN.resx
+++ b/src/Baballonia/Assets/Resources.vi-VN.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.zh-CN.resx b/src/Baballonia/Assets/Resources.zh-CN.resx
index ee61fac4..f579eca5 100644
--- a/src/Baballonia/Assets/Resources.zh-CN.resx
+++ b/src/Baballonia/Assets/Resources.zh-CN.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Assets/Resources.zh-TW.resx b/src/Baballonia/Assets/Resources.zh-TW.resx
index 70b336a7..c26a1282 100644
--- a/src/Baballonia/Assets/Resources.zh-TW.resx
+++ b/src/Baballonia/Assets/Resources.zh-TW.resx
@@ -721,4 +721,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Baballonia/Contracts/ICalibrationService.cs b/src/Baballonia/Contracts/ICalibrationService.cs
index c30384ef..145f638e 100644
--- a/src/Baballonia/Contracts/ICalibrationService.cs
+++ b/src/Baballonia/Contracts/ICalibrationService.cs
@@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Baballonia.Services.Calibration;
+using Baballonia.Services.Inference.Filters;
namespace Baballonia.Contracts;
@@ -9,6 +10,10 @@ public interface ICalibrationService
CalibrationParameter GetExpressionSettings(string parameterName);
+ AutocalibOptimized? FaceAutocalib { get; set; }
+
+ float ApplyCalibrationSetting(string expression, float value);
+ float[] ApplyFaceCalibration(float[] expression);
float GetExpressionSetting(string expression);
void ResetValues();
void ResetMinimums();
diff --git a/src/Baballonia/Services/CalibrationService.cs b/src/Baballonia/Services/CalibrationService.cs
index a883775e..5ab63369 100644
--- a/src/Baballonia/Services/CalibrationService.cs
+++ b/src/Baballonia/Services/CalibrationService.cs
@@ -1,8 +1,11 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Threading.Tasks;
using Baballonia.Contracts;
+using Baballonia.Helpers;
using Baballonia.Services.Calibration;
+using Baballonia.Services.Inference.Filters;
namespace Baballonia.Services;
@@ -15,12 +18,12 @@ public class CalibrationService : ICalibrationService
{ "LeftEyeY", "/LeftEyeY" },
{ "RightEyeX", "/RightEyeX" },
{ "RightEyeY", "/RightEyeY" },
+ { "LeftEyeLid", "/LeftEyeLid" },
+ { "RightEyeLid", "/RightEyeLid" },
};
private readonly Dictionary _faceExpressionMap = new()
{
- { "LeftEyeLid", "/LeftEyeLid" },
- { "RightEyeLid", "/RightEyeLid" },
{ "CheekPuffLeft", "/cheekPuffLeft" },
{ "CheekPuffRight", "/cheekPuffRight" },
{ "CheekSuckLeft", "/cheekSuckLeft" },
@@ -72,10 +75,12 @@ public class CalibrationService : ICalibrationService
private readonly ILocalSettingsService _localSettingsService;
+ public AutocalibOptimized? FaceAutocalib { get; set; }
+
public CalibrationService(ILocalSettingsService localSettingsService)
{
- _localSettingsService = localSettingsService;
+ _localSettingsService = localSettingsService;
Load();
}
@@ -98,7 +103,7 @@ public void SetExpression(string expression, float value)
var param = new CalibrationParameter(lower, upper, min, max);
_expressionSettings[parameterName] = param;
- SaveAsync();
+ Save();
}
public CalibrationParameter GetExpressionSettings(string parameterName)
@@ -108,6 +113,32 @@ public CalibrationParameter GetExpressionSettings(string parameterName)
new CalibrationParameter();
}
+ public float ApplyCalibrationSetting(string expression, float value)
+ {
+ var settings = GetExpressionSettings(expression);
+ return value.Remap(settings.Lower, settings.Upper, settings.Min, settings.Max);
+ }
+
+ public float[] ApplyFaceCalibration(float[] expression)
+ {
+ Debug.Assert(expression.Length == Utils.FaceRawExpressions);
+
+ if (FaceAutocalib != null)
+ {
+ return FaceAutocalib.Filter(expression);
+ }
+
+ var res = new float[Utils.FaceRawExpressions];
+ var i = 0;
+ foreach (var faceExp in _faceExpressionMap)
+ {
+ res[i] = ApplyCalibrationSetting(faceExp.Value, expression[i]);
+ i++;
+ }
+
+ return res;
+ }
+
public float GetExpressionSetting(string expression)
{
if (!expression.EndsWith("Lower") && !expression.EndsWith("Upper")) return 0;
@@ -123,13 +154,16 @@ public float GetExpressionSetting(string expression)
return isUpper ? currentSettings.Upper : currentSettings.Lower;
}
- private void SaveAsync()
+ private void Save()
{
_localSettingsService.SaveSetting("CalibrationParams", _expressionSettings);
}
private void Load()
{
+ var useAutocalib = _localSettingsService.ReadSetting("AppSettings_UseAutocalib", false);
+ FaceAutocalib = useAutocalib ? new AutocalibOptimized(Utils.FaceRawExpressions) : null;
+
var parameters = _localSettingsService.ReadSetting?>("CalibrationParams");
_expressionSettings.Clear();
if (parameters == null)
@@ -159,6 +193,8 @@ private void Load()
_expressionSettings[parameterName] = param ?? new CalibrationParameter(0f, 1f, 0f, 1f);
}
}
+
+
}
public void ResetValues()
@@ -168,7 +204,7 @@ public void ResetValues()
parameter.Lower = parameter.Min;
parameter.Upper = parameter.Max;
}
- SaveAsync();
+ Save();
}
public void ResetMinimums()
@@ -177,7 +213,7 @@ public void ResetMinimums()
{
parameter.Lower = parameter.Min;
}
- SaveAsync();
+ Save();
}
public void ResetMaximums()
@@ -186,6 +222,6 @@ public void ResetMaximums()
{
parameter.Upper = parameter.Max;
}
- SaveAsync();
+ Save();
}
}
diff --git a/src/Baballonia/Services/Inference/FaceProcessingPipeline.cs b/src/Baballonia/Services/Inference/FaceProcessingPipeline.cs
index bb195bf0..410482c6 100644
--- a/src/Baballonia/Services/Inference/FaceProcessingPipeline.cs
+++ b/src/Baballonia/Services/Inference/FaceProcessingPipeline.cs
@@ -2,23 +2,23 @@
using Baballonia.Contracts;
using Baballonia.Services.Inference.Enums;
using OpenCvSharp;
+using SoundFlow.Components;
namespace Baballonia.Services.Inference;
public class FaceProcessingPipeline : DefaultProcessingPipeline
{
-
- public float[]? RunUpdate()
+ public float[]? RunUpdate()
{
var frame = VideoSource?.GetFrame(ColorType.Gray8);
- if(frame == null)
+ if (frame == null)
return null;
InvokeNewFrameEvent(frame);
var transformed = ImageTransformer?.Apply(frame);
- if(transformed == null)
+ if (transformed == null)
return null;
InvokeTransformedFrameEvent(transformed);
@@ -31,15 +31,14 @@ public class FaceProcessingPipeline : DefaultProcessingPipeline
transformed.Dispose();
var inferenceResult = InferenceService?.Run();
- if(inferenceResult == null)
+ if (inferenceResult == null)
return null;
- if(Filter != null)
+ if (Filter != null)
inferenceResult = Filter.Filter(inferenceResult);
InvokeFilteredResultEvent(inferenceResult);
-
return inferenceResult;
}
}
diff --git a/src/Baballonia/Services/Inference/Filters/AutocalibOptimized.cs b/src/Baballonia/Services/Inference/Filters/AutocalibOptimized.cs
new file mode 100644
index 00000000..a5fbb57b
--- /dev/null
+++ b/src/Baballonia/Services/Inference/Filters/AutocalibOptimized.cs
@@ -0,0 +1,203 @@
+using System;
+
+namespace Baballonia.Services.Inference.Filters;
+
+public class AutocalibOptimized : IFilter
+{
+ private int _expressionCount;
+
+ private float _alpha;
+ private float _beta;
+ private float _multiplier;
+ private bool _isInitialized;
+
+ private readonly float[] _neutralMask;
+ private readonly float[] _activeMask;
+ private readonly float[] _minDiff;
+ private readonly float[] _maxDiff;
+ private readonly float[] _diff;
+ private readonly float[] _std;
+ private readonly float[] _min;
+ private readonly float[] _max;
+ private readonly float[] _mean;
+ private readonly float[] _variance;
+ private readonly float[] _threshold;
+ private float _sampleCount;
+ private float[] _sampleCounts;
+ private bool[] _calibratedFlags;
+ private int _warmupFrames;
+ private float _adaptationRate;
+ private float _minAdaptationRate;
+ private float _adaptationDecay;
+ private float _hysteresisThreshold;
+ private int[] _decayCounters;
+ private int _daceyThreshold;
+ private float[] _decayLevels;
+
+ public AutocalibOptimized(int expressionCount, float alpha = 0.1f, float beta = 0.1f,
+ float thresholdMultiplier = 2.0f)
+ {
+ _expressionCount = expressionCount;
+ _alpha = alpha;
+ _beta = beta;
+ _multiplier = thresholdMultiplier;
+ _isInitialized = false;
+
+ _neutralMask = InitAndFill(expressionCount);
+
+ _neutralMask = InitAndFill(expressionCount);
+ _activeMask = InitAndFill(expressionCount);
+ _minDiff = InitAndFill(expressionCount);
+ _maxDiff = InitAndFill(expressionCount);
+ _diff = InitAndFill(expressionCount);
+ _std = InitAndFill(expressionCount);
+
+ _min = InitAndFill(expressionCount, float.PositiveInfinity);
+ _max = InitAndFill(expressionCount, float.NegativeInfinity);
+
+ _mean = InitAndFill(expressionCount);
+ _variance = InitAndFill(expressionCount);
+ _threshold = InitAndFill(expressionCount);
+ _sampleCounts = InitAndFill(expressionCount);
+ _calibratedFlags = InitAndFill(expressionCount);
+ _decayCounters = InitAndFill(expressionCount);
+ _decayLevels = InitAndFill(expressionCount);
+
+ _sampleCount = 0f;
+ _warmupFrames = 300;
+
+ _adaptationRate = 1f;
+ _minAdaptationRate = 0.01f;
+ _adaptationDecay = 0.99998f;
+ _hysteresisThreshold = 0.05f;
+ }
+
+ public float[] Filter(float[] input)
+ {
+ var (minVals, maxVals, calibratedFlags) = Update(input);
+
+ // Reuse buffer for denominator & calibrated
+ var calibrated = new float[_expressionCount];
+ for (var i = 0; i < _expressionCount; i++)
+ {
+ var denom = maxVals[i] - minVals[i];
+ if (denom == 0) denom = float.MinValue; // avoid divide by zero
+
+ if (!calibratedFlags[i]) continue;
+
+ calibrated[i] = (input[i] - minVals[i]) / denom;
+ calibrated[i] = Math.Min(Math.Max(calibrated[i], 0f), 1f);
+ }
+ return calibrated;
+ }
+
+ private T[] InitAndFill(int count, T defaultValue = default!)
+ {
+ var result = new T[count];
+ Array.Fill(result, defaultValue);
+ return result;
+ }
+
+ private (float[] minVals, float[] maxVals, bool[] calibratedFlags) Update(float[] input)
+ {
+ if (input.Length != _expressionCount)
+ throw new ArgumentException(
+ $@"Input length mismatch. Expected: {_expressionCount}, got: {input.Length}",
+ nameof(input));
+
+ if (_sampleCount > 0)
+ _adaptationRate = Math.Max(_minAdaptationRate, _adaptationRate * _adaptationDecay);
+
+ if (!_isInitialized)
+ {
+ input.CopyTo(_min, 0);
+ input.CopyTo(_max, 0);
+
+ for (var i = 0; i < _expressionCount; i++)
+ _mean[i] = _alpha * input[i] + (1 - _alpha) * _mean[i];
+
+ _sampleCount++;
+ _isInitialized = true;
+ return (_min, _max, _calibratedFlags);
+ }
+
+ const float neutralThreshold = 0.15f;
+ var neutralCount = 0;
+ for (var i = 0; i < _expressionCount; i++)
+ {
+ var neutral = Math.Abs(input[i]) < neutralThreshold;
+ if (neutral) neutralCount++;
+ _neutralMask[i] = neutral ? 1f : 0f;
+ _activeMask[i] = neutral ? 0f : 1f;
+
+ _minDiff[i] = _min[i] - input[i];
+ _maxDiff[i] = input[i] - _max[i];
+ }
+
+ var isNeutralPose = neutralCount >= (int)(0.8f * _expressionCount);
+
+ if (isNeutralPose)
+ {
+ for (var i = 0; i < _expressionCount; i++)
+ {
+ if (_minDiff[i] > _hysteresisThreshold && _neutralMask[i] > 0)
+ _min[i] = _adaptationRate * input[i] + (1 - _adaptationRate) * _min[i];
+
+ if (_neutralMask[i] > 0)
+ _mean[i] = _alpha * input[i] + (1 - _alpha) * _mean[i];
+ }
+ }
+
+ for (var i = 0; i < _expressionCount; i++)
+ {
+ if (_maxDiff[i] > _hysteresisThreshold && _activeMask[i] > 0)
+ _max[i] = ((_decayLevels[i] > 0.1f) ? 0.5f : _adaptationRate) * input[i]
+ + (1 - ((_decayLevels[i] > 0.1f) ? 0.5f : _adaptationRate)) * _max[i];
+
+ if (input[i] < _max[i] * 0.9f)
+ _decayCounters[i]++;
+
+ if (_decayCounters[i] > _daceyThreshold)
+ {
+ _decayLevels[i] += 0.01f;
+ _max[i] *= 0.999f;
+ }
+ else
+ {
+ _decayCounters[i] = 0;
+ _decayLevels[i] *= 0.95f;
+ }
+
+ if (!(_min[i] > _max[i])) continue;
+
+ var avg = (_min[i] + _max[i]) / 2f;
+ _min[i] = avg;
+ _max[i] = avg;
+ }
+
+ for (var i = 0; i < _expressionCount; i++)
+ {
+ _diff[i] = input[i] - _mean[i];
+ _variance[i] = _beta * (_diff[i] * _diff[i]) + (1 - _beta) * _variance[i];
+
+ _std[i] = (float)Math.Sqrt(_variance[i]) + 1e-6f;
+ _threshold[i] = _multiplier * _std[i];
+
+ _sampleCounts[i]++;
+ }
+
+ for (var i = 0; i < _expressionCount; i++)
+ {
+ if (!_calibratedFlags[i] &&
+ (_max[i] - _min[i] > 1e-3f) &&
+ (_sampleCounts[i] >= 300) &&
+ (_variance[i] > 1e-4f))
+ {
+ _calibratedFlags[i] = true;
+ }
+ }
+
+ _sampleCount++;
+ return (_min, _max, _calibratedFlags);
+ }
+}
diff --git a/src/Baballonia/Services/Inference/Filters/TimeBasedFloorNormalizationFilter.cs b/src/Baballonia/Services/Inference/Filters/TimeBasedFloorNormalizationFilter.cs
new file mode 100644
index 00000000..71668e38
--- /dev/null
+++ b/src/Baballonia/Services/Inference/Filters/TimeBasedFloorNormalizationFilter.cs
@@ -0,0 +1,77 @@
+using System;
+
+namespace Baballonia.Services.Inference.Filters;
+
+public class TimeBasedFloorNormalizationFilter : IFilter
+{
+ private readonly float _targetFloor;
+
+ private readonly float _floorStep;
+ private float[] _minVal;
+ private float[] _maxVal;
+ private readonly float[] _floor;
+ private readonly int _count;
+
+ private readonly float[] _rawNorm;
+ private readonly bool[] _newMin;
+
+ public TimeBasedFloorNormalizationFilter(int count = Utils.FaceRawExpressions, float inputFrequency = 60f, float decayMinutes = 50f, float targetFloor = 0.5f)
+ {
+ _targetFloor = targetFloor;
+ _count = count;
+
+ var steps = Math.Max(1, inputFrequency * decayMinutes * 60);
+ _floorStep = targetFloor / steps;
+
+ _minVal = InitAndFill(count, float.NaN);
+ _maxVal = InitAndFill(count, float.NaN);
+ _maxVal = InitAndFill(count);
+ _rawNorm = InitAndFill(count);
+ _newMin = InitAndFill(count);
+ }
+
+ private T[] InitAndFill(int count, T defaultValue = default!)
+ {
+ var result = new T[count];
+ Array.Fill(result, defaultValue);
+ return result;
+ }
+
+ public float[] Filter(float[] input)
+ {
+ if (float.IsNaN(_minVal[0]))
+ {
+ _minVal = input;
+ _maxVal = input;
+ }
+
+ var normalized = new float[_count];
+ for (var i = 0; i < _count; i++)
+ {
+ if (input[i] > _maxVal[i])
+ _maxVal[i] = input[i];
+
+ _newMin[i] = input[i] < _minVal[i];
+ if (_newMin[i])
+ {
+ _minVal[i] = input[i];
+ _floor[i] = 0f;
+ }
+
+ if (Math.Abs(_maxVal[i] - _minVal[i]) < 0.001)
+ _rawNorm[i] = 0.5f;
+ else
+ {
+ _rawNorm[i] = (input[i] - _minVal[i]) / (_maxVal[i] - _minVal[i]);
+ _rawNorm[i] = Math.Max(0f, Math.Min(1f, _rawNorm[i]));
+ }
+
+ if (!_newMin[i] && _floor[i] < _targetFloor)
+ _floor[i] = Math.Min(_targetFloor, _floor[i] + _floorStep);
+
+ normalized[i] = _floor[i] + (1f - _floor[i]);
+ }
+
+ return normalized;
+ }
+}
diff --git a/src/Baballonia/Services/ParameterSenderService.cs b/src/Baballonia/Services/ParameterSenderService.cs
index 60e77320..63a85746 100644
--- a/src/Baballonia/Services/ParameterSenderService.cs
+++ b/src/Baballonia/Services/ParameterSenderService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -177,20 +178,17 @@ private void ProcessNativeVrcEyeTracking(float[] expressions)
private void ProcessFaceExpressionData(float[] expressions)
{
- if (expressions == null) return;
- if (expressions.Length == 0) return;
+ Debug.Assert(expressions != null);
+ Debug.Assert(expressions.Length == Utils.FaceRawExpressions);
+
+ var calibrated = calibrationService.ApplyFaceCalibration(expressions);
- for (int i = 0; i < Math.Min(expressions.Length, FaceExpressionMap.Count); i++)
+ for (int i = 0; i < Utils.FaceRawExpressions; i++)
{
- var weight = expressions[i];
+ var weight = calibrated[i];
var faceElement = FaceExpressionMap.ElementAt(i);
- var settings = calibrationService.GetExpressionSettings(faceElement.Key);
- var msg = new OscMessage(prefix + faceElement.Value,
- Math.Clamp(
- weight.Remap(settings.Lower, settings.Upper, settings.Min, settings.Max),
- settings.Min,
- settings.Max));
+ var msg = new OscMessage(prefix + faceElement.Value, weight);
_sendQueue.Enqueue(msg);
}
}
diff --git a/src/Baballonia/Themes/Fluent/Controls/RangeSlider.axaml b/src/Baballonia/Themes/Fluent/Controls/RangeSlider.axaml
index 68b2af0d..e4ab9500 100644
--- a/src/Baballonia/Themes/Fluent/Controls/RangeSlider.axaml
+++ b/src/Baballonia/Themes/Fluent/Controls/RangeSlider.axaml
@@ -94,6 +94,12 @@
+
+
+
diff --git a/src/Baballonia/ViewModels/SplitViewPane/CalibrationViewModel.cs b/src/Baballonia/ViewModels/SplitViewPane/CalibrationViewModel.cs
index 884af50d..bb0ebcf1 100644
--- a/src/Baballonia/ViewModels/SplitViewPane/CalibrationViewModel.cs
+++ b/src/Baballonia/ViewModels/SplitViewPane/CalibrationViewModel.cs
@@ -10,6 +10,7 @@
using Avalonia.Threading;
using Baballonia.Helpers;
using Baballonia.Services;
+using Baballonia.Services.Inference.Filters;
using CommunityToolkit.Mvvm.Input;
namespace Baballonia.ViewModels.SplitViewPane;
@@ -27,6 +28,9 @@ public partial class CalibrationViewModel : ViewModelBase, IDisposable
[property: SavedSetting("AppSettings_StabilizeEyes", false)]
private bool _stabilizeEyes;
+ [property: SavedSetting("AppSettings_UseAutocalib", false)]
+ [ObservableProperty] private bool _useAutocalib;
+
private ILocalSettingsService _settingsService { get; }
private readonly ICalibrationService _calibrationService;
private readonly ParameterSenderService _parameterSenderService;
@@ -159,17 +163,31 @@ public CalibrationViewModel()
};
}
+ partial void OnUseAutocalibChanged(bool value)
+ {
+ var prev = _settingsService.ReadSetting("AppSettings_UseAutocalib", true);
+ if (prev == value)
+ return;
+
+ _settingsService.SaveSetting("AppSettings_UseAutocalib", UseAutocalib);
+ _calibrationService.FaceAutocalib = value ? new AutocalibOptimized(Utils.FaceRawExpressions) : null;
+ }
+
private void ExpressionUpdateHandler(ProcessingLoopService.Expressions expressions)
{
- if(expressions.FaceExpression != null)
+ if (expressions.FaceExpression != null)
+ {
Dispatcher.UIThread.Post(() =>
{
- ApplyCurrentFaceExpressionValues(expressions.FaceExpression, CheekSettings);
- ApplyCurrentFaceExpressionValues(expressions.FaceExpression, MouthSettings);
- ApplyCurrentFaceExpressionValues(expressions.FaceExpression, JawSettings);
- ApplyCurrentFaceExpressionValues(expressions.FaceExpression, NoseSettings);
- ApplyCurrentFaceExpressionValues(expressions.FaceExpression, TongueSettings);
+ var expr = _calibrationService.ApplyFaceCalibration(expressions.FaceExpression);
+ ApplyCurrentFaceExpressionValues(expr, CheekSettings);
+ ApplyCurrentFaceExpressionValues(expr, MouthSettings);
+ ApplyCurrentFaceExpressionValues(expr, JawSettings);
+ ApplyCurrentFaceExpressionValues(expr, NoseSettings);
+ ApplyCurrentFaceExpressionValues(expr, TongueSettings);
});
+ }
+
if(expressions.EyeExpression != null)
Dispatcher.UIThread.Post(() =>
{
@@ -261,8 +279,10 @@ private void LoadInitialSettings(IEnumerable settings)
}
}
+
+
public void Dispose()
{
- // _processingLoopService.ExpressionUpdateEvent -= ExpressionUpdateHandler;
+ _processingLoopService.ExpressionChangeEvent -= ExpressionUpdateHandler;
}
}
diff --git a/src/Baballonia/Views/CalibrationView.axaml b/src/Baballonia/Views/CalibrationView.axaml
index 9afb6977..941cb8bd 100644
--- a/src/Baballonia/Views/CalibrationView.axaml
+++ b/src/Baballonia/Views/CalibrationView.axaml
@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:controls="clr-namespace:Baballonia.Controls"
xmlns:splitViewPane="clr-namespace:Baballonia.ViewModels.SplitViewPane"
xmlns:models="clr-namespace:Baballonia.Models"
xmlns:twoRangeSlider="clr-namespace:Baballonia.Controls"
@@ -15,294 +16,306 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+ IsEnabled="{Binding !UseAutocalib}"
+ x:Name="ResetMobileStackPanel"
+ Margin="0 12"
+ Orientation="Vertical">
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+