feat: Add mutable infer to input graphs, eye expressions#253
Conversation
|
|
| 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
left a comment
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
Two things:
- 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] -> Listbecomes_knownMappings[ExpressionMappings.Eye] -> List. Yes we don't really index into the list anywhere but I don't want this sneaking up on us. - For (reused) strings, let's move this to a static class full of
conststrings.
I also see there's some string parsing in the VRCFT module, this would help us re-use/update strings in one "shared" file .
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
Change this to LogDebug, this is more for us and less for the end user.
| _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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
We need to keep the use of needsEye and needsExpression. I forget the exact reason why but maybe @benaclejames can chime in on this.
There was a problem hiding this comment.
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++) | ||
| { |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
If this method will be empty we should be able to delete this method outright. Any blocking will happen in BabbleOsc
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.
| 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"]; |
There was a problem hiding this comment.
@acmdf reported these OSC addresses need to be updated. This may also effect DFR.
| 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"]; |
There was a problem hiding this comment.
DFR route should be handled fine I believe, still probably worth checking before release though
|
Superseded by #256 |
No description provided.