135 lines
5.7 KiB
C#
135 lines
5.7 KiB
C#
/*
|
|
godotVmcSharp
|
|
Copyright (C) 2023 Cassandra de la Cruz-Munoz
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Affero General Public License as published
|
|
by the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Affero General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
using godotOscSharp;
|
|
using System;
|
|
|
|
#nullable enable
|
|
|
|
namespace godotVmcSharp
|
|
{
|
|
public class VmcExtBlendVal : VmcMessage
|
|
{
|
|
public readonly string? Name;
|
|
public readonly float Value;
|
|
public static VmcExtBlendVal CreateFromMessage(OscMessage m)
|
|
{
|
|
if (m.Data.Count <= 2)
|
|
{
|
|
throw new MissingArgumentsException(m.Address, "2", m.Data.Count);
|
|
}
|
|
var blendShape = m.Data[0].GetAsString();
|
|
var value = m.Data[1].GetAsFloat();
|
|
if (value < 0 || value > 1) {
|
|
throw new DataOutOfRangeException(m.Address, 1, "value", "0 <= value <= 1", value);
|
|
}
|
|
if (IsVrm0BlendShape(blendShape))
|
|
{
|
|
return new VmcExtBlendVal(blendShape, value);
|
|
}
|
|
if (IsVrm1Expression(blendShape))
|
|
{
|
|
return new VmcExtBlendVal(blendShape, value);
|
|
}
|
|
if (IsArkitBlendShape(blendShape))
|
|
{
|
|
return new VmcExtBlendVal(blendShape, value);
|
|
}
|
|
throw new DataOutOfRangeException(m.Address, 0, "name", "name in valid blendshape names", blendShape);
|
|
}
|
|
|
|
public static VmcExtBlendVal CreateFromParams(string name, float value)
|
|
{
|
|
if (value < 0 || value > 1) {
|
|
throw new DataOutOfRangeException("VMC/Ext/Blend/Val", 1, "value", "0 <= value <= 1", value);
|
|
}
|
|
if (IsVrm0BlendShape(name))
|
|
{
|
|
return new VmcExtBlendVal(name, value);
|
|
}
|
|
if (IsVrm1Expression(name))
|
|
{
|
|
return new VmcExtBlendVal(name, value);
|
|
}
|
|
if (IsArkitBlendShape(name))
|
|
{
|
|
return new VmcExtBlendVal(name, value);
|
|
}
|
|
throw new DataOutOfRangeException("VMC/Ext/Blend/Val", 0, "name", "name in valid blendshape names", name);
|
|
}
|
|
|
|
private VmcExtBlendVal(String name, float value): base(new OscAddress("VMC/Ext/Blend/Val")) {
|
|
Name = name;
|
|
Value = value;
|
|
}
|
|
|
|
private static bool IsVrm0BlendShape(string name)
|
|
{
|
|
return name == "Joy" || name == "Angry" || name == "Sorrow" || name == "Fun" ||
|
|
name == "A" || name == "I" || name == "U" || name == "E" || name == "O" ||
|
|
name == "Blink_L" || name == "Blink_R";
|
|
}
|
|
|
|
private static bool IsVrm1Expression(string name)
|
|
{
|
|
return name == "happy" || name == "angry" || name == "sad" || name == "relaxed" ||
|
|
name == "aa" || name == "ih" || name == "ou" || name == "ee" || name == "oh" ||
|
|
name == "blinkLeft" || name == "blinkRight";
|
|
}
|
|
|
|
private static bool IsArkitBlendShape(string name)
|
|
{
|
|
return name == "browInnerUp" ||
|
|
name == "browDownLeft" || name == "browDownRight" ||
|
|
name == "browOuterUpLeft" || name == "browOuterUpRight" ||
|
|
name == "eyeLookUpLeft" || name == "eyeLookUpRight" ||
|
|
name == "eyeLookDownLeft" || name == "eyeLookDownRight" ||
|
|
name == "eyeLookInLeft" || name == "eyeLookInRight" ||
|
|
name == "eyeLookOutLeft" || name == "eyeLookOutRight" ||
|
|
name == "eyeBlinkLeft" || name == "eyeBlinkRight" ||
|
|
name == "eyeSquintLeft" || name == "eyeSquintRight" ||
|
|
name == "eyeWideLeft" || name == "eyeWideRight" ||
|
|
name == "cheekPuff" ||
|
|
name == "cheekSquintLeft" || name == "cheekSquintRight" ||
|
|
name == "noseSneerLeft" || name == "noseSneerRight" ||
|
|
name == "jawOpen" || name == "jawForward" ||
|
|
name == "jawLeft" || name == "jawRight" ||
|
|
name == "mouthFunnel" || name == "mouthPucker" ||
|
|
name == "mouthLeft" || name == "mouthRight" ||
|
|
name == "mouthRollUpper" || name == "mouthRollLower" ||
|
|
name == "mouthShrugUpper" || name == "mouthShrugLower" ||
|
|
name == "mouthClose" ||
|
|
name == "mouthSmileLeft" || name == "mouthSmileRight" ||
|
|
name == "mouthFrownLeft" || name == "mouthFrownRight" ||
|
|
name == "mouthDimpleLeft" || name == "mouthDimpleRight" ||
|
|
name == "mouthUpperUpLeft" || name == "mouthUpperUpRight" ||
|
|
name == "mouthLowerDownLeft" || name == "mouthLowerDownRight" ||
|
|
name == "mouthPressLeft" || name == "mouthPressRight" ||
|
|
name == "mouthStretchLeft" || name == "mouthStretchRight" ||
|
|
name == "tongueOut";
|
|
}
|
|
public new OscMessage ToMessage()
|
|
{
|
|
return new OscMessage(Addr, new System.Collections.Generic.List<OscArgument> {
|
|
OscArgument.CreateFromParams(Name, 's')!,
|
|
OscArgument.CreateFromParams(Value, 'f')!
|
|
});
|
|
}
|
|
}
|
|
}
|