Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: inactive dynamics only at applying cabinet and various fixes #151

Merged
merged 1 commit into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading