Skip to content

Commit

Permalink
Merge pull request #1008 from anatawa12/merge-1.6
Browse files Browse the repository at this point in the history
Merge 1.6.13
  • Loading branch information
anatawa12 authored Apr 13, 2024
2 parents 391c5c6 + 0442442 commit d7b76c1
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 19 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ The format is based on [Keep a Changelog].

### Security

## [1.6.13] - 2024-04-13
### Fixed
- Animator Controller on the VRCStation will be broken [`#1002`](https://github.com/anatawa12/AvatarOptimizer/pull/1002)
- Remove Component can be fails with RequireComponent attribute [`#1003`](https://github.com/anatawa12/AvatarOptimizer/pull/1003)

## [1.6.12] - 2024-04-09
### Removed
- Activeness Optimization for Constraint component [`#996`](https://github.com/anatawa12/AvatarOptimizer/pull/996)
Expand Down Expand Up @@ -1322,7 +1327,8 @@ This release is mistake.
- Merge Bone
- Clear Endpoint Position

[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.12...HEAD
[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.13...HEAD
[1.6.13]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.12...v1.6.13
[1.6.12]: https://github.com/anatawa12/AvatarOptimizer/compare/1.7.0-beta.5...v1.6.12
[1.7.0-beta.5]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.11...v1.7.0-beta.5
[1.6.11]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.7.0-beta.4...v1.6.11
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ The format is based on [Keep a Changelog].

### Security

## [1.6.13] - 2024-04-13
### Fixed
- Animator Controller on the VRCStation will be broken [`#1002`](https://github.com/anatawa12/AvatarOptimizer/pull/1002)
- Remove Component can be fails with RequireComponent attribute [`#1003`](https://github.com/anatawa12/AvatarOptimizer/pull/1003)

## [1.6.12] - 2024-04-09
### Removed
- Activeness Optimization for Constraint component [`#996`](https://github.com/anatawa12/AvatarOptimizer/pull/996)
Expand Down Expand Up @@ -859,7 +864,8 @@ The format is based on [Keep a Changelog].
- Merge Bone
- Clear Endpoint Position

[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.12...HEAD
[Unreleased]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.13...HEAD
[1.6.13]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.12...v1.6.13
[1.6.12]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.11...v1.6.12
[1.6.11]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.10...v1.6.11
[1.6.10]: https://github.com/anatawa12/AvatarOptimizer/compare/v1.6.9...v1.6.10
Expand Down
57 changes: 41 additions & 16 deletions Editor/ObjectMapping/ObjectMappingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@ internal class ObjectMappingContext : IExtensionContext

public void OnActivate(BuildContext context)
{
MappingBuilder = new ObjectMappingBuilder<PropertyInfo>(context.AvatarRootObject);
var avatarTagComponent = context.AvatarRootObject.GetComponentInChildren<AvatarTagComponent>(true);
if (avatarTagComponent == null)
MappingBuilder = null;
else
MappingBuilder = new ObjectMappingBuilder<PropertyInfo>(context.AvatarRootObject);
}

public void OnDeactivate(BuildContext context)
{
if (MappingBuilder == null) return;

var mapping = MappingBuilder.BuildObjectMapping();
var mappingSource = new MappingSourceImpl(mapping);

Expand All @@ -36,6 +42,22 @@ public void OnDeactivate(BuildContext context)
if (ComponentInfoRegistry.TryGetInformation(component.GetType(), out var info))
info.ApplySpecialMappingInternal(component, mappingSource);

var mapAnimatorController = false;

switch (component)
{
case Animator _:
case VRC.SDK3.Avatars.Components.VRCAvatarDescriptor _:
#if AAO_VRM0
case VRM.VRMBlendShapeProxy _:
#endif
#if AAO_VRM1
case UniVRM10.Vrm10Instance _:
#endif
mapAnimatorController = true;
break;
}

var serialized = new SerializedObject(component);
AnimatorControllerMapper mapper = null;

Expand All @@ -44,25 +66,28 @@ public void OnDeactivate(BuildContext context)
if (mapping.MapComponentInstance(p.objectReferenceInstanceIDValue, out var mappedComponent))
p.objectReferenceValue = mappedComponent;

var objectReferenceValue = p.objectReferenceValue;
switch (objectReferenceValue)
if (mapAnimatorController)
{
case RuntimeAnimatorController _:
var objectReferenceValue = p.objectReferenceValue;
switch (objectReferenceValue)
{
case RuntimeAnimatorController _:
#if AAO_VRM0
case VRM.BlendShapeAvatar _:
case VRM.BlendShapeAvatar _:
#endif
#if AAO_VRM1
case UniVRM10.VRM10Object _:
case UniVRM10.VRM10Object _:
#endif
if (mapper == null)
mapper = new AnimatorControllerMapper(
mapping.CreateAnimationMapper(component.gameObject));

// ReSharper disable once AccessToModifiedClosure
var mapped = mapper.MapObject(objectReferenceValue);
if (mapped != objectReferenceValue)
p.objectReferenceValue = mapped;
break;
if (mapper == null)
mapper = new AnimatorControllerMapper(
mapping.CreateAnimationMapper(component.gameObject));

// ReSharper disable once AccessToModifiedClosure
var mapped = mapper.MapObject(objectReferenceValue);
if (mapped != objectReferenceValue)
p.objectReferenceValue = mapped;
break;
}
}
}

Expand Down Expand Up @@ -422,4 +447,4 @@ protected override ComponentSupport GetComponentSupport(Object original)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ public void CollectAllUsages()
FallbackDependenciesParser(component, collector);
}

foreach (var requiredComponent in RequireComponentCache.GetRequiredComponents(component.GetType()))
foreach (var required in component.GetComponents(requiredComponent))
collector.AddDependency(component, required)
.EvenIfDependantDisabled();

collector.FinalizeForComponent();
}
}
Expand Down
11 changes: 10 additions & 1 deletion Editor/Processors/TraceAndOptimize/FindUnusedObjectsProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,21 @@ private void Sweep(GCComponentInfoHolder componentInfos)
}
else
{
DestroyTracker.DestroyImmediate(componentInfo.Component);
DestroyWithDependencies(componentInfo.Component);
}
}
}
}

private static void DestroyWithDependencies(Component component)
{
if (component == null) return;
foreach (var dependantType in RequireComponentCache.GetDependantComponents(component.GetType()))
foreach (var child in component.GetComponents(dependantType))
DestroyWithDependencies(child);
DestroyTracker.DestroyImmediate(component);
}

private void MarkDependant(GCComponentInfoHolder componentInfos)
{
// entrypoint for mark & sweep is active-able GameObjects
Expand Down
52 changes: 52 additions & 0 deletions Editor/Processors/TraceAndOptimize/RequireComponentCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
using UnityEngine;

namespace Anatawa12.AvatarOptimizer.Processors.TraceAndOptimizes
{
internal static class RequireComponentCache
{
private static Dictionary<Type, HashSet<Type>> _requireComponentCache = new Dictionary<Type, HashSet<Type>>();
private static Dictionary<Type, HashSet<Type>> _dependantComponentCache = new Dictionary<Type, HashSet<Type>>();

[NotNull]
[ItemNotNull]
public static HashSet<Type> GetRequiredComponents([NotNull] Type type)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (_requireComponentCache.TryGetValue(type, out var result)) return result;

result = new HashSet<Type>();

foreach (var requireComponent in type.GetCustomAttributes<RequireComponent>(true))
{
if (requireComponent.m_Type0 != null) result.Add(requireComponent.m_Type0);
if (requireComponent.m_Type1 != null) result.Add(requireComponent.m_Type1);
if (requireComponent.m_Type2 != null) result.Add(requireComponent.m_Type2);
}

// add to dependantComponentCache
foreach (var requiredComponent in result)
{
if (!_dependantComponentCache.TryGetValue(requiredComponent, out var dependants))
_dependantComponentCache.Add(requiredComponent, dependants = new HashSet<Type>());
dependants.Add(type);
}

_requireComponentCache.Add(type, result);
return result;
}

[NotNull]
[ItemNotNull]
public static HashSet<Type> GetDependantComponents([NotNull] Type type)
{
if (type == null) throw new ArgumentNullException(nameof(type));
if (!_dependantComponentCache.TryGetValue(type, out var result))
_dependantComponentCache.Add(type, result = new HashSet<Type>());
return result;
}
}
}

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

0 comments on commit d7b76c1

Please sign in to comment.