-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBoneWeightThresholdViewer.cs
134 lines (114 loc) · 4.02 KB
/
BoneWeightThresholdViewer.cs
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
124
125
126
127
128
129
130
131
132
133
134
///
/// Created by Kenamis
///
#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace RainyReignGames
{
public class BoneWeightThresholdViewer : MonoBehaviour
{
[Range(0.001f, 0.01f), Tooltip("Size of the Gizmos cubes displayed for each vertex.")]
public float size = 0.01f;
[Range(0, 0.999f), Tooltip("Bone Weight Threshold")]
public float threshold;
public SkinnedMeshRenderer skinnedMeshRenderer;
public Transform boneToSplit;
[SerializeField, HideInInspector]
private SkinnedMeshRenderer previousRenderer;
[SerializeField, HideInInspector]
private Transform previousBone;
[SerializeField, HideInInspector]
private Vector3[] vertices;
[SerializeField, HideInInspector]
private BoneWeight[] boneWeights;
[SerializeField, HideInInspector]
private bool[] boneMask;
private Vector3 gizmoSize;
private void OnValidate()
{
gizmoSize = new Vector3(size, size, size);
if (skinnedMeshRenderer == null)
{
skinnedMeshRenderer = GetComponent<SkinnedMeshRenderer>();
}
if (skinnedMeshRenderer != null && skinnedMeshRenderer.sharedMesh != null)
{
if (skinnedMeshRenderer != previousRenderer)
{
UpdateMesh();
}
if(boneToSplit != previousBone)
{
UpdateBoneData();
}
}
}
void UpdateMesh()
{
Mesh bakedMesh = new Mesh();
skinnedMeshRenderer.BakeMesh(bakedMesh);
vertices = bakedMesh.vertices;
boneWeights = skinnedMeshRenderer.sharedMesh.boneWeights;
previousRenderer = skinnedMeshRenderer;
}
void UpdateBoneData()
{
List<Transform> bonesToSplit = new List<Transform>();
if (boneToSplit != null)
{
boneToSplit.GetComponentsInChildren<Transform>(bonesToSplit);
}
Transform[] bones = skinnedMeshRenderer.bones;
boneMask = new bool[bones.Length];
for (int i = 0; i < bones.Length; i++)
{
if (bonesToSplit.Contains(bones[i]))
{
boneMask[i] = true;
}
}
previousBone = boneToSplit;
}
void OnDrawGizmos()
{
if(vertices != null)
{
if (boneToSplit != null)
{
for (int i = 0; i < vertices.Length; i++)
{
if (IsPartOf(boneWeights[i], boneMask, threshold))
{
Gizmos.color = Color.red;
}
else
{
Gizmos.color = Color.black;
}
Gizmos.DrawCube(transform.TransformPoint(vertices[i]), gizmoSize);
}
}
else
{
Gizmos.color = Color.black;
for (int i = 0; i < vertices.Length; i++)
{
Gizmos.DrawCube(transform.TransformPoint(vertices[i]), gizmoSize);
}
}
}
}
private static bool IsPartOf(BoneWeight b, bool[] mask, float threshold)
{
float weight = 0;
if (mask[b.boneIndex0]) weight += b.weight0;
if (mask[b.boneIndex1]) weight += b.weight1;
if (mask[b.boneIndex2]) weight += b.weight2;
if (mask[b.boneIndex3]) weight += b.weight3;
return (weight > threshold);
}
}
}
#endif