Tanoda
LeapBoxGraphic.cs
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) Ultraleap, Inc. 2011-2020. *
3 * *
4 * Use subject to the terms of the Apache License 2.0 available at *
5 * http://www.apache.org/licenses/LICENSE-2.0, or another agreement *
6 * between Ultraleap and you, your company or other organization. *
7 ******************************************************************************/
8
9using System.Collections.Generic;
10using UnityEngine;
11using UnityEngine.Rendering;
12using Leap.Unity.Query;
14using System;
15
17
25 [DisallowMultipleComponent]
27
28 [MinValue(0.0001f)]
30 [SerializeField]
31 private float _thickness = 0.01f;
32
36 public Vector3 size {
37 get { return new Vector3(_size.x, _size.y, _thickness); }
38 private set { _size = new Vector2(value.x, value.y); _thickness = value.z; }
39 }
40
41 public override void RefreshSlicedMeshData(Vector2i resolution,
42 RectMargins meshMargins,
43 RectMargins uvMargins) {
44 List<Vector3> verts = new List<Vector3>();
45 List<Vector2> uvs = new List<Vector2>();
46 List<Vector3> normals = new List<Vector3>();
47 List<int> tris = new List<int>();
48
49 // Back
50 for (int vy = 0; vy < resolution.y; vy++) {
51 for (int vx = 0; vx < resolution.x; vx++) {
52 Vector2 vert;
53 vert.x = calculateVertAxis(vx, resolution.x, rect.width, meshMargins.left, meshMargins.right);
54 vert.y = calculateVertAxis(vy, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
55 verts.Add(vert + new Vector2(rect.x, rect.y));
56 normals.Add(Vector3.forward);
57
58 Vector2 uv;
59 uv.x = calculateVertAxis(vx, resolution.x, 1, uvMargins.left, uvMargins.right);
60 uv.y = calculateVertAxis(vy, resolution.y, 1, uvMargins.top, uvMargins.bottom);
61 uvs.Add(uv);
62 }
63 }
64
65 int backVertsCount = verts.Count;
66
67 // Front
68 float depth = -size.z;
69 for (int vy = 0; vy < resolution.y; vy++) {
70 for (int vx = 0; vx < resolution.x; vx++) {
71 Vector3 vert = Vector3.zero;
72 vert.x = calculateVertAxis(vx, resolution.x, rect.width, meshMargins.left, meshMargins.right);
73 vert.y = calculateVertAxis(vy, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
74 verts.Add(vert + new Vector3(rect.x, rect.y, depth));
75 normals.Add(Vector3.back);
76
77 Vector2 uv;
78 uv.x = calculateVertAxis(vx, resolution.x, 1, uvMargins.left, uvMargins.right);
79 uv.y = calculateVertAxis(vy, resolution.y, 1, uvMargins.top, uvMargins.bottom);
80 uvs.Add(uv);
81 }
82 }
83
84 // Back
85 for (int vy = 0; vy < resolution.y - 1; vy++) {
86 for (int vx = 0; vx < resolution.x - 1; vx++) {
87 int vertIndex = vy * resolution.x + vx;
88
89 tris.Add(vertIndex);
90 tris.Add(vertIndex + 1);
91 tris.Add(vertIndex + 1 + resolution.x);
92
93 tris.Add(vertIndex);
94 tris.Add(vertIndex + 1 + resolution.x);
95 tris.Add(vertIndex + resolution.x);
96 }
97 }
98
99 // Front
100 for (int vy = 0; vy < resolution.y - 1; vy++) {
101 for (int vx = 0; vx < resolution.x - 1; vx++) {
102 int vertIndex = backVertsCount + (vy * resolution.x + vx);
103
104 tris.Add(vertIndex);
105 tris.Add(vertIndex + 1 + resolution.x);
106 tris.Add(vertIndex + 1);
107
108 tris.Add(vertIndex);
109 tris.Add(vertIndex + resolution.x);
110 tris.Add(vertIndex + 1 + resolution.x);
111 }
112 }
113
114 // Edges
115 int ex = 0, ey = 0;
116 int backVertIdx = verts.Count, frontVertIdx = verts.Count;
117
118 // Left
119 for (int vy = 0; vy < resolution.y; vy++) { // Repeat back edge, left side
120 Vector2 vert;
121 vert.x = calculateVertAxis(ex, resolution.x, rect.width, meshMargins.left, meshMargins.right);
122 vert.y = calculateVertAxis(vy, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
123 verts.Add(vert + new Vector2(rect.x, rect.y));
124 normals.Add(Vector3.left);
125
126 frontVertIdx += 1;
127
128 Vector2 uv;
129 uv.x = calculateVertAxis(ex, resolution.x, 1, uvMargins.left, uvMargins.right) + 0.01F /* cheat UVs in, prevents edge tearing */;
130 uv.y = calculateVertAxis(vy, resolution.y, 1, uvMargins.top, uvMargins.bottom);
131 uvs.Add(uv);
132 }
133 for (int vy = 0; vy < resolution.y; vy++) { // Repeat front edge, left side
134 Vector3 vert = Vector3.zero;
135 vert.x = calculateVertAxis(ex, resolution.x, rect.width, meshMargins.left, meshMargins.right);
136 vert.y = calculateVertAxis(vy, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
137 verts.Add(vert + new Vector3(rect.x, rect.y, depth));
138 normals.Add(Vector3.left);
139
140 Vector2 uv;
141 uv.x = calculateVertAxis(ex, resolution.x, 1, uvMargins.left, uvMargins.right);
142 uv.y = calculateVertAxis(vy, resolution.y, 1, uvMargins.top, uvMargins.bottom);
143 uvs.Add(uv);
144 }
145 for (int vy = 0; vy < resolution.y - 1; vy++) { // Add quads
146 addQuad(tris, frontVertIdx + vy, backVertIdx + vy, backVertIdx + vy + 1, frontVertIdx + vy + 1);
147 }
148
149 // Right
150 ex = resolution.x - 1;
151 backVertIdx = verts.Count;
152 frontVertIdx = verts.Count;
153 for (int vy = 0; vy < resolution.y; vy++) { // Repeat back edge, right side
154 Vector2 vert;
155 vert.x = calculateVertAxis(ex, resolution.x, rect.width, meshMargins.left, meshMargins.right);
156 vert.y = calculateVertAxis(vy, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
157 verts.Add(vert + new Vector2(rect.x, rect.y));
158 normals.Add(Vector3.right);
159
160 frontVertIdx += 1;
161
162 Vector2 uv;
163 uv.x = calculateVertAxis(ex, resolution.x, 1, uvMargins.left, uvMargins.right) - 0.01F /* cheat UVs in, prevents edge tearing */;
164 uv.y = calculateVertAxis(vy, resolution.y, 1, uvMargins.top, uvMargins.bottom);
165 uvs.Add(uv);
166 }
167 for (int vy = 0; vy < resolution.y; vy++) { // Repeat front edge, right side
168 Vector3 vert = Vector3.zero;
169 vert.x = calculateVertAxis(ex, resolution.x, rect.width, meshMargins.left, meshMargins.right);
170 vert.y = calculateVertAxis(vy, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
171 verts.Add(vert + new Vector3(rect.x, rect.y, depth));
172 normals.Add(Vector3.right);
173
174 Vector2 uv;
175 uv.x = calculateVertAxis(ex, resolution.x, 1, uvMargins.left, uvMargins.right);
176 uv.y = calculateVertAxis(vy, resolution.y, 1, uvMargins.top, uvMargins.bottom);
177 uvs.Add(uv);
178 }
179 for (int vy = 0; vy < resolution.y - 1; vy++) { // Add quads
180 addQuad(tris, frontVertIdx + vy + 1, backVertIdx + vy + 1, backVertIdx + vy, frontVertIdx + vy);
181 }
182
183 // Top
184 ey = resolution.y - 1;
185 backVertIdx = verts.Count;
186 frontVertIdx = verts.Count;
187 for (int vx = 0; vx < resolution.x; vx++) { // Repeat back edge, upper side
188 Vector2 vert;
189 vert.x = calculateVertAxis(vx, resolution.x, rect.width, meshMargins.left, meshMargins.right);
190 vert.y = calculateVertAxis(ey, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
191 verts.Add(vert + new Vector2(rect.x, rect.y));
192 normals.Add(Vector3.up);
193
194 frontVertIdx += 1;
195
196 Vector2 uv;
197 uv.x = calculateVertAxis(vx, resolution.x, 1, uvMargins.left, uvMargins.right);
198 uv.y = calculateVertAxis(ey, resolution.y, 1, uvMargins.top, uvMargins.bottom) - 0.01F /* cheat UVs in, prevents edge tearing */;
199 uvs.Add(uv);
200 }
201 for (int vx = 0; vx < resolution.x; vx++) { // Repeat front edge, upper side
202 Vector3 vert = Vector3.zero;
203 vert.x = calculateVertAxis(vx, resolution.x, rect.width, meshMargins.left, meshMargins.right);
204 vert.y = calculateVertAxis(ey, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
205 verts.Add(vert + new Vector3(rect.x, rect.y, depth));
206 normals.Add(Vector3.up);
207
208 Vector2 uv;
209 uv.x = calculateVertAxis(vx, resolution.x, 1, uvMargins.left, uvMargins.right);
210 uv.y = calculateVertAxis(ey, resolution.y, 1, uvMargins.top, uvMargins.bottom);
211 uvs.Add(uv);
212 }
213 for (int vx = 0; vx < resolution.x - 1; vx++) { // Add quads
214 addQuad(tris, frontVertIdx + vx, backVertIdx + vx, backVertIdx + vx + 1, frontVertIdx + vx + 1);
215 }
216
217 // Bottom
218 ey = 0;
219 backVertIdx = verts.Count;
220 frontVertIdx = verts.Count;
221 for (int vx = 0; vx < resolution.x; vx++) { // Repeat back edge, upper side
222 Vector2 vert;
223 vert.x = calculateVertAxis(vx, resolution.x, rect.width, meshMargins.left, meshMargins.right);
224 vert.y = calculateVertAxis(ey, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
225 verts.Add(vert + new Vector2(rect.x, rect.y));
226 normals.Add(Vector3.down);
227
228 frontVertIdx += 1;
229
230 Vector2 uv;
231 uv.x = calculateVertAxis(vx, resolution.x, 1, uvMargins.left, uvMargins.right);
232 uv.y = calculateVertAxis(ey, resolution.y, 1, uvMargins.top, uvMargins.bottom) + 0.01F /* cheat UVs in, prevents edge tearing */;
233 uvs.Add(uv);
234 }
235 for (int vx = 0; vx < resolution.x; vx++) { // Repeat front edge, upper side
236 Vector3 vert = Vector3.zero;
237 vert.x = calculateVertAxis(vx, resolution.x, rect.width, meshMargins.left, meshMargins.right);
238 vert.y = calculateVertAxis(ey, resolution.y, rect.height, meshMargins.top, meshMargins.bottom);
239 verts.Add(vert + new Vector3(rect.x, rect.y, depth));
240 normals.Add(Vector3.down);
241
242 Vector2 uv;
243 uv.x = calculateVertAxis(vx, resolution.x, 1, uvMargins.left, uvMargins.right);
244 uv.y = calculateVertAxis(ey, resolution.y, 1, uvMargins.top, uvMargins.bottom);
245 uvs.Add(uv);
246 }
247 for (int vx = 0; vx < resolution.x - 1; vx++) { // Add quads
248 addQuad(tris, frontVertIdx + vx + 1, backVertIdx + vx + 1, backVertIdx + vx, frontVertIdx + vx);
249 }
250
251 if (mesh == null) {
252 mesh = new Mesh();
253 }
254
255 mesh.name = "Box Mesh";
256 mesh.hideFlags = HideFlags.HideAndDontSave;
257
258 mesh.Clear(keepVertexLayout: false);
259 mesh.SetVertices(verts);
260 mesh.SetNormals(normals);
261 mesh.SetTriangles(tris, 0);
262 mesh.SetUVs(uvChannel.Index(), uvs);
263 mesh.RecalculateBounds();
264
265 remappableChannels = UVChannelFlags.UV0;
266 }
267
268 private void addQuad(List<int> tris, int idx0, int idx1, int idx2, int idx3) {
269 tris.Add(idx0);
270 tris.Add(idx1);
271 tris.Add(idx2);
272
273 tris.Add(idx0);
274 tris.Add(idx2);
275 tris.Add(idx3);
276 }
277 }
278}
The Box Graphic is a type of procedural mesh graphic that can generate thick panels with a number of ...
override void RefreshSlicedMeshData(Vector2i resolution, RectMargins meshMargins, RectMargins uvMargins)
Set the mesh property equal to the correct mesh given the Sliced Graphic's current settings.
Vector3 size
Gets the dimensions of the box graphic in local space.
Mesh mesh
Returns the mesh that represents this graphic. It can have any topology, any number of uv channels,...
UVChannelFlags remappableChannels
Returns an enum mask that represents the union of all channels that are allowed to be remapped for th...
The base class for LeapPanelGraphic, LeapBoxGraphic, and similar generators.
float calculateVertAxis(int vertIdx, int vertCount, float size, float border0, float border1, bool alwaysRespectBorder=false)
Given a vertex index from an edge, the total vertCount and size along the current dimension,...
Rect rect
Returns the current local-space rect of this panel. If there is a RectTransform attached to this pane...
UVChannelFlags uvChannel
Returns which uv channel is being used for this panel. It will always match the uv channel being used...