Neodroid  0.2.0
Machine Learning Environment Prototyping Tool
BoundingBoxUtilities.cs
Go to the documentation of this file.
1 using UnityEngine;
2 
3 namespace droid.Runtime.Utilities.GameObjects.BoundingBoxes.Experimental.Unused {
4  public static class BoundingBoxUtilities {
11  public static void DrawBoxFromCenter(Vector3 p, float r, Color c) {
12  // p is pos.yition of the center, r is "radius" and c is the color of the box
13  //Bottom lines
14  Debug.DrawLine(new Vector3(-r + p.x, -r + p.y, -r + p.z), new Vector3(r + p.x, -r + p.y, -r + p.z), c);
15  Debug.DrawLine(new Vector3(-r + p.x, -r + p.y, -r + p.z), new Vector3(-r + p.x, -r + p.y, r + p.z), c);
16  Debug.DrawLine(new Vector3(r + p.x, -r + p.y, r + p.z), new Vector3(-r + p.x, -r + p.y, r + p.z), c);
17  Debug.DrawLine(new Vector3(r + p.x, -r + p.y, r + p.z), new Vector3(r + p.x, -r + p.y, -r + p.z), c);
18 
19  //Vertical lines
20  Debug.DrawLine(new Vector3(-r + p.x, r + p.y, -r + p.z), new Vector3(r + p.x, r + p.y, -r + p.z), c);
21  Debug.DrawLine(new Vector3(-r + p.x, r + p.y, -r + p.z), new Vector3(-r + p.x, r + p.y, r + p.z), c);
22  Debug.DrawLine(new Vector3(r + p.x, r + p.y, r + p.z), new Vector3(-r + p.x, r + p.y, r + p.z), c);
23  Debug.DrawLine(new Vector3(r + p.x, r + p.y, r + p.z), new Vector3(r + p.x, r + p.y, -r + p.z), c);
24 
25  //Top lines
26  Debug.DrawLine(new Vector3(-r + p.x, -r + p.y, -r + p.z), new Vector3(-r + p.x, r + p.y, -r + p.z), c);
27  Debug.DrawLine(new Vector3(-r + p.x, -r + p.y, r + p.z), new Vector3(-r + p.x, r + p.y, r + p.z), c);
28  Debug.DrawLine(new Vector3(r + p.x, -r + p.y, -r + p.z), new Vector3(r + p.x, r + p.y, -r + p.z), c);
29  Debug.DrawLine(new Vector3(r + p.x, -r + p.y, r + p.z), new Vector3(r + p.x, r + p.y, r + p.z), c);
30  }
31 
40  public static void DrawRect(float x_size, float y_size, float z_size, Vector3 pos, Color color) {
41  var x = x_size / 2;
42  var y = y_size / 2;
43  var z = z_size / 2;
44 
45  //Vertical lines
46  Debug.DrawLine(new Vector3(-x + pos.x, -y + pos.y, -z + pos.z),
47  new Vector3(-x + pos.x, y + pos.y, -z + pos.z),
48  color);
49  Debug.DrawLine(new Vector3(x + pos.x, -y + pos.y, -z + pos.z),
50  new Vector3(x + pos.x, y + pos.y, -z + pos.z),
51  color);
52  Debug.DrawLine(new Vector3(-x + pos.x, -y + pos.y, z + pos.z),
53  new Vector3(-x + pos.x, y + pos.y, z + pos.z),
54  color);
55  Debug.DrawLine(new Vector3(x + pos.x, -y + pos.y, z + pos.z),
56  new Vector3(x + pos.x, y + pos.y, z + pos.z),
57  color);
58 
59  //Horizontal top
60  Debug.DrawLine(new Vector3(-x + pos.x, y + pos.y, -z + pos.z),
61  new Vector3(x + pos.x, y + pos.y, -z + pos.z),
62  color);
63  Debug.DrawLine(new Vector3(-x + pos.x, y + pos.y, z + pos.z),
64  new Vector3(x + pos.x, y + pos.y, z + pos.z),
65  color);
66  Debug.DrawLine(new Vector3(-x + pos.x, y + pos.y, -z + pos.z),
67  new Vector3(-x + pos.x, y + pos.y, z + pos.z),
68  color);
69  Debug.DrawLine(new Vector3(x + pos.x, y + pos.y, -z + pos.z),
70  new Vector3(x + pos.x, y + pos.y, z + pos.z),
71  color);
72 
73  //Horizontal bottom
74  Debug.DrawLine(new Vector3(-x + pos.x, -y + pos.y, -z + pos.z),
75  new Vector3(x + pos.x, -y + pos.y, -z + pos.z),
76  color);
77  Debug.DrawLine(new Vector3(-x + pos.x, -y + pos.y, z + pos.z),
78  new Vector3(x + pos.x, -y + pos.y, z + pos.z),
79  color);
80  Debug.DrawLine(new Vector3(-x + pos.x, -y + pos.y, -z + pos.z),
81  new Vector3(-x + pos.x, -y + pos.y, z + pos.z),
82  color);
83  Debug.DrawLine(new Vector3(x + pos.x, -y + pos.y, -z + pos.z),
84  new Vector3(x + pos.x, -y + pos.y, z + pos.z),
85  color);
86  }
87 
94  public static bool DidTransformsChange(
95  Transform[] old_transforms,
96  Transform[] newly_acquired_transforms) {
97  if (old_transforms.Length != newly_acquired_transforms.Length) {
98  return true;
99  }
100 
101  var i = 0;
102  foreach (var old in old_transforms) {
103  if (old.position != newly_acquired_transforms[i].position
104  || old.rotation != newly_acquired_transforms[i].rotation) {
105  return true;
106  }
107 
108  i++;
109  }
110 
111  return false;
112  }
113 
119  public static Bounds GetTotalMeshFilterBounds(Transform object_transform) {
120  var mesh_filter = object_transform.GetComponent<MeshFilter>();
121 
122  var result = mesh_filter != null ? mesh_filter.mesh.bounds : new Bounds();
123 
124  foreach (Transform transform in object_transform) {
125  var bounds = GetTotalMeshFilterBounds(transform);
126  result.Encapsulate(bounds.min);
127  result.Encapsulate(bounds.max);
128  }
129 
130  /*var bounds1 = GetTotalColliderBounds(objectTransform);
131  result.Encapsulate(bounds1.min);
132  result.Encapsulate(bounds1.max);
133  */
134  /*
135  foreach (Transform transform in objectTransform) {
136  var bounds = GetTotalColliderBounds(transform);
137  result.Encapsulate(bounds.min);
138  result.Encapsulate(bounds.max);
139  }
140  */
141  var scaled_min = result.min;
142  var local_scale = object_transform.localScale;
143  scaled_min.Scale(local_scale);
144  result.min = scaled_min;
145  var scaled_max = result.max;
146  scaled_max.Scale(local_scale);
147  result.max = scaled_max;
148  return result;
149  }
150 
155  public static Bounds GetTotalColliderBounds(Transform object_transform) {
156  var mesh_filter = object_transform.GetComponent<Collider>();
157 
158  var result = mesh_filter != null ? mesh_filter.bounds : new Bounds();
159 
160  foreach (Transform transform in object_transform) {
161  var bounds = GetTotalColliderBounds(transform);
162  result.Encapsulate(bounds.min);
163  result.Encapsulate(bounds.max);
164  }
165 
166  var scaled_min = result.min;
167  var local_scale = object_transform.localScale;
168  scaled_min.Scale(local_scale);
169  result.min = scaled_min;
170  var scaled_max = result.max;
171  scaled_max.Scale(local_scale);
172  result.max = scaled_max;
173  return result;
174  }
175 
180  public static Bounds GetMaxBounds(GameObject g) {
181  var b = new Bounds(g.transform.position, Vector3.zero);
182  foreach (var r in g.GetComponentsInChildren<Renderer>()) {
183  b.Encapsulate(r.bounds);
184  }
185 
186  return b;
187  }
188 
196  public static Rect GetBoundsScreenRectEncapsulationSlow(this Bounds bounds,
197  Camera cam,
198  float margin = 0) {
199  var rect = new Rect();
200 
201  var points = new Vector3[8];
202  var screen_pos = new Vector3[8];
203 
204  var b = bounds; // reference object ex Simple
205  points[0] = new Vector3(b.min.x, b.min.y, b.min.z);
206  points[1] = new Vector3(b.max.x, b.min.y, b.min.z);
207  points[2] = new Vector3(b.max.x, b.max.y, b.min.z);
208  points[3] = new Vector3(b.min.x, b.max.y, b.min.z);
209  points[4] = new Vector3(b.min.x, b.min.y, b.max.z);
210  points[5] = new Vector3(b.max.x, b.min.y, b.max.z);
211  points[6] = new Vector3(b.max.x, b.max.y, b.max.z);
212  points[7] = new Vector3(b.min.x, b.max.y, b.max.z);
213 
214  var screen_bounds = new Bounds();
215  for (var i = 0; i < 8; i++) {
216  screen_pos[i] = cam.WorldToScreenPoint(points[i]);
217 
218  if (i == 0) {
219  screen_bounds = new Bounds(screen_pos[0], Vector3.zero);
220  }
221 
222  screen_bounds.Encapsulate(screen_pos[i]);
223  }
224 
225  //Debug.Log(screen_bounds.ToString());
226 
227  rect.xMin = screen_bounds.min.x;
228  rect.yMin = screen_bounds.min.y;
229  rect.xMax = screen_bounds.max.x;
230  rect.yMax = screen_bounds.max.y;
231 
232  return rect;
233  }
234 
235  /*
243  public static Rect GetBoundingBoxScreenRect(this BoundingBox bb, Camera cam, Single margin = 0) {
244  var min = Vector2.zero;
245 
246  if (bb != null && bb.Points?.Length > 0) {
247  if (bb._use_bb_transform && bb._bb_transform) {
248  min = cam.WorldToScreenPoint(bb._bb_transform.TransformPoint(bb.Points[0]));
249  } else {
250  min = cam.WorldToScreenPoint(bb.Points[0]);
251  }
252  }
253 
254  var max = min;
255 
256  var point = min;
257  GetMinMax(point, ref min, ref max);
258 
259  if (bb != null) {
260  for (var i = 1; i < bb.Points?.Length; i++) {
261  if (bb._use_bb_transform && bb._bb_transform) {
262  point = cam.WorldToScreenPoint(bb._bb_transform.TransformPoint(bb.Points[i]));
263  } else {
264  point = cam.WorldToScreenPoint(bb.Points[i]);
265  }
266 
267  GetMinMax(point, ref min, ref max);
268  }
269  }
270 
271  var r = Rect.MinMaxRect(min.x, min.y, max.x, max.y);
272  r.xMin -= margin;
273  r.xMax += margin;
274  r.yMin -= margin;
275  r.yMax += margin;
276 
277  return r;
278  }
279  */
280 
288  public static void CalculateLimits(Camera a_cam,
289  Bounds a_area,
290  out Rect a_limits,
291  out float a_max_height) {
292  // Half the FOV angle in radians
293  var angle = a_cam.fieldOfView * Mathf.Deg2Rad * 0.5f;
294 
295  // half the size of the viewing frustum at a distance of "1" from the camera
296  var tan = Vector2.one * Mathf.Tan(angle);
297  tan.x *= a_cam.aspect;
298 
299  // the center point of the area and it's extents
300  // the center point is taken from the bottom center of the bounding box
301  var dim = a_area.extents;
302  var center = a_area.center - new Vector3(0, a_area.extents.y, 0);
303 
304  // the maximum distance the camera can be above the area plane for each direction
305  var max_dist = new Vector2(dim.x / tan.x, dim.z / tan.y);
306 
307  // actual distance of the camera above our plane
308  var dist = a_cam.transform.position.y - center.y;
309 
310  // the max movement range around the center of the plane
311  dim.x *= 1f - dist / max_dist.x;
312  dim.z *= 1f - dist / max_dist.y;
313 
314  // maximum world space y coordinate the camera can be moved to
315  a_max_height = center.y + Mathf.Min(max_dist.x, max_dist.y);
316 
317  // the min and max x and z coordinates the camera can be at the current distance.
318  a_limits = new Rect(center.x - dim.x, center.z - dim.z, dim.x * 2, dim.z * 2);
319  }
320 
321  public static bool CullToFrustum(Mesh mesh, Camera cam, Transform trans, bool update_position) {
322  var fov = cam.fieldOfView;
323  cam.fieldOfView = fov * 0.97f;
324  var planes = GeometryUtility.CalculateFrustumPlanes(cam);
325  cam.fieldOfView = fov;
326  if (GeometryUtility.TestPlanesAABB(planes, mesh.bounds)) {
327  return true;
328  }
329 
330  Debug.Log("Culling :" + trans.name);
331  return false;
332  }
333 
342  public static Rect GetMinMaxRect(this Bounds bounds, Transform t, Camera cam, float margin = 0) {
343  var cen = bounds.center;
344  var ext = bounds.extents;
345 
346  var x_min = cen.x - ext.x;
347  var y_min = cen.y - ext.y;
348  var z_min = cen.z - ext.z;
349  var x_max = cen.x + ext.x;
350  var y_max = cen.y + ext.y;
351  var z_max = cen.z + ext.z;
352 
353  Vector2 min = cam.WorldToScreenPoint(new Vector3(x_min, y_min, z_min));
354  var max = min;
355 
356  var point = min;
357  point.GetMinMax(ref min, ref max);
358 
359  point = cam.WorldToScreenPoint(new Vector3(x_max, y_max, z_max));
360  point.GetMinMax(ref min, ref max);
361 
362  point = cam.WorldToScreenPoint(new Vector3(x_max, y_min, z_min));
363  point.GetMinMax(ref min, ref max);
364 
365  point = cam.WorldToScreenPoint(new Vector3(x_min, y_max, z_min));
366  point.GetMinMax(ref min, ref max);
367 
368  point = cam.WorldToScreenPoint(new Vector3(x_min, y_min, z_max));
369  point.GetMinMax(ref min, ref max);
370 
371  point = cam.WorldToScreenPoint(new Vector3(x_max, y_min, z_max));
372  point.GetMinMax(ref min, ref max);
373 
374  point = cam.WorldToScreenPoint(new Vector3(x_max, y_max, z_min));
375  point.GetMinMax(ref min, ref max);
376 
377  point = cam.WorldToScreenPoint(new Vector3(x_min, y_max, z_max));
378  point.GetMinMax(ref min, ref max);
379 
380  var r = Rect.MinMaxRect(min.x, min.y, max.x, max.y);
381  r.xMin -= margin;
382  r.xMax += margin;
383  r.yMin -= margin;
384  r.yMax += margin;
385 
386  return r;
387  }
388 
394  public static float MaxDim(this Vector3 vec) { return Mathf.Max(vec.x, vec.y, vec.z); }
395 
401  public static float MinDim(this Vector3 vec) { return Mathf.Min(vec.x, vec.y, vec.z); }
402 
410  public static Vector3[] GetMinMaxPoints(this MeshCollider mesh, Transform t, Camera cam) {
411  return mesh.sharedMesh.GetCameraMinMaxPoints(t, cam);
412  }
413  }
414 }