Skip to content

Commit b4bafd6

Browse files
committed
- Changed way expressions are handled
- Added configuration json file - Updated documentation
1 parent 23f61e5 commit b4bafd6

File tree

6 files changed

+287
-40
lines changed

6 files changed

+287
-40
lines changed

BFI_VRCFT_Module/BFI_VRCFT_Module.cs

Lines changed: 127 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
namespace BFI_VRCFT_Module
22
{
33
using Microsoft.Extensions.Logging;
4+
using System.Text.Json;
5+
using System.Text.Json.Serialization;
46
using VRCFaceTracking;
57
using VRCFaceTracking.Core.Library;
68
using VRCFaceTracking.Core.Params.Data;
@@ -9,16 +11,27 @@
911

1012
public class BFI_VRCFT_Module : ExtTrackingModule
1113
{
12-
public static bool debug = true;
14+
15+
private static string tagEyeClosed = "eyeclosed";
16+
private static string tagSmile = "smile";
17+
private static string tagFrown = "frown";
18+
private static string tagAnger = "anger";
19+
private static string tagCringe = "cringe";
20+
private static string tagCheekPuff = "cheekpuff";
21+
private static string tagApeShape = "apeshape";
22+
23+
public static bool debug = false;
1324
OscReceiver reciever = new OscReceiver(8999);
1425

1526
UnifiedExpressionShape frown = new UnifiedExpressionShape();
1627
UnifiedExpressionShape mouthUpperUp = new UnifiedExpressionShape();
1728
UnifiedExpressionShape mouthLowerDown = new UnifiedExpressionShape();
1829
UnifiedExpressionShape MouthStretch = new UnifiedExpressionShape();
30+
UnifiedExpressionShape browDown = new UnifiedExpressionShape();
31+
UnifiedExpressionShape cheekPuff = new UnifiedExpressionShape();
32+
UnifiedExpressionShape apeShape = new UnifiedExpressionShape();
1933

2034

21-
UnifiedExpressionShape browDown = new UnifiedExpressionShape();
2235
// What your interface is able to send as tracking data.
2336
public override (bool SupportsEye, bool SupportsExpression) Supported => (true, true);
2437

@@ -40,7 +53,38 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
4053
ModuleInformation.StaticImages = stream != null ? new List<Stream> { stream } : ModuleInformation.StaticImages;
4154
if (debug) Logger.LogInformation("is stream to picture null: " + (stream == null).ToString());
4255
//... Initializing module. Modify state tuple as needed (or use bool contexts to determine what should be initialized).
56+
57+
58+
//parsing json file for expressions
59+
try
60+
{
61+
62+
JsonParser parser = new JsonParser();
63+
SupportedExpressions expressions = parser.ParseJson();
64+
reciever.expressions = expressions;
65+
if (expressions != null && expressions.Expressions != null)
66+
{
67+
if (expressions.Expressions != null)
68+
{
69+
foreach (var expression in expressions.Expressions)
70+
{
71+
Logger.LogInformation($"Expression: {expression.Key}, Id: {expression.Value.Id}, Weight: {expression.Value.Weight}");
72+
}
73+
}
74+
}
75+
else
76+
{
77+
Logger.LogInformation($"No expressions found in the JSON file");
78+
}
79+
}
80+
catch (Exception ex)
81+
{
82+
Logger.LogInformation($"Error parsing JSON file: {ex.Message}");
83+
return (false, false);
84+
}
4385
return state;
86+
87+
4488
}
4589

4690
// Polls data from the tracking interface.
@@ -57,7 +101,8 @@ public override void Update()
57101

58102
if (debug) Logger.LogInformation(reciever.OSCDebugData);
59103

60-
UpdateValues();
104+
//UpdateValues();
105+
UpdateValuesExpressions();
61106

62107
if (reciever.EvaluateTimout())
63108
{
@@ -72,8 +117,19 @@ public override void Update()
72117
UnifiedTracking.Data.Eye.Left.Gaze = new Vector2(0, 0);
73118
UnifiedTracking.Data.Eye.Right.Gaze = new Vector2(0, 0);
74119

75-
UnifiedTracking.Data.Eye.Left.Openness = 1 - reciever.eyeClosed;
76-
UnifiedTracking.Data.Eye.Right.Openness = 1 - reciever.eyeClosed;
120+
if (reciever.expressions.Expressions.ContainsKey(tagEyeClosed))
121+
{
122+
123+
UnifiedTracking.Data.Eye.Left.Openness = 1 - reciever.expressions.Expressions[tagEyeClosed].Weight;
124+
UnifiedTracking.Data.Eye.Right.Openness = 1 - reciever.expressions.Expressions[tagEyeClosed].Weight;
125+
126+
}
127+
else
128+
{
129+
130+
UnifiedTracking.Data.Eye.Left.Openness = 1f;
131+
UnifiedTracking.Data.Eye.Right.Openness = 1f;
132+
}
77133
}
78134

79135
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthFrownRight] = frown;
@@ -90,6 +146,12 @@ public override void Update()
90146
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthStretchLeft] = MouthStretch;
91147
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthStretchRight] = MouthStretch;
92148

149+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.CheekPuffRight] = cheekPuff;
150+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.CheekPuffLeft] = cheekPuff;
151+
152+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.JawOpen] = apeShape;
153+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthClosed] = apeShape;
154+
93155
}
94156

95157
// Add a delay or halt for the next update cycle for performance. eg:
@@ -109,6 +171,60 @@ private void UpdateValues()
109171
MouthStretch.Weight = reciever.cringe;
110172
}
111173

174+
private void UpdateValuesExpressions()
175+
{
176+
try
177+
{
178+
179+
if (reciever.expressions.Expressions.ContainsKey(tagSmile))
180+
{
181+
frown.Weight = (-reciever.expressions.Expressions[tagSmile].Weight);
182+
mouthUpperUp.Weight = reciever.expressions.Expressions[tagSmile].Weight;
183+
mouthLowerDown.Weight = reciever.expressions.Expressions[tagSmile].Weight;
184+
}
185+
if (reciever.expressions.Expressions.ContainsKey(tagFrown))
186+
{
187+
if (reciever.expressions.Expressions.ContainsKey(tagSmile))
188+
{
189+
frown.Weight = (-reciever.expressions.Expressions[tagSmile].Weight) + reciever.expressions.Expressions[tagFrown].Weight;
190+
}
191+
else
192+
{
193+
frown.Weight = reciever.expressions.Expressions[tagFrown].Weight;
194+
}
195+
}
196+
if (reciever.expressions.Expressions.ContainsKey(tagCringe))
197+
{
198+
if (reciever.expressions.Expressions.ContainsKey(tagSmile))
199+
{
200+
mouthLowerDown.Weight = Math.Clamp(reciever.expressions.Expressions[tagSmile].Weight + reciever.expressions.Expressions[tagCringe].Weight, 0, 1);
201+
}
202+
else
203+
{
204+
mouthLowerDown.Weight = reciever.expressions.Expressions[tagCringe].Weight;
205+
}
206+
MouthStretch.Weight = reciever.expressions.Expressions[tagCringe].Weight;
207+
}
208+
if (reciever.expressions.Expressions.ContainsKey(tagAnger))
209+
{
210+
browDown.Weight = reciever.expressions.Expressions[tagAnger].Weight;
211+
}
212+
if (reciever.expressions.Expressions.ContainsKey(tagCheekPuff))
213+
{
214+
cheekPuff.Weight = reciever.expressions.Expressions[tagCheekPuff].Weight;
215+
}
216+
if (reciever.expressions.Expressions.ContainsKey(tagApeShape))
217+
{
218+
apeShape.Weight = reciever.expressions.Expressions[tagCheekPuff].Weight;
219+
}
220+
221+
}
222+
catch (Exception ex)
223+
{
224+
Logger.LogInformation($"Error trying to acces values: {ex.Message}");
225+
}
226+
}
227+
112228
// Called when the module is unloaded or VRCFaceTracking itself tears down.
113229
public override void Teardown()
114230
{
@@ -123,6 +239,7 @@ public override void Teardown()
123239
mouthLowerDown.Weight = 0;
124240
browDown.Weight = 0;
125241
MouthStretch.Weight = 0;
242+
cheekPuff.Weight = 0;
126243

127244
UnifiedTracking.Data.Eye.Left.Openness = 1;
128245
UnifiedTracking.Data.Eye.Right.Openness = 1;
@@ -140,6 +257,10 @@ public override void Teardown()
140257

141258
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthStretchLeft] = MouthStretch;
142259
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthStretchRight] = MouthStretch;
260+
261+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.CheekPuffRight] = cheekPuff;
262+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.CheekPuffLeft] = cheekPuff;
263+
143264
}
144265

145266
float map(float x, float in_min, float in_max, float out_min, float out_max)
@@ -148,4 +269,5 @@ float map(float x, float in_min, float in_max, float out_min, float out_max)
148269
}
149270

150271
}
272+
151273
}

BFI_VRCFT_Module/BFI_VRCFT_Module.generated.sln

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
44
VisualStudioVersion = 17.5.002.0
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BFI_VRCFT_Module", "BFI_VRCFT_Module.csproj", "{3A677077-1852-4919-AF74-7B70C535D56B}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BFI_VRCFT_Module", "BFI_VRCFT_Module.csproj", "{CE09F365-1A99-4D46-98D4-237173943522}"
77
EndProject
88
Global
99
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1010
Debug|Any CPU = Debug|Any CPU
1111
Release|Any CPU = Release|Any CPU
1212
EndGlobalSection
1313
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14-
{3A677077-1852-4919-AF74-7B70C535D56B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15-
{3A677077-1852-4919-AF74-7B70C535D56B}.Debug|Any CPU.Build.0 = Debug|Any CPU
16-
{3A677077-1852-4919-AF74-7B70C535D56B}.Release|Any CPU.ActiveCfg = Release|Any CPU
17-
{3A677077-1852-4919-AF74-7B70C535D56B}.Release|Any CPU.Build.0 = Release|Any CPU
14+
{CE09F365-1A99-4D46-98D4-237173943522}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{CE09F365-1A99-4D46-98D4-237173943522}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{CE09F365-1A99-4D46-98D4-237173943522}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{CE09F365-1A99-4D46-98D4-237173943522}.Release|Any CPU.Build.0 = Release|Any CPU
1818
EndGlobalSection
1919
GlobalSection(SolutionProperties) = preSolution
2020
HideSolutionNode = FALSE

BFI_VRCFT_Module/JsonParser.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Text.Json;
5+
using System.Text.Json.Serialization;
6+
7+
namespace BFI_VRCFT_Module
8+
{
9+
public class Expression
10+
{
11+
12+
[JsonPropertyName("id")]
13+
public int Id { get; set; } = 0;
14+
15+
[JsonPropertyName("supportedexpressions")]
16+
public float ConfigWeight { get; set; } = 0;
17+
18+
public float Weight { get; set; } = 0;
19+
}
20+
21+
public class SupportedExpressions
22+
{
23+
[JsonPropertyName("supportedexpressions")]
24+
public Dictionary<string, Expression> Expressions { get; set; }
25+
}
26+
27+
public class JsonParser
28+
{
29+
public JsonParser() {
30+
this.data = null;
31+
}
32+
public string data;//just to debug if file was not found
33+
private const string JsonFileName = "expressions.json";//expected location of json file relative to the dll
34+
35+
public SupportedExpressions ParseJson()
36+
{
37+
string jsonFilePath = Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), JsonFileName);
38+
if (!File.Exists(jsonFilePath))
39+
{
40+
//throw new FileNotFoundException($"The file {JsonFileName} was not found.");
41+
data = ($"The file {JsonFileName} was not found.");
42+
}
43+
44+
string jsonString = File.ReadAllText(jsonFilePath);
45+
SupportedExpressions supportedExpressions = JsonSerializer.Deserialize<SupportedExpressions>(jsonString);
46+
return supportedExpressions;
47+
}
48+
}
49+
}

BFI_VRCFT_Module/OscReceiver.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ public class OscReceiver
2222

2323
public string OSCDebugData;//debug string to display in the console
2424

25+
26+
public SupportedExpressions expressions;
2527
public float eyeClosed = 0;
2628
public float smile = 0;
2729
public float frown = 0;
@@ -58,7 +60,17 @@ private void HandleOscMessage(byte[] bytes)
5860

5961
if (oscMessage != null)
6062
{
61-
if (oscMessage.Address.ToString().Contains(_oscAddress + "1"))
63+
64+
foreach (var expression in expressions.Expressions)
65+
{
66+
if(oscMessage.Address.ToString().Contains(_oscAddress + expression.Value.Id))
67+
{
68+
expression.Value.Weight = (float)oscMessage.Value;
69+
resetStopwatch();
70+
}
71+
//Logger.LogInformation($"Expression: {expression.Key}, Id: {expression.Value.Id}, Weight: {expression.Value.Weight}");
72+
}
73+
/*if (oscMessage.Address.ToString().Contains(_oscAddress + "1"))
6274
{
6375
eyeClosed = (float)oscMessage.Value;
6476
resetStopwatch();
@@ -82,10 +94,11 @@ private void HandleOscMessage(byte[] bytes)
8294
{
8395
cringe = (float)oscMessage.Value;
8496
resetStopwatch();
85-
}
97+
}*/
8698

99+
OSCDebugData = $"message recieved: {oscMessage.Value}";
87100

88-
OSCDebugData = $"RawData{oscMessage.Value}\nEyeClosed = {eyeClosed.ToString()} \nSmile = {smile.ToString()}\nFrown = {frown.ToString()}\nAnger = {anger.ToString()}\ncringe = {cringe.ToString()}\n\n";
101+
//OSCDebugData = $"RawData{oscMessage.Value}\nEyeClosed = {eyeClosed.ToString()} \nSmile = {smile.ToString()}\nFrown = {frown.ToString()}\nAnger = {anger.ToString()}\ncringe = {cringe.ToString()}\n\n";
89102

90103
}
91104
else

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy