Decompiled source of MikuShowcase v0.2.5
plugins/com.github.Thanks.MikuShowcase.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using MikuDanceProject.Core; using MikuDanceProject.Mmd; using MikuDanceProject.Runtime; using Photon.Pun; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } internal static class IsExternalInit { } } namespace MikuDanceProject.Runtime { internal sealed class DanceController : MonoBehaviour { private readonly struct PlacementPose { public Vector3 Position { get; } public Vector3 Forward { get; } public string Source { get; } private PlacementPose(Vector3 position, Vector3 forward, string source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Position = position; Forward = forward; Source = source; } public static PlacementPose Create(Vector3 position, Vector3 forward, string source) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return new PlacementPose(position, forward, source); } } [CompilerGenerated] private sealed class <LoadAssetsRoutine>d__60 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public DanceController <>4__this; private string <resolvedUnityBundlePath>5__2; object? IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadAssetsRoutine>d__60(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <resolvedUnityBundlePath>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; DanceController danceController = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (danceController._config == null || danceController._logger == null || danceController._isLoading) { return false; } danceController._isLoading = true; <resolvedUnityBundlePath>5__2 = danceController._config.ResolveUnityBundlePath(); <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { if (!File.Exists(<resolvedUnityBundlePath>5__2)) { danceController._logger.LogError((object)("Required Unity asset bundle file was not found: '" + <resolvedUnityBundlePath>5__2 + "'.")); return false; } danceController._loadedPrefab = danceController._unityBundleLoader.Load(<resolvedUnityBundlePath>5__2, danceController._logger); Object.DontDestroyOnLoad((Object)(object)danceController._loadedPrefab.Template); danceController._logger.LogInfo((object)("Using Unity asset bundle dancer source '" + <resolvedUnityBundlePath>5__2 + "'.")); } catch (Exception arg) { danceController._logger.LogError((object)$"Failed to load Unity asset bundle dancer source '{<resolvedUnityBundlePath>5__2}': {arg}"); } finally { danceController._isLoading = false; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float GroundProbeStartHeight = 80f; private const float GroundProbeDistance = 200f; private const float PlayerGroundProbeStartHeight = 1.25f; private const float PlayerGroundProbeMaxRise = 0.6f; private const float PlayerGroundProbePreferredMaxDrop = 0.9f; private const float PlayerGroundProbeFallbackMaxDrop = 1.25f; private const float PlayerGroundProbeSearchRadius = 3f; private const float PlayerColliderFootPadding = 0.05f; private const float RuntimeRefreshInterval = 0.25f; private const float OfflinePauseTimeScaleThreshold = 0.001f; private const float AudioMinDistanceMeters = 1f; private const float MotionTrimStartFrame = 435f; private const float MotionFrameRate = 30f; private const float AudioFadeDurationSeconds = 0.35f; private const float AudioRestartLeadTimeSeconds = 0.05f; private const BindingFlags InstanceBindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private const BindingFlags StaticBindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private const string DancerObjectName = "MikuDanceDisplay"; private static readonly Vector3 AirportDisplayPosition = new Vector3(-16.78f, 2.55f, 64.85f); private static readonly Vector3 AirportDisplayForward = Vector3.forward; private static readonly Vector3[] PlayerGroundProbeSampleOffsets = BuildPlayerGroundSampleOffsets(); private static readonly Type? CharacterType = FindGameType("Character"); private static readonly Type? PlayerType = FindGameType("Player"); private static readonly Type? MenuWindowType = FindGameType("MenuWindow"); private static readonly FieldInfo? LocalCharacterField = CharacterType?.GetField("localCharacter", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? LocalPlayerField = PlayerType?.GetField("localPlayer", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? AllActiveWindowsField = MenuWindowType?.GetField("AllActiveWindows", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private static readonly PropertyInfo? CharacterCenterProperty = CharacterType?.GetProperty("Center", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly PropertyInfo? CharacterVirtualCenterProperty = CharacterType?.GetProperty("VirtualCenter", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly PropertyInfo? PlayerCharacterProperty = PlayerType?.GetProperty("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo? PlayerCharacterField = PlayerType?.GetField("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly PropertyInfo? MenuWindowIsOpenProperty = MenuWindowType?.GetProperty("isOpen", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private readonly UnityAssetBundleLoader _unityBundleLoader = new UnityAssetBundleLoader(); private DancePluginConfig? _config; private ManualLogSource? _logger; private LoadedDancePrefab? _loadedPrefab; private GameObject? _activeDancer; private Animator? _activeAnimator; private Animation? _activeAnimation; private AudioSource? _activeAudioSource; private AnimationClip? _activePrimaryAnimatorClip; private bool _activeUsesMmdMorphBridge; private PlacementPose _activePlacement; private bool _hasActivePlacement; private bool _isLoading; private float _nextRefreshTime; private string? _lastSceneName; private bool _loggedSceneHint; private bool _lastAudioEnabledState; private bool _audioRetrySuppressed; private bool _isPausedForOfflineMenu; private bool _audioPausedForOfflineMenu; private AudioSource? _fadingAudioSource; private float _audioFadeStartTime; private float _audioFadeDuration; private float _audioFadeTargetVolume; public void Initialize(DancePluginConfig config, ManualLogSource logger) { _config = config; _logger = logger; _lastAudioEnabledState = config.EnableAudio.Value; } private void Start() { ((MonoBehaviour)this).StartCoroutine(LoadAssetsRoutine()); } private void OnDestroy() { _unityBundleLoader.UnloadRetainedBundle(); } private void Update() { if (_config == null || _logger == null) { return; } TrackSceneTransitions(); if (!_config.ModEnabled.Value) { if ((Object)(object)_activeDancer != (Object)null) { DestroyActiveDancer("Model hidden because ModEnabled=False."); } _hasActivePlacement = false; return; } EnsureAirportLobbyDisplay(); ProcessSpawnHotkey(); MaintainSynchronizedLoopPlayback(); UpdateActiveAudioFade(); if (Time.unscaledTime < _nextRefreshTime) { return; } _nextRefreshTime = Time.unscaledTime + 0.25f; if (!((Object)(object)_activeDancer == (Object)null)) { if (_hasActivePlacement) { ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab); } RefreshLivePlayback(_activeDancer); } } [IteratorStateMachine(typeof(<LoadAssetsRoutine>d__60))] private IEnumerator LoadAssetsRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LoadAssetsRoutine>d__60(0) { <>4__this = this }; } private void TrackSceneTransitions() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; if (!string.Equals(name, _lastSceneName, StringComparison.Ordinal)) { _lastSceneName = name; _loggedSceneHint = false; _nextRefreshTime = 0f; if ((Object)(object)_activeDancer != (Object)null) { DestroyActiveDancer("Scene changed to '" + name + "'. The model must be placed again in the new scene."); } _hasActivePlacement = false; _isPausedForOfflineMenu = false; _audioPausedForOfflineMenu = false; } } private void EnsureAirportLobbyDisplay() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if (_loadedPrefab == null || (Object)(object)_activeDancer != (Object)null || _hasActivePlacement) { return; } Scene activeScene = SceneManager.GetActiveScene(); if (!string.Equals(((Scene)(ref activeScene)).name, "Airport", StringComparison.OrdinalIgnoreCase)) { return; } _activePlacement = CreateGroundLockedPlacement(AirportDisplayPosition, AirportDisplayForward, "AirportLobbyDisplay"); _hasActivePlacement = true; if (EnsureDancerInstance() && !((Object)(object)_activeDancer == (Object)null)) { ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab); ConfigurePlayback(_activeDancer); ManualLogSource? logger = _logger; if (logger != null) { string text = $"Spawned default Airport display model at {_activeDancer.transform.position}. "; Quaternion rotation = _activeDancer.transform.rotation; logger.LogInfo((object)(text + $"rotation={((Quaternion)(ref rotation)).eulerAngles}, scale={_activeDancer.transform.localScale}.")); } } } private void ProcessSpawnHotkey() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (_config != null && _logger != null) { if (!_loggedSceneHint) { _loggedSceneHint = true; ManualLogSource? logger = _logger; Scene activeScene = SceneManager.GetActiveScene(); logger.LogInfo((object)$"Placement hotkey ready in scene '{((Scene)(ref activeScene)).name}'. Press {_config.SpawnModelKey.Value} to spawn the model or move it to the local player's current ground position."); } KeyCode value = _config.SpawnModelKey.Value; if ((int)value != 0 && Input.GetKeyDown(value)) { SpawnOrMoveToCurrentPlayer(); } } } private void SpawnOrMoveToCurrentPlayer() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) if (_config == null || _logger == null) { return; } if (_loadedPrefab == null) { _logger.LogWarning((object)(_isLoading ? "The Unity asset bundle is still loading. Try the placement hotkey again in a moment." : "The Unity asset bundle has not been loaded successfully, so the model cannot be spawned.")); return; } if (!TryResolveCurrentLocalPlayerPose(out Vector3 position, out Vector3 forward, out Transform ignoredRoot, out string source)) { _logger.LogWarning((object)"The local player transform is not available yet, so the model cannot be moved right now."); return; } Vector3 forward2 = ResolveFacingDirection(-forward); _activePlacement = CreatePlayerGroundLockedPlacement(position, forward2, source, ignoredRoot); _hasActivePlacement = true; bool flag = EnsureDancerInstance(); if (!((Object)(object)_activeDancer == (Object)null)) { ApplyPlacement(_activeDancer.transform, _activePlacement, _config, _loadedPrefab); if (flag) { ConfigurePlayback(_activeDancer); } else { RefreshLivePlayback(_activeDancer); } ManualLogSource? logger = _logger; string[] obj = new string[7] { flag ? "Spawned" : "Moved", " display model in scene '", null, null, null, null, null }; Scene activeScene = SceneManager.GetActiveScene(); obj[2] = ((Scene)(ref activeScene)).name; obj[3] = "'. "; obj[4] = $"source={source}, playerPosition={position}, groundedPosition={_activePlacement.Position}, "; object arg = _activeDancer.transform.position; Quaternion rotation = _activeDancer.transform.rotation; obj[5] = $"modelPosition={arg}, modelRotation={((Quaternion)(ref rotation)).eulerAngles}, "; obj[6] = $"modelScale={_activeDancer.transform.localScale}."; logger.LogInfo((object)string.Concat(obj)); } } private bool EnsureDancerInstance() { if ((Object)(object)_activeDancer != (Object)null || _loadedPrefab == null) { return false; } _activeDancer = Object.Instantiate<GameObject>(_loadedPrefab.Template); ((Object)_activeDancer).name = "MikuDanceDisplay"; RemoveAllColliders(_activeDancer); ResetAudioPlaybackState(); CacheActiveRuntimeComponents(_activeDancer); _activeUsesMmdMorphBridge = false; if (_loadedPrefab.Source == LoadedPrefabSource.UnityAssetBundle) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)("Using embedded Animator playback for '" + ((Object)_activeDancer).name + "'. Runtime MMD4Mecanim morph bridge is disabled for Unity AssetBundle models to avoid CreateMMDModel errors and blendshape overrides.")); } } if (0 == 0 && _loadedPrefab.Source == LoadedPrefabSource.RuntimePmx) { DancePhysicsConfigurator.Apply(_activeDancer); } if (_loadedPrefab.Source == LoadedPrefabSource.RuntimePmx) { ConfigureMotionSolvers(_activeDancer); } NormalizeRendererMaterials(_activeDancer); ConfigureFacialExpressions(_activeDancer); _activeDancer.SetActive(true); return true; } private void DestroyActiveDancer(string reason) { if (!((Object)(object)_activeDancer == (Object)null)) { AudioSource activeAudioSource = _activeAudioSource; if ((Object)(object)activeAudioSource != (Object)null && activeAudioSource.isPlaying) { activeAudioSource.Stop(); } ClearActiveAudioFade(activeAudioSource); Object.Destroy((Object)(object)_activeDancer); _activeDancer = null; _activeUsesMmdMorphBridge = false; ClearActiveRuntimeComponents(); ResetAudioPlaybackState(); ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)reason); } } } private static void ApplyPlacement(Transform dancerTransform, PlacementPose placement, DancePluginConfig config, LoadedDancePrefab? prefab) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) float resolvedModelScale = config.ResolvedModelScale; float num = ((prefab == null) ? 0f : ((0f - prefab.LocalMinY) * resolvedModelScale)); Vector3 position = placement.Position; position.y += num; dancerTransform.localScale = Vector3.one * resolvedModelScale; dancerTransform.position = position; dancerTransform.rotation = Quaternion.LookRotation(ResolveFacingDirection(placement.Forward), Vector3.up) * Quaternion.Euler(0f, config.ModelYawCorrection.Value, 0f); } private static PlacementPose CreateGroundLockedPlacement(Vector3 desiredPosition, Vector3 forward, string source) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) Vector3 position = desiredPosition; position.y = ResolveGroundYExact(desiredPosition, desiredPosition.y + 80f, 200f, float.PositiveInfinity); return PlacementPose.Create(position, forward, source); } private static PlacementPose CreatePlayerGroundLockedPlacement(Vector3 desiredPosition, Vector3 forward, string source, Transform? ignoredRoot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Vector3 position = desiredPosition; position.y = ResolveGroundYNearPlayer(desiredPosition, desiredPosition.y + 1.25f, 200f, desiredPosition.y + 0.6f, ignoredRoot); return PlacementPose.Create(position, forward, source); } private static Vector3 ResolveFacingDirection(Vector3 forward) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(forward, Vector3.up); if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f)) { return Vector3.forward; } return ((Vector3)(ref val)).normalized; } private static bool TryResolveCurrentLocalPlayerPose(out Vector3 position, out Vector3 forward, out Transform? ignoredRoot, out string source) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (TryGetLocalCharacterObject(out object source2) && TryResolveCharacterPose(source2, "Character.localCharacter", out position, out forward, out ignoredRoot, out source)) { return true; } if (TryGetLocalPlayerCharacterObject(out object source3) && TryResolveCharacterPose(source3, "Player.localPlayer.character", out position, out forward, out ignoredRoot, out source)) { return true; } position = default(Vector3); forward = Vector3.forward; ignoredRoot = null; source = string.Empty; return false; } private static float ResolveGroundYExact(Vector3 desiredPosition, float startY, float maxDistance, float maxAcceptedY, Transform? ignoredRoot = null) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) Transform ignoredRoot2 = ignoredRoot; RaycastHit[] array = Physics.RaycastAll(new Vector3(desiredPosition.x, startY, desiredPosition.z), Vector3.down, maxDistance, -1, (QueryTriggerInteraction)1); if (array.Length == 0) { return desiredPosition.y; } RaycastHit[] array2 = (from hit in array where (Object)(object)((RaycastHit)(ref hit)).collider != (Object)null where ((RaycastHit)(ref hit)).normal.y > 0.35f where !ShouldIgnoreGroundHit(hit, ignoredRoot2) select hit).ToArray(); if (array2.Length == 0) { return desiredPosition.y; } if (!float.IsPositiveInfinity(maxAcceptedY)) { RaycastHit val = (from hit in array2 where ((RaycastHit)(ref hit)).point.y <= maxAcceptedY orderby ((RaycastHit)(ref hit)).point.y descending, ((RaycastHit)(ref hit)).distance select hit).FirstOrDefault(); if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null) { return ((RaycastHit)(ref val)).point.y; } return desiredPosition.y; } RaycastHit val2 = (from hit in array2 orderby ((RaycastHit)(ref hit)).point.y descending, ((RaycastHit)(ref hit)).distance select hit).FirstOrDefault(); if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null)) { return ((RaycastHit)(ref val2)).point.y; } return desiredPosition.y; } private static float ResolveGroundYNearPlayer(Vector3 desiredPosition, float startY, float maxDistance, float maxAcceptedY, Transform? ignoredRoot) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) GroundSampleCandidate? groundSampleCandidate = null; GroundSampleCandidate? groundSampleCandidate2 = null; for (int i = 0; i < PlayerGroundProbeSampleOffsets.Length; i++) { GroundSampleCandidate? groundSampleCandidate3 = TryResolveGroundCandidate(desiredPosition + PlayerGroundProbeSampleOffsets[i], startY, maxDistance, maxAcceptedY, ignoredRoot); if (groundSampleCandidate3.HasValue) { if (!groundSampleCandidate2.HasValue || groundSampleCandidate3.Value.IsBetterThan(groundSampleCandidate2.Value)) { groundSampleCandidate2 = groundSampleCandidate3; } if (!(desiredPosition.y - groundSampleCandidate3.Value.Y > 0.9f) && (!groundSampleCandidate.HasValue || groundSampleCandidate3.Value.IsBetterThan(groundSampleCandidate.Value))) { groundSampleCandidate = groundSampleCandidate3; } } } if (groundSampleCandidate.HasValue) { return groundSampleCandidate.Value.Y; } if (groundSampleCandidate2.HasValue && desiredPosition.y - groundSampleCandidate2.Value.Y <= 1.25f) { return groundSampleCandidate2.Value.Y; } return desiredPosition.y; } private static GroundSampleCandidate? TryResolveGroundCandidate(Vector3 desiredPosition, float startY, float maxDistance, float maxAcceptedY, Transform? ignoredRoot) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) Transform ignoredRoot2 = ignoredRoot; RaycastHit[] array = Physics.RaycastAll(new Vector3(desiredPosition.x, startY, desiredPosition.z), Vector3.down, maxDistance, -1, (QueryTriggerInteraction)1); if (array.Length == 0) { return null; } GroundSampleCandidate[] array2 = (from hit in array where (Object)(object)((RaycastHit)(ref hit)).collider != (Object)null where ((RaycastHit)(ref hit)).normal.y > 0.35f where !ShouldIgnoreGroundHit(hit, ignoredRoot2) where ((RaycastHit)(ref hit)).point.y <= maxAcceptedY select new GroundSampleCandidate(((RaycastHit)(ref hit)).point.y, Mathf.Abs(desiredPosition.y - ((RaycastHit)(ref hit)).point.y), Vector2.Distance(new Vector2(desiredPosition.x, desiredPosition.z), new Vector2(((RaycastHit)(ref hit)).point.x, ((RaycastHit)(ref hit)).point.z)), ((RaycastHit)(ref hit)).distance) into hit orderby hit.VerticalDelta, hit.HorizontalDelta, hit.RaycastDistance select hit).ToArray(); if (array2.Length != 0) { return array2[0]; } return null; } private static bool TryGetLocalCharacterObject(out object source) { source = LocalCharacterField?.GetValue(null); return source != null; } private static bool TryGetLocalPlayerCharacterObject(out object source) { object obj = LocalPlayerField?.GetValue(null); if (obj == null) { source = null; return false; } source = PlayerCharacterProperty?.GetValue(obj, null) ?? PlayerCharacterField?.GetValue(obj); return source != null; } private static bool TryResolveCharacterPose(object source, string sourceName, out Vector3 position, out Vector3 forward, out Transform? ignoredRoot, out string resolvedSource) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) resolvedSource = sourceName; if (!TryExtractTransform(source, out Transform transform)) { position = default(Vector3); forward = Vector3.forward; ignoredRoot = null; return false; } ignoredRoot = transform; position = transform.position; Vector3 vector2; if (TryExtractVector3(CharacterCenterProperty?.GetValue(source, null), out var vector)) { position = new Vector3(vector.x, position.y, vector.z); resolvedSource = sourceName + ".CenterXZ"; } else if (TryExtractVector3(CharacterVirtualCenterProperty?.GetValue(source, null), out vector2)) { position = new Vector3(vector2.x, position.y, vector2.z); resolvedSource = sourceName + ".VirtualCenterXZ"; } position = new Vector3(position.x, ResolveCharacterFootY(transform, position.y), position.z); resolvedSource += ".FootY"; forward = ResolvePlanarForward(transform); return true; } private static float ResolveCharacterFootY(Transform root, float fallbackY) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) bool flag = false; float num = float.PositiveInfinity; Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && val.enabled && !val.isTrigger) { Bounds bounds = val.bounds; float y = ((Bounds)(ref bounds)).min.y; if (!float.IsNaN(y) && !float.IsInfinity(y)) { num = Mathf.Min(num, y); flag = true; } } } if (!flag) { return fallbackY; } return num + 0.05f; } private static bool ShouldIgnoreGroundHit(RaycastHit hit, Transform? ignoredRoot) { if ((Object)(object)ignoredRoot == (Object)null || (Object)(object)((RaycastHit)(ref hit)).collider == (Object)null) { return false; } if (IsSameOrChildTransform(((Component)((RaycastHit)(ref hit)).collider).transform, ignoredRoot)) { return true; } Rigidbody attachedRigidbody = ((RaycastHit)(ref hit)).collider.attachedRigidbody; if ((Object)(object)attachedRigidbody != (Object)null) { return IsSameOrChildTransform(((Component)attachedRigidbody).transform, ignoredRoot); } return false; } private static bool IsSameOrChildTransform(Transform? candidate, Transform root) { if ((Object)(object)candidate != (Object)null) { if (!((Object)(object)candidate == (Object)(object)root)) { return candidate.IsChildOf(root); } return true; } return false; } private static Vector3[] BuildPlayerGroundSampleOffsets() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) Vector2[] obj = new Vector2[8] { new Vector2(1f, 0f), new Vector2(-1f, 0f), new Vector2(0f, 1f), new Vector2(0f, -1f), default(Vector2), default(Vector2), default(Vector2), default(Vector2) }; Vector2 val = new Vector2(1f, 1f); obj[4] = ((Vector2)(ref val)).normalized; val = new Vector2(1f, -1f); obj[5] = ((Vector2)(ref val)).normalized; val = new Vector2(-1f, 1f); obj[6] = ((Vector2)(ref val)).normalized; val = new Vector2(-1f, -1f); obj[7] = ((Vector2)(ref val)).normalized; Vector2[] array = (Vector2[])(object)obj; float[] array2 = new float[6] { 0.35f, 0.7f, 1.1f, 1.6f, 2.2f, 3f }; List<Vector3> list = new List<Vector3>(1 + array.Length * array2.Length) { Vector3.zero }; float[] array3 = array2; foreach (float num in array3) { foreach (Vector2 val2 in array) { list.Add(new Vector3(val2.x * num, 0f, val2.y * num)); } } return list.ToArray(); } private void ConfigureMotionSolvers(GameObject dancer) { if (_logger != null && _loadedPrefab != null) { (dancer.GetComponent<MmdLegIkSolver>() ?? dancer.AddComponent<MmdLegIkSolver>()).Initialize(_loadedPrefab, _logger); } } private static bool TryExtractTransform(object? source, out Transform transform) { Transform val = (Transform)((source is Transform) ? source : null); if (val == null) { Component val2 = (Component)((source is Component) ? source : null); if (val2 == null) { GameObject val3 = (GameObject)((source is GameObject) ? source : null); if (val3 != null) { transform = val3.transform; return true; } transform = null; return false; } transform = val2.transform; return (Object)(object)transform != (Object)null; } transform = val; return true; } private static bool TryExtractVector3(object? value, out Vector3 vector) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (value is Vector3 val) { vector = val; return true; } vector = default(Vector3); return false; } private static Vector3 ResolvePlanarForward(Transform transform) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.ProjectOnPlane(transform.forward, Vector3.up); if (!(((Vector3)(ref val)).sqrMagnitude > 0.01f)) { return Vector3.forward; } return ((Vector3)(ref val)).normalized; } private static Type? FindGameType(string typeName) { return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly) => string.Equals(assembly.GetName().Name, "Assembly-CSharp", StringComparison.Ordinal))?.GetType(typeName, throwOnError: false, ignoreCase: false); } private static void RemoveAllColliders(GameObject root) { Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } private void NormalizeRendererMaterials(GameObject root) { if (_logger == null) { return; } Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { val.enabled = true; SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((val is SkinnedMeshRenderer) ? val : null); if (val2 == null) { continue; } val2.updateWhenOffscreen = true; Mesh sharedMesh = val2.sharedMesh; if ((Object)(object)sharedMesh == (Object)null) { continue; } int num = Mathf.Max(1, sharedMesh.subMeshCount); if (val.sharedMaterials.Length == num) { continue; } Material[] array = val.sharedMaterials.Where((Material material) => (Object)(object)material != (Object)null).Take(num).ToArray(); if (array.Length == 0) { continue; } if (array.Length < num) { Array.Resize(ref array, num); for (int j = 0; j < num; j++) { Material[] array2 = array; int num2 = j; if (array2[num2] == null) { array2[num2] = array[Mathf.Max(0, j - 1)]; } } } val.sharedMaterials = array; _logger.LogInfo((object)$"Normalized runtime materials for '{((Object)val).name}'. subMeshes={num}, materials={val.sharedMaterials.Length}."); } } private void ConfigurePlayback(GameObject dancer) { CacheActiveRuntimeComponents(dancer); AudioSource activeAudioSource = _activeAudioSource; AudioClip val = ResolveAudioClip(activeAudioSource); Animator activeAnimator = _activeAnimator; if ((Object)(object)activeAnimator != (Object)null && (Object)(object)activeAnimator.runtimeAnimatorController != (Object)null) { ConfigureAudioSource(activeAudioSource, val); AnimationClip activePrimaryAnimatorClip = _activePrimaryAnimatorClip; float num = ResolveSynchronizedAnimatorSpeed(activePrimaryAnimatorClip, val); activeAnimator.cullingMode = (AnimatorCullingMode)0; activeAnimator.applyRootMotion = false; activeAnimator.updateMode = (AnimatorUpdateMode)0; activeAnimator.speed = num; activeAnimator.Rebind(); activeAnimator.Update(0f); StartAnimatorAtBeginning(activeAnimator, activePrimaryAnimatorClip); StartMorphPlayback(dancer); bool flag = StartAudioIfEnabled(activeAudioSource, val, activePrimaryAnimatorClip, suppressFurtherRetries: true); ManualLogSource? logger = _logger; if (logger != null) { string[] obj = new string[11] { "Animator configured for '", ((Object)dancer).name, "', controller='", ((Object)activeAnimator.runtimeAnimatorController).name, "', avatar='", null, null, null, null, null, null }; Avatar avatar = activeAnimator.avatar; obj[5] = ((avatar != null) ? ((Object)avatar).name : null) ?? "(none)"; obj[6] = "', "; obj[7] = string.Format("clip='{0}', clipLength={1:0.###}, ", ((activePrimaryAnimatorClip != null) ? ((Object)activePrimaryAnimatorClip).name : null) ?? "(none)", (activePrimaryAnimatorClip != null) ? activePrimaryAnimatorClip.length : 0f); obj[8] = string.Format("audioEnabled={0}, audioClip='{1}', audioLength={2:0.###}, ", _config?.EnableAudio.Value ?? false, ((val != null) ? ((Object)val).name : null) ?? "(none)", (val != null) ? val.length : 0f); obj[9] = $"audioSegmentStart={ResolveAudioSegmentStartSeconds(activePrimaryAnimatorClip, val):0.###}, audioSegmentLength={ResolveAudioSegmentDuration(activePrimaryAnimatorClip, val):0.###}, "; obj[10] = $"animatorSpeed={num:0.###}, audioVolume={_config?.ResolvedAudioVolume ?? 0f:0.###}, audioRange={_config?.ResolvedAudioRangeMeters ?? 0f:0.###}, audioStarted={flag}, audioIsPlaying={activeAudioSource != null && activeAudioSource.isPlaying}."; logger.LogInfo((object)string.Concat(obj)); } return; } Animation activeAnimation = _activeAnimation; if ((Object)(object)activeAnimation != (Object)null && (Object)(object)_loadedPrefab?.Clip != (Object)null) { activeAnimation.cullingType = (AnimationCullingType)0; if ((Object)(object)activeAnimation.GetClip(((Object)_loadedPrefab.Clip).name) == (Object)null) { activeAnimation.AddClip(_loadedPrefab.Clip, ((Object)_loadedPrefab.Clip).name); } activeAnimation.clip = _loadedPrefab.Clip; activeAnimation.wrapMode = (WrapMode)2; activeAnimation.Stop(); activeAnimation.Rewind(); activeAnimation.Play(((Object)_loadedPrefab.Clip).name); ConfigureAudioSource(activeAudioSource, val); StartAudioIfEnabled(activeAudioSource, val, _loadedPrefab.Clip, suppressFurtherRetries: true); ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogInfo((object)$"Animation configured for '{((Object)dancer).name}', clip='{((Object)_loadedPrefab.Clip).name}', isPlaying={activeAnimation.isPlaying}."); } } else { StartMorphPlayback(dancer); } } private void ConfigureFacialExpressions(GameObject dancer) { CacheActiveRuntimeComponents(dancer); if ((Object)(object)_loadedPrefab?.MorphClip != (Object)null) { MikuFacialExpressionController component = dancer.GetComponent<MikuFacialExpressionController>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = false; } ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)("Skipping fallback facial expression controller for '" + ((Object)dancer).name + "' because a VMD morph clip is available.")); } return; } if (_activeUsesMmdMorphBridge) { MikuFacialExpressionController component2 = dancer.GetComponent<MikuFacialExpressionController>(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogInfo((object)("Skipping fallback facial expression controller for '" + ((Object)dancer).name + "' because the runtime MMD4Mecanim morph bridge is active.")); } return; } LoadedDancePrefab? loadedPrefab = _loadedPrefab; if (loadedPrefab != null && loadedPrefab.Source == LoadedPrefabSource.UnityAssetBundle && (Object)(object)_activeAnimator != (Object)null && (Object)(object)_activeAnimator.runtimeAnimatorController != (Object)null && (Object)(object)_activePrimaryAnimatorClip != (Object)null) { ManualLogSource? logger3 = _logger; if (logger3 != null) { logger3.LogInfo((object)("Unity AssetBundle Animator clip '" + ((Object)_activePrimaryAnimatorClip).name + "' is active on '" + ((Object)dancer).name + "', but no morph bridge is available. Falling back to simplified facial controller.")); } } (dancer.GetComponent<MikuFacialExpressionController>() ?? dancer.AddComponent<MikuFacialExpressionController>()).Initialize(_activeAudioSource, _activeAnimator, _logger); } private void RefreshLivePlayback(GameObject dancer) { CacheActiveRuntimeComponents(dancer); Animator activeAnimator = _activeAnimator; AudioSource activeAudioSource = _activeAudioSource; AudioClip val = ResolveAudioClip(activeAudioSource); ConfigureAudioSource(activeAudioSource, val); HandleAudioToggleState(); if (HandleOfflineMenuPause(activeAnimator, activeAudioSource, val)) { return; } if ((Object)(object)activeAnimator != (Object)null && (Object)(object)activeAnimator.runtimeAnimatorController != (Object)null) { AnimationClip val2 = ResolvePrimaryAnimatorClip(activeAnimator); activeAnimator.speed = ResolveSynchronizedAnimatorSpeed(val2, val); DancePluginConfig? config = _config; if (config == null || !config.EnableAudio.Value || !((Object)(object)activeAudioSource != (Object)null) || !((Object)(object)val != (Object)null) || activeAudioSource.isPlaying || _audioRetrySuppressed) { return; } StartAnimatorAtBeginning(activeAnimator, val2); StartMorphPlayback(dancer); if (StartAudioIfEnabled(activeAudioSource, val, val2, suppressFurtherRetries: true)) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)("Audio was enabled while the model was already active. Restarted synchronized playback with clip '" + ((Object)val).name + "'.")); } } } else { DancePluginConfig? config2 = _config; if (config2 != null && config2.EnableAudio.Value && (Object)(object)activeAudioSource != (Object)null && (Object)(object)val != (Object)null && !activeAudioSource.isPlaying && !_audioRetrySuppressed) { StartAudioIfEnabled(activeAudioSource, val, _loadedPrefab?.Clip, suppressFurtherRetries: true); } } } private void HandleAudioToggleState() { bool flag = _config?.EnableAudio.Value ?? false; if (flag != _lastAudioEnabledState) { _audioRetrySuppressed = false; _lastAudioEnabledState = flag; } } private void ResetAudioPlaybackState() { _audioRetrySuppressed = false; _lastAudioEnabledState = _config?.EnableAudio.Value ?? false; ClearActiveAudioFade(); } private void ConfigureAudioSource(AudioSource? audioSource, AudioClip? audioClip) { if (!((Object)(object)audioSource == (Object)null)) { if ((Object)(object)audioClip != (Object)null && (Object)(object)audioSource.clip == (Object)null) { audioSource.clip = audioClip; } audioSource.playOnAwake = false; audioSource.loop = false; DancePluginConfig? config = _config; audioSource.mute = config == null || !config.EnableAudio.Value; if (!IsActiveAudioFade(audioSource)) { audioSource.volume = _config?.ResolvedAudioVolume ?? 1f; } float maxDistance = Mathf.Max(1.01f, _config?.ResolvedAudioRangeMeters ?? 5f); audioSource.spatialBlend = 1f; audioSource.dopplerLevel = 0f; audioSource.rolloffMode = (AudioRolloffMode)1; audioSource.minDistance = 1f; audioSource.maxDistance = maxDistance; audioSource.spread = 0f; DancePluginConfig? config2 = _config; if ((config2 == null || !config2.EnableAudio.Value) && audioSource.isPlaying) { ClearActiveAudioFade(audioSource); audioSource.Stop(); audioSource.time = 0f; } } } private bool StartAudioIfEnabled(AudioSource? audioSource, AudioClip? audioClip, AnimationClip? animationClip, bool suppressFurtherRetries) { DancePluginConfig? config = _config; if (config == null || !config.EnableAudio.Value || (Object)(object)audioSource == (Object)null || (Object)(object)audioClip == (Object)null) { if ((Object)(object)audioSource != (Object)null) { ClearActiveAudioFade(audioSource); audioSource.Stop(); audioSource.time = 0f; } _audioRetrySuppressed = false; return false; } float num = ResolveAudioSegmentStartSeconds(animationClip, audioClip); float num2 = ResolveAudioSegmentDuration(animationClip, audioClip); if (num2 <= 0.01f) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Audio segment duration is invalid for clip '" + ((Object)audioClip).name + "'.")); } return false; } try { audioClip.LoadAudioData(); audioSource.clip = audioClip; audioSource.loop = false; audioSource.time = Mathf.Clamp(num, 0f, Mathf.Max(0f, audioClip.length - 0.01f)); audioSource.volume = 0f; audioSource.Play(); BeginAudioFade(audioSource, Mathf.Min(0.35f, num2 * 0.5f)); } catch (Exception ex) { if (suppressFurtherRetries) { _audioRetrySuppressed = true; } ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)("Audio playback failed for clip '" + ((Object)audioClip).name + "': " + ex.Message)); } return false; } bool isPlaying = audioSource.isPlaying; if (!isPlaying && suppressFurtherRetries) { _audioRetrySuppressed = true; ManualLogSource? logger3 = _logger; if (logger3 == null) { return isPlaying; } logger3.LogWarning((object)("Audio playback could not start for clip '" + ((Object)audioClip).name + "'. Automatic retries are suppressed until audio is toggled again or the model is respawned.")); } return isPlaying; } private void MaintainSynchronizedLoopPlayback() { if ((Object)(object)_activeDancer == (Object)null) { return; } DancePluginConfig? config = _config; if (config == null || !config.EnableAudio.Value || _isPausedForOfflineMenu) { return; } if ((Object)(object)_activeAnimator == (Object)null || (Object)(object)_activeAudioSource == (Object)null) { CacheActiveRuntimeComponents(_activeDancer); } Animator activeAnimator = _activeAnimator; AudioSource activeAudioSource = _activeAudioSource; AudioClip val = ResolveAudioClip(activeAudioSource); if ((Object)(object)activeAnimator == (Object)null || (Object)(object)activeAnimator.runtimeAnimatorController == (Object)null || (Object)(object)activeAudioSource == (Object)null || (Object)(object)val == (Object)null || !activeAudioSource.isPlaying) { return; } AnimationClip activePrimaryAnimatorClip = _activePrimaryAnimatorClip; if (!((Object)(object)activePrimaryAnimatorClip == (Object)null)) { float num = ResolveAudioSegmentEndSeconds(activePrimaryAnimatorClip, val); if (!(activeAudioSource.time < num - 0.05f)) { StartAnimatorAtBeginning(activeAnimator, activePrimaryAnimatorClip); StartMorphPlayback(_activeDancer); StartAudioIfEnabled(activeAudioSource, val, activePrimaryAnimatorClip, suppressFurtherRetries: true); } } } private void StartMorphPlayback(GameObject? dancer) { if (!((Object)(object)dancer == (Object)null) && !((Object)(object)_loadedPrefab?.MorphClip == (Object)null)) { Animation val = (_activeAnimation = dancer.GetComponent<Animation>() ?? dancer.AddComponent<Animation>()); val.cullingType = (AnimationCullingType)0; if ((Object)(object)val.GetClip(((Object)_loadedPrefab.MorphClip).name) == (Object)null) { val.AddClip(_loadedPrefab.MorphClip, ((Object)_loadedPrefab.MorphClip).name); } val.clip = _loadedPrefab.MorphClip; val.wrapMode = (WrapMode)2; val.Stop(((Object)_loadedPrefab.MorphClip).name); val.Rewind(((Object)_loadedPrefab.MorphClip).name); val.Play(((Object)_loadedPrefab.MorphClip).name); } } private void BeginAudioFade(AudioSource audioSource, float durationSeconds) { _fadingAudioSource = audioSource; _audioFadeStartTime = Time.unscaledTime; _audioFadeDuration = Mathf.Max(0.01f, durationSeconds); _audioFadeTargetVolume = _config?.ResolvedAudioVolume ?? 1f; audioSource.volume = 0f; } private void UpdateActiveAudioFade() { if ((Object)(object)_fadingAudioSource == (Object)null) { return; } DancePluginConfig? config = _config; if (config == null || !config.EnableAudio.Value || !_fadingAudioSource.isPlaying) { ClearActiveAudioFade(_fadingAudioSource); return; } float num = Mathf.Clamp01((Time.unscaledTime - _audioFadeStartTime) / _audioFadeDuration); _fadingAudioSource.volume = Mathf.Lerp(0f, _audioFadeTargetVolume, num); if (num >= 0.999f) { ClearActiveAudioFade(_fadingAudioSource); } } private bool IsActiveAudioFade(AudioSource? audioSource) { if ((Object)(object)audioSource != (Object)null) { return audioSource == _fadingAudioSource; } return false; } private void ClearActiveAudioFade(AudioSource? audioSource = null) { if (!((Object)(object)_fadingAudioSource == (Object)null) && (!((Object)(object)audioSource != (Object)null) || audioSource == _fadingAudioSource)) { if ((Object)(object)_fadingAudioSource != (Object)null) { _fadingAudioSource.volume = _config?.ResolvedAudioVolume ?? 1f; } _fadingAudioSource = null; _audioFadeStartTime = 0f; _audioFadeDuration = 0f; _audioFadeTargetVolume = 0f; } } private bool HandleOfflineMenuPause(Animator? animator, AudioSource? audioSource, AudioClip? audioClip) { if (ShouldPauseForOfflineMenu()) { if (!_isPausedForOfflineMenu) { _isPausedForOfflineMenu = true; _audioPausedForOfflineMenu = (Object)(object)audioSource != (Object)null && audioSource.isPlaying; if (_audioPausedForOfflineMenu) { audioSource.Pause(); } ManualLogSource? logger = _logger; if (logger != null) { logger.LogInfo((object)"Paused dancer playback because the offline menu is open."); } } if ((Object)(object)animator != (Object)null) { animator.speed = 0f; } Animation activeAnimation = _activeAnimation; if ((Object)(object)activeAnimation != (Object)null && (Object)(object)activeAnimation.clip != (Object)null && (TrackedReference)(object)activeAnimation[((Object)activeAnimation.clip).name] != (TrackedReference)null) { activeAnimation[((Object)activeAnimation.clip).name].speed = 0f; } return true; } if (!_isPausedForOfflineMenu) { return false; } _isPausedForOfflineMenu = false; if (_audioPausedForOfflineMenu) { DancePluginConfig? config = _config; if (config != null && config.EnableAudio.Value && (Object)(object)audioSource != (Object)null && (Object)(object)audioClip != (Object)null) { audioSource.UnPause(); } } Animation activeAnimation2 = _activeAnimation; if ((Object)(object)activeAnimation2 != (Object)null && (Object)(object)activeAnimation2.clip != (Object)null && (TrackedReference)(object)activeAnimation2[((Object)activeAnimation2.clip).name] != (TrackedReference)null) { activeAnimation2[((Object)activeAnimation2.clip).name].speed = 1f; } _audioPausedForOfflineMenu = false; ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogInfo((object)"Resumed dancer playback after closing the offline menu."); } return false; } private static bool ShouldPauseForOfflineMenu() { if (!PhotonNetwork.OfflineMode) { return false; } if (Time.timeScale <= 0.001f) { return true; } if (!(AllActiveWindowsField?.GetValue(null) is IEnumerable enumerable)) { return false; } bool flag = default(bool); foreach (object item in enumerable) { if (item != null) { object obj = MenuWindowIsOpenProperty?.GetValue(item, null); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0) { return true; } } } return false; } private static AudioClip? ResolveAudioClip(AudioSource? audioSource) { if ((Object)(object)audioSource == (Object)null) { return null; } if ((Object)(object)audioSource.clip != (Object)null) { return audioSource.clip; } AudioResource resource = audioSource.resource; return (AudioClip?)(object)((resource is AudioClip) ? resource : null); } private void CacheActiveRuntimeComponents(GameObject? dancer) { if ((Object)(object)dancer == (Object)null) { ClearActiveRuntimeComponents(); return; } _activeAnimator = dancer.GetComponentInChildren<Animator>(true); _activeAnimation = dancer.GetComponentInChildren<Animation>(true); _activeAudioSource = dancer.GetComponentInChildren<AudioSource>(true); _activePrimaryAnimatorClip = (((Object)(object)_activeAnimator != (Object)null && (Object)(object)_activeAnimator.runtimeAnimatorController != (Object)null) ? ResolvePrimaryAnimatorClip(_activeAnimator) : null); } private void ClearActiveRuntimeComponents() { _activeAnimator = null; _activeAnimation = null; _activeAudioSource = null; _activePrimaryAnimatorClip = null; } private static AnimationClip? ResolvePrimaryAnimatorClip(Animator animator) { RuntimeAnimatorController runtimeAnimatorController = animator.runtimeAnimatorController; if (runtimeAnimatorController == null) { return null; } return (from clip in runtimeAnimatorController.animationClips where (Object)(object)clip != (Object)null orderby clip.length descending select clip).FirstOrDefault(); } private static float ResolveSynchronizedAnimatorSpeed(AnimationClip? animationClip, AudioClip? audioClip) { if ((Object)(object)animationClip == (Object)null || animationClip.length <= 0.01f) { return 1f; } if ((Object)(object)audioClip == (Object)null || audioClip.length <= 0.01f) { return 1f; } float num = ResolveAudioSegmentDuration(animationClip, audioClip); if (num <= 0.01f) { return 1f; } return Mathf.Clamp(animationClip.length / num, 0.25f, 4f); } private static float ResolveAudioSegmentStartSeconds(AnimationClip? animationClip, AudioClip? audioClip) { if ((Object)(object)animationClip == (Object)null || (Object)(object)audioClip == (Object)null || audioClip.length <= 0.01f) { return 0f; } return Mathf.Clamp(14.5f, 0f, Mathf.Max(0f, audioClip.length - 0.01f)); } private static float ResolveAudioSegmentDuration(AnimationClip? animationClip, AudioClip? audioClip) { if ((Object)(object)audioClip == (Object)null || audioClip.length <= 0.01f) { return 0f; } float num = ResolveAudioSegmentStartSeconds(animationClip, audioClip); float num2 = Mathf.Max(0f, audioClip.length - num); if ((Object)(object)animationClip == (Object)null || animationClip.length <= 0.01f) { return num2; } return Mathf.Min(animationClip.length, num2); } private static float ResolveAudioSegmentEndSeconds(AnimationClip? animationClip, AudioClip? audioClip) { return ResolveAudioSegmentStartSeconds(animationClip, audioClip) + ResolveAudioSegmentDuration(animationClip, audioClip); } private static void StartAnimatorAtBeginning(Animator animator, AnimationClip? primaryClip) { animator.Play(0, 0, 0f); animator.Update(0f); } } internal readonly struct GroundSampleCandidate { public float Y { get; } public float VerticalDelta { get; } public float HorizontalDelta { get; } public float RaycastDistance { get; } public GroundSampleCandidate(float y, float verticalDelta, float horizontalDelta, float raycastDistance) { Y = y; VerticalDelta = verticalDelta; HorizontalDelta = horizontalDelta; RaycastDistance = raycastDistance; } public bool IsBetterThan(GroundSampleCandidate other) { if (VerticalDelta < other.VerticalDelta - 0.001f) { return true; } if (Mathf.Abs(VerticalDelta - other.VerticalDelta) > 0.001f) { return false; } if (HorizontalDelta < other.HorizontalDelta - 0.001f) { return true; } if (Mathf.Abs(HorizontalDelta - other.HorizontalDelta) > 0.001f) { return false; } return RaycastDistance < other.RaycastDistance; } } internal static class DancePhysicsConfigurator { private static readonly string[] HairPatterns = new string[8] { "ツインテ", "テール", "髪", "前髪", "横髪", "後髪", "おさげ", "ahoge" }; private static readonly string[] SkirtPatterns = new string[6] { "スカート", "skirt", "裾", "ひら", "リボン", "ネクタイ" }; public static void Apply(GameObject instanceRoot) { Transform[] componentsInChildren = instanceRoot.GetComponentsInChildren<Transform>(true); AttachDynamicBones(componentsInChildren, HairPatterns, ConfigureHair); AttachDynamicBones(componentsInChildren, SkirtPatterns, ConfigureSkirt); } private static void AttachDynamicBones(IEnumerable<Transform> transforms, IReadOnlyList<string> patterns, Action<DynamicBone> configure) { IReadOnlyList<string> patterns2 = patterns; Transform[] array = (from transform in transforms where transform.childCount > 0 where ContainsPattern(((Object)transform).name, patterns2) where !AncestorMatches(transform, patterns2) select transform).ToArray(); foreach (Transform val in array) { DynamicBone val2 = ((Component)val).gameObject.GetComponent<DynamicBone>() ?? ((Component)val).gameObject.AddComponent<DynamicBone>(); val2.m_Root = val; configure(val2); val2.SetupParticles(); } } private static void ConfigureHair(DynamicBone dynamicBone) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) dynamicBone.m_Damping = 0.12f; dynamicBone.m_Elasticity = 0.08f; dynamicBone.m_Stiffness = 0.12f; dynamicBone.m_Inert = 0.35f; dynamicBone.m_Friction = 0.03f; dynamicBone.m_Radius = 0.02f; dynamicBone.m_EndLength = 0.05f; dynamicBone.m_Gravity = new Vector3(0f, -0.12f, 0f); dynamicBone.m_Force = new Vector3(0f, 0f, 0.02f); } private static void ConfigureSkirt(DynamicBone dynamicBone) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) dynamicBone.m_Damping = 0.18f; dynamicBone.m_Elasticity = 0.04f; dynamicBone.m_Stiffness = 0.2f; dynamicBone.m_Inert = 0.22f; dynamicBone.m_Friction = 0.04f; dynamicBone.m_Radius = 0.03f; dynamicBone.m_EndLength = 0.03f; dynamicBone.m_Gravity = new Vector3(0f, -0.22f, 0f); dynamicBone.m_Force = Vector3.zero; } private static bool ContainsPattern(string name, IReadOnlyList<string> patterns) { string name2 = name; return patterns.Any((string pattern) => name2.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >= 0); } private static bool AncestorMatches(Transform transform, IReadOnlyList<string> patterns) { Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { if (ContainsPattern(((Object)parent).name, patterns)) { return true; } parent = parent.parent; } return false; } } internal sealed class MikuFacialExpressionController : MonoBehaviour { private readonly struct BlendShapeBinding { public SkinnedMeshRenderer Renderer { get; } public int Index { get; } public string Name { get; } public BlendShapeBinding(SkinnedMeshRenderer renderer, int index, string name) { Renderer = renderer; Index = index; Name = name; } } private readonly struct FacialShapeGroup { public string Key { get; } public string[] ExactAliases { get; } public string[] PartialAliases { get; } public FacialShapeGroup(string key, string[] exactAliases, string[] partialAliases) { Key = key; ExactAliases = exactAliases; PartialAliases = partialAliases; } public bool Matches(string rawName, string normalizedName) { for (int i = 0; i < ExactAliases.Length; i++) { string text = NormalizeName(ExactAliases[i]); if (string.Equals(rawName, ExactAliases[i], StringComparison.OrdinalIgnoreCase) || string.Equals(normalizedName, text, StringComparison.Ordinal) || (!string.IsNullOrWhiteSpace(text) && normalizedName.EndsWith(text, StringComparison.Ordinal))) { return true; } } for (int j = 0; j < PartialAliases.Length; j++) { string value = NormalizeName(PartialAliases[j]); if (!string.IsNullOrWhiteSpace(value) && normalizedName.IndexOf(value, StringComparison.Ordinal) >= 0) { return true; } } return false; } } private readonly struct BoneCandidate { public Transform Transform { get; } public int Score { get; } public BoneCandidate(Transform transform, int score) { Transform = transform; Score = score; } } private readonly struct BonePoseBinding { public Transform Transform { get; } public Vector3 ClosedLocalPosition { get; } public Quaternion ClosedLocalRotation { get; } public BonePoseBinding(Transform transform, Vector3 closedLocalPosition, Quaternion closedLocalRotation) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Transform = transform; ClosedLocalPosition = closedLocalPosition; ClosedLocalRotation = closedLocalRotation; } } private const string MouthAGroupKey = "MouthA"; private const string MouthIGroupKey = "MouthI"; private const string MouthUGroupKey = "MouthU"; private const string MouthEGroupKey = "MouthE"; private const string MouthOGroupKey = "MouthO"; private const string SmileGroupKey = "Smile"; private static readonly string[] MouthShapePriority = new string[5] { "MouthA", "MouthI", "MouthU", "MouthE", "MouthO" }; private static readonly FacialShapeGroup[] ManagedShapeGroups = new FacialShapeGroup[6] { new FacialShapeGroup("MouthA", new string[5] { "あ", "あ2", "a", "aa", "A" }, new string[7] { "moutha", "mouthaa", "phonemea", "visemeaa", "vaa", "jawopen", "mouthopen" }), new FacialShapeGroup("MouthI", new string[3] { "い", "i", "I" }, new string[4] { "mouthi", "phonemei", "visemeih", "vih" }), new FacialShapeGroup("MouthU", new string[3] { "う", "u", "U" }, new string[4] { "mouthu", "phonemeu", "visemeou", "vou" }), new FacialShapeGroup("MouthE", new string[3] { "え", "e", "E" }, new string[4] { "mouthe", "phonemee", "visemee", "ve" }), new FacialShapeGroup("MouthO", new string[3] { "お", "o", "O" }, new string[5] { "moutho", "phonemeo", "visemeoh", "voh", "mouthround" }), new FacialShapeGroup("Smile", new string[4] { "笑い", "smile", "Smile", "口角上げ" }, new string[4] { "warai", "happy", "grin", "mouthsmile" }) }; private static readonly string[] JawBoneTokens = new string[6] { "jaw", "chin", "顎", "あご", "下顎", "下あご" }; private static readonly string[] LipBoneTokens = new string[5] { "mouth", "lip", "口", "くち", "唇" }; private static readonly string[] ExcludedBoneTokens = new string[12] { "eye", "瞳", "眉", "brow", "nose", "鼻", "hair", "髪", "ear", "耳", "cheek", "頬" }; private const float SmileWeight = 10f; private const float MinimumMouthWeight = 4f; private const float MouthWeightSmoothing = 10f; private const float AudioAmplitudeScale = 28f; private const float JawOpenAngleDegrees = 10f; private const float JawOpenOffsetMeters = 0.005f; private const float LipOpenOffsetMeters = 0.0035f; private const int LoggedBlendShapeNamesPerRenderer = 12; private readonly Dictionary<string, List<BlendShapeBinding>> _bindingsByGroupKey = new Dictionary<string, List<BlendShapeBinding>>(StringComparer.OrdinalIgnoreCase); private readonly List<BonePoseBinding> _jawBindings = new List<BonePoseBinding>(); private readonly List<BonePoseBinding> _lipBindings = new List<BonePoseBinding>(); private readonly float[] _audioSamples = new float[256]; private AudioSource? _audioSource; private Animator? _animator; private ManualLogSource? _logger; private bool _initialized; private float _currentMouthWeight; private string? _lastPrimaryShapeGroupKey; public void Initialize(AudioSource? audioSource, Animator? animator, ManualLogSource? logger) { ((Behaviour)this).enabled = true; _audioSource = audioSource; _animator = animator; _logger = logger; _bindingsByGroupKey.Clear(); _jawBindings.Clear(); _lipBindings.Clear(); List<string> list = new List<string>(); SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { Mesh sharedMesh = val.sharedMesh; if ((Object)(object)sharedMesh == (Object)null) { continue; } List<string> list2 = new List<string>(Mathf.Min(sharedMesh.blendShapeCount, 12)); for (int j = 0; j < sharedMesh.blendShapeCount; j++) { string blendShapeName = sharedMesh.GetBlendShapeName(j); if (list2.Count < 12) { list2.Add(string.IsNullOrWhiteSpace(blendShapeName) ? $"#{j}" : blendShapeName); } if (!string.IsNullOrWhiteSpace(blendShapeName) && TryResolveManagedShapeGroup(blendShapeName, out string groupKey)) { if (!_bindingsByGroupKey.TryGetValue(groupKey, out List<BlendShapeBinding> value)) { value = new List<BlendShapeBinding>(); _bindingsByGroupKey.Add(groupKey, value); } value.Add(new BlendShapeBinding(val, j, blendShapeName)); } } list.Add(string.Format("{0}:{1}[{2}{3}]", ((Object)val).name, sharedMesh.blendShapeCount, string.Join(", ", list2), (sharedMesh.blendShapeCount > list2.Count) ? ", ..." : string.Empty)); } DiscoverBoneBindings(); _initialized = true; if (_bindingsByGroupKey.Count == 0 && _jawBindings.Count == 0 && _lipBindings.Count == 0) { ((Behaviour)this).enabled = false; ManualLogSource? logger2 = _logger; if (logger2 != null) { logger2.LogInfo((object)("Facial expression controller disabled because no supported blendshapes or mouth bones were found on the loaded model. Skinned renderers: " + ((list.Count == 0) ? "(none)" : string.Join(" | ", list)) + ".")); } return; } string text = ((_bindingsByGroupKey.Count == 0) ? "(none)" : string.Join(", ", _bindingsByGroupKey.Keys.OrderBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase))); string text2 = ((_jawBindings.Count == 0) ? "(none)" : string.Join(", ", _jawBindings.Select((BonePoseBinding binding) => ((Object)binding.Transform).name))); string text3 = ((_lipBindings.Count == 0) ? "(none)" : string.Join(", ", _lipBindings.Select((BonePoseBinding binding) => ((Object)binding.Transform).name))); ManualLogSource? logger3 = _logger; if (logger3 != null) { logger3.LogInfo((object)("Facial expression controller initialized. blendshapeGroups=[" + text + "], jawBones=[" + text2 + "], lipBones=[" + text3 + "], skinnedRenderers=" + ((list.Count == 0) ? "(none)" : string.Join(" | ", list)) + ".")); } } private void LateUpdate() { if (_initialized) { float num = ResolveMouthWeight(); string text = ResolvePrimaryMouthShapeGroupKey(num); ResetManagedWeights(); ApplySmileWeight(); ApplyBoneMouthPose(num); if (!string.IsNullOrWhiteSpace(text) && num > 4f) { ApplyWeight(text, num); } _lastPrimaryShapeGroupKey = text; } } private float ResolveMouthWeight() { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if ((Object)(object)_audioSource != (Object)null && (Object)(object)_audioSource.clip != (Object)null && _audioSource.isPlaying) { try { _audioSource.GetOutputData(_audioSamples, 0); float num2 = 0f; for (int i = 0; i < _audioSamples.Length; i++) { num2 += _audioSamples[i] * _audioSamples[i]; } num = Mathf.Clamp(Mathf.Sqrt(num2 / (float)_audioSamples.Length) * 28f * 100f, 0f, 100f); } catch (Exception ex) { ManualLogSource? logger = _logger; if (logger != null) { logger.LogWarning((object)("Facial expression audio sampling failed: " + ex.Message)); } } } else if ((Object)(object)_animator != (Object)null && (Object)(object)_animator.runtimeAnimatorController != (Object)null) { AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(0); num = Mathf.Clamp01(Mathf.Sin(Mathf.Repeat(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, 1f) * (float)Math.PI * 8f) * 0.5f + 0.5f) * 18f; } _currentMouthWeight = Mathf.Lerp(_currentMouthWeight, num, Time.deltaTime * 10f); return _currentMouthWeight; } private string? ResolvePrimaryMouthShapeGroupKey(float mouthWeight) { if (mouthWeight <= 4f) { return null; } float num = 0f; if ((Object)(object)_audioSource != (Object)null && (Object)(object)_audioSource.clip != (Object)null) { num = _audioSource.time; } else if ((Object)(object)_animator != (Object)null) { num = Time.time; } string[] array = (Mathf.Abs(Mathf.FloorToInt(num * 7f)) % 5) switch { 0 => new string[2] { "MouthA", "MouthO" }, 1 => new string[2] { "MouthI", "MouthE" }, 2 => new string[2] { "MouthU", "MouthO" }, 3 => new string[2] { "MouthE", "MouthI" }, _ => new string[2] { "MouthO", "MouthA" }, }; foreach (string text in array) { if (_bindingsByGroupKey.ContainsKey(text)) { return text; } } array = MouthShapePriority; foreach (string text2 in array) { if (_bindingsByGroupKey.ContainsKey(text2)) { return text2; } } return _lastPrimaryShapeGroupKey; } private void ResetManagedWeights() { foreach (List<BlendShapeBinding> value in _bindingsByGroupKey.Values) { foreach (BlendShapeBinding item in value) { item.Renderer.SetBlendShapeWeight(item.Index, 0f); } } } private void ApplySmileWeight() { if (_bindingsByGroupKey.ContainsKey("Smile")) { ApplyWeight("Smile", 10f); } } private void ApplyWeight(string groupKey, float weight) { if (_bindingsByGroupKey.TryGetValue(groupKey, out List<BlendShapeBinding> value)) { for (int i = 0; i < value.Count; i++) { value[i].Renderer.SetBlendShapeWeight(value[i].Index, weight); } } } private void ApplyBoneMouthPose(float mouthWeight) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01((mouthWeight - 4f) / 96f); for (int i = 0; i < _jawBindings.Count; i++) { BonePoseBinding bonePoseBinding = _jawBindings[i]; bonePoseBinding.Transform.localRotation = bonePoseBinding.ClosedLocalRotation * Quaternion.Euler(-10f * num, 0f, 0f); bonePoseBinding.Transform.localPosition = bonePoseBinding.ClosedLocalPosition + ResolveLocalDownDirection(bonePoseBinding.Transform) * (0.005f * num); } for (int j = 0; j < _lipBindings.Count; j++) { BonePoseBinding bonePoseBinding2 = _lipBindings[j]; bonePoseBinding2.Transform.localRotation = bonePoseBinding2.ClosedLocalRotation; bonePoseBinding2.Transform.localPosition = bonePoseBinding2.ClosedLocalPosition + ResolveLocalDownDirection(bonePoseBinding2.Transform) * (0.0035f * num); } } private void DiscoverBoneBindings() { HashSet<Transform> hashSet = new HashSet<Transform>(); AddTopBoneBindings(_jawBindings, JawBoneTokens, hashSet, 2); foreach (BonePoseBinding jawBinding in _jawBindings) { hashSet.Add(jawBinding.Transform); } AddTopBoneBindings(_lipBindings, LipBoneTokens, hashSet, 2); } private void AddTopBoneBindings(ICollection<BonePoseBinding> destination, IEnumerable<string> tokens, ISet<Transform> excludedTransforms, int maxCount) { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) ISet<Transform> excludedTransforms2 = excludedTransforms; IEnumerable<string> tokens2 = tokens; BoneCandidate[] array = (from candidate in ((Component)this).GetComponentsInChildren<Transform>(true) where (Object)(object)candidate != (Object)(object)((Component)this).transform where !excludedTransforms2.Contains(candidate) select new BoneCandidate(candidate, ScoreBoneCandidate(((Object)candidate).name, tokens2)) into candidate where candidate.Score > 0 orderby candidate.Score descending, ((Object)candidate.Transform).name.Length select candidate).ThenBy<BoneCandidate, string>((BoneCandidate candidate) => ((Object)candidate.Transform).name, StringComparer.OrdinalIgnoreCase).Take(maxCount).ToArray(); for (int i = 0; i < array.Length; i++) { destination.Add(new BonePoseBinding(array[i].Transform, array[i].Transform.localPosition, array[i].Transform.localRotation)); } } private static int ScoreBoneCandidate(string candidateName, IEnumerable<string> tokens) { string normalizedName = NormalizeName(candidateName); if (string.IsNullOrWhiteSpace(normalizedName)) { return 0; } if (ExcludedBoneTokens.Any((string token) => normalizedName.IndexOf(NormalizeName(token), StringComparison.Ordinal) >= 0)) { return 0; } int num = 0; foreach (string token in tokens) { string text = NormalizeName(token); if (normalizedName == text) { num = Mathf.Max(num, 300); } else if (normalizedName.EndsWith(text, StringComparison.Ordinal)) { num = Mathf.Max(num, 220); } else if (normalizedName.IndexOf(text, StringComparison.Ordinal) >= 0) { num = Mathf.Max(num, 160); } } return num; } private static bool TryResolveManagedShapeGroup(string blendShapeName, out string groupKey) { string normalizedName = NormalizeName(blendShapeName); for (int i = 0; i < ManagedShapeGroups.Length; i++) { if (ManagedShapeGroups[i].Matches(blendShapeName, normalizedName)) { groupKey = ManagedShapeGroups[i].Key; return true; } } groupKey = string.Empty; return false; } private static string NormalizeName(string value) { if (string.IsNullOrWhiteSpace(value)) { return string.Empty; } char[] array = new char[value.Length]; int num = 0; for (int i = 0; i < value.Length; i++) { char c = char.ToLowerInvariant(value[i]); if (!char.IsWhiteSpace(c) && c != '_' && c != '-' && c != '.' && c != '/' && c != '\\' && c != '(' && c != ')' && c != '[' && c != ']' && c != '・') { array[num++] = c; } } if (num == 0) { return string.Empty; } string text = new string(array, 0, num); int j; for (j = 0; j < text.Length && char.IsDigit(text[j]); j++) { } if (j <= 0 || j >= text.Length) { return text; } return text.Substring(j); } private static Vector3 ResolveLocalDownDirection(Transform transform) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform.parent == (Object)null) { return Vector3.down; } Vector3 val = transform.parent.InverseTransformDirection(Vector3.down); if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f)) { return Vector3.down; } return ((Vector3)(ref val)).normalized; } } internal sealed class MmdLegIkSolver : MonoBehaviour { private sealed class IkChain { public string Name { get; } public Transform Target { get; } public Transform EndEffector { get; } public IkLink[] Links { get; } public int IterationCount { get; } public float StepDegrees { get; } public Quaternion EndEffectorRotationOffset { get; } public IkChain(string name, Transform target, Transform endEffector, IkLink[] links, int iterationCount, float stepDegrees, Quaternion endEffectorRotationOffset) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) Name = name; Target = target; EndEffector = endEffector; Links = links; IterationCount = iterationCount; StepDegrees = stepDegrees; EndEffectorRotationOffset = endEffectorRotationOffset; } } private sealed class IkLink { public Transform Transform { get; } public bool HasAngleLimit { get; } public Vector3 MinimumAngleDegrees { get; } public Vector3 MaximumAngleDegrees { get; } public IkLink(Transform transform, bool hasAngleLimit, Vector3 minimumAngleDegrees, Vector3 maximumAngleDegrees) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Transform = transform; HasAngleLimit = hasAngleLimit; MinimumAngleDegrees = minimumAngleDegrees; MaximumAngleDegrees = maximumAngleDegrees; } } private const float TargetReachToleranceSqr = 1E-06f; private readonly List<IkChain> _chains = new List<IkChain>(); private bool _isInitialized; public void Initialize(LoadedDancePrefab prefab, ManualLogSource logger) { if (_isInitialized) { return; } _isInitialized = true; _chains.Clear(); if (prefab.Bones.Count == 0 || prefab.BonePaths.Count != prefab.Bones.Count) { logger.LogInfo((object)"PMX IK metadata is unavailable; leg solver skipped."); return; } Transform[] boneTransforms = ResolveBoneTransforms(prefab.BonePaths); for (int i = 0; i < prefab.Bones.Count; i++) { PmxBone pmxBone = prefab.Bones[i]; if (IsLegIkBone(pmxBone.DisplayName) && pmxBone.IkDefinition != null) { TryAddIkChain(i, pmxBone, boneTransforms, logger); } } logger.LogInfo((object)((_chains.Count > 0) ? ("Enabled PMX leg IK solver for " + string.Join(", ", _chains.Select((IkChain chain) => chain.Name)) + ".") : "No compatible PMX leg IK chains found; leg solver skipped.")); } private void LateUpdate() { if (_chains.Count == 0) { return; } foreach (IkChain chain in _chains) { SolveChain(chain); } } private Transform?[] ResolveBoneTransforms(IReadOnlyList<string> bonePaths) { Transform[] array = (Transform[])(object)new Transform[bonePaths.Count]; for (int i = 0; i < bonePaths.Count; i++) { string text = bonePaths[i]; array[i] = (string.IsNullOrWhiteSpace(text) ? ((Component)this).transform : ((Component)this).transform.Find(text)); } return array; } private void TryAddIkChain(int boneIndex, PmxBone bone, Transform?[] boneTransforms, ManualLogSource logger) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) PmxIkDefinition ikDefinition = bone.IkDefinition; if (ikDefinition == null) { return; } if (!TryGetBoneTransform(boneTransforms, boneIndex, out Transform transform) || !TryGetBoneTransform(boneTransforms, ikDefinition.TargetBoneIndex, out Transform transform2)) { logger.LogInfo((object)("Skipping leg IK chain '" + bone.DisplayName + "' because required target bones are missing.")); return; } List<IkLink> list = new List<IkLink>(ikDefinition.Links.Count); foreach (PmxIkLink link in ikDefinition.Links) { if (TryGetBoneTransform(boneTransforms, link.BoneIndex, out Transform transform3)) { list.Add(new IkLink(transform3, link.HasAngleLimit, ToDegrees(link.MinimumAngle), ToDegrees(link.MaximumAngle))); } } if (list.Count == 0) { logger.LogInfo((object)("Skipping leg IK chain '" + bone.DisplayName + "' because its link list is empty.")); return; } float stepDegrees = ((ikDefinition.LimitRadian <= 0f) ? 180f : Mathf.Clamp(ikDefinition.LimitRadian * 57.29578f, 1f, 180f)); _chains.Add(new IkChain(bone.DisplayName, transform, transform2, list.ToArray(), Mathf.Clamp(ikDefinition.LoopCount, 1, 32), stepDegrees, Quaternion.Inverse(transform.rotation) * transform2.rotation)); } private static bool TryGetBoneTransform(Transform?[] transforms, int boneIndex, out Transform transform) { if (boneIndex >= 0 && boneIndex < transforms.Length && (Object)(object)transforms[boneIndex] != (Object)null) { transform = transforms[boneIndex]; return true; } transform = null; return false; } private static bool IsLegIkBone(string name) { if (string.IsNullOrWhiteSpace(name)) { return false; } bool num = name.IndexOf("左足", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("右足", StringComparison.OrdinalIgnoreCase) >= 0; bool flag = name.IndexOf("IK", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("IK", StringComparison.Ordinal) >= 0; bool flag2 = name.IndexOf("つま先", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("toe", StringComparison.OrdinalIgnoreCase) >= 0; if (num && flag) { return !flag2; } return false; } private static Vector3 ToDegrees(Vector3 radians) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return radians * 57.29578f; } private static void SolveChain(IkChain chain) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < chain.IterationCount; i++) { Vector3 val = chain.Target.position - chain.EndEffector.position; if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f) { break; } IkLink[] links = chain.Links; foreach (IkLink link in links) { RotateLinkTowardTarget(chain, link); ApplyAngleLimitIfNeeded(link); val = chain.Target.position - chain.EndEffector.position; if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f) { break; } } } chain.EndEffector.rotation = chain.Target.rotation * chain.EndEffectorRotationOffset; } private static void RotateLinkTowardTarget(IkChain chain, IkLink link) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) Vector3 position = link.Transform.position; Vector3 val = chain.EndEffector.position - position; Vector3 val2 = chain.Target.position - position; if (!(((Vector3)(ref val)).sqrMagnitude <= 1E-06f) && !(((Vector3)(ref val2)).sqrMagnitude <= 1E-06f)) { Quaternion val3 = Quaternion.FromToRotation(val, val2); if (chain.StepDegrees < 179.9f) { val3 = Quaternion.RotateTowards(Quaternion.identity, val3, chain.StepDegrees); } link.Transform.rotation = val3 * link.Transform.rotation; } } private static void ApplyAngleLimitIfNeeded(IkLink link) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) if (link.HasAngleLimit) { Vector3 val = NormalizeSignedEuler(link.Transform.localEulerAngles); val.x = Mathf.Clamp(val.x, link.MinimumAngleDegrees.x, link.MaximumAngleDegrees.x); val.y = Mathf.Clamp(val.y, link.MinimumAngleDegrees.y, link.MaximumAngleDegrees.y); val.z = Mathf.Clamp(val.z, link.MinimumAngleDegrees.z, link.MaximumAngleDegrees.z); link.Transform.localRotation = Quaternion.Euler(val); } } private static Vector3 NormalizeSignedEuler(Vector3 euler) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return new Vector3(NormalizeSignedAngle(euler.x), NormalizeSignedAngle(euler.y), NormalizeSignedAngle(euler.z)); } private static float NormalizeSignedAngle(float angle) { angle %= 360f; if (angle > 180f) { angle -= 360f; } else if (angle < -180f) { angle += 360f; } return angle; } } internal static class MmdMorphRuntimeBridge { private const string AssemblySimpleName = "MMD4Mecanim"; private const string DefaultAnimatorStateName = "Base Layer.motion_vmd"; private static readonly string[] ModelTypeCandidates = new string[2] { "MMD4MecanimModelImpl", "MMD4MecanimModel" }; private static readonly string[] AnimTypeCandidates = new string[2] { "MMD4MecanimModelImpl+Anim", "MMD4MecanimModel+Anim" }; private static Assembly? _loadedAssembly; private static string? _loadedAssemblyPath; private static IntPtr _loadedNativePhysicsHandle; private static string? _loadedNativePhysicsPath; public static void TryPreloadAssembly(string assemblyPath, ManualLogSource logger) { TryResolveAssembly(assemblyPath, logger, logMissingFileAsWarning: false); } public static bool TryAttach(GameObject dancer, LoadedDancePrefab prefab, Animator? animator, AudioSource? audioSource, string assemblyPath, ManualLogSource logger) { if ((Object)(object)prefab.MmdModelFile == (Object)null || (Object)(object)prefab.MmdIndexFile == (Object)null || (Object)(object)prefab.MmdAnimFile == (Object)null) { logger.LogInfo((object)"Skipped MMD4Mecanim morph bridge because required model/index/anim bytes are unavailable."); return false; } if (!TryEnsureNativePhysicsLibraryLoaded(assemblyPath, logger)) { return false; } Assembly assembly = TryResolveAssembly(assemblyPath, logger, logMissingFileAsWarning: true); if (assembly == null) { return false; } Type type2 = ResolveType(assembly, ModelTypeCandidates); Type type3 = ResolveType(assembly, AnimTypeCandidates); if (type2 == null || type3 == null) { string text = string.Join(", ", (from type in assembly.GetTypes() select type.FullName into name whe