Skip to content

Commit 44f7722

Browse files
committed
Merge branch 'dev' into main
2 parents 5039e29 + 033950e commit 44f7722

File tree

10 files changed

+138
-101
lines changed

10 files changed

+138
-101
lines changed

VRCOSC.Game/Graphics/ModuleRun/TerminalContainer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public sealed partial class TerminalContainer : Container<TerminalEntry>
1717

1818
protected override FillFlowContainer<TerminalEntry> Content { get; }
1919

20-
private readonly DrawablePool<TerminalEntry> terminalEntryPool = new(50);
20+
private readonly DrawablePool<TerminalEntry> terminalEntryPool = new(75);
2121

2222
public TerminalContainer()
2323
{

VRCOSC.Game/Modules/Avatar/AvatarConfigLoader.cs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.IO;
66
using System.Linq;
77
using Newtonsoft.Json;
8+
using osu.Framework.Logging;
89

910
namespace VRCOSC.Game.Modules.Avatar;
1011

@@ -14,17 +15,59 @@ public static class AvatarConfigLoader
1415

1516
public static AvatarConfig? LoadConfigFor(string avatarId)
1617
{
17-
var oscFolder = Directory.GetDirectories(Directory.GetDirectories(vr_chat_osc_folder_path).First()).First();
18-
var avatarFiles = Directory.GetFiles(oscFolder);
18+
Logger.Log($"Attempting to load avatar {avatarId}...");
1919

20-
if (!avatarFiles.Any()) return null;
20+
if (!Directory.Exists(vr_chat_osc_folder_path))
21+
{
22+
Logger.Log("OSC folder unavailable");
23+
return null;
24+
}
2125

22-
var avatarIdFiles = avatarFiles.Where(filePath => filePath.Contains(avatarId)).ToList();
26+
Logger.Log("OSC folder exists...");
27+
var oscFolderContents = Directory.GetDirectories(vr_chat_osc_folder_path);
2328

24-
if (!avatarIdFiles.Any()) return null;
29+
if (!oscFolderContents.Any())
30+
{
31+
Logger.Log("User folder unavailable");
32+
return null;
33+
}
2534

35+
Logger.Log("User folder exists...");
36+
var userFolder = oscFolderContents.First();
37+
38+
var avatarFolderPath = Path.Combine(userFolder, "Avatars");
39+
40+
if (!Directory.Exists(avatarFolderPath))
41+
{
42+
Logger.Log("Avatars folder unavailable");
43+
return null;
44+
}
45+
46+
Logger.Log("Avatars folder exists...");
47+
var avatarFiles = Directory.GetFiles(avatarFolderPath);
48+
49+
if (!avatarFiles.Any())
50+
{
51+
Logger.Log("No configs present");
52+
return null;
53+
}
54+
55+
Logger.Log($"Found {avatarFiles.Length} total configs");
56+
var avatarIdFiles = avatarFiles.Where(filePath => filePath.Contains(avatarId)).ToArray();
57+
58+
if (!avatarIdFiles.Any())
59+
{
60+
Logger.Log("No config available for specified Id");
61+
return null;
62+
}
63+
64+
Logger.Log($"Final matching config count: {avatarIdFiles.Length}");
2665
var avatarFile = avatarIdFiles.First();
27-
var avatarConfigRaw = File.ReadAllText(avatarFile);
28-
return JsonConvert.DeserializeObject<AvatarConfig>(avatarConfigRaw);
66+
67+
Logger.Log($"Attempting to load avatar config named: {avatarFile}");
68+
var data = JsonConvert.DeserializeObject<AvatarConfig>(File.ReadAllText(avatarFile));
69+
70+
if (data is not null) Logger.Log($"Successfully loaded config for avatar {data.Name} containing {data.Parameters.Count} parameters");
71+
return data;
2972
}
3073
}

VRCOSC.Game/Modules/GameManager.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using Valve.VR;
1616
using VRCOSC.Game.Config;
1717
using VRCOSC.Game.Graphics.Notifications;
18+
using VRCOSC.Game.Modules.Avatar;
1819
using VRCOSC.Game.OpenVR;
1920
using VRCOSC.Game.OpenVR.Metadata;
2021
using VRCOSC.Game.OSC;
@@ -56,6 +57,7 @@ public partial class GameManager : CompositeComponent
5657
public Player Player = null!;
5758
public OVRClient OVRClient = null!;
5859
public ChatBoxInterface ChatBoxInterface = null!;
60+
public AvatarConfig? AvatarConfig;
5961

6062
[BackgroundDependencyLoader]
6163
private void load(Storage storage)
@@ -116,32 +118,35 @@ protected override void LoadComplete()
116118
};
117119
}
118120

