Tanoda
pb_SelectionHighlight.cs
Go to the documentation of this file.
1using UnityEngine;
2using System.Collections.Generic;
4using UnityEngine.Rendering;
5
6namespace GILES
7{
11 [pb_JsonIgnore]
12 [pb_EditorComponent]
13 public class pb_SelectionHighlight : MonoBehaviour
14 {
15 enum HighlightType
16 {
17 Wireframe,
18 Glow,
19 Bounds
20 }
21
22 HighlightType highlightType = HighlightType.Wireframe;
23
24 public Material material;
25 Mesh mesh;
26 private bool fallback = false;
27
28 void Awake()
29 {
30 MeshFilter mf = GetComponent<MeshFilter>();
31
32 if(mf == null || mf.sharedMesh == null)
33 {
34 mf = GetComponentInChildren<MeshFilter>();
35 if (mf)
36 {
37 mf.gameObject.AddComponent<pb_SelectionHighlight>();
38 Destroy(this);
39 return;
40 }
41 }
42
43 if(mf == null || mf.sharedMesh == null)
44 highlightType = HighlightType.Bounds;
45
46 switch( highlightType )
47 {
48 case HighlightType.Wireframe:
49 mesh = GenerateWireframe( mf.sharedMesh );
50 material = pb_BuiltinResource.GetMaterial(pb_BuiltinResource.mat_Wireframe);
51 break;
52
53 case HighlightType.Bounds:
54
55 Bounds bounds = mf != null && mf.sharedMesh != null ? mf.sharedMesh.bounds : new Bounds(Vector3.zero, Vector3.one);
56 if (!mf)
57 {
58 var coll = GetComponentInChildren<Collider>();
59 if (coll)
60 {
61 if (coll.gameObject != gameObject)
62 {
63 coll.gameObject.AddComponent<pb_SelectionHighlight>();
64 Destroy(this);
65 return;
66 }
67 bounds = coll.bounds;
68 bounds.center = Vector3.zero;
69 //bounds.extents *= Macro.SmallestAxis(coll.transform.localScale);
70 bounds.extents *= 0.9f;
71 }
72 }
73 mesh = GenerateBounds( bounds );
74 material = pb_BuiltinResource.GetMaterial(pb_BuiltinResource.mat_UnlitVertexColor);
75 break;
76
77 case HighlightType.Glow:
78 mesh = mf.sharedMesh;
79 material = pb_BuiltinResource.GetMaterial(pb_BuiltinResource.mat_Highlight);
80 break;
81 }
82
83 mesh.RecalculateBounds();
84 material.SetVector("_Center", mesh.bounds.center);
85
86 Graphics.DrawMesh(mesh, transform.localToWorldMatrix, material, 0);
87 }
88
89 internal void OnDestroy()
90 {
91 if( highlightType == HighlightType.Wireframe || highlightType == HighlightType.Bounds )
92 pb_ObjectUtility.Destroy(mesh);
93 }
94
95 void Update()
96 {
97 Graphics.DrawMesh(mesh, transform.localToWorldMatrix, material, 0);
98 }
99
103 Mesh GenerateWireframe(Mesh mesh)
104 {
105 Mesh m = new Mesh();
106 m.indexFormat = IndexFormat.UInt32;
107 m.vertices = mesh.vertices;
108 m.normals = mesh.normals;
109 int[] tris = new int[mesh.triangles.Length * 2];
110 int[] mtris = mesh.triangles;
111
112 int c = 0;
113 for(int i = 0; i < mtris.Length; i+=3)
114 {
115 tris[c++] = mtris[i+0];
116 tris[c++] = mtris[i+1];
117 tris[c++] = mtris[i+1];
118 tris[c++] = mtris[i+2];
119 tris[c++] = mtris[i+2];
120 tris[c++] = mtris[i+0];
121 }
122
123 m.subMeshCount = 1;
124 m.SetIndices(tris, MeshTopology.Lines, 0);
125
126 return m;
127 }
128
132 Mesh GenerateBounds(Bounds bounds)
133 {
134 Vector3 cen = bounds.center;
135 Vector3 ext = bounds.extents + bounds.extents.normalized * .1f;
136
137 // Draw Wireframe
138 List<Vector3> v = new List<Vector3>();
139
140 v.AddRange( DrawBoundsEdge(cen, -ext.x, -ext.y, -ext.z, .2f) );
141 v.AddRange( DrawBoundsEdge(cen, -ext.x, -ext.y, ext.z, .2f) );
142 v.AddRange( DrawBoundsEdge(cen, ext.x, -ext.y, -ext.z, .2f) );
143 v.AddRange( DrawBoundsEdge(cen, ext.x, -ext.y, ext.z, .2f) );
144
145 v.AddRange( DrawBoundsEdge(cen, -ext.x, ext.y, -ext.z, .2f) );
146 v.AddRange( DrawBoundsEdge(cen, -ext.x, ext.y, ext.z, .2f) );
147 v.AddRange( DrawBoundsEdge(cen, ext.x, ext.y, -ext.z, .2f) );
148 v.AddRange( DrawBoundsEdge(cen, ext.x, ext.y, ext.z, .2f) );
149
150 Vector2[] u = new Vector2[48];
151 int[] t = new int[48];
152 Color[] c = new Color[48];
153
154 for(int i = 0; i < 48; i++)
155 {
156 t[i] = i;
157 u[i] = Vector2.zero;
158 c[i] = Color.white;
159 c[i].a = .5f;
160 }
161
162 Mesh m = new Mesh();
163 m.indexFormat = IndexFormat.UInt32;
164 m.vertices = v.ToArray();
165 m.subMeshCount = 1;
166 m.SetIndices(t, MeshTopology.Lines, 0);
167
168 m.uv = u;
169 m.normals = v.ToArray();
170 m.colors = c;
171
172 return m;
173 }
174
175 Vector3[] DrawBoundsEdge(Vector3 center, float x, float y, float z, float size)
176 {
177 Vector3 p = center;
178 Vector3[] v = new Vector3[6];
179
180 p.x += x;
181 p.y += y;
182 p.z += z;
183
184 v[0] = p;
185 v[1] = (p + ( -(x/Mathf.Abs(x)) * Vector3.right * Mathf.Min(size, Mathf.Abs(x))));
186
187 v[2] = p;
188 v[3] = (p + ( -(y/Mathf.Abs(y)) * Vector3.up * Mathf.Min(size, Mathf.Abs(y))));
189
190 v[4] = p;
191 v[5] = (p + ( -(z/Mathf.Abs(z)) * Vector3.forward * Mathf.Min(size, Mathf.Abs(z))));
192
193 return v;
194 }
195 }
196}
UnityEngine.Color Color
Definition: TestScript.cs:32