Skip to content

Commit

Permalink
fix: inactive dynamics only at applying cabinet and various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
poi-vrc committed Aug 23, 2023
1 parent bd67d08 commit b0c1e84
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public abstract class ModuleProviderBase
public abstract IModuleConfig DeserializeModuleConfig(JObject jObject);
public virtual string SerializeModuleConfig(IModuleConfig moduleConfig) => JsonConvert.SerializeObject(moduleConfig);
public abstract IModuleConfig NewModuleConfig();
public virtual bool OnBeforeApplyCabinet(ApplyCabinetContext ctx, IModuleConfig moduleConfig) => true;
public virtual bool OnApplyWearable(ApplyCabinetContext cabCtx, ApplyWearableContext wearCtx, IModuleConfig moduleConfig) => true;
public virtual bool OnAfterApplyCabinet(ApplyCabinetContext ctx, IModuleConfig moduleConfig) => true;
public virtual bool OnBeforeApplyCabinet(ApplyCabinetContext ctx) => true;
public virtual bool OnApplyWearable(ApplyCabinetContext cabCtx, ApplyWearableContext wearCtx, WearableModule moduleConfig) => true;
public virtual bool OnAfterApplyCabinet(ApplyCabinetContext ctx) => true;
public virtual bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig config, GameObject wearableGameObject, WearableModule module) => true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public static class MessageCode
public const string IncompatibleConfigVersion = "cabinet.applier.msgCode.error.incompatibleConfigVersion";
public const string ConfigMigrationFailed = "cabinet.applier.msgCode.error.configMigrationFailed";
public const string ModuleHasNoProviderAvailable = "cabinet.applier.msgCode.error.moduleHasNoProviderAvailable";
public const string BeforeApplyCabinetProviderHookHasErrors = "cabinet.applier.msgCode.error.beforeApplyCabinetProviderHookHasErrors";
public const string AfterApplyCabinetProviderHookHasErrors = "cabinet.applier.msgCode.error.afterApplyCabinetProviderHookHasErrors";
}

private ApplyCabinetContext _cabCtx;
Expand Down Expand Up @@ -240,7 +242,7 @@ private bool ApplyWearable(ApplyWearableContext wearCtx)
return false;
}

if (!provider.OnApplyWearable(_cabCtx, wearCtx, module.config))
if (!provider.OnApplyWearable(_cabCtx, wearCtx, module))
{
DTReportUtils.LogErrorLocalized(_cabCtx.report, LogLabel, MessageCode.ApplyingModuleHasErrors);
return false;
Expand All @@ -258,10 +260,46 @@ private bool ApplyWearable(ApplyWearableContext wearCtx)
return true;
}

private static bool DoBeforeApplyCabinetProviderHooks(ApplyCabinetContext ctx)
{
// do provider hooks
var providers = ModuleProviderLocator.Instance.GetAllProviders();
foreach (var provider in providers)
{
if (!provider.OnBeforeApplyCabinet(ctx))
{
DTReportUtils.LogErrorLocalized(ctx.report, LogLabel, MessageCode.BeforeApplyCabinetProviderHookHasErrors, provider.ModuleIdentifier);
return false;
}
}
return true;
}

private static bool DoAfterApplyCabinetProviderHooks(ApplyCabinetContext ctx)
{
// do provider hooks
var providers = ModuleProviderLocator.Instance.GetAllProviders();
foreach (var provider in providers)
{
if (!provider.OnAfterApplyCabinet(ctx))
{
DTReportUtils.LogErrorLocalized(ctx.report, LogLabel, MessageCode.AfterApplyCabinetProviderHookHasErrors, provider.ModuleIdentifier);
return false;
}
}
return true;
}

public void Execute()
{
// scan for avatar dynamics
_cabCtx.avatarDynamics = DTRuntimeUtils.ScanDynamics(_cabCtx.cabinet.AvatarGameObject, true);

if (!DoBeforeApplyCabinetProviderHooks(_cabCtx))
{
return;
}

var wearables = _cabCtx.cabinet.GetWearables();

foreach (var wearable in wearables)
Expand Down Expand Up @@ -299,6 +337,11 @@ public void Execute()
break;
}
}

