Tanoda
Plugins/LeapMotion/Core/Scripts/Geometry/Shapes/Circle.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 Leap.Unity.Infix;
12using UnityEngine;
13
14namespace Leap.Unity.Geometry {
15
16 using UnityRect = UnityEngine.Rect;
17
18 [System.Serializable]
19 public struct Circle {
20
21 public Transform transform;
22 public Vector3 center;
23 private Direction3 direction;
24 public float radius;
25
26 private Matrix4x4? _overrideMatrix;
27 public Matrix4x4? overrideMatrix {
28 get { return _overrideMatrix; }
29 set { _overrideMatrix = value; }
30 }
31
32 #region Constructors
33
34 public Circle(LocalCircle localCircle, Transform withTransform)
35 : this(localCircle.center, localCircle.direction, localCircle.radius,
36 withTransform) { }
37
38 public Circle(float radius = 0.5f, Component transformSource = null)
39 : this(default(Vector3), default(Direction3), radius, transformSource) { }
40
41 public Circle(Vector3 center = default(Vector3),
42 Direction3 direction = default(Direction3), float radius = 0.5f,
43 Component transformSource = null)
44 {
45 this.transform = (transformSource == null ? null : transformSource.transform);
46 this.center = center;
47 this.direction = direction;
48 this.radius = radius;
49 this._overrideMatrix = null;
50 }
51
52 public Circle(Vector3 center = default(Vector3),
53 Direction3 direction = default(Direction3), float radius = 0.5f,
54 Transform transform = null) : this(center, direction, radius,
56
57 public Circle(Vector3 center = default(Vector3),
58 Direction3 direction = default(Direction3), float radius = 0.5f,
59 Matrix4x4? overrideMatrix = null) : this(center, direction, radius,
60 (Component)null)
61 {
62 this._overrideMatrix = overrideMatrix;
63 }
64
65 #endregion
66
67 #region Accessors
68
72 public Matrix4x4 matrix {
73 get {
74 if (overrideMatrix != null) {
75 return overrideMatrix.Value * Matrix4x4.Translate(center);
76 }
77 else if (transform == null) {
78 return Matrix4x4.Translate(center);
79 }
80 return transform.localToWorldMatrix * Matrix4x4.Translate(center);
81 }
82 }
83
89 public Vector3 position {
90 get {
91 return this.matrix.MultiplyPoint3x4(Vector3.zero);
92 }
93 }
94
95 #endregion
96
97 #region Debug Rendering
98
100 Matrix4x4 m = Matrix4x4.identity;
101 if (transform != null) {
102 m = transform.localToWorldMatrix;
103 }
104
105 drawer.PushMatrix();
106 drawer.matrix = m;
107
108 drawer.DrawWireArc(
109 center: center,
110 normal: direction,
111 radialStartDirection: direction.Vec().GetPerpendicular(),
112 radius: radius,
113 fractionOfCircleToDraw: 1f,
114 numCircleSegments: 44
115 );
116
117 drawer.PopMatrix();
118 }
119
120 public void Draw(Drawer drawer, Color? color = null) {
121 if (color != null) { drawer.color = color.Value; }
123 center: center,
124 normal: direction,
125 radialStartDirection: direction.Vec().GetPerpendicular(),
126 radius: radius,
127 fractionOfCircleToDraw: 1f,
128 numCircleSegments: 44,
129 matrix: transform == null ?
130 Matrix4x4.identity : transform.localToWorldMatrix,
131 lineDrawingFunc: drawer.Line
132 );
133 }
134
135 public void DrawLines(Action<Vector3, Vector3> lineDrawingFunc) {
137 center: center,
138 normal: direction,
139 radialStartDirection: direction.Vec().GetPerpendicular(),
140 radius: radius,
141 fractionOfCircleToDraw: 1f,
142 numCircleSegments: 44,
143 matrix: transform == null ?
144 Matrix4x4.identity : transform.localToWorldMatrix,
145 lineDrawingFunc: lineDrawingFunc
146 );
147 }
148
149 // Welp, RuntimeGizmos might need an overhaul to accept arbitrary drawing
150 // functions, because this is super useful.
151 public static void DrawWireArc(Vector3 center, Vector3 normal,
152 float radius, int numCircleSegments,
153 Action<Vector3, Vector3> lineDrawingFunc,
154 float fractionOfCircleToDraw = 1.0f,
155 Matrix4x4? matrix = null,
156 Vector3? radialStartDirection = null) {
157 if (!matrix.HasValue) {
158 matrix = Matrix4x4.identity;
159 }
160 if (!radialStartDirection.HasValue) {
161 radialStartDirection = normal.GetPerpendicular();
162 }
163
164 normal = normal.normalized;
165 Vector3 radiusVector = radialStartDirection.Value.normalized * radius;
166 Vector3 nextVector;
167 int numSegmentsToDraw = (int)(numCircleSegments * fractionOfCircleToDraw);
168 Quaternion rotator = Quaternion.AngleAxis(360f / numCircleSegments, normal);
169 for (int i = 0; i < numSegmentsToDraw; i++) {
170 nextVector = rotator * radiusVector;
171 lineDrawingFunc(
172 matrix.Value.MultiplyPoint3x4(center + radiusVector),
173 matrix.Value.MultiplyPoint3x4(center + nextVector)
174 );
175 radiusVector = nextVector;
176 }
177 }
178
179 #endregion
180
181 #region Enumerators
182
183 public CirclePointEnumerator Points(int numPoints) {
184 return new CirclePointEnumerator(this, numPoints);
185 }
186
187 public CircleSegmentEnumerator Segments(int numLines) {
188 return new CircleSegmentEnumerator(this, numLines);
189 }
190
191 public struct CirclePointEnumerator {
193 Vector3 startRadiusVector; Quaternion rotator;
194 Vector3? radiusVector;
196 this.circle = circle;
197 this.numPoints = Mathf.Max(3, numPoints);
198 this.idx = -1;
199 this.startRadiusVector = ((Vector3)circle.direction).GetPerpendicular()
200 * circle.radius;
201 this.rotator = Quaternion.AngleAxis(360f / numPoints, circle.direction);
202 this.radiusVector = null;
203 }
204 public Vector3 Current { get {
205 return circle.matrix.MultiplyPoint3x4(radiusVector.GetValueOrDefault());
206 }}
207 public bool MoveNext() {
208 if (idx == numPoints - 1) { return false; }
209 idx += 1;
211 else { radiusVector = rotator * radiusVector; }
212 return true;
213 }
214 public CirclePointEnumerator GetEnumerator() { return this; }
215 }
216
219 Vector3? firstPoint;
222 public CircleSegmentEnumerator(Circle circle, int numLines) {
223 numLines = Mathf.Max(1, numLines);
224 this.points = new CirclePointEnumerator(circle, numLines + 1);
225 firstPoint = null;
226 lastPointReturned = null;
227 reachedLastSegment = false;
228 }
229 public LocalSegment3 Current { get {
230 if (reachedLastSegment) {
231 return new LocalSegment3(lastPointReturned.Value, firstPoint.Value);
232 }
233 if (!lastPointReturned.HasValue) {
235 }
236 else {
238 }
239 }}
240 public bool MoveNext() {
241 if (!lastPointReturned.HasValue) {
242 if (!points.MoveNext()) { return false; }
243 else { firstPoint = points.Current; }
244 }
246
247 if (!points.MoveNext()) {
248 if (!reachedLastSegment) {
249 reachedLastSegment = true;
250 return true;
251 }
252 return false;
253 }
254 return true;
255 }
256 public CircleSegmentEnumerator GetEnumerator() { return this; }
257 }
258
259 #endregion
260
261 }
262
263 public static class CircleExtensions {
264
265 public static Vector3 GetPerpendicular(this Vector3 v) {
266 return Utils.Perpendicular(v);
267 }
268
269 }
270
271}
UnityEngine.Component Component
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 Line(Vector3 a, Vector3 b)
Definition: Drawer.cs:140
Color color
Calls the setColor delegate.
Definition: Drawer.cs:26
void DrawWireArc(Vector3 center, Vector3 normal, Vector3 radialStartDirection, float radius, float fractionOfCircleToDraw, int numCircleSegments=16)
void PushMatrix()
Saves the current gizmo matrix to the gizmo matrix stack.
void PopMatrix()
Restores the current gizmo matrix from the gizmo matrix stack.
Matrix4x4 matrix
Sets or gets the matrix used to transform all gizmos.
UnityEngine.Rect UnityRect
Definition: LeapGrid.cs:14
Circle(Vector3 center=default(Vector3), Direction3 direction=default(Direction3), float radius=0.5f, Matrix4x4? overrideMatrix=null)
Circle(LocalCircle localCircle, Transform withTransform)
void DrawLines(Action< Vector3, Vector3 > lineDrawingFunc)
Circle(float radius=0.5f, Component transformSource=null)
Vector3 position
The world position of the center of this Circle (read only). This is dependent on the state of its Tr...
Matrix4x4 matrix
Local-to-world matrix for this Circle.
Circle(Vector3 center=default(Vector3), Direction3 direction=default(Direction3), float radius=0.5f, Transform transform=null)
Circle(Vector3 center=default(Vector3), Direction3 direction=default(Direction3), float radius=0.5f, Component transformSource=null)
static void DrawWireArc(Vector3 center, Vector3 normal, float radius, int numCircleSegments, Action< Vector3, Vector3 > lineDrawingFunc, float fractionOfCircleToDraw=1.0f, Matrix4x4? matrix=null, Vector3? radialStartDirection=null)
A struct very similar to Vector3, but that prevents itself from ever being converted to Vector3....
Definition: Direction3.cs:24
Vector3 Vec()
Explicitly converts this Direction3 to a Vector3.
Definition: Direction3.cs:51