Skip to content

Commit

Permalink
s
Browse files Browse the repository at this point in the history
  • Loading branch information
poi-vrc committed Jan 12, 2024
1 parent ba0f523 commit c9a989f
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Editor/Animations/AnimatorParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace Chocopoi.DressingFramework.Animations
{
Expand Down
8 changes: 8 additions & 0 deletions Editor/Animations/VRChat.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 74 additions & 0 deletions Editor/Animations/VRChat/VRCAnimUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright (c) 2023 chocopoi
*
* This file is part of DressingFramework.
*
* DressingFramework is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* DressingFramework 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with DressingFramework. If not, see <https://www.gnu.org/licenses/>.
*/

#if DK_VRCSDK3A
using UnityEditor;
using UnityEditor.Animations;
using VRC.SDK3.Avatars.Components;

namespace Chocopoi.DressingFramework.Animations.VRChat
{
public class VRCAnimUtils
{
public static AnimatorController GetAnimLayerAnimator(VRCAvatarDescriptor.CustomAnimLayer animLayer)
{
return !animLayer.isDefault && animLayer.animatorController != null && animLayer.animatorController is AnimatorController controller ?
controller :
GetDefaultLayerAnimator(animLayer.type);
}

public static AnimatorController GetDefaultLayerAnimator(VRCAvatarDescriptor.AnimLayerType animLayerType)
{
string defaultControllerName = null;
switch (animLayerType)
{
case VRCAvatarDescriptor.AnimLayerType.Base:
defaultControllerName = "LocomotionLayer";
break;
case VRCAvatarDescriptor.AnimLayerType.Additive:
defaultControllerName = "IdleLayer";
break;
case VRCAvatarDescriptor.AnimLayerType.Action:
defaultControllerName = "ActionLayer";
break;
case VRCAvatarDescriptor.AnimLayerType.Gesture:
defaultControllerName = "HandsLayer";
break;
case VRCAvatarDescriptor.AnimLayerType.FX:
defaultControllerName = "FaceLayer";
break;
case VRCAvatarDescriptor.AnimLayerType.Sitting:
defaultControllerName = "SittingLayer";
break;
case VRCAvatarDescriptor.AnimLayerType.IKPose:
defaultControllerName = "UtilityIKPose";
break;
case VRCAvatarDescriptor.AnimLayerType.TPose:
defaultControllerName = "UtilityTPose";
break;
}

if (defaultControllerName == null)
{
return null;
}

var controller = AssetDatabase.LoadAssetAtPath<AnimatorController>("Packages/com.vrchat.avatars/Samples/AV3 Demo Assets/Animation/Controllers/vrc_AvatarV3" + defaultControllerName + ".controller");
if (controller == null)
{
controller = AssetDatabase.LoadAssetAtPath<AnimatorController>("Assets/VRCSDK/Examples3/Animation/Controllers/vrc_AvatarV3" + defaultControllerName + ".controller");
}
return controller;
}
}
}
#endif
11 changes: 11 additions & 0 deletions Editor/Animations/VRChat/VRCAnimUtils.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 126 additions & 1 deletion Editor/Detail/DK/DKNativeContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@
* You should have received a copy of the GNU General Public License along with DressingFramework. If not, see <https://www.gnu.org/licenses/>.
*/

using System.Collections.Generic;
using System.Linq;
using Chocopoi.DressingFramework.Animations;
using Chocopoi.DressingFramework.Animations.VRChat;
using Chocopoi.DressingFramework.Detail.DK.Logging;
using Chocopoi.DressingFramework.Localization;
using Chocopoi.DressingFramework.Logging;
using Chocopoi.DressingFramework.Menu;
using UnityEditor;
using UnityEngine;
#if DK_VRCSDK3A
using VRC.SDK3.Avatars.Components;
using VRC.SDK3.Avatars.ScriptableObjects;
#endif

namespace Chocopoi.DressingFramework.Detail.DK
{
Expand All @@ -24,6 +31,15 @@ namespace Chocopoi.DressingFramework.Detail.DK
/// </summary>
internal class DKNativeContext : Context
{
private const string LogLabel = "DKNativeContext";
public static class MessageCode
{
// Warn
public const string UnsupportedUnityParamTypeForVRC = "detail.dk.msgCode.warn.unsupportedUnityParamTypeForVRC";
// Error
public const string MismatchParameterTypesBetweenAnimators = "detail.dk.msgCode.error.mismatchParameterTypesBetweenAnimators";
}

/// <summary>
/// Folder of generated assets
/// </summary>
Expand Down Expand Up @@ -62,5 +78,114 @@ public override void CreateUniqueAsset(Object obj, string name)
{
AssetDatabase.CreateAsset(obj, MakeUniqueAssetPath(name));
}

internal override void OnDisable()
{
var ap = Feature<AnimatorParameters>();
ap.AddConfig(new AnimatorParameters.ParameterConfig("^Test2$")
{
networkSynced = false,
saved = true
});
base.OnDisable();
#if DK_VRCSDK3A
ApplyAnimParamsToVRCParams();
#endif
}

#if DK_VRCSDK3A
private void ScanAnimatorParameters(Dictionary<string, AnimatorControllerParameterType> parameters, VRCAvatarDescriptor.CustomAnimLayer[] customAnimLayers)
{
foreach (var customAnimLayer in customAnimLayers)
{
var animator = VRCAnimUtils.GetAnimLayerAnimator(customAnimLayer);
foreach (var animParam in animator.parameters)
{
if (parameters.TryGetValue(animParam.name, out var type))
{
if (type != animParam.type)
{
Report.LogErrorLocalized(I18nManager.Instance.FrameworkTranslator, LogLabel, MessageCode.MismatchParameterTypesBetweenAnimators);
}
}
else
{
parameters[animParam.name] = animParam.type;
}
}
}
}

private static VRCExpressionParameters.ValueType? UnityParamTypeToVRCParamType(AnimatorControllerParameterType type)
{
switch (type)
{
case AnimatorControllerParameterType.Int:
return VRCExpressionParameters.ValueType.Int;
case AnimatorControllerParameterType.Bool:
return VRCExpressionParameters.ValueType.Bool;
case AnimatorControllerParameterType.Float:
return VRCExpressionParameters.ValueType.Float;
}
return null;
}

private void ApplyAnimParamsToVRCParams()
{
if (!AvatarGameObject.TryGetComponent<VRCAvatarDescriptor>(out var avatarDesc))
{
// not a VRC avatar
return;
}

// make copy
var vrcParams = ScriptableObject.CreateInstance<VRCExpressionParameters>();
if (avatarDesc.expressionParameters != null)
{
EditorUtility.CopySerialized(avatarDesc.expressionParameters, vrcParams);
}
CreateUniqueAsset(vrcParams, "RootParameters.asset");
avatarDesc.expressionParameters = vrcParams;

var parameters = new Dictionary<string, AnimatorControllerParameterType>();
ScanAnimatorParameters(parameters, avatarDesc.baseAnimationLayers);
ScanAnimatorParameters(parameters, avatarDesc.specialAnimationLayers);

var animParams = Feature<AnimatorParameters>();
foreach (var parameterName in parameters.Keys)
{
var paramConfig = animParams.FindConfig(parameterName);
// no param config means unsynced / original
if (paramConfig == null)
{
continue;
}

var vrcParamType = UnityParamTypeToVRCParamType(parameters[parameterName]);
if (vrcParamType == null)
{
Report.LogWarnLocalized(I18nManager.Instance.FrameworkTranslator, LogLabel, MessageCode.UnsupportedUnityParamTypeForVRC);
continue;
}

var vrcParamList = new List<VRCExpressionParameters.Parameter>(vrcParams.parameters ?? new VRCExpressionParameters.Parameter[0]);

var vrcParam = vrcParamList.Where(p => p.name == parameterName).FirstOrDefault();
if (vrcParam == null)
{
vrcParam = new VRCExpressionParameters.Parameter();
vrcParamList.Add(vrcParam);
}

vrcParam.name = parameterName;
vrcParam.saved = paramConfig.saved;
vrcParam.defaultValue = paramConfig.defaultValue;
vrcParam.networkSynced = paramConfig.networkSynced;
vrcParam.valueType = vrcParamType.Value;

vrcParams.parameters = vrcParamList.ToArray();
}
}
#endif
}
}

0 comments on commit c9a989f

Please sign in to comment.