Skip to content

Commit 07f9b1f

Browse files
committed
Created Config
Made it configurable by the user Renamed expressions.json to config.json Added description of the expressions in the readme Added Eyebrows to cringe expression Fixed reset for apeshape
1 parent 00c3c4c commit 07f9b1f

File tree

6 files changed

+199
-142
lines changed

6 files changed

+199
-142
lines changed

BFI_VRCFT_Module/BFI_VRCFT_Module.cs

Lines changed: 59 additions & 22 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.Linq.Expressions;
5+
using System.Net;
46
using System.Text.Json;
57
using System.Text.Json.Serialization;
68
using VRCFaceTracking;
@@ -22,7 +24,7 @@ public class BFI_VRCFT_Module : ExtTrackingModule
2224

2325
//osc info
2426
public static bool debug = false;
25-
OscReceiver reciever = new OscReceiver(8999);
27+
OscReceiver reciever;
2628

2729
//expressions
2830
UnifiedExpressionShape frown = new UnifiedExpressionShape();
@@ -32,6 +34,8 @@ public class BFI_VRCFT_Module : ExtTrackingModule
3234
UnifiedExpressionShape browDown = new UnifiedExpressionShape();
3335
UnifiedExpressionShape cheekPuff = new UnifiedExpressionShape();
3436
UnifiedExpressionShape apeShape = new UnifiedExpressionShape();
37+
UnifiedExpressionShape browInnerUp = new UnifiedExpressionShape();
38+
UnifiedExpressionShape browOuterUp = new UnifiedExpressionShape();
3539

3640

3741
// What your interface is able to send as tracking data.
@@ -43,7 +47,23 @@ public class BFI_VRCFT_Module : ExtTrackingModule
4347
public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAvailable, bool expressionAvailable)
4448
{
4549

50+
JsonParser parser = new JsonParser();
51+
Config config = new Config();
52+
try
53+
{
54+
config = parser.ParseConfig();
55+
}
56+
catch (Exception ex)
57+
{
58+
Logger.LogInformation($"Error parsing JSON file: {ex.Message}");
59+
}
60+
61+
Logger.LogInformation(parser.debugString);
62+
63+
reciever = new OscReceiver(IPAddress.Parse(config.ip),config.port,config.timoutTime) ;
64+
4665
reciever.StartListening();//starts OSC listener
66+
Logger.LogInformation(reciever.debugString);
4767
var state = (eyeAvailable, expressionAvailable);
4868

4969
ModuleInformation.Name = "BFI Module";
@@ -60,10 +80,9 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
6080
//parsing json file for expressions
6181
try
6282
{
63-
64-
JsonParser parser = new JsonParser();
65-
SupportedExpressions expressions = parser.ParseJson(); //parsing json file
83+
SupportedExpressions expressions = parser.ParseExpressions(); //parsing json file
6684
reciever.expressions = expressions; //assigning expressions to the reciever
85+
6786
if (expressions != null && expressions.Expressions != null)
6887
{
6988
if (expressions.Expressions != null)
@@ -78,6 +97,7 @@ public override (bool eyeSuccess, bool expressionSuccess) Initialize(bool eyeAva
7897
{
7998
Logger.LogInformation($"No expressions found in the JSON file");
8099
}
100+
81101
}
82102
catch (Exception ex)
83103
{
@@ -101,7 +121,7 @@ public override void Update()
101121
// ... Execute update cycle.
102122

103123

104-
if (debug) Logger.LogInformation(reciever.OSCDebugData);
124+
if (debug) Logger.LogInformation(reciever.debugString);
105125

106126
//UpdateValues();
107127
UpdateValuesExpressions();
@@ -154,10 +174,10 @@ public override void Update()
154174
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.JawOpen] = apeShape;
155175
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthClosed] = apeShape;
156176

157-
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowInnerUpLeft] = apeShape;
158-
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowInnerUpRight] = apeShape;
159-
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowOuterUpLeft] = apeShape;
160-
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowOuterUpRight] = apeShape;
177+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowInnerUpLeft] = browInnerUp;
178+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowInnerUpRight] = browInnerUp;
179+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowOuterUpLeft] = browOuterUp;
180+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowOuterUpRight] = browOuterUp;
161181

162182

163183

@@ -167,19 +187,6 @@ public override void Update()
167187
Thread.Sleep(10);
168188
}
169189

