BoneMeshEraser.cs
4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace VRM
{
public static class BoneMeshEraser
{
[Serializable]
public struct EraseBone
{
public Transform Bone;
public bool Erase;
public override string ToString()
{
return Bone.name + ":" + Erase;
}
}
static int ExcludeTriangles(int[] triangles, BoneWeight[] bws, int[] exclude)
{
int count = 0;
if (bws != null && bws.Length>0)
{
for (int i = 0; i < triangles.Length; i += 3)
{
var a = triangles[i];
var b = triangles[i + 1];
var c = triangles[i + 2];
{
var bw = bws[a];
if (bw.weight0 > 0 && exclude.Contains(bw.boneIndex0)) continue;
if (bw.weight1 > 0 && exclude.Contains(bw.boneIndex1)) continue;
if (bw.weight2 > 0 && exclude.Contains(bw.boneIndex2)) continue;
if (bw.weight3 > 0 && exclude.Contains(bw.boneIndex3)) continue;
}
{
var bw = bws[b];
if (bw.weight0 > 0 && exclude.Contains(bw.boneIndex0)) continue;
if (bw.weight1 > 0 && exclude.Contains(bw.boneIndex1)) continue;
if (bw.weight2 > 0 && exclude.Contains(bw.boneIndex2)) continue;
if (bw.weight3 > 0 && exclude.Contains(bw.boneIndex3)) continue;
}
{
var bw = bws[c];
if (bw.weight0 > 0 && exclude.Contains(bw.boneIndex0)) continue;
if (bw.weight1 > 0 && exclude.Contains(bw.boneIndex1)) continue;
if (bw.weight2 > 0 && exclude.Contains(bw.boneIndex2)) continue;
if (bw.weight3 > 0 && exclude.Contains(bw.boneIndex3)) continue;
}
triangles[count++] = a;
triangles[count++] = b;
triangles[count++] = c;
}
}
return count;
}
public static Mesh CreateErasedMesh(Mesh src, int[] eraseBoneIndices)
{
/*
Debug.LogFormat("{0} exclude: {1}",
src.name,
String.Join(", ", eraseBoneIndices.Select(x => x.ToString()).ToArray())
);
*/
var mesh = new Mesh();
mesh.name = src.name + "(erased)";
#if UNITY_2017_3_OR_NEWER
mesh.indexFormat = src.indexFormat;
#endif
mesh.vertices = src.vertices;
mesh.normals = src.normals;
mesh.uv = src.uv;
mesh.tangents = src.tangents;
mesh.boneWeights = src.boneWeights;
mesh.bindposes = src.bindposes;
mesh.subMeshCount = src.subMeshCount;
for (int i = 0; i < src.subMeshCount; ++i)
{
var indices = src.GetIndices(i);
var count = ExcludeTriangles(indices, mesh.boneWeights, eraseBoneIndices);
var dst = new int[count];
Array.Copy(indices, 0, dst, 0, count);
mesh.SetIndices(dst, MeshTopology.Triangles, i);
}
return mesh;
}
public static int IndexOf(this Transform[] list, Transform target)
{
for (int i = 0; i < list.Length; ++i)
{
if (list[i] == target)
{
return i;
}
}
return -1;
}
public static IEnumerable<Transform> Ancestor(this Transform t)
{
yield return t;
if (t.parent != null)
{
foreach (var x in Ancestor(t.parent))
{
yield return x;
}
}
}
}
}