6 using System.Collections.Generic;
10 namespace HoloToolkit.Examples.SpatialUnderstandingFeatureOverview
15 public const float DefaultLineWidth = 0.001f;
16 public const float DefaultBasisLength = 0.2f;
25 public Line(Vector3 _p0, Vector3 _p1, Color _c0, Color _c1,
float _lineWidth = DefaultLineWidth)
31 lineWidth = _lineWidth;
34 public bool Set_IfDifferent(Vector3 _p0, Vector3 _p1, Color _c0, Color _c1,
float _lineWidth)
37 if ((p0 != _p0) || (p1 != _p1) || (c0 != _c0) || (c1 != _c1) || (lineWidth != _lineWidth))
43 lineWidth = _lineWidth;
60 public List<Line> Lines =
new List<Line>();
66 public void AddKey(
float time, Vector3 pos)
68 CurveX.AddKey(time, pos.x);
69 CurveY.AddKey(time, pos.y);
70 CurveZ.AddKey(time, pos.z);
74 return new Vector3(CurveX.Evaluate(time), CurveY.Evaluate(time), CurveZ.Evaluate(time));
77 public AnimationCurve CurveX =
new AnimationCurve();
78 public AnimationCurve CurveY =
new AnimationCurve();
79 public AnimationCurve CurveZ =
new AnimationCurve();
83 public const float InitialPositionForwardMaxDistance = 2.0f;
84 public const float AnimationTime = 2.5f;
85 public const float DelayPerItem = 0.35f;
93 float lineWidth = DefaultLineWidth * 3.0f)
95 TimeDelay = timeDelay;
100 LineWidth = lineWidth;
103 if (TimeDelay <= 0.0f)
114 if (!IsAnimationSetup &&
120 return (Time >= TimeDelay);
123 private void SetupAnimation()
132 Vector3 rayVec =
CameraCache.
Main.transform.forward * InitialPositionForwardMaxDistance;
135 rayPos.x, rayPos.y, rayPos.z, rayVec.x, rayVec.y, rayVec.z,
139 rayPos + rayVec.normalized * Mathf.Max((rayCastResult.IntersectPoint - rayPos).magnitude - 0.3f, 0.0f) :
140 rayPos + rayVec * InitialPositionForwardMaxDistance;
145 AnimPosition.AddKey(TimeDelay + 0.0f,
new Vector3(animOrigin.x, alignment.FloorYValue, animOrigin.z));
146 AnimPosition.AddKey(TimeDelay + AnimationTime * 0.5f,
new Vector3(animOrigin.x, alignment.FloorYValue + 1.25f, animOrigin.z));
147 AnimPosition.AddKey(TimeDelay + AnimationTime * 0.6f,
new Vector3(animOrigin.x, alignment.FloorYValue + 1.0f, animOrigin.z));
148 AnimPosition.AddKey(TimeDelay + AnimationTime * 0.95f, Center);
149 AnimPosition.AddKey(TimeDelay + AnimationTime * 1.0f, Center);
151 AnimScale.AddKey(TimeDelay + 0.0f, 0.0f);
152 AnimScale.AddKey(TimeDelay + AnimationTime * 0.5f, 0.5f);
153 AnimScale.AddKey(TimeDelay + AnimationTime * 0.8f, 1.0f);
154 AnimScale.AddKey(TimeDelay + AnimationTime * 1.0f, 1.0f);
156 AnimRotation.AddKey(TimeDelay + 0.0f, -1.5f);
157 AnimRotation.AddKey(TimeDelay + AnimationTime * 0.2f, -0.5f);
158 AnimRotation.AddKey(TimeDelay + AnimationTime * 0.9f, 0.0f);
159 AnimRotation.AddKey(TimeDelay + AnimationTime * 1.0f, 0.0f);
161 IsAnimationSetup =
true;
174 public AnimationCurve AnimScale =
new AnimationCurve();
176 public AnimationCurve AnimRotation =
new AnimationCurve();
190 if (lineData != null)
196 if (lineData.
Filter != null)
204 protected const int PointsOnCircle = 50;
205 protected bool Draw_Circle(Vector3 center, Vector3 normal, Color color,
float radius = 0.25f,
float lineWidth = DefaultLineWidth)
207 bool returnValue =
false;
209 float radPerPoint = (2.0f * Mathf.PI) / (
float)PointsOnCircle;
210 Quaternion q = Quaternion.FromToRotation(Vector3.up, normal);
211 Vector3 start = q *
new Vector3(Mathf.Cos(theta) * radius, 0.0f, Mathf.Sin(theta) * radius) + center;
213 for (
int i = 1; i <= PointsOnCircle; i++)
215 theta = (i % PointsOnCircle) * radPerPoint;
217 Vector3 end = q *
new Vector3(Mathf.Cos(theta) * radius, 0.0f, Mathf.Sin(theta) * radius) + center;
218 returnValue |= Draw_Line(start, end, color, color, lineWidth);
226 protected bool Draw_Circle_Partial(Vector3 center, Vector3 normal, Color color,
float radius = 0.25f,
float lineWidth = DefaultLineWidth,
float circleAngleArc = 360.0f)
228 bool returnValue =
false;
230 float radPerPoint = (circleAngleArc * Mathf.Deg2Rad * 0.5f) / (
float)PointsOnCircle;
231 Quaternion q = Quaternion.FromToRotation(Vector3.up, normal);
232 Vector3 start0 = q *
new Vector3(Mathf.Cos(theta) * radius, 0.0f, Mathf.Sin(theta) * radius) + center;
233 Vector3 start1 = q *
new Vector3(Mathf.Cos(theta) * -radius, 0.0f, Mathf.Sin(theta) * -radius) + center;
235 int maxPointCount = (circleAngleArc < 360.0f) ? (PointsOnCircle - 1) : PointsOnCircle;
236 for (
int i = 1; i <= maxPointCount; i++)
238 theta = (i % PointsOnCircle) * radPerPoint;
240 Vector3 end0 = q *
new Vector3(Mathf.Cos(theta) * radius, 0.0f, Mathf.Sin(theta) * radius) + center;
241 Vector3 end1 = q *
new Vector3(Mathf.Cos(theta) * -radius, 0.0f, Mathf.Sin(theta) * -radius) + center;
242 returnValue |= Draw_Line(start0, end0, color, color, lineWidth);
243 returnValue |= Draw_Line(start1, end1, color, color, lineWidth);
252 protected bool Draw_Cube(Vector3 point, Color color,
float halfSize = DefaultLineWidth)
254 return Draw_Line(point - Vector3.right * halfSize, point + Vector3.right * halfSize, color, color, halfSize);
260 if (!box.
Update(Time.deltaTime))
279 protected bool Draw_Box(Vector3 center, Quaternion rotation, Color color, Vector3 halfSize,
float lineWidth = DefaultLineWidth)
281 bool needsUpdate =
false;
283 Vector3 basisX = rotation * Vector3.right;
284 Vector3 basisY = rotation * Vector3.up;
285 Vector3 basisZ = rotation * Vector3.forward;
288 center + basisX * halfSize.x + basisY * halfSize.y + basisZ * halfSize.z,
289 center + basisX * halfSize.x + basisY * halfSize.y - basisZ * halfSize.z,
290 center - basisX * halfSize.x + basisY * halfSize.y - basisZ * halfSize.z,
291 center - basisX * halfSize.x + basisY * halfSize.y + basisZ * halfSize.z,
293 center + basisX * halfSize.x - basisY * halfSize.y + basisZ * halfSize.z,
294 center + basisX * halfSize.x - basisY * halfSize.y - basisZ * halfSize.z,
295 center - basisX * halfSize.x - basisY * halfSize.y - basisZ * halfSize.z,
296 center - basisX * halfSize.x - basisY * halfSize.y + basisZ * halfSize.z
300 needsUpdate |= Draw_Line(pts[0], pts[1], color, color, lineWidth);
301 needsUpdate |= Draw_Line(pts[1], pts[2], color, color, lineWidth);
302 needsUpdate |= Draw_Line(pts[2], pts[3], color, color, lineWidth);
303 needsUpdate |= Draw_Line(pts[3], pts[0], color, color, lineWidth);
306 needsUpdate |= Draw_Line(pts[4], pts[5], color, color, lineWidth);
307 needsUpdate |= Draw_Line(pts[5], pts[6], color, color, lineWidth);
308 needsUpdate |= Draw_Line(pts[6], pts[7], color, color, lineWidth);
309 needsUpdate |= Draw_Line(pts[7], pts[4], color, color, lineWidth);
312 needsUpdate |= Draw_Line(pts[0], pts[4], color, color, lineWidth);
313 needsUpdate |= Draw_Line(pts[1], pts[5], color, color, lineWidth);
314 needsUpdate |= Draw_Line(pts[2], pts[6], color, color, lineWidth);
315 needsUpdate |= Draw_Line(pts[3], pts[7], color, color, lineWidth);
320 protected bool Draw_Line(Vector3 start, Vector3 end, Color colorStart, Color colorEnd,
float lineWidth = DefaultLineWidth)
329 bool needsUpdate = lineData.
Lines[lineData.
LineIndex].Set_IfDifferent(transform.InverseTransformPoint(start), transform.InverseTransformPoint(end), colorStart, colorEnd, lineWidth);
337 protected bool Draw_TransformBasis(Transform transformToDraw,
float basisLength = DefaultBasisLength,
float lineWidth = DefaultLineWidth * 2.0f)
340 bool needsUpdate =
false;
341 needsUpdate |= Draw_Line(transformToDraw.transform.position, transformToDraw.transform.position + transformToDraw.transform.right * basisLength, Color.red, Color.red, lineWidth);
342 needsUpdate |= Draw_Line(transformToDraw.transform.position, transformToDraw.transform.position + transformToDraw.transform.up * basisLength, Color.green, Color.green, lineWidth);
343 needsUpdate |= Draw_Line(transformToDraw.transform.position, transformToDraw.transform.position + transformToDraw.transform.forward * basisLength, Color.blue, Color.blue, lineWidth);
348 private void Lines_LineDataToMesh()
351 Vector3[] verts =
new Vector3[lineData.
Lines.Count * 8];
352 int[] tris =
new int[lineData.
Lines.Count * 12 * 3];
353 Color[] colors =
new Color[verts.Length];
356 for (
int i = 0; i < lineData.
Lines.Count; ++i)
361 int tri = i * 12 * 3;
364 Vector3 dirUnit = (lineData.
Lines[i].p1 - lineData.
Lines[i].p0).normalized;
365 Vector3 normX = Vector3.Cross((Mathf.Abs(dirUnit.y) >= 0.99f) ? Vector3.right : Vector3.up, dirUnit).normalized;
366 Vector3 normy = Vector3.Cross(normX, dirUnit);
369 verts[vert] = lineData.
Lines[i].p0 + normX * lineData.
Lines[i].lineWidth + normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c0; ++vert;
370 verts[vert] = lineData.
Lines[i].p0 - normX * lineData.
Lines[i].lineWidth + normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c0; ++vert;
371 verts[vert] = lineData.
Lines[i].p0 - normX * lineData.
Lines[i].lineWidth - normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c0; ++vert;
372 verts[vert] = lineData.
Lines[i].p0 + normX * lineData.
Lines[i].lineWidth - normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c0; ++vert;
374 verts[vert] = lineData.
Lines[i].p1 + normX * lineData.
Lines[i].lineWidth + normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c1; ++vert;
375 verts[vert] = lineData.
Lines[i].p1 - normX * lineData.
Lines[i].lineWidth + normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c1; ++vert;
376 verts[vert] = lineData.
Lines[i].p1 - normX * lineData.
Lines[i].lineWidth - normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c1; ++vert;
377 verts[vert] = lineData.
Lines[i].p1 + normX * lineData.
Lines[i].lineWidth - normy * lineData.
Lines[i].lineWidth; colors[vert] = lineData.
Lines[i].c1; ++vert;
380 tris[tri + 0] = (v0 + 0); tris[tri + 1] = (v0 + 5); tris[tri + 2] = (v0 + 4); tri += 3;
381 tris[tri + 0] = (v0 + 1); tris[tri + 1] = (v0 + 5); tris[tri + 2] = (v0 + 0); tri += 3;
383 tris[tri + 0] = (v0 + 1); tris[tri + 1] = (v0 + 6); tris[tri + 2] = (v0 + 5); tri += 3;
384 tris[tri + 0] = (v0 + 2); tris[tri + 1] = (v0 + 6); tris[tri + 2] = (v0 + 1); tri += 3;
386 tris[tri + 0] = (v0 + 2); tris[tri + 1] = (v0 + 7); tris[tri + 2] = (v0 + 6); tri += 3;
387 tris[tri + 0] = (v0 + 3); tris[tri + 1] = (v0 + 7); tris[tri + 2] = (v0 + 2); tri += 3;
389 tris[tri + 0] = (v0 + 3); tris[tri + 1] = (v0 + 7); tris[tri + 2] = (v0 + 4); tri += 3;
390 tris[tri + 0] = (v0 + 3); tris[tri + 1] = (v0 + 4); tris[tri + 2] = (v0 + 0); tri += 3;
392 tris[tri + 0] = (v0 + 0); tris[tri + 1] = (v0 + 3); tris[tri + 2] = (v0 + 2); tri += 3;
393 tris[tri + 0] = (v0 + 0); tris[tri + 1] = (v0 + 2); tris[tri + 2] = (v0 + 1); tri += 3;
395 tris[tri + 0] = (v0 + 5); tris[tri + 1] = (v0 + 6); tris[tri + 2] = (v0 + 7); tri += 3;
396 tris[tri + 0] = (v0 + 5); tris[tri + 1] = (v0 + 7); tris[tri + 2] = (v0 + 4); tri += 3;
400 if (lineData.
Filter == null)
402 lineData.
Filter = gameObject.AddComponent<MeshFilter>();
406 lineData.
Renderer = gameObject.AddComponent<MeshRenderer>();
407 lineData.
Renderer.material = MaterialLine;
412 if (lineData.
Filter.mesh != null)
414 mesh = lineData.
Filter.mesh;
420 mesh.name =
"LineDrawer.Lines_LineDataToMesh";
424 mesh.vertices = verts;
425 mesh.triangles = tris;
426 mesh.colors = colors;
427 mesh.RecalculateBounds();
428 mesh.RecalculateNormals();
430 lineData.
Filter.mesh = mesh;
433 lineData.
Renderer.enabled = (lineData.
Lines.Count == 0) ?
false :
true;
442 for (
int i = 0; i < lineData.
Lines.Count; ++i)
444 lineData.
Lines[i].isValid =
false;
450 if (lineData == null)
457 while (i < lineData.
Lines.Count)
459 if (!lineData.
Lines[i].isValid)
462 lineData.
Lines.RemoveAt(i);
471 Lines_LineDataToMesh();