Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Ndmf/Editor/Meshia.MeshSimplification.Ndmf.Editor.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
"Meshia.MeshSimplification.Ndmf.Runtime",
"nadena.dev.ndmf",
"nadena.dev.ndmf.runtime",
"nadena.dev.modular-avatar.core",
"Unity.Mathematics"
"nadena.dev.modular-avatar.core"
],
"includePlatforms": [
"Editor"
Expand Down
16 changes: 10 additions & 6 deletions Ndmf/Editor/NdmfPlugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using nadena.dev.ndmf;
using nadena.dev.ndmf.preview;
using System;
using System.Collections;
using UnityEditor;
using UnityEngine;
using UnityEngine.Pool;
Expand Down Expand Up @@ -39,19 +40,19 @@ protected override void Configure()
{
var meshiaMeshSimplifiers = context.AvatarRootObject.GetComponentsInChildren<MeshiaMeshSimplifier>(true);
#if ENABLE_MODULAR_AVATAR

var meshiaCascadingMeshSimplifiers = context.AvatarRootObject.GetComponentsInChildren<MeshiaCascadingAvatarMeshSimplifier>(true);
#endif

using (ListPool<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, Mesh Destination)>.Get(out var parameters))
using (ListPool<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, BitArray? preserveBorderEdgesBoneIndices, Mesh Destination)>.Get(out var parameters))
{
foreach (var meshiaMeshSimplifier in meshiaMeshSimplifiers)
{
if(meshiaMeshSimplifier.enabled && meshiaMeshSimplifier.TryGetComponent<Renderer>(out var renderer))
{
var sourceMesh = RendererUtility.GetRequiredMesh(renderer);
Mesh simplifiedMesh = new();
parameters.Add((sourceMesh, meshiaMeshSimplifier.target, meshiaMeshSimplifier.options, simplifiedMesh));
parameters.Add((sourceMesh, meshiaMeshSimplifier.target, meshiaMeshSimplifier.options, null, simplifiedMesh));
}
}
#if ENABLE_MODULAR_AVATAR
Expand All @@ -64,7 +65,10 @@ protected override void Configure()
var mesh = RendererUtility.GetRequiredMesh(entry.GetTargetRenderer(meshiaCascadingMeshSimplifier)!);
var target = new MeshSimplificationTarget() { Kind = MeshSimplificationTargetKind.AbsoluteTriangleCount, Value = entry.TargetTriangleCount };
Mesh simplifiedMesh = new();
parameters.Add((mesh, target, entry.Options, simplifiedMesh));

var preserveBorderEdgesBoneIndices = MeshiaCascadingAvatarMeshSimplifier.GetPreserveBorderEdgesBoneIndices(context.AvatarRootObject, meshiaCascadingMeshSimplifier, entry);

parameters.Add((mesh, target, entry.Options, preserveBorderEdgesBoneIndices, simplifiedMesh));
}
}

Expand All @@ -78,7 +82,7 @@ protected override void Configure()
{
if(meshiaMeshSimplifier.enabled && meshiaMeshSimplifier.TryGetComponent<Renderer>(out var renderer))
{
var (mesh, target, options, simplifiedMesh) = parameters[i++];
var (mesh, target, options, _, simplifiedMesh) = parameters[i++];
AssetDatabase.AddObjectToAsset(simplifiedMesh, context.AssetContainer);
RendererUtility.SetMesh(renderer, simplifiedMesh);
}
Expand All @@ -96,7 +100,7 @@ protected override void Configure()
{
if (!cascadingTarget.IsValid(meshiaCascadingMeshSimplifier) || !cascadingTarget.Enabled) continue;
var renderer = cascadingTarget.GetTargetRenderer(meshiaCascadingMeshSimplifier)!;
var (mesh, target, options, simplifiedMesh) = parameters[i++];
var (mesh, target, options, _, simplifiedMesh) = parameters[i++];
AssetDatabase.AddObjectToAsset(simplifiedMesh, context.AssetContainer);
RendererUtility.SetMesh(renderer, simplifiedMesh);

Expand Down
42 changes: 5 additions & 37 deletions Ndmf/Editor/Preview/MeshiaCascadingAvatarMeshSimplifierPreview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
using System.Collections.Immutable;
using System.Linq;
using nadena.dev.ndmf.preview;
using nadena.dev.ndmf.util;
using Unity.Mathematics;
using UnityEngine;

namespace Meshia.MeshSimplification.Ndmf.Editor.Preview
Expand Down Expand Up @@ -50,42 +48,12 @@ protected override (MeshSimplificationTarget, MeshSimplifierOptions, BitArray?)
var cascadingTarget = context.Observe(component, c => c.Entries[index] with { }, (a, b) => a.Equals(b));
var target = new MeshSimplificationTarget() { Kind = MeshSimplificationTargetKind.AbsoluteTriangleCount, Value = cascadingTarget.TargetTriangleCount };




if(original is SkinnedMeshRenderer skinnedMeshRenderer)
{
var avatarRoot = context.GetAvatarRoot(original.gameObject);
if(avatarRoot != null)
{
var avatarAnimator = avatarRoot.GetComponent<Animator>();

var bones = skinnedMeshRenderer.bones;
var preserveBorderEdgeBoneIndices = new BitArray(bones.Length);

for (ulong boneMask = cascadingTarget.PreserveBorderEdgesBones; boneMask != 0ul; boneMask &= boneMask - 1)
{
var bone = (HumanBodyBones)math.tzcnt(boneMask);
var boneTransform = avatarAnimator.GetBoneTransform(bone);
if (boneTransform != null)
{
var boneIndex = Array.IndexOf(bones, boneTransform);
if (boneIndex >= 0)
{
preserveBorderEdgeBoneIndices.Set(boneIndex, true);
}
}
}

return (target, cascadingTarget.Options, preserveBorderEdgeBoneIndices);
}

}
return (target, cascadingTarget.Options, null);



var avatarRoot = context.GetAvatarRoot(original.gameObject);
var preserveBorderEdgeBoneIndices = MeshiaCascadingAvatarMeshSimplifier.GetPreserveBorderEdgesBoneIndices(avatarRoot, component, cascadingTarget);
return (target, cascadingTarget.Options, preserveBorderEdgeBoneIndices);
}


}
}

