Skip to content

feat: Add mutable infer to input graphs, eye expressions#253

Closed
dfgHiatus wants to merge 9 commits into
mainfrom
mutable-infer
Closed

feat: Add mutable infer to input graphs, eye expressions#253
dfgHiatus wants to merge 9 commits into
mainfrom
mutable-infer

Conversation

@dfgHiatus

Copy link
Copy Markdown
Collaborator

No description provided.

@dfgHiatus
dfgHiatus requested a review from AeroScripts May 26, 2026 19:45
@dfgHiatus dfgHiatus self-assigned this May 26, 2026
@dfgHiatus dfgHiatus added the enhancement New feature or request label May 26, 2026
@CLAassistant

CLAassistant commented May 26, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ SummerSigh
❌ AeroScripts
You have signed the CLA already but the status is still pending? Let us recheck it.

private float[] dxPrev;
private DateTime tPrev;
public OneEuroFilter(float[] x0, float minCutoff = 1.0f, float beta = 0.0f)
private const float TwoPi = 2.0f * MathF.PI;

@dfgHiatus dfgHiatus May 26, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Math.Tau here!

@dfgHiatus dfgHiatus left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure to run things through a code formatter once you're finished! Thank you :)

private bool _hasModelMetadata;
private OrderedFloatMap _outputs;

private readonly List<List<string>> _knownMappings = new()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things:

  1. Instead of a list of lists, let's make the outer collection a Dictionary<enum, <List<string>> so we can more explicitly index into it. IE _knownMappings[0] -> List becomes _knownMappings[ExpressionMappings.Eye] -> List. Yes we don't really index into the list anywhere but I don't want this sneaking up on us.
  2. For (reused) strings, let's move this to a static class full of const strings.

I also see there's some string parsing in the VRCFT module, this would help us re-use/update strings in one "shared" file .

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this PR gets merged in, we need to implement separate filters for gaze, eye and face expressions.

}
}

_logger.LogInformation("Initialized model that predicts {Expressions}", string.Join(", ", _outputExpressionNames));

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to LogDebug, this is more for us and less for the end user.

Suggested change
_logger.LogInformation("Initialized model that predicts {Expressions}", string.Join(", ", _outputExpressionNames));
_logger.LogDebug("Initialized model that predicts {Expressions}", string.Join(", ", _outputExpressionNames));

var outputSize = _session.OutputMetadata.Values.First().Dimensions[1];
foreach(List<string> mapping in _knownMappings)
{
if(mapping.Count == outputSize)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we throw a warning/error here if we're not able to load a face model at all? IE if model input size doesn't match what were are expecting


public override void Update()
{
if (needsEye)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep the use of needsEye and needsExpression. I forget the exact reason why but maybe @benaclejames can chime in on this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to bump the version number (we're on 3.2.0 now IIRC) as well the the module.json!

xPrev = (float[])x.Clone();
return x;
for (int i = 0; i < length; i++)
{

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If all we're doing here is copying a span, wouldn't it make more sense to use Span.CopyTo or Span.TryCopyTo?

}

// Expose the raw array/span directly so the ONNX runner can write to it
public Span<float> ValuesSpan => _values;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed in https://github.com/Project-Babble/Baballonia/pull/253/changes#diff-5431c54da43664d697c115e0d9478a7e3a1f380cd37ff0a176042848e2d82685R49 we're doing something like this:

OrderedFloatMap x;
ReadOnlySpan<float> xSpan = x.ValuesSpan;
int length = _xPrev.Length;

Should we return a ReadOnlySpan here instead of a Span? Why/why not?


Also, is there any difference between:

public Span<float> ValuesSpan => _values;

And

public Span<float> ValuesSpan => _values.ToSpan();

I think there's an implicit conversion happening here, but I'm not too certain 🤔

}
}

Thread.Sleep(10);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this method will be empty we should be able to delete this method outright. Any blocking will happen in BabbleOsc

AeroScripts and others added 5 commits May 30, 2026 00:43
Store a cloned orderedKeys array and use it for Keys and enumeration. This makes sure enumeration follows the provided key order (rather than relying on FrozenDictionary iteration) and protects against external mutation of the input array by cloning it in the constructor.
Comment on lines +97 to +104
private void ProcessNativeVrcEyeTracking(OrderedFloatMap expressions, ConcurrentQueue<OscMessage> queue)
{
var leftEyeX = expressions[0];
var leftEyeY = expressions[1];
var leftEyeLid = expressions[2];
var rightEyeX = expressions[3];
var rightEyeY = expressions[4];
var rightEyeLid = expressions[5];
var leftEyeX = expressions["/leftEyePitch"];
var leftEyeY = expressions["/leftEyeYaw"];
var leftEyeLid = expressions["/leftEyeLid"];
var rightEyeX = expressions["/rightEyePitch"];
var rightEyeY = expressions["/rightEyeYaw"];
var rightEyeLid = expressions["/rightEyeLid"];

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@acmdf reported these OSC addresses need to be updated. This may also effect DFR.

Suggested change
private void ProcessNativeVrcEyeTracking(OrderedFloatMap expressions, ConcurrentQueue<OscMessage> queue)
{
var leftEyeX = expressions[0];
var leftEyeY = expressions[1];
var leftEyeLid = expressions[2];
var rightEyeX = expressions[3];
var rightEyeY = expressions[4];
var rightEyeLid = expressions[5];
var leftEyeX = expressions["/leftEyePitch"];
var leftEyeY = expressions["/leftEyeYaw"];
var leftEyeLid = expressions["/leftEyeLid"];
var rightEyeX = expressions["/rightEyePitch"];
var rightEyeY = expressions["/rightEyeYaw"];
var rightEyeLid = expressions["/rightEyeLid"];
private void ProcessNativeVrcEyeTracking(OrderedFloatMap expressions, ConcurrentQueue<OscMessage> queue)
{
var leftEyeX = expressions["/leftEyeX"];
var leftEyeY = expressions["/leftEyeY"];
var leftEyeLid = expressions["/leftEyeLid"];
var rightEyeX = expressions["/rightEyeX"];
var rightEyeY = expressions["/rightEyeY"];
var rightEyeLid = expressions["/rightEyeLid"];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DFR route should be handled fine I believe, still probably worth checking before release though

@dfgHiatus

Copy link
Copy Markdown
Collaborator Author

Superseded by #256

@dfgHiatus dfgHiatus closed this Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants