Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix(T&O): VRMのFirstPersonFlagをCategorizationKeyに追加する #1103

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-PRERELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog].
### Removed

### Fixed
- VRM: Fix Trace and Optimize incorrectly merging Skinned Meshes with different FirstPerson settings [`#1103`](https://github.com/anatawa12/AvatarOptimizer/pull/1103)

### Security

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog].
### Removed

### Fixed
- VRM: Fix Trace and Optimize incorrectly merging Skinned Meshes with different FirstPerson settings [`#1103`](https://github.com/anatawa12/AvatarOptimizer/pull/1103)

### Security

Expand Down
70 changes: 68 additions & 2 deletions Editor/Processors/TraceAndOptimize/AutoMergeSkinnedMesh.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;

#if AAO_VRM0
using VRM;
#endif
#if AAO_VRM1
using UniGLTF.Extensions.VRMC_vrm;
using UniVRM10;
#endif

using Debug = System.Diagnostics.Debug;

namespace Anatawa12.AvatarOptimizer.Processors.TraceAndOptimizes
Expand Down Expand Up @@ -106,8 +115,10 @@ protected override void Execute(BuildContext context, TraceAndOptimizeState stat
if (rendererAnimationLocations == null)
continue; // animating renderer properties with non animator is not supported

var vrmFirstPersonFlag = GetVrmFirstPersonFlag(context, meshInfo2.SourceRenderer);

var key = new CategorizationKey(meshInfo2, activeness, activenessAnimationLocations,
rendererAnimationLocations);
rendererAnimationLocations, vrmFirstPersonFlag);
if (!categorizedMeshes.TryGetValue(key, out var list))
{
list = new List<MeshInfo2>();
Expand Down Expand Up @@ -396,6 +407,48 @@ private static (Activeness, EqualsHashSet<(bool initial, EqualsHashSet<Animation
return new EqualsHashSet<(string property, AnimationLocation location)>(locations);
}

private static VrmFirstPersonFlag GetVrmFirstPersonFlag(BuildContext context, Component component)
{
#if AAO_VRM0
if (context.AvatarRootObject.GetComponent<VRMFirstPerson>() is VRMFirstPerson vrmFirstPerson)
{
switch (vrmFirstPerson.Renderers.FirstOrDefault(c => c.Renderer == component).FirstPersonFlag)
{
case FirstPersonFlag.Auto:
return VrmFirstPersonFlag.Auto;
case FirstPersonFlag.Both:
return VrmFirstPersonFlag.Both;
case FirstPersonFlag.ThirdPersonOnly:
return VrmFirstPersonFlag.ThirdPersonOnly;
case FirstPersonFlag.FirstPersonOnly:
return VrmFirstPersonFlag.FirstPersonOnly;
default:
throw new ArgumentOutOfRangeException();
}
}
#endif
#if AAO_VRM1
if (context.AvatarRootObject.GetComponent<Vrm10Instance>() is Vrm10Instance vrm10Object)
{
switch (vrm10Object.Vrm.FirstPerson.Renderers.FirstOrDefault(c => c.GetRenderer(context.AvatarRootTransform) == component).FirstPersonFlag)
{
case FirstPersonType.auto:
return VrmFirstPersonFlag.Auto;
case FirstPersonType.both:
return VrmFirstPersonFlag.Both;
case FirstPersonType.thirdPersonOnly:
return VrmFirstPersonFlag.ThirdPersonOnly;
case FirstPersonType.firstPersonOnly:
return VrmFirstPersonFlag.FirstPersonOnly;
default:
throw new ArgumentOutOfRangeException();
}
}
#endif
// note: unset will fallback to Auto
return VrmFirstPersonFlag.Auto;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このままだと手動MergeSkinMedMeshのあとのやつがすべてAutoに化けたりしちゃぃませんかね

少し対処法考えさせてください

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ObjectMappingの方でFirstPerson性を持たせせてあげる必要がありそうかなぁ

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

component.Renderers = component.Renderers
.Select(r => new VRMFirstPerson.RendererFirstPersonFlags
{
Renderer = mappingSource.GetMappedComponent(r.Renderer).MappedComponent,
FirstPersonFlag = r.FirstPersonFlag
})
.Where(r => r.Renderer)
.GroupBy(r => r.Renderer, r => r.FirstPersonFlag)

みたいなことをObjectMappingBuilderを少しいじって取得できるようにしてもいいかも

}

private SkinnedMeshRenderer CreateNewRenderer(
Func<GameObject> gameObjectFactory,
Transform parent,
Expand Down Expand Up @@ -611,6 +664,14 @@ enum Activeness
Animating,
}

enum VrmFirstPersonFlag
{
Auto,
Both,
ThirdPersonOnly,
FirstPersonOnly,
}

// Here's the all list of properties in SkinnedMeshRenderer
// Renderer:
// - bounds (local bounds) - must be same
Expand Down Expand Up @@ -653,6 +714,7 @@ private struct CategorizationKey : IEquatable<CategorizationKey>

public EqualsHashSet<(string property, AnimationLocation location)> RendererAnimationLocations;
public Activeness Activeness;
public VrmFirstPersonFlag VrmFirstPersonFlag;

// renderer properties
public Bounds Bounds;
Expand All @@ -674,7 +736,8 @@ public CategorizationKey(
MeshInfo2 meshInfo2,
Activeness activeness,
EqualsHashSet<(bool initial, EqualsHashSet<AnimationLocation> animation)> activenessAnimationLocations,
EqualsHashSet<(string property, AnimationLocation location)> rendererAnimationLocations
EqualsHashSet<(string property, AnimationLocation location)> rendererAnimationLocations,
VrmFirstPersonFlag vrmFirstPersonFlag
)
{
var renderer = (SkinnedMeshRenderer)meshInfo2.SourceRenderer;
Expand All @@ -683,6 +746,7 @@ public CategorizationKey(
ActivenessAnimationLocations = activenessAnimationLocations;
RendererAnimationLocations = rendererAnimationLocations;
Activeness = activeness;
VrmFirstPersonFlag = vrmFirstPersonFlag;

Bounds = RoundError.Bounds(meshInfo2.Bounds);
ShadowCastingMode = renderer.shadowCastingMode;
Expand All @@ -705,6 +769,7 @@ public bool Equals(CategorizationKey other)
ActivenessAnimationLocations.Equals(other.ActivenessAnimationLocations) &&
RendererAnimationLocations.Equals(other.RendererAnimationLocations) &&
Activeness == other.Activeness &&
VrmFirstPersonFlag == other.VrmFirstPersonFlag &&
Bounds.Equals(other.Bounds) &&
ShadowCastingMode == other.ShadowCastingMode &&
ReceiveShadows == other.ReceiveShadows &&
Expand Down Expand Up @@ -732,6 +797,7 @@ public override int GetHashCode()
hashCode = (hashCode * 397) ^ ActivenessAnimationLocations.GetHashCode();
hashCode = (hashCode * 397) ^ RendererAnimationLocations.GetHashCode();
hashCode = (hashCode * 397) ^ Activeness.GetHashCode();
hashCode = (hashCode * 397) ^ (int)VrmFirstPersonFlag;
hashCode = (hashCode * 397) ^ Bounds.GetHashCode();
hashCode = (hashCode * 397) ^ (int)ShadowCastingMode;
hashCode = (hashCode * 397) ^ ReceiveShadows.GetHashCode();
Expand Down
Loading