170-
/*private void UpdateValues()//legacy function, easier to read
171-
{
172-
frown.Weight = reciever.frown + (-reciever.smile);
173-
174-
mouthUpperUp.Weight = reciever.smile;
175-
176-
mouthLowerDown.Weight = Math.Clamp(reciever.smile + reciever.cringe, 0, 1);
177-
178-
browDown.Weight = reciever.anger;
179-
180-
MouthStretch.Weight = reciever.cringe;
181-
}*/
182-
183190
private void UpdateValuesExpressions()//sets values of expressions based on the values recieved from OSC if present
184191
{
185192
try
@@ -212,7 +219,14 @@ public override void Update()
212219
{
213220
mouthLowerDown.Weight = Clampf01(reciever.expressions.Expressions[tagCringe].Weight);
214221
}
222+
223+
if (!reciever.expressions.Expressions.ContainsKey(tagApeShape))
224+
{
225+
browInnerUp.Weight = Clampf01(reciever.expressions.Expressions[tagCringe].Weight);
226+
}
227+
215228
MouthStretch.Weight = Clampf01(reciever.expressions.Expressions[tagCringe].Weight);
229+
216230
}
217231
if (reciever.expressions.Expressions.ContainsKey(tagAnger))
218232
{
@@ -225,6 +239,17 @@ public override void Update()
225239
if (reciever.expressions.Expressions.ContainsKey(tagApeShape))
226240
{
227241
apeShape.Weight = Clampf01(reciever.expressions.Expressions[tagApeShape].Weight);
242+
243+
if (reciever.expressions.Expressions.ContainsKey(tagCringe))
244+
{
245+
browInnerUp.Weight = Clampf01(reciever.expressions.Expressions[tagCringe].Weight + reciever.expressions.Expressions[tagApeShape].Weight);
246+
247+
}
248+
else
249+
{
250+
browInnerUp.Weight = Clampf01(reciever.expressions.Expressions[tagApeShape].Weight);
251+
}
252+
browOuterUp.Weight = Clampf01(reciever.expressions.Expressions[tagApeShape].Weight);
228253
}
229254

230255
}
@@ -249,6 +274,10 @@ public override void Teardown()
249274
browDown.Weight = 0;
250275
MouthStretch.Weight = 0;
251276
cheekPuff.Weight = 0;
277+
apeShape.Weight = 0;
278+
browInnerUp.Weight = 0 ;
279+
browOuterUp.Weight = 0;
280+
252281

253282
UnifiedTracking.Data.Eye.Left.Openness = 1;
254283
UnifiedTracking.Data.Eye.Right.Openness = 1;
@@ -270,6 +299,14 @@ public override void Teardown()
270299
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.CheekPuffRight] = cheekPuff;
271300
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.CheekPuffLeft] = cheekPuff;
272301

302+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.JawOpen] = apeShape;
303+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.MouthClosed] = apeShape;
304+
305+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowInnerUpLeft] = browInnerUp;
306+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowInnerUpRight] = browInnerUp;
307+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowOuterUpLeft] = browOuterUp;
308+
UnifiedTracking.Data.Shapes[(int)UnifiedExpressions.BrowOuterUpRight] = browOuterUp;
309+
273310
}
274311

275312
float map(float x, float in_min, float in_max, float out_min, float out_max)//remapping function, could prove useful

BFI_VRCFT_Module/JsonParser.cs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
using System;
1+
using Microsoft.Extensions.Logging;
2+
using System;
23
using System.Collections.Generic;
34
using System.IO;
5+
using System.Net;
46
using System.Text.Json;
57
using System.Text.Json.Serialization;
68

@@ -22,6 +24,23 @@ public float Weight {
2224
}
2325
}
2426

27+
public class Config
28+
{
29+
public Config()
30+
{
31+
this.ip = "127.0.0.1";
32+
port = 8999;
33+
timoutTime = 3;
34+
}
35+
36+
[JsonPropertyName("ip")]
37+
public string ip { get; set; } = "127.0.0.1";
38+
[JsonPropertyName("port")]
39+
public int port { get; set; } = 8999;
40+
[JsonPropertyName("timouttime")]
41+
public double timoutTime { get; set; } = 3;
42+
}
43+
2544
public class SupportedExpressions
2645
{
2746
[JsonPropertyName("supportedexpressions")]
@@ -31,23 +50,38 @@ public class SupportedExpressions
3150
public class JsonParser
3251
{
3352
public JsonParser() {
34-
this.data = null;
53+
this.debugString = null;
3554
}
36-
public string data;//just to debug if file was not found
37-
private const string JsonFileName = "expressions.json";//expected location of json file relative to the dll
55+
public string debugString;//just to debug if file was not found
56+
private const string JsonFileName = "config.json";//expected location of json file relative to the dll
3857

39-
public SupportedExpressions ParseJson()
58+
public SupportedExpressions ParseExpressions()
4059
{
4160
string jsonFilePath = Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), JsonFileName);
4261
if (!File.Exists(jsonFilePath))
4362
{
4463
//throw new FileNotFoundException($"The file {JsonFileName} was not found.");
45-
data = ($"The file {JsonFileName} was not found.");
64+
debugString = ($"The file {JsonFileName} was not found.");
4665
}
4766

4867
string jsonString = File.ReadAllText(jsonFilePath);
4968
SupportedExpressions supportedExpressions = JsonSerializer.Deserialize<SupportedExpressions>(jsonString);//gotrough the json and deserialize it into the object
5069
return supportedExpressions;
5170
}
71+
72+
public Config ParseConfig()
73+
{
74+
string jsonFilePath = Path.Combine(System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), JsonFileName);
75+
if (!File.Exists(jsonFilePath))
76+
{
77+
//throw new FileNotFoundException($"The file {JsonFileName} was not found.");
78+
debugString = ($"The file {JsonFileName} was not found.");
79+
}
80+
81+
string jsonString = File.ReadAllText(jsonFilePath);
82+
Config config = JsonSerializer.Deserialize<Config>(jsonString);//gotrough the json and deserialize it into the object
83+
debugString = $"config: ip={config.ip}, port={config.port}, timout={config.timoutTime}";
84+
return config;
85+
}
5286
}
5387
}

