fix: multiple issues with auto parameter value assignment (#1136)

Closes: #1110
This commit is contained in:
bd_ 2024-09-13 22:27:01 -04:00 committed by GitHub
parent a9c2815106
commit fed6a22d72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 129 additions and 4 deletions

View File

@ -41,6 +41,11 @@ namespace nadena.dev.modular_avatar.core.editor
return false; return false;
} }
internal void TestExecute(ndmf.BuildContext context)
{
Execute(context);
}
protected override void Execute(ndmf.BuildContext context) protected override void Execute(ndmf.BuildContext context)
{ {
if (!context.AvatarDescriptor) return; if (!context.AvatarDescriptor) return;
@ -94,15 +99,19 @@ namespace nadena.dev.modular_avatar.core.editor
if (list.Count == 1) if (list.Count == 1)
// If we have only a single entry, it's probably an on-off toggle, so we'll implicitly let 0 // If we have only a single entry, it's probably an on-off toggle, so we'll implicitly let 0
// be the 'unselected' default value (if this is not default) // be the 'unselected' default value (if this is not default)
defaultValue = list[0].isDefault ? 1 : 0; defaultValue = 0;
} }
HashSet<int> usedValues = new(); HashSet<int> usedValues = new();
usedValues.Add((int)defaultValue); usedValues.Add((int)defaultValue);
foreach (var item in list) foreach (var item in list)
if (!item.automaticValue && Mathf.Abs(item.Control.value - Mathf.Round(item.Control.value)) < 0.01f) {
usedValues.Add(Mathf.RoundToInt(item.Control.value)); if (!item.automaticValue)
{
usedValues.Add((int)item.Control.value);
}
}
var nextValue = 1; var nextValue = 1;
@ -119,6 +128,10 @@ namespace nadena.dev.modular_avatar.core.editor
{ {
mami.Control.value = 1; mami.Control.value = 1;
} }
else if (mami.isDefault)
{
mami.Control.value = defaultValue;
}
else else
{ {
while (usedValues.Contains(nextValue)) nextValue++; while (usedValues.Contains(nextValue)) nextValue++;

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 669cbbad6e83460b9ca556b3eb09892c
timeCreated: 1726276590

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5c5ab15efda74442a395eaff69d63374
timeCreated: 1726276597

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Linq;
using modular_avatar_tests;
using nadena.dev.modular_avatar.core;
using nadena.dev.modular_avatar.core.editor;
using NUnit.Framework;
using UnityEngine;
using VRC.SDK3.Avatars.Components;
using VRC.SDK3.Avatars.ScriptableObjects;
namespace UnitTests.ReactiveComponent.ParameterAssignment
{
public class AutoValueAssignmentTests : TestBase
{
[Test]
public void ManuallyAssignedParametersAreNotReplaced()
{
TestAssignments(
new[] { (false, 1.0f), (false, 4.0f) },
new[] { 1.0f, 4.0f }
);
}
[Test]
public void SingleEntryToggles()
{
TestAssignments(new[] { (true, 0.0f) }, new[] { 1.0f });
TestAssignments(new[] { (true, 0.0f) }, new[] { 1.0f }, 0);
}
[Test]
public void MultiEntryToggles()
{
TestAssignments(new[] { (true, 0.0f), (true, 0.0f) }, new[] { 0.0f, 1.0f }, 0);
TestAssignments(new[] { (true, 0.0f), (true, 0.0f) }, new[] { 1.0f, 0.0f }, 1);
TestAssignments(new[] { (true, 0.0f), (true, 0.0f) }, new[] { 1.0f, 2.0f }, null);
TestAssignments(new[] { (true, 0.0f), (true, 0.0f), (true, 0.0f) }, new[] { 1.0f, 0.0f, 2.0f }, 1);
}
[Test]
public void MixedAutoTests()
{
TestAssignments(new[] { (false, 2.0f), (true, 0.0f), (true, 0.0f) }, new[] { 2.0f, 1.0f, 3.0f }, null);
TestAssignments(new[] { (false, 2.7f), (true, 0.0f), (true, 0.0f) }, new[] { 2.7f, 1.0f, 3.0f }, null);
}
void TestAssignments(
(bool, float)[] assignments,
float[] expectedAssignments,
int? defaultIndex = null,
Action<List<ModularAvatarMenuItem>> customize = null
)
{
var root = CreateRoot("root");
var avDesc = root.GetComponent<VRCAvatarDescriptor>();
avDesc.expressionParameters = ScriptableObject.CreateInstance<VRCExpressionParameters>();
avDesc.expressionParameters.parameters = Array.Empty<VRCExpressionParameters.Parameter>();
List<ModularAvatarMenuItem> menuItems = new();
foreach (var (auto, value) in assignments)
{
var obj = CreateChild(root, "m" + (menuItems.Count));
var mami = obj.AddComponent<ModularAvatarMenuItem>();
mami.Control = new VRCExpressionsMenu.Control()
{
name = obj.name,
type = VRCExpressionsMenu.Control.ControlType.Toggle,
value = value,
parameter = new()
{
name = "test_parameter"
}
};
mami.automaticValue = auto;
mami.isDefault = false;
menuItems.Add(mami);
}
if (defaultIndex.HasValue)
{
menuItems[defaultIndex.Value].isDefault = true;
}
customize?.Invoke(menuItems);
var context = new nadena.dev.ndmf.BuildContext(root, null);
new ParameterAssignerPass().TestExecute(context);
foreach (var (mami, expected) in menuItems.Zip(expectedAssignments, (m, e) => (m, e)))
{
Assert.AreEqual(expected, mami.Control.value);
}
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3bd4c63c1feb4efa91a2ee4c53e606d3
timeCreated: 1726276608