Skip to content

Commit

Permalink
Implemented OscPhysBone (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChanyaVRC committed Jul 9, 2022
1 parent eb56c1a commit 7ffa373
Showing 1 changed file with 78 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/vrcosclib/Avatar/OscPhysBone.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BuildSoft.VRChat.Osc.Avatar;

public class OscPhysBone
{
public OscAvatarConfig Avatar { get; }
public string ParamName { get; }

public bool IsGrabbed => GetParameterValue<bool>(nameof(IsGrabbed));
public float Angle => GetParameterValue<float>(nameof(Angle));
public float Stretch => GetParameterValue<float>(nameof(Stretch));

public event OscAvatarParameterChangedEventHandler? ParameterChanged;

public OscPhysBone(OscAvatarConfig avatar, string paramName)
{
string[] actualParamName = {
paramName + "_" + nameof(IsGrabbed),
paramName + "_" + nameof(Angle),
paramName + "_" + nameof(Stretch),
};
ThrowArgumentException_IfNotExistParameters(avatar, paramName, actualParamName);

Avatar = avatar;
ParamName = paramName;

var allParams = OscParameter.Parameters;
for (int i = 0; i < actualParamName.Length; i++)
{
var address = OscConst.AvatarParameterAddressSpace + actualParamName[i];
allParams.AddValueChangedEventByAddress(address, GetValueCallback);
}
}

private static void ThrowArgumentException_IfNotExistParameters(OscAvatarConfig avatar, string paramName, string[] actualParamName)
{
int count = 0;
foreach (var name in avatar.Parameters.Names)
{
for (int i = 0; i < actualParamName.Length; i++)
{
if (actualParamName[i] == name)
{
count++;
break;
}
}
if (count == actualParamName.Length)
{
break;
}
}
if (count != actualParamName.Length)
{
throw new ArgumentException($"The avatar don't have the parameter \"{paramName}\".", nameof(avatar));
}
}

private void GetValueCallback(IReadOnlyOscParameterCollection sender, ParameterChangedEventArgs e)
{
var name = e.Address[OscConst.AvatarParameterAddressSpace.Length..];
OnParameterChanged(Avatar.Parameters.Get(name), e);
}

protected internal void OnParameterChanged(OscAvatarParameter param, ValueChangedEventArgs e)
{
ParameterChanged?.Invoke(param, e);
}


private T? GetParameterValue<T>(string name) where T : notnull
{
return Avatar.Parameters.GetAs<T>(ParamName + "_" + name);
}
}

0 comments on commit 7ffa373

Please sign in to comment.