BFI_VRCFT_Module/OscReceiver.cs

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,27 @@ public class OscReceiver
1414
{
1515
private UdpClient _udpClient;
1616
private IPEndPoint _endPoint;
17-
private int Port;
1817
private static string _oscAddress = "/BFI/MLAction/Action";//adress to listen for OSC messages
1918

2019
private Stopwatch timer = new Stopwatch();//timout timer
21-
public static double timeoutTime = 3;//timout time in seconds
20+
private double timeoutTime = 3;//timout time in seconds
2221

23-
public string OSCDebugData;//debug string to display in the console
22+
public string debugString;//debug string to display in the console
2423

2524

2625
public SupportedExpressions expressions;
27-
/* Legacy code
28-
public float eyeClosed = 0;
29-
public float smile = 0;
30-
public float frown = 0;
31-
public float anger = 0;
32-
public float cringe = 0;*/
3326

3427

35-
public OscReceiver(int port)
28+
public OscReceiver(IPAddress address, int port, double timouttime)
3629
{
37-
Port = port;
38-
_endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
30+
_endPoint = new IPEndPoint(address, port);
3931
_udpClient = new UdpClient(_endPoint);
32+
timouttime = timeoutTime;
4033
}
4134

4235
public async Task StartListening()//starts listening for OSC messages
4336
{
44-
Console.WriteLine($"Listening for OSC messageson port {Port} ...");
37+
debugString = ($"Listening for OSC messages on ip: {_endPoint.Address.ToString()} port: {_endPoint.Port} ...");
4538
timer.Start();
4639
while (true)
4740
{
@@ -54,7 +47,7 @@ public OscReceiver(int port)
5447
return timer.Elapsed.TotalSeconds > timeoutTime;
5548
}
5649

57-
private void HandleOscMessage(byte[] bytes)
50+
private void HandleOscMessage(byte[] bytes)//treats data from OSC messages
5851
{
5952
int messageIndex = 0;
6053
OscMessage oscMessage = new OscMessage(bytes, bytes.Length, ref messageIndex);
@@ -69,45 +62,16 @@ private void HandleOscMessage(byte[] bytes)
6962
expression.Value.Weight = (float)oscMessage.Value;
7063
resetStopwatch();
7164
}
72-
//Logger.LogInformation($"Expression: {expression.Key}, Id: {expression.Value.Id}, Weight: {expression.Value.Weight}");
65+
7366
}
7467

75-
/* Legacy code
76-
*
77-
* if (oscMessage.Address.ToString().Contains(_oscAddress + "1"))
78-
{
79-
eyeClosed = (float)oscMessage.Value;
80-
resetStopwatch();
81-
}
82-
else if (oscMessage.Address.ToString().Contains(_oscAddress + "2"))
83-
{
84-
smile = (float)oscMessage.Value;
85-
resetStopwatch();
86-
}
87-
else if (oscMessage.Address.ToString().Contains(_oscAddress + "3"))
88-
{
89-
frown = (float)oscMessage.Value;
90-
resetStopwatch();
91-
}
92-
else if (oscMessage.Address.ToString().Contains(_oscAddress + "4"))
93-
{
94-
anger = (float)oscMessage.Value;
95-
resetStopwatch();
96-
}
97-
else if (oscMessage.Address.ToString().Contains(_oscAddress + "5"))
98-
{
99-
cringe = (float)oscMessage.Value;
100-
resetStopwatch();
101-
}*/
102-
103-
OSCDebugData = $"message recieved: {oscMessage.Address.ToString()} = {oscMessage.Value}";
104-
105-
//OSCDebugData = $"RawData{oscMessage.Value}\nEyeClosed = {eyeClosed.ToString()} \nSmile = {smile.ToString()}\nFrown = {frown.ToString()}\nAnger = {anger.ToString()}\ncringe = {cringe.ToString()}\n\n";
68+
debugString = $"message recieved: {oscMessage.Address.ToString()} = {oscMessage.Value}";
10669

70+
10771
}
10872
else
10973
{
110-
OSCDebugData = "Failed to parse OSC message.";
74+
debugString = "Failed to parse OSC message.";
11175
}
11276
}
11377

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