121+
private const string avatar_id_format = "avtr_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
122+
119123
private void handleOscDataCache()
120124
{
121125
lock (oscDataCacheLock)
122126
{
123127
oscDataCache.ForEach(data =>
124128
{
125-
ModuleManager.OnParameterReceived(data);
126-
127129
if (data.IsAvatarChangeEvent)
128130
{
131+
var avatarId = ((string)data.ParameterValue)[..avatar_id_format.Length];
132+
AvatarConfig = AvatarConfigLoader.LoadConfigFor(avatarId);
133+
129134
sendControlValues();
130-
return;
131135
}
132-
133-
if (!data.IsAvatarParameter) return;
134-
135-
Player.Update(data.ParameterName, data.Values[0]);
136-
137-
switch (data.ParameterName)
136+
else
138137
{
139-
case @"VRCOSC/Controls/ChatBox":
140-
ChatBoxInterface.SendEnabled = (bool)data.Values[0];
141-
break;
138+
Player.Update(data.ParameterName, data.ParameterValue);
139+
140+
switch (data.ParameterName)
141+
{
142+
case @"VRCOSC/Controls/ChatBox":
143+
ChatBoxInterface.SendEnabled = (bool)data.ParameterValue;
144+
break;
145+
}
142146
}
143-
});
144147

148+
ModuleManager.OnParameterReceived(data);
149+
});
145150
oscDataCache.Clear();
146151
}
147152
}
@@ -164,6 +169,8 @@ private async Task startAsync()
164169
oscDataCache.Clear();
165170
}
166171

172+
AvatarConfig = null;
173+
167174
if (!initialiseOscClient())
168175
{
169176
hasAutoStarted = false;

VRCOSC.Game/Modules/Module.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public abstract partial class Module : Component, IComparable<Module>
3939
protected ChatBoxInterface ChatBoxInterface => GameManager.ChatBoxInterface;
4040
protected Bindable<ModuleState> State = new(ModuleState.Stopped);
4141
protected IVRCOSCSecrets Secrets => secrets;
42-
protected AvatarConfig? AvatarConfig;
42+
protected AvatarConfig? AvatarConfig => GameManager.AvatarConfig;
4343

4444
internal readonly BindableBool Enabled = new();
4545
internal readonly Dictionary<string, ModuleAttribute> Settings = new();
@@ -221,17 +221,13 @@ protected void SendParameter<T>(Enum lookup, T value, string suffix = "") where
221221
OscClient.SendValue(data.FormattedAddress + suffix, value);
222222
}
223223

224-
private const string avatarIdFormat = "avtr_XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
225-
226224
internal void OnParameterReceived(VRChatOscData data)
227225
{
228226
if (!IsEnabled) return;
229227
if (!HasStarted) return;
230228

231229
if (data.IsAvatarChangeEvent)
232230
{
233-
var avatarId = ((string)data.ParameterValue)[..avatarIdFormat.Length];
234-
AvatarConfig = AvatarConfigLoader.LoadConfigFor(avatarId);
235231
OnAvatarChange();
236232
return;
237233
}

VRCOSC.Game/Modules/SRanipalAPIInterface.cs

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ public class SRanipalAPIInterface
1212
public LipDataV2 LipData;
1313
public EyeDataV2 EyeData;
1414

15-
private bool eyeAvailable => EyeStatus.Value != Error.UNDEFINED;
16-
private bool lipAvailable => LipStatus.Value != Error.UNDEFINED;
15+
private bool eyeAvailable => EyeStatus.Value == Error.WORK;
16+
private bool lipAvailable => LipStatus.Value == Error.WORK;
1717

1818
public void Initialise(bool eye, bool lip)
1919
{
@@ -26,26 +26,16 @@ public void Initialise(bool eye, bool lip)
2626

2727
public void Release()
2828
{
29-
if (eyeAvailable) SRanipalAPI.Release(2);
30-
if (lipAvailable) SRanipalAPI.Release(3);
29+
SRanipalAPI.Release(2);
30+
SRanipalAPI.Release(3);
3131

3232
EyeStatus.SetDefault();
3333
LipStatus.SetDefault();
3434
}
3535

3636
public void Update()
3737
{
38-
if (eyeAvailable) updateEye();
39-
if (lipAvailable) updateLip();
40-
}
41-
42-
private void updateEye()
43-
{
44-
SRanipalAPI.GetEyeData(ref EyeData);
45-
}
46-
47-
private void updateLip()
48-
{
49-
SRanipalAPI.GetLipData(ref LipData);
38+
if (eyeAvailable) SRanipalAPI.GetEyeData(ref EyeData);
39+
if (lipAvailable) SRanipalAPI.GetLipData(ref LipData);
5040
}
5141
}

VRCOSC.Game/Providers/Hardware/HardwareStatsProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ private static void handleCPU(CPU cpu, ISensor sensor)
122122
// AMD
123123
case @"Core (Tctl/Tdie)":
124124
case @"Core (Tctl)":
125+
case @"CPU Cores":
125126
// Intel
126127
case @"CPU Package":
127128
cpu.Temperature = (int?)sensor.Value ?? 0;

VRCOSC.Modules/FaceTracking/Interface/Eyes/Eye.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ public void Initialise()
2222

2323
public void Update(SingleEyeData eyeData, SingleEyeExpression? expression = null)
2424
{
25-
if (eyeData.GetValidity(SingleEyeDataValidity.SINGLE_EYE_DATA_GAZE_DIRECTION_VALIDITY))
26-
Look = eyeData.gaze_direction_normalized.Invert().ToVec2();
27-
25+
Look = eyeData.GetValidity(SingleEyeDataValidity.SINGLE_EYE_DATA_GAZE_DIRECTION_VALIDITY) ? eyeData.gaze_direction_normalized.Invert().ToVec2() : new Vector2();
2826
Openness = eyeData.eye_openness;
2927

3028
if (expression is null) return;

VRCOSC.Modules/FaceTracking/Interface/Eyes/EyeTrackingData.cs

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,27 @@ public class EyeTrackingData
1616

1717
private float maxDilation;
1818
private float minDilation;
19+
private float rawDilation;
1920

2021
public void Initialise()
2122
{
2223
Left.Initialise();
2324
Right.Initialise();
25+
Combined.Initialise();
2426

2527
EyesDilation = 0f;
2628
EyesPupilDiameter = 0f;
2729

28-
maxDilation = float.MaxValue;
29-
minDilation = 0f;
30+
maxDilation = 0f;
31+
minDilation = float.MaxValue;
3032
}
3133

3234
public void Update(EyeDataV2 eyeData)
3335
{
34-
var dilation = 0f;
35-
36-
if (eyeData.verbose_data.right.GetValidity(SingleEyeDataValidity.SINGLE_EYE_DATA_PUPIL_DIAMETER_VALIDITY))
37-
{
38-
dilation = eyeData.verbose_data.right.pupil_diameter_mm;
39-
updateMinMaxDilation(eyeData.verbose_data.right.pupil_diameter_mm);
40-
}
41-
else if (eyeData.verbose_data.left.GetValidity(SingleEyeDataValidity.SINGLE_EYE_DATA_PUPIL_DIAMETER_VALIDITY))
42-
{
43-
dilation = eyeData.verbose_data.left.pupil_diameter_mm;
44-
updateMinMaxDilation(eyeData.verbose_data.left.pupil_diameter_mm);
45-
}
36+
rawDilation = 0f;
37+
38+
updatePupil(eyeData.verbose_data.left);
39+
updatePupil(eyeData.verbose_data.right);
4640

4741
Left.Update(eyeData.verbose_data.left, eyeData.expression_data.left);
4842
Right.Update(eyeData.verbose_data.right, eyeData.expression_data.right);
@@ -51,18 +45,18 @@ public void Update(EyeDataV2 eyeData)
5145
Combined.Widen = (Left.Widen + Right.Widen) / 2f;
5246
Combined.Squeeze = (Left.Squeeze + Right.Squeeze) / 2f;
5347

54-
if (dilation == 0) return;
48+
if (rawDilation == 0) return;
5549

56-
EyesDilation = (dilation - minDilation) / (maxDilation - minDilation);
57-
EyesPupilDiameter = dilation > 10f ? 1f : dilation / 10f;
50+
EyesDilation = (rawDilation - minDilation) / (maxDilation - minDilation);
51+
EyesPupilDiameter = rawDilation > 10f ? 1f : rawDilation / 10f;
5852
}
5953

60-
private void updateMinMaxDilation(float readDilation)
54+
private void updatePupil(SingleEyeData data)
6155
{
62-
if (readDilation > maxDilation)
63-
maxDilation = readDilation;
56+
if (!data.GetValidity(SingleEyeDataValidity.SINGLE_EYE_DATA_PUPIL_DIAMETER_VALIDITY)) return;
6457

65-
if (readDilation < minDilation)
66-
minDilation = readDilation;
58+
rawDilation = data.pupil_diameter_mm;
59+
maxDilation = Math.Max(maxDilation, rawDilation);
60+
minDilation = Math.Min(minDilation, rawDilation);
6761
}
6862
}

VRCOSC.Modules/FaceTracking/Interface/SRanipalInterface.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) VolcanicArts. Licensed under the GPL-3.0 License.
22
// See the LICENSE file in the repository root for full license text.
33

4+
using SRanipalLib;
45
using VRCOSC.Game.Modules;
56
using VRCOSC.Modules.FaceTracking.Interface.Eyes;
67
using VRCOSC.Modules.FaceTracking.Interface.Lips;
@@ -13,6 +14,9 @@ public class SRanipalInterface
1314
public readonly EyeTrackingData EyeData = new();
1415
public readonly LipTrackingData LipData = new();
1516

17+
public bool EyeAvailable => APIInterface.EyeStatus.Value == Error.WORK;
18+
public bool LipAvailable => APIInterface.LipStatus.Value == Error.WORK;
19+
1620
public void Initialise(bool eye, bool lip)
1721
{
1822
APIInterface.Initialise(eye, lip);
@@ -23,8 +27,8 @@ public void Initialise(bool eye, bool lip)
2327
public void Update()
2428
{
2529
APIInterface.Update();
26-
EyeData.Update(APIInterface.EyeData);
27-
LipData.Update(APIInterface.LipData);
30+
if (EyeAvailable) EyeData.Update(APIInterface.EyeData);
31+
if (LipAvailable) LipData.Update(APIInterface.LipData);
2832
}
2933

3034
public void Release()

0 commit comments

Comments
 (0)