if (!DoAfterApplyCabinetProviderHooks(_cabCtx))
{
return;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public static List<IDynamicsProxy> ScanDynamics(GameObject obj, bool doNotScanCo
// scan dynbones
if (DynamicBoneType != null)
{
var dynBones = obj.GetComponentsInChildren(DynamicBoneType);
var dynBones = obj.GetComponentsInChildren(DynamicBoneType, true);
foreach (var dynBone in dynBones)
{
if (doNotScanContainingWearables && IsOriginatedFromAnyWearable(obj.transform, dynBone.transform))
Expand All @@ -148,7 +148,7 @@ public static List<IDynamicsProxy> ScanDynamics(GameObject obj, bool doNotScanCo
// scan physbones
if (PhysBoneType != null)
{
var physBones = obj.GetComponentsInChildren(PhysBoneType);
var physBones = obj.GetComponentsInChildren(PhysBoneType, true);
foreach (var physBone in physBones)
{
if (doNotScanContainingWearables && IsOriginatedFromAnyWearable(obj.transform, physBone.transform))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Chocopoi.DressingTools.Lib;
using Chocopoi.DressingTools.Lib.Cabinet;
using Chocopoi.DressingTools.Lib.Logging;
using Chocopoi.DressingTools.Lib.Proxy;
Expand Down Expand Up @@ -62,7 +63,7 @@ static AnimationGenerationModuleProvider()

public override IModuleConfig NewModuleConfig() => new AnimationGenerationModuleConfig();

public override bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig config, GameObject wearableGameObject, WearableModule module)
private static void InvertToggleStates(ICabinet cabinet, WearableConfig config, GameObject wearableGameObject, WearableModule module)
{
var agm = (AnimationGenerationModuleConfig)module.config;
var avatarGameObject = cabinet.AvatarGameObject;
Expand Down Expand Up @@ -90,23 +91,61 @@ public override bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig con
}
wearableToggleObj.gameObject.SetActive(!toggle.state);
}
}

// set wearable dynamics inactive
var wearableDynamics = DTRuntimeUtils.ScanDynamics(wearableGameObject, false);
var visitedDynamicsTransforms = new List<Transform>();
foreach (var dynamics in wearableDynamics)
public override bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig config, GameObject wearableGameObject, WearableModule module)
{
if (module == null)
{
if (visitedDynamicsTransforms.Contains(dynamics.Transform))
// we need the wearable to have our module installed
return true;
}

InvertToggleStates(cabinet, config, wearableGameObject, module);
return true;
}

public override bool OnAfterApplyCabinet(ApplyCabinetContext ctx)
{
var wearables = ctx.cabinet.GetWearables();

foreach (var wearable in wearables)
{
var config = WearableConfig.Deserialize(wearable.configJson);

if (config == null)
{
Debug.LogWarning("[DressingTools] [AnimationGenerationModule] Unable to deserialize one of the wearable configuration: " + wearable.name);
return false;
}

var module = DTRuntimeUtils.FindWearableModule(config, Identifier);

if (module == null)
{
// skip duplicates since it's meaningless
// no animation generation module, skipping
continue;
}

// we toggle GameObjects instead of components
dynamics.GameObject.SetActive(false);
InvertToggleStates(ctx.cabinet, config, wearable.wearableGameObject, module);

// set wearable dynamics inactive
var wearableDynamics = DTRuntimeUtils.ScanDynamics(wearable.wearableGameObject, false);
var visitedDynamicsTransforms = new List<Transform>();
foreach (var dynamics in wearableDynamics)
{
if (visitedDynamicsTransforms.Contains(dynamics.Transform))
{
// skip duplicates since it's meaningless
continue;
}

// mark as visited
visitedDynamicsTransforms.Add(dynamics.Transform);
// we toggle GameObjects instead of components
dynamics.GameObject.SetActive(false);

// mark as visited
visitedDynamicsTransforms.Add(dynamics.Transform);
}
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,9 @@ private static string RandomString(int length)
.Select(s => s[Random.Next(s.Length)]).ToArray());
}

public override bool OnApplyWearable(ApplyCabinetContext cabCtx, ApplyWearableContext wearCtx, IModuleConfig moduleConfig)
public override bool OnApplyWearable(ApplyCabinetContext cabCtx, ApplyWearableContext wearCtx, WearableModule module)
{
var armatureMappingConfig = (ArmatureMappingModuleConfig)moduleConfig;
var armatureMappingConfig = (ArmatureMappingModuleConfig)module.config;

if (!GenerateMappings(cabCtx, wearCtx, armatureMappingConfig, wearCtx.config.Info.name, out var boneMappings))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Chocopoi.DressingTools.Lib;
using Chocopoi.DressingTools.Lib.Cabinet;
using Chocopoi.DressingTools.Lib.Logging;
using Chocopoi.DressingTools.Lib.Proxy;
Expand Down Expand Up @@ -58,7 +59,7 @@ static BlendshapeSyncModuleProvider()

public override IModuleConfig NewModuleConfig() => new BlendshapeSyncModuleConfig();

public override bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig config, GameObject wearableGameObject, WearableModule module)
private static void FollowBlendshapeSyncValues(ICabinet cabinet, GameObject wearableGameObject, WearableModule module)
{
var avatarGameObject = cabinet.AvatarGameObject;
var bsm = (BlendshapeSyncModuleConfig)module.config;
Expand Down Expand Up @@ -111,7 +112,38 @@ public override bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig con
// copy value from avatar to wearable
wearableSmr.SetBlendShapeWeight(wearableBlendshapeIndex, avatarSmr.GetBlendShapeWeight(avatarBlendshapeIndex));
}
}

public override bool OnAddWearableToCabinet(ICabinet cabinet, WearableConfig config, GameObject wearableGameObject, WearableModule module)
{
FollowBlendshapeSyncValues(cabinet, wearableGameObject, module);
return true;
}

public override bool OnAfterApplyCabinet(ApplyCabinetContext ctx)
{
var wearables = ctx.cabinet.GetWearables();

foreach (var wearable in wearables)
{
var config = WearableConfig.Deserialize(wearable.configJson);

if (config == null)
{
Debug.LogWarning("[DressingTools] [BlendshapeSyncModule] Unable to deserialize one of the wearable configuration: " + wearable.name);
return false;
}

var module = DTRuntimeUtils.FindWearableModule(config, Identifier);

if (module == null)
{
// no blendshape sync module, skipping
continue;
}

FollowBlendshapeSyncValues(ctx.cabinet, wearable.wearableGameObject, module);
}
return true;
}
}
Expand Down

0 comments on commit b0c1e84

Please sign in to comment.