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

feat: vrc integration editor (partial) #150

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 @@ -21,6 +21,7 @@
using Chocopoi.AvatarLib.Expressions;
using Chocopoi.DressingTools.Animations;
using Chocopoi.DressingTools.Cabinet;
using Chocopoi.DressingTools.Integration.VRChat.Modules;
using Chocopoi.DressingTools.Lib.Logging;
using Chocopoi.DressingTools.Lib.Wearable;
using Chocopoi.DressingTools.Logging;
Expand Down Expand Up @@ -57,8 +58,6 @@ public bool OnPreprocessAvatar()
// obtain FX layer
var fxController = CopyAndReplaceLayerAnimator(avatarDescriptor, VRCAvatarDescriptor.AnimLayerType.FX);

// TODO: these operations are just temporary for testing, need rework to do exception catching etc

EditorUtility.DisplayProgressBar("DressingTools", "Removing old animator layers and parameters...", 0);
AnimationUtils.RemoveAnimatorLayers(fxController, "^cpDT_Cabinet");
AnimationUtils.RemoveAnimatorParameters(fxController, "^cpDT_Cabinet");
Expand Down Expand Up @@ -135,29 +134,37 @@ public bool OnPreprocessAvatar()
continue;
}

// obtain module
var vrcm = DTRuntimeUtils.FindWearableModuleConfig<VRChatIntegrationModuleConfig>(config);
if (vrcm == null)
{
// use default settings if no module
vrcm = new VRChatIntegrationModuleConfig();
}

EditorUtility.DisplayProgressBar("DressingTools", "Generating animations for " + config.Info.name + "...", i / (float)wearables.Length * 100);
var wearableDynamics = DTRuntimeUtils.ScanDynamics(wearables[i].wearableGameObject, false);

// find the animation generation module
var module = DTRuntimeUtils.FindWearableModuleConfig<AnimationGenerationModuleConfig>(config);
if (module == null)
var agm = DTRuntimeUtils.FindWearableModuleConfig<AnimationGenerationModuleConfig>(config);
if (agm == null)
{
Debug.Log("[DressingTools] [BuildDTCabinetCallback] [GenerateAnimationHook] " + config.Info.name + " has no AnimationGenerationModule, skipping this wearable generation");
continue;
}

var animationGenerator = new AnimationGenerator(_report, _cabinet.AvatarGameObject, module, wearables[i].wearableGameObject, wearableDynamics);
var animationGenerator = new AnimationGenerator(_report, _cabinet.AvatarGameObject, agm, wearables[i].wearableGameObject, wearableDynamics);

// TODO: write defaults settings
var wearAnimations = animationGenerator.GenerateWearAnimations(true);
// TODO: merge disable clips and check for conflicts
var wearAnimations = animationGenerator.GenerateWearAnimations(_cabinet.AnimationGenerationWriteDefaults);
pairs.Add(i + 1, wearAnimations.Item1); // enable clip
AssetDatabase.CreateAsset(wearAnimations.Item1, BuildDTCabinetCallback.GeneratedAssetsPath + "/cpDT_" + wearables[i].name + ".anim");

// generate expression menu
subMenu.AddToggle(config.Info.name, "cpDT_Cabinet", i + 1);
subMenu.AddToggle(vrcm.customCabinetToggleName ?? config.Info.name, "cpDT_Cabinet", i + 1);
}

AnimationUtils.GenerateAnyStateLayer(fxController, "cpDT_Cabinet", "cpDT_Cabinet", pairs, true, null, refTransition);
AnimationUtils.GenerateAnyStateLayer(fxController, "cpDT_Cabinet", "cpDT_Cabinet", pairs, _cabinet.AnimationGenerationWriteDefaults, null, refTransition);

EditorUtility.DisplayProgressBar("DressingTools", "Generating expression menu...", 0);
subMenu.CreateAsset(BuildDTCabinetCallback.GeneratedAssetsPath + "/cpDT_Cabinet.asset")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* File: IVRChatIntegrationModuleEditorView.cs
* Project: DressingTools
* Created Date: Wednesday, August 23th 2023, 7:56:36 pm
* Author: chocopoi ([email protected])
* -----
* Copyright (c) 2023 chocopoi
*
* This file is part of DressingTools.
*
* DressingTools 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.
*
* DressingTools 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 DressingTools. If not, see <https://www.gnu.org/licenses/>.
*/

using System;
using Chocopoi.DressingTools.Lib.UI;
using UnityEngine;

namespace Chocopoi.DressingTools.Integrations.VRChat
{
internal interface IVRChatIntegrationModuleEditorView : IEditorView
{
event Action ConfigChange;

bool UseCustomCabinetToggleName { get; set; }
string CustomCabinetToggleName { get; set; }
}
}

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* File: VRChatIntegrationModuleEditor.cs
* Project: DressingTools
* Created Date: Wednesday, August 23th 2023, 7:56:36 pm
* Author: chocopoi ([email protected])
* -----
* Copyright (c) 2023 chocopoi
*
* This file is part of DressingTools.
*
* DressingTools 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.
*
* DressingTools 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 DressingTools. If not, see <https://www.gnu.org/licenses/>.
*/

using System;
using System.Diagnostics.CodeAnalysis;
using Chocopoi.DressingTools.Integration.VRChat.Modules;
using Chocopoi.DressingTools.Lib.UI;
using Chocopoi.DressingTools.Lib.Wearable.Modules;
using Chocopoi.DressingTools.UI.Presenters.Modules;
using Chocopoi.DressingTools.UIBase.Views;
using Chocopoi.DressingTools.Wearable.Modules;
using UnityEditor;
using UnityEngine;

namespace Chocopoi.DressingTools.Integrations.VRChat
{
[ExcludeFromCodeCoverage]
[CustomModuleEditor(typeof(VRChatIntegrationModuleProvider))]
internal class VRChatIntegrationModuleEditor : ModuleEditor, IVRChatIntegrationModuleEditorView
{
public event Action ConfigChange;

public bool UseCustomCabinetToggleName { get => _useCustomCabinetToggleName; set => _useCustomCabinetToggleName = value; }
public string CustomCabinetToggleName { get => _customCabinetToggleName; set => _customCabinetToggleName = value; }

private IModuleEditorViewParent _parentView;
private VRChatIntegrationModuleEditorPresenter _presenter;

private bool _useCustomCabinetToggleName;
private string _customCabinetToggleName;

public VRChatIntegrationModuleEditor(IModuleEditorViewParent parentView, VRChatIntegrationModuleProvider provider, IModuleConfig target) : base(parentView, provider, target)
{
_parentView = parentView;
_presenter = new VRChatIntegrationModuleEditorPresenter(this, parentView, (VRChatIntegrationModuleConfig)target);

_useCustomCabinetToggleName = false;
}

public override void OnGUI()
{
ToggleLeft("Use custom cabinet toggle name", ref _useCustomCabinetToggleName, ConfigChange);
BeginDisabled(!_useCustomCabinetToggleName);
{
EditorGUI.indentLevel += 1;
TextField("Toggle Name", ref _customCabinetToggleName, ConfigChange);
EditorGUI.indentLevel -= 1;
}
EndDisabled();
}

public override bool IsValid() => _presenter.IsValid();
}
}

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

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* File: VRChatIntegrationModuleEditorPresenter.cs
* Project: DressingTools
* Created Date: Wednesday, August 23th 2023, 7:56:36 pm
* Author: chocopoi ([email protected])
* -----
* Copyright (c) 2023 chocopoi
*
* This file is part of DressingTools.
*
* DressingTools 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.
*
* DressingTools 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 DressingTools. If not, see <https://www.gnu.org/licenses/>.
*/

using Chocopoi.DressingTools.Integration.VRChat.Modules;
using Chocopoi.DressingTools.Lib.UI;
using Chocopoi.DressingTools.UIBase.Views;
using Chocopoi.DressingTools.Wearable.Modules;

namespace Chocopoi.DressingTools.Integrations.VRChat
{
internal class VRChatIntegrationModuleEditorPresenter
{
private IVRChatIntegrationModuleEditorView _view;
private IModuleEditorViewParent _parentView;
private VRChatIntegrationModuleConfig _module;

public VRChatIntegrationModuleEditorPresenter(IVRChatIntegrationModuleEditorView view, IModuleEditorViewParent parentView, VRChatIntegrationModuleConfig module)
{
_view = view;
_parentView = parentView;
_module = module;

SubscribeEvents();
}

private void SubscribeEvents()
{
_view.Load += OnLoad;
_view.Unload += OnUnload;

_view.ForceUpdateView += OnForceUpdateView;
_view.ConfigChange += OnConfigChange;
}

private void UnsubscribeEvents()
{
_view.Load -= OnLoad;
_view.Unload -= OnUnload;

_view.ForceUpdateView -= OnForceUpdateView;
_view.ConfigChange -= OnConfigChange;
}

private void OnForceUpdateView()
{
UpdateView();
}

private void OnConfigChange()
{
_module.customCabinetToggleName = _view.UseCustomCabinetToggleName ? _view.CustomCabinetToggleName : null;
}

public bool IsValid()
{
return _module.customCabinetToggleName != null ? _module.customCabinetToggleName.Trim() != "" : true;
}

private void UpdateView()
{
if (_module.customCabinetToggleName != null)
{
_view.UseCustomCabinetToggleName = true;
_view.CustomCabinetToggleName = _module.customCabinetToggleName;
}
else
{
_view.UseCustomCabinetToggleName = false;
_view.CustomCabinetToggleName = "";
}
}

private void OnLoad()
{
UpdateView();
}

private void OnUnload()
{
UnsubscribeEvents();
}
}
}

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

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public interface ICabinet

bool GroupDynamicsSeparateGameObjects { get; set; }

bool AnimationGenerationWriteDefaults { get; set; }

DTCabinetWearable[] GetWearables();

void Apply(DTReport report);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class DTCabinet : DTBaseComponent, ICabinet
[field: SerializeField] public string AvatarArmatureName { get; set; }
[field: SerializeField] public bool GroupDynamics { get; set; }
[field: SerializeField] public bool GroupDynamicsSeparateGameObjects { get; set; }
[field: SerializeField] public bool AnimationGenerationWriteDefaults { get; set; }

public DTCabinet()
{
Expand All @@ -41,6 +42,7 @@ public DTCabinet()
AvatarArmatureName = "Armature";
GroupDynamics = true;
GroupDynamicsSeparateGameObjects = true;
AnimationGenerationWriteDefaults = true;
}

public DTCabinetWearable[] GetWearables()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ namespace Chocopoi.DressingTools.Integration.VRChat.Modules
{
internal class VRChatIntegrationModuleConfig : IModuleConfig
{
public string customCabinetToggleName;

public VRChatIntegrationModuleConfig()
{
customCabinetToggleName = null;
}
}

[InitializeOnLoad]
Expand Down
Loading