Expand Down
3 changes: 2 additions & 1 deletion Ndmf/Runtime/Meshia.MeshSimplification.Ndmf.Runtime.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"Meshia.MeshSimplification.Runtime",
"VRC.SDKBase",
"nadena.dev.modular-avatar.core",
"nadena.dev.ndmf.runtime"
"nadena.dev.ndmf.runtime",
"Unity.Mathematics"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down
32 changes: 31 additions & 1 deletion Ndmf/Runtime/MeshiaCascadingAvatarMeshSimplifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using nadena.dev.ndmf.runtime;
using nadena.dev.modular_avatar.core;
using UnityEngine.Pool;
using System.Diagnostics.CodeAnalysis;
using System.Collections;
using Unity.Mathematics;

namespace Meshia.MeshSimplification.Ndmf
{
Expand Down Expand Up @@ -127,6 +128,35 @@ public void ResolveReferences()
target.ResolveReference(this);
}
}
public static BitArray? GetPreserveBorderEdgesBoneIndices(GameObject avatarRoot, MeshiaCascadingAvatarMeshSimplifier avatarMeshSimplifier, MeshiaCascadingAvatarMeshSimplifierRendererEntry entry)
{
if (avatarRoot.TryGetComponent(out Animator avatarAnimator) && entry.GetTargetRenderer(avatarMeshSimplifier) is SkinnedMeshRenderer skinnedMeshRenderer)
{
var bones = skinnedMeshRenderer.bones;
var preserveBorderEdgeBoneIndices = new BitArray(bones.Length);

for (ulong boneMask = entry.PreserveBorderEdgesBones; boneMask != 0ul; boneMask &= boneMask - 1)
{
var bone = (HumanBodyBones)math.tzcnt(boneMask);
var boneTransform = avatarAnimator.GetBoneTransform(bone);
if (boneTransform != null)
{
var boneIndex = Array.IndexOf(bones, boneTransform);
if (boneIndex != -1)
{
preserveBorderEdgeBoneIndices.Set(boneIndex, true);
}
}
}
return preserveBorderEdgeBoneIndices;
}
else
{
return null;
}


}
}

[Serializable]
Expand Down
43 changes: 38 additions & 5 deletions Runtime/MeshSimplifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Unity.Collections;
Expand Down Expand Up @@ -67,7 +68,17 @@ public struct MeshSimplifier : INativeDisposable
/// <param name="options">The options for this mesh simplification.</param>
/// <param name="destination">The destination to write simplified mesh.</param>
/// <remarks>To process multiple meshes at once, use <see cref="SimplifyBatch(IReadOnlyList{ValueTuple{Mesh, MeshSimplificationTarget, MeshSimplifierOptions, Mesh}})"/> instead.</remarks>
public static void Simplify(Mesh mesh, MeshSimplificationTarget target, MeshSimplifierOptions options, Mesh destination)
public static void Simplify(Mesh mesh, MeshSimplificationTarget target, MeshSimplifierOptions options, Mesh destination)
=> Simplify(mesh, target, options, null, destination);
/// <summary>
/// Simplifies the given <paramref name="mesh"/> and writes the result to <paramref name="destination"/>.
/// </summary>
/// <param name="mesh">The mesh to simplify.</param>
/// <param name="target">The simplification target for this mesh simplification.</param>
/// <param name="options">The options for this mesh simplification.</param>
/// <param name="destination">The destination to write simplified mesh.</param>
/// <remarks>To process multiple meshes at once, use <see cref="SimplifyBatch(IReadOnlyList{ValueTuple{Mesh, MeshSimplificationTarget, MeshSimplifierOptions, Mesh}})"/> instead.</remarks>
public static void Simplify(Mesh mesh, MeshSimplificationTarget target, MeshSimplifierOptions options, BitArray? preserveBorderEdgesBoneIndices, Mesh destination)
{
Allocator allocator = Unity.Collections.Allocator.TempJob;
var originalMeshDataArray = Mesh.AcquireReadOnlyMeshData(mesh);
Expand All @@ -76,11 +87,21 @@ public static void Simplify(Mesh mesh, MeshSimplificationTarget target, MeshSimp

var meshSimplifier = new MeshSimplifier(allocator);

NativeBitArray nativePreserveBorderEdgesBoneIndices = new(preserveBorderEdgesBoneIndices?.Length ?? 0, allocator, NativeArrayOptions.UninitializedMemory);
if (preserveBorderEdgesBoneIndices is not null)
{
for (int i = 0; i < preserveBorderEdgesBoneIndices.Length; i++)
{
nativePreserveBorderEdgesBoneIndices.Set(i, preserveBorderEdgesBoneIndices[i]);
}
}

var load = meshSimplifier.ScheduleLoadMeshData(originalMeshData, options);

var simplifiedMeshDataArray = Mesh.AllocateWritableMeshData(1);
NativeList<BlendShapeData> simplifiedBlendShapes = new(allocator);
var simplify = meshSimplifier.ScheduleSimplify(originalMeshData, blendShapes, target, load);
var simplify = meshSimplifier.ScheduleSimplify(originalMeshData, blendShapes, target, nativePreserveBorderEdgesBoneIndices, load);
nativePreserveBorderEdgesBoneIndices.Dispose(simplify);
var write = meshSimplifier.ScheduleWriteMeshData(originalMeshData, blendShapes, simplifiedMeshDataArray[0], simplifiedBlendShapes, simplify);
meshSimplifier.Dispose(write);
JobHandle.ScheduleBatchedJobs();
Expand All @@ -102,7 +123,10 @@ public static void Simplify(Mesh mesh, MeshSimplificationTarget target, MeshSimp
}
simplifiedBlendShapes.Dispose();
}
public static void SimplifyBatch(IReadOnlyList<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, Mesh Destination)> parameters)
public static void SimplifyBatch(IReadOnlyList<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, Mesh Destination)> parameters)
=> SimplifyBatch(parameters.Select<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, Mesh Destination), (Mesh, MeshSimplificationTarget, MeshSimplifierOptions, BitArray?, Mesh)>(p => (p.Mesh, p.Target, p.Options, null, p.Destination)).ToList());

public static void SimplifyBatch(IReadOnlyList<(Mesh Mesh, MeshSimplificationTarget Target, MeshSimplifierOptions Options, BitArray? PreserveBorderEdgesBoneIndices, Mesh Destination)> parameters)
{
Allocator allocator = Unity.Collections.Allocator.TempJob;

Expand All @@ -124,16 +148,25 @@ public static void SimplifyBatch(IReadOnlyList<(Mesh Mesh, MeshSimplificationTar

for (int i = 0; i < parameters.Count; i++)
{
var (mesh, target, options, destination) = parameters[i];
var (mesh, target, options, preserveBorderEdgesBoneIndices, destination) = parameters[i];
var originalMeshData = originalMeshDataArray[i];
var blendShapes = BlendShapeData.GetMeshBlendShapes(mesh, allocator);
blendShapesList[i] = blendShapes;
var meshSimplifier = new MeshSimplifier(allocator);
NativeBitArray nativePreserveBorderEdgesBoneIndices = new(preserveBorderEdgesBoneIndices?.Length ?? 0, allocator, NativeArrayOptions.UninitializedMemory);
if (preserveBorderEdgesBoneIndices is not null)
{
for (int boneIndex = 0; boneIndex < preserveBorderEdgesBoneIndices.Length; boneIndex++)
{
nativePreserveBorderEdgesBoneIndices.Set(boneIndex, preserveBorderEdgesBoneIndices[boneIndex]);
}
}
var load = meshSimplifier.ScheduleLoadMeshData(originalMeshData, options);
NativeList<BlendShapeData> simplifiedBlendShapes = new(allocator);
simplifiedBlendShapesList[i] = simplifiedBlendShapes;

var simplify = meshSimplifier.ScheduleSimplify(originalMeshData, blendShapes, target, load);
var simplify = meshSimplifier.ScheduleSimplify(originalMeshData, blendShapes, target, nativePreserveBorderEdgesBoneIndices, load);
nativePreserveBorderEdgesBoneIndices.Dispose(simplify);
var write = meshSimplifier.ScheduleWriteMeshData(originalMeshData, blendShapes, simplifiedMeshDataArray[i], simplifiedBlendShapes, simplify);
meshSimplifier.Dispose(write);
jobHandles[i] = write;
Expand Down
Loading