Tanoda
Drawer.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;
10using System.Collections.Generic;
11using Leap.Unity.Infix;
12using UnityEngine;
13
14namespace Leap.Unity {
15
19 public class Drawer {
20
21 // Minimum Drawer Functions.
22 public System.Action<Vector3, Vector3> implDrawLine;
23 public System.Action<Color> implSetColor;
24
26 public Color color { set { implSetColor(value); }}
27
28 public Stack<Matrix4x4> _matrices;
29 public Matrix4x4 _currMatrix = Matrix4x4.identity;
30 public bool MaybePushMatrix(Matrix4x4? m) {
31 if (m != null) { PushMatrix(m.Value); return true; } else { return false; }
32 }
33 public void PushMatrix(Matrix4x4 m) {
34 _matrices.Push(m);
35 _currMatrix = m;
36 }
37 public void PopMatrix() {
38 _currMatrix = _matrices.Pop();
39 }
40
41 // Extended Drawer Functions.
42 public System.Action<Matrix4x4> implDrawUnitSphere;
43
44 public bool isActiveAndEnabled = true;
45
46 public void MaybeSetColor(Color? maybeColor) {
47 if (maybeColor != null) { implSetColor(maybeColor.Value); }
48 }
49
50 #region Implementations
51
52 //private static Drawer _hyperMegaDrawer;
53 //private static Leap.Unity.HyperMegaStuff.HyperMegaLines _hyperMegaLines;
54 //public static Drawer HyperMegaDrawer { get {
55 // var drawer = Utils.Require(ref _hyperMegaDrawer);
56 // if (_hyperMegaLines == null) {
57 // _hyperMegaLines = HyperMegaStuff.HyperMegaLines.drawer;
58 // }
59 // drawer.isActiveAndEnabled = _hyperMegaLines.isActiveAndEnabled;
60 // drawer.implDrawLine = (a, b) => {
61 // _hyperMegaLines.DrawLine(a, b);
62 // };
63 // drawer.implSetColor = (c) => {
64 // _hyperMegaLines.color = c;
65 // };
66 // return drawer;
67 //}}
68
69 private static Drawer _unityDebugDrawer;
70 private static Color _unityDebugColor = Color.white;
71 public static Drawer UnityDebugDrawer { get {
72 var drawer = Utils.Require(ref _unityDebugDrawer);
73 // Debug Lines are cleared on Update, don't use in edit mode
74 drawer.isActiveAndEnabled = Application.isPlaying;
75 drawer.implDrawLine = (a, b) => {
76 var color = Drawer._unityDebugColor;
77 UnityEngine.Debug.DrawLine(a, b, color);
78 };
79 drawer.implSetColor = (c) => {
80 _unityDebugColor = c;
81 };
82 return drawer;
83 }}
84
85 private static Drawer _unityGizmoDrawer;
87 public static Drawer UnityGizmoDrawer { get {
88 var drawer = Utils.Require(ref _unityGizmoDrawer);
89 drawer.isActiveAndEnabled = true;
90 drawer.implDrawLine = (a, b) => {
91 Gizmos.DrawLine(a, b);
92 };
93 drawer.implSetColor = (c) => {
94 Gizmos.color = c;
95 };
96 drawer.implDrawUnitSphere = (m) => {
97 var origM = Gizmos.matrix;
98 Gizmos.matrix = m;
99 Gizmos.DrawSphere(Vector3.zero, 1f);
100 Gizmos.matrix = origM;
101 };
102 return drawer;
103 }}
104
105 private static Drawer _unityGizmoHandlesDrawer;
107 public static Drawer UnityGizmoHandlesDrawer { get {
108 var drawer = Utils.Require(ref _unityGizmoHandlesDrawer);
109 drawer.isActiveAndEnabled = true;
110 drawer.implDrawLine = (a, b) => {
111 #if UNITY_EDITOR
112 UnityEditor.Handles.DrawLine(a, b);
113 #endif
114 };
115 drawer.implSetColor = (c) => {
116 #if UNITY_EDITOR
117 UnityEditor.Handles.color = c;
118 #endif
119 };
120 drawer.implDrawUnitSphere = (m) => {
121 #if UNITY_EDITOR
122 var origM = UnityEditor.Handles.matrix;
123 var origColor = UnityEditor.Handles.color;
124 float h, s, v;
125 Color.RGBToHSV(origColor, out h, out s, out v);
126 UnityEditor.Handles.color = origColor.WithHSV(h, s * 1f, v * 3f);
127 UnityEditor.Handles.matrix = m;
128 // UnityEditor.Handles.SphereHandleCap
129 UnityEditor.Handles.SphereHandleCap(0, Vector3.zero, Quaternion.identity, 1f, EventType.Repaint);
130 UnityEditor.Handles.matrix = origM;
131 #endif
132 };
133 return drawer;
134 }}
135
136 #endregion // Implementations
137
138 #region Line Drawing
139
140 public void Line(Vector3 a, Vector3 b) {
141 this.implDrawLine(
142 _currMatrix.MultiplyPoint3x4(a),
143 _currMatrix.MultiplyPoint3x4(b)
144 );
145 }
146 public void Line(Vector3 a, Vector3 b, Color? color) {
148 Line(a, b);
149 }
150 private Action<Vector3, Vector3> drawLineAction { get {
151 return Utils.Require(ref _b_drawLineAction, () => (a, b) => Line(a, b));
152 }}
153 private Action<Vector3, Vector3> _b_drawLineAction;
154
155 public void Lines(
156 System.Action<System.Action<Vector3, Vector3>> drawLineFuncFunc,
157 Color? color = null)
158 {
160 drawLineFuncFunc(drawLineAction);
161 }
162
163 #endregion
164
165 #region Sphere Drawing
166
167 public void Sphere(Vector3 center = default(Vector3), float radius = 1f,
168 Color? color = null, Matrix4x4? matrix = null)
169 {
170 try {
171 if (implDrawUnitSphere != null) {
172 var useMatrix = (matrix ?? Matrix4x4.identity) * Matrix4x4.TRS(center, Quaternion.identity, Vector3.one * radius);
174 implDrawUnitSphere(useMatrix);
175 } else {
176 // Fall back to line drawing.
177 this.WireSphere(center, radius, color, matrix);
178 }
179 } catch (System.Exception e) { Debug.LogError(e); }
180 }
181
182 #endregion
183
184 }
185
186 public static class DrawerExtensions {
187
188 public static void WireSphere(this Drawer drawer,
189 Vector3 center = default(Vector3), float radius = 1f, Color? color = null,
190 Matrix4x4? matrix = null)
191 {
192 drawer.Lines(drawLineFunc =>
193 new Geometry.Sphere(center, radius, overrideMatrix: matrix)
194 .DrawLines(drawLineFunc), color);
195 }
196
197 public static void Lines(this Drawer drawer, Vector3 a, Vector3 b,
198 Vector3 c)
199 {
200 drawer.Line(a, b); drawer.Line(b, c);
201 }
202
203 public static void Lines(this Drawer drawer, Vector3 a, Vector3 b,
204 Vector3 c, Vector3 d)
205 {
206 drawer.Line(a, b); drawer.Line(b, c); drawer.Line(c, d);
207 }
208
209 public static void Lines(this Drawer drawer, Vector3 a, Vector3 b,
210 Vector3 c, Vector3 d, Vector3 e)
211 {
212 drawer.Line(a, b); drawer.Line(b, c); drawer.Line(c, d);
213 drawer.Line(d, e);
214 }
215
216 private static Color[] _basisColors;
217 public static void DrawBasis(this Transform t, Drawer drawer,
218 float? length = null,
219 Color? overrideAxesColor = null,
220 float? axesHueShift = null,
221 Matrix4x4? overrideMatrix = null)
222 {
223 var useLength = length.UnwrapOr(0.5f);
224 var useMatrix = overrideMatrix.UnwrapOr(t.localToWorldMatrix);
225 var a = Vector3.zero;
226 Color xColor = Color.red, yColor = Color.green, zColor = Color.blue;
227 if (overrideAxesColor != null) {
228 xColor = yColor = zColor = overrideAxesColor.Value;
229 }
230 if (axesHueShift != null) {
231 var hueShift = axesHueShift.Value;
232 xColor = xColor.ShiftHue(hueShift);
233 yColor = yColor.ShiftHue(hueShift);
234 zColor = zColor.ShiftHue(hueShift);
235 }
236 Utils.Require(ref _basisColors, 3);
237 _basisColors[0] = xColor;
238 _basisColors[1] = yColor;
239 _basisColors[2] = zColor;
240
241 var octahedron = new Geometry.Bipyramid(a: a, b: Vector3.zero,
242 polySegments: 4, lengthFraction: 0.5f,
243 overrideMatrix: useMatrix);
244 for (var bIdx = 0; bIdx < 3; bIdx++) {
245 var b = Vector3.zero; b[bIdx] = useLength;
246 octahedron.b = b;
247 drawer.color = _basisColors[bIdx];
248 octahedron.DrawLines(drawer.implDrawLine);
249 }
250 }
251
258 public static void Draw(this Pose pose, Drawer drawer,
259 float length, Color? overrideAxesColor = null,
260 float? hueShift = null)
261 {
262 Color xColor = Color.red, yColor = Color.green, zColor = Color.blue;
263 if (overrideAxesColor != null) {
264 xColor = yColor = zColor = overrideAxesColor.Value;
265 }
266 if (hueShift != null) {
267 var useHueShift = hueShift.Value;
268 xColor = xColor.ShiftHue((float)useHueShift);
269 yColor = yColor.ShiftHue((float)useHueShift);
270 zColor = zColor.ShiftHue((float)useHueShift);
271 }
272
273 Utils.Require(ref _basisColors, 3);
274 _basisColors[0] = xColor;
275 _basisColors[1] = yColor;
276 _basisColors[2] = zColor;
277
278 var bipyramid = new Geometry.Bipyramid(a: Vector3.zero, b: Vector3.zero,
279 polySegments: 16, lengthFraction: 0.5f, overrideMatrix: pose.matrix);
280 for (var bIdx = 0; bIdx < 3; bIdx++) {
281 var b = Vector3.zero; b[bIdx] = length;
282 bipyramid.b = b;
283 drawer.color = _basisColors[bIdx];
284 bipyramid.DrawLines(drawer.implDrawLine);
285 }
286 }
287
288 public static void Draw(this Matrix4x4 m, Drawer drawer,
289 float axisLengths, float? hueShift = null,
290 Color? color = null,
291 Color? xColor = null, Color? yColor = null, Color? zColor = null,
292 bool drawBips = false)
293 {
294 var useXColor = xColor ?? color ?? Color.red;
295 var useYColor = yColor ?? color ?? Color.green;
296 var useZColor = zColor ?? color ?? Color.blue;
297 if (hueShift != null) {
298 useXColor = useXColor.ShiftHue(hueShift.Value);
299 useYColor = useYColor.ShiftHue(hueShift.Value);
300 useZColor = useZColor.ShiftHue(hueShift.Value);
301 }
302 if (drawBips) {
303 var bipyramid = new Geometry.Bipyramid(a: Vector3.zero, b: Vector3.zero,
304 polySegments: 16, lengthFraction: 0.5f, overrideMatrix: m);
305 for (var bIdx = 0; bIdx < 3; bIdx++) {
306 var b = Vector3.zero; b[bIdx] = axisLengths;
307 bipyramid.b = b;
308 if (bIdx == 0) { drawer.color = useXColor; }
309 if (bIdx == 1) { drawer.color = useYColor; }
310 if (bIdx == 2) { drawer.color = useZColor; }
311 bipyramid.DrawLines(drawer.implDrawLine);
312 }
313 } else {
314 for (var i = 0; i < 3; i++) {
315 var pos = m.GetPosition();
316 if (i == 0) { drawer.color = useXColor; }
317 if (i == 1) { drawer.color = useYColor; }
318 if (i == 2) { drawer.color = useZColor; }
319 drawer.implDrawLine(pos, pos + m.GetAxis(i) * axisLengths);
320 }
321 }
322 }
323
324 }
325
326}
UnityEngine.Debug Debug
Definition: TanodaServer.cs:19
UnityEngine.Color Color
Definition: TestScript.cs:32
Simple drawing interface abstraction (intended for debug drawing, not production!) with statically-ac...
Definition: Drawer.cs:19
void Lines(System.Action< System.Action< Vector3, Vector3 > > drawLineFuncFunc, Color? color=null)
Definition: Drawer.cs:155
System.Action< Vector3, Vector3 > implDrawLine
Definition: Drawer.cs:22
void PopMatrix()
Definition: Drawer.cs:37
Matrix4x4 _currMatrix
Definition: Drawer.cs:29
Stack< Matrix4x4 > _matrices
Definition: Drawer.cs:28
static Drawer UnityDebugDrawer
Definition: Drawer.cs:71
void MaybeSetColor(Color? maybeColor)
Definition: Drawer.cs:46
bool MaybePushMatrix(Matrix4x4? m)
Definition: Drawer.cs:30
static Drawer UnityGizmoHandlesDrawer
For use in OnDrawGizmos and OnDrawGizmosSelected via the Handles API. By default, draws on top of any...
Definition: Drawer.cs:107
bool isActiveAndEnabled
Definition: Drawer.cs:44
void Sphere(Vector3 center=default(Vector3), float radius=1f, Color? color=null, Matrix4x4? matrix=null)
Definition: Drawer.cs:167
void Line(Vector3 a, Vector3 b, Color? color)
Definition: Drawer.cs:146
void PushMatrix(Matrix4x4 m)
Definition: Drawer.cs:33
static Drawer UnityGizmoDrawer
For use in OnDrawGizmos and OnDrawGizmosSelected.
Definition: Drawer.cs:87
void Line(Vector3 a, Vector3 b)
Definition: Drawer.cs:140
System.Action< Matrix4x4 > implDrawUnitSphere
Definition: Drawer.cs:42
System.Action< Color > implSetColor
Definition: Drawer.cs:23
Color color
Calls the setColor delegate.
Definition: Drawer.cs:26