2 using System.Collections.Generic;
15 namespace droid.Runtime.Utilities.GameObjects.BoundingBoxes {
23 Transform _bb_transform = null;
27 protected Bounds _Bounds =
new Bounds();
35 Collider[] _children_colliders = null;
39 MeshFilter[] _children_meshes = null;
41 GameObject _empty_go = null;
45 Vector3[,] _lines = null;
47 List<Vector3[]> _lines_list =
new List<Vector3[]>();
49 Collider _local_collider;
51 MeshFilter _local_mesh;
64 Vector3[] _points = null;
71 public bool _use_bb_transform =
false;
73 [SerializeField]
bool _use_shared_mesh =
false;
93 bool cacheChildren =
true;
98 Color editorPreviewLineColor =
new Color(1f, 0.36f, 0.38f, 0.74f);
108 bool freezeAfterFirstCalculation =
true;
113 bool includeChildren =
false;
118 bool _only_active_children =
true;
123 bool includeSelf =
true;
128 bool OnAwakeSetup =
false;
133 bool RunInEditModeSetup =
false;
141 public Vector3[] BoundingBoxCoordinates {
158 public Bounds Bounds {
get {
return this._Bounds; } }
160 public Vector3 Max {
get {
return this._Bounds.max; } }
162 public Vector3 Min {
get {
return this._Bounds.min; } }
166 public string BoundingBoxCoordinatesAsString {
169 str_rep += $
"\"_top_front_left\":{this.BoundingBoxCoordinates[0]}, ";
170 str_rep += $
"\"_top_front_right\":{this.BoundingBoxCoordinates[1]}, ";
171 str_rep += $
"\"_top_back_left\":{this.BoundingBoxCoordinates[2]}, ";
172 str_rep += $
"\"_top_back_right\":{this.BoundingBoxCoordinates[3]}, ";
173 str_rep += $
"\"_bottom_front_left\":{this.BoundingBoxCoordinates[4]}, ";
174 str_rep += $
"\"_bottom_front_right\":{this.BoundingBoxCoordinates[5]}, ";
175 str_rep += $
"\"_bottom_back_left\":{this.BoundingBoxCoordinates[6]}, ";
176 str_rep += $
"\"_bottom_back_right\":{this.BoundingBoxCoordinates[7]}";
183 public string BoundingBoxCoordinatesWorldSpaceAsJson {
186 var transform1 = this.transform;
187 if (this._use_bb_transform) {
188 transform1 = this._bb_transform;
191 var rotation = transform1.rotation;
192 var position = transform1.position;
193 if (this.environment != null) {
195 $
"\"top_front_left\":{this.JsonifyVec3(this.environment.TransformPoint(rotation * this._point_tfl + position))}, ";
197 $
"\"bottom_back_right\":{this.JsonifyVec3(this.environment.TransformPoint(rotation * this._point_bbr + position))}";
207 public Vector3[,] Lines {
get {
return this._lines; } }
211 public Vector3[] Points {
get {
return this._points; } }
213 public Color EditorPreviewLineColor {
214 get {
return this.editorPreviewLineColor; }
215 set { this.editorPreviewLineColor = value; }
226 if (this.basedOn ==
BasedOn.Collider_) {
227 var a = this._local_collider as MeshCollider;
229 return a.sharedMesh.GetCameraMinMaxRect(this.transform, a_camera, this.bb_margin - margin);
233 if (this._local_mesh) {
234 if (this._use_shared_mesh || !Application.isPlaying) {
235 var a = this._local_mesh.sharedMesh.GetCameraMinMaxPoints(this.transform, a_camera);
236 if (this.includeChildren) {
237 foreach (var children_mesh
in this._children_meshes) {
238 a = children_mesh.sharedMesh.GetCameraMinMaxPoints(children_mesh.transform,
244 return BoundingBoxUtilities.GetMinMaxRect(a[0], a[1], this.bb_margin - margin);
247 var a = this._local_mesh.mesh.GetCameraMinMaxPoints(this.transform, a_camera);
248 if (this.includeChildren) {
249 foreach (var children_mesh
in this._children_meshes) {
250 a = children_mesh.mesh.GetCameraMinMaxPoints(children_mesh.transform, a_camera, a[0], a[1]);
253 return BoundingBoxUtilities.GetMinMaxRect(a[0], a[1], this.bb_margin - margin);
257 if (this._use_shared_mesh || !Application.isPlaying) {
258 if (this._children_meshes != null && this._children_meshes.Length > 0) {
259 var a = this._children_meshes[0].sharedMesh
260 .GetCameraMinMaxPoints(this._children_meshes[0].transform, a_camera);
261 if (this.includeChildren) {
262 for (var index = 1; index < this._children_meshes.Length; index++) {
263 var children_mesh = this._children_meshes[index];
264 a = children_mesh.sharedMesh.GetCameraMinMaxPoints(children_mesh.transform,
270 return BoundingBoxUtilities.GetMinMaxRect(a[0], a[1], this.bb_margin - margin);
274 if (this._children_meshes != null && this._children_meshes.Length > 0) {
275 var a = this._children_meshes[0].mesh
276 .GetCameraMinMaxPoints(this._children_meshes[0].transform, a_camera);
277 if (this.includeChildren) {
278 for (var index = 1; index < this._children_meshes.Length; index++) {
279 var children_mesh = this._children_meshes[index];
280 a = children_mesh.mesh.GetCameraMinMaxPoints(children_mesh.transform, a_camera, a[0], a[1]);
283 return BoundingBoxUtilities.GetMinMaxRect(a[0], a[1], this.bb_margin - margin);
296 string JsonifyVec3(Vector3 vec) {
return $
"[{vec.x},{vec.y},{vec.z}]"; }
308 if (!this.OnAwakeSetup) {
320 if (this.environment == null) {
321 this.environment = FindObjectOfType<ActorisedPrototypingEnvironment>();
324 if (!this._bb_transform) {
325 this._empty_go =
new GameObject {hideFlags = HideFlags.HideAndDontSave};
326 this._bb_transform = this._empty_go.transform;
329 if (this.OnAwakeSetup) {
337 if (!this.RunInEditModeSetup && !Application.isPlaying) {
341 if (!this._bb_transform) {
342 this._empty_go =
new GameObject {hideFlags = HideFlags.HideAndDontSave};
343 this._bb_transform = this._empty_go.transform;
346 if (this.includeSelf) {
347 this._local_collider = this.GetComponent<BoxCollider>();
348 this._local_mesh = this.GetComponent<MeshFilter>();
351 if (this.includeChildren) {
352 this._children_meshes = this.GetComponentsInChildren<MeshFilter>();
353 this._children_colliders = this.GetComponentsInChildren<Collider>();
356 this.CalculateBoundingBox();
362 if (this.freezeAfterFirstCalculation) {
366 if (this.includeChildren && !this.cacheChildren) {
367 if (this._children_meshes != this.GetComponentsInChildren<MeshFilter>()) {
371 if (this._children_colliders != this.GetComponentsInChildren<Collider>()) {
375 this.CalculateBoundingBox();
381 void FitCollidersAabb() {
382 var transform1 = this.transform;
383 this._bb_transform.rotation = transform1.rotation;
384 this._bb_transform.position = transform1.position;
386 var bounds =
new Bounds(this._bb_transform.position, Vector3.zero);
388 if (this.includeSelf && this._local_collider) {
389 this._bb_transform.position = this._local_collider.bounds.center;
390 bounds = this._local_collider.bounds;
393 if (this.includeChildren && this._children_colliders != null) {
394 foreach (var a_collider
in this._children_colliders) {
395 if (a_collider && a_collider != this._local_collider) {
396 if (this._only_active_children) {
397 if (a_collider.gameObject.activeInHierarchy
398 && a_collider.gameObject.activeSelf
399 && a_collider.enabled) {
400 if (bounds.size == Vector3.zero) {
401 this._bb_transform.rotation = a_collider.transform.rotation;
402 this._bb_transform.position = a_collider.bounds.center;
403 bounds = a_collider.bounds;
405 bounds.Encapsulate(a_collider.bounds);
409 if (bounds.size == Vector3.zero) {
410 this._bb_transform.rotation = a_collider.transform.rotation;
411 this._bb_transform.position = a_collider.bounds.center;
412 bounds = a_collider.bounds;
414 bounds.Encapsulate(a_collider.bounds);
421 this._Bounds = bounds;
422 this._Bounds_Offset = this._Bounds.center - this._bb_transform.position;
427 void FitRenderersAabb() {
428 var transform1 = this.transform;
429 var position = transform1.position;
430 this._bb_transform.position = position;
431 this._bb_transform.rotation = transform1.rotation;
433 var bounds =
new Bounds(position, Vector3.zero);
435 if (this.includeSelf && this._local_mesh) {
438 if (this._use_shared_mesh) {
439 a_mesh = this._local_mesh.sharedMesh;
441 a_mesh = this._local_mesh.mesh;
444 if (a_mesh.isReadable) {
445 var vc = a_mesh.vertexCount;
446 for (var i = 0; i < vc; i++) {
447 bounds.Encapsulate(this._local_mesh.transform.TransformPoint(a_mesh.vertices[i]));
450 Debug.LogWarning(
"Make sure mesh is marked as readable when imported!");
454 if (this.includeChildren && this._children_meshes != null) {
455 foreach (var t
in this._children_meshes) {
457 if (this._only_active_children) {
458 if (t.gameObject.activeInHierarchy && t.gameObject.activeSelf) {
459 if (bounds.size == Vector3.zero) {
460 var transform2 = t.transform;
461 position = transform2.position;
462 this._bb_transform.position = position;
463 this._bb_transform.rotation = transform2.rotation;
464 bounds =
new Bounds(position, Vector3.zero);
469 if (this._use_shared_mesh) {
470 a_mesh = t.sharedMesh;
476 if (a_mesh.isReadable) {
477 var vc = a_mesh.vertexCount;
478 for (var j = 0; j < vc; j++) {
479 bounds.Encapsulate(t.transform.TransformPoint(a_mesh.vertices[j]));
482 Debug.LogWarning(
"Make sure mesh is marked as readable when imported!");
487 if (bounds.size == Vector3.zero) {
488 bounds =
new Bounds(t.transform.position, Vector3.zero);
493 if (this._use_shared_mesh) {
494 a_mesh = t.sharedMesh;
500 var vc = a_mesh.vertexCount;
501 for (var j = 0; j < vc; j++) {
502 bounds.Encapsulate(t.transform.TransformPoint(a_mesh.vertices[j]));
510 this._Bounds = bounds;
511 this._Bounds_Offset = this._Bounds.center - position;
516 void CalculateBoundingBox() {
517 if (!this.RunInEditModeSetup && !Application.isPlaying ||
this._bb_transform == null) {
521 if (this.basedOn ==
BasedOn.Collider_) {
522 switch (this.BbAligning) {
524 this.FitCollidersAabb();
525 this.RecalculatePoints();
526 this.RecalculateLines();
529 this.FitCollidersOobb();
532 this.FitRenderersCabb();
534 default:
throw new ArgumentOutOfRangeException();
537 switch (this.BbAligning) {
539 this.FitRenderersAabb();
540 this.RecalculatePoints();
541 this.RecalculateLines();
544 this.FitRenderersOobb();
547 this.FitRenderersCabb();
550 default:
throw new ArgumentOutOfRangeException();
555 void FitRenderersCabb() {
556 throw new NotImplementedException();
637 void FitRenderersOobb() {
throw new NotImplementedException(); }
639 void FitCollidersOobb() {
throw new NotImplementedException(); }
643 void RecalculatePoints() {
644 this._point_tfr = this._Bounds_Offset
645 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Top_Front_Right);
646 this._point_tfl = this._Bounds_Offset
647 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Top_Front_Left);
648 this._point_tbl = this._Bounds_Offset
649 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Top_Back_Left);
650 this._point_tbr = this._Bounds_Offset
651 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Top_Back_Right);
652 this._point_bfr = this._Bounds_Offset
653 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Bottom_Front_Right);
654 this._point_bfl = this._Bounds_Offset
655 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Bottom_Front_Left);
656 this._point_bbl = this._Bounds_Offset
657 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Bottom_Back_Left);
658 this._point_bbr = this._Bounds_Offset
659 + Vector3.Scale(this._Bounds.extents, BoundingBoxUtilities._Bottom_Back_Right);
661 this._points =
new[] {
675 void RecalculateLines() {
676 var transform1 = this.transform;
677 if (this._bb_transform) {
678 transform1 = this._bb_transform;
681 var rot = Quaternion.identity;
682 var pos = Vector3.zero;
683 if (this._use_bb_transform) {
684 rot = transform1.rotation;
687 pos = transform1.position;
689 this._lines_list.Clear();
691 for (var i = 0; i < 4; i++) {
693 var line =
new[] {rot * this.Points[2 * i] + pos, rot * this.Points[2 * i + 1] + pos};
694 this._lines_list.Add(line);
697 line =
new[] {rot * this.Points[i] + pos, rot * this.Points[i + 4] + pos};
698 this._lines_list.Add(line);
701 line =
new[] {rot * this.Points[2 * i] + pos, rot * this.Points[2 * i + 3 - 4 * (i % 2)] + pos};
702 this._lines_list.Add(line);
705 this._lines =
new Vector3[BoundingBoxUtilities._Num_Lines, BoundingBoxUtilities._Num_Points_Per_Line];
706 for (var j = 0; j < BoundingBoxUtilities._Num_Lines; j++) {
707 this.Lines[j, 0] = this._lines_list[j][0];
708 this.Lines[j, 1] = this._lines_list[j][1];
728 if (EditorApplication.isPlaying) {
732 this.CalculateBoundingBox();
737 void OnDrawGizmos() {
739 Gizmos.color = this.editorPreviewLineColor;
741 if (this._use_bb_transform) {
742 if (this.Lines != null) {
743 for (var i = 0; i < this.Lines.GetLength(0); i++) {
744 Gizmos.DrawLine(this.Lines[i, 0], this.Lines[i, 1]);
747 Gizmos.DrawWireCube(this.Bounds.center,
this.Bounds.size);
750 if (this._bb_transform) {
751 Handles.Label(this._bb_transform.position,
this._bb_transform.gameObject.name);
753 Handles.Label(this.transform.position,
this.gameObject.name);
Rect ScreenSpaceBoundingRect(Camera a_camera, float margin=0f)