/// <summary> /// Attempts to calculate geometry for a collider. Not tested yet. /// </summary> /// <param name="c"></param> /// <returns></returns> public static IGeom GetGeom(this Collider c, BoundingSphereAlgorithm algorithm, bool local = false) { if(c == null) return null; if (c is CharacterController) { return Capsule.FromCollider(c as CharacterController, local); } if (c is CapsuleCollider) { return Capsule.FromCollider(c as CapsuleCollider, local); } else if (c is BoxCollider) { return AABBox.FromCollider(c as BoxCollider, local); } else if (c is SphereCollider) { return Sphere.FromCollider(c as SphereCollider, local); } else if (algorithm != BoundingSphereAlgorithm.FromBounds && c is MeshCollider) { if(local) { return Sphere.FromMesh((c as MeshCollider).sharedMesh, algorithm); } else { return Sphere.FromMesh((c as MeshCollider).sharedMesh, algorithm, Trans.GetGlobal(c.transform)); } } else { //otherwise just return bounds as AABBox return AABBox.FromCollider(c, local); } }
public static Sphere GetLocalBoundingSphere(this Renderer rend, BoundingSphereAlgorithm algorithm) { if (algorithm != BoundingSphereAlgorithm.FromBounds && rend is SkinnedMeshRenderer) { return Sphere.FromMesh((rend as SkinnedMeshRenderer).sharedMesh, algorithm); } else if (algorithm != BoundingSphereAlgorithm.FromBounds && rend is MeshRenderer && rend.HasComponent<MeshFilter>()) { return Sphere.FromMesh((rend as MeshRenderer).GetComponent<MeshFilter>().sharedMesh, algorithm); } else { var bounds = rend.bounds; var c = rend.transform.InverseTransformPoint(bounds.center); var v = rend.transform.InverseTransformDirection(bounds.extents); return new Sphere(c, v.magnitude); } }
public static Sphere GetLocalBoundingSphere(this Collider c, BoundingSphereAlgorithm algorithm) { return Sphere.FromCollider(c, algorithm, true); }
public static Sphere GetGlobalBoundingSphere(this Collider c, BoundingSphereAlgorithm algorithm) { return Sphere.FromCollider(c, algorithm, false); }
public static Sphere GetGlobalBoundingSphere(this GameObject go, BoundingSphereAlgorithm algorithm, bool bRecurseChildren = true) { var s = new Sphere(go.transform.position, 0.0f); if (go.renderer != null) s.Encapsulate(go.renderer.GetGlobalBoundingSphere(algorithm)); if (go.collider != null) s.Encapsulate(go.collider.GetGlobalBoundingSphere(algorithm)); if (bRecurseChildren) { foreach (Transform child in go.transform) { s.Encapsulate(GetGlobalBoundingSphere(child.gameObject, algorithm, bRecurseChildren)); } } return s; }
public static Capsule FromCollider(Collider c, BoundingSphereAlgorithm algorithm, bool local = false) { if (c is SphereCollider) { return FromCollider(c as SphereCollider, local); } else if (c is CapsuleCollider) { return FromCollider(c as CapsuleCollider, local); } else { var s = Sphere.FromCollider(c, algorithm, local); return new Capsule(s.Center, s.Center, s.Radius); } }
public static Sphere GetGlobalBoundingSphere(this Renderer rend, BoundingSphereAlgorithm algorithm) { if (algorithm != BoundingSphereAlgorithm.FromBounds && rend is SkinnedMeshRenderer) { return Sphere.FromMesh((rend as SkinnedMeshRenderer).sharedMesh, algorithm, Trans.GetGlobal(rend.transform)); } else if (algorithm != BoundingSphereAlgorithm.FromBounds && rend is MeshRenderer && rend.HasComponent<MeshFilter>()) { return Sphere.FromMesh((rend as MeshRenderer).GetComponent<MeshFilter>().sharedMesh, algorithm, Trans.GetGlobal(rend.transform)); } else { var bounds = rend.bounds; return new Sphere(bounds.center, bounds.extents.magnitude); } }
public static Sphere FromPoints(IEnumerable<Vector3> points, BoundingSphereAlgorithm algorithm) { return FromPoints(points.ToArray(), algorithm); }
public static Sphere FromPoints(Vector3[] points, BoundingSphereAlgorithm algorithm) { switch (algorithm) { case BoundingSphereAlgorithm.FromBounds: { var bounds = AABBox.FromPoints(points); return new Sphere(bounds.Center, bounds.Extents.magnitude); } case BoundingSphereAlgorithm.Average: { Vector3 sum = Vector3.zero; foreach(var v in points) { sum += v; } sum /= points.Length; float dist = 0f; float d; foreach(var v in points) { d = (v - sum).sqrMagnitude; if (d > dist) dist = d; } dist = Mathf.Sqrt(dist); return new Sphere(sum, dist); } case BoundingSphereAlgorithm.Ritter: { Vector3 xmin, xmax, ymin, ymax, zmin, zmax; xmin = ymin = zmin = Vector3.one * float.PositiveInfinity; xmax = ymax = zmax = Vector3.one * float.NegativeInfinity; foreach (var p in points) { if (p.x < xmin.x) xmin = p; if (p.x > xmax.x) xmax = p; if (p.y < ymin.y) ymin = p; if (p.y > ymax.y) ymax = p; if (p.z < zmin.z) zmin = p; if (p.z > zmax.z) zmax = p; } var xSpan = (xmax - xmin).sqrMagnitude; var ySpan = (ymax - ymin).sqrMagnitude; var zSpan = (zmax - zmin).sqrMagnitude; var dia1 = xmin; var dia2 = xmax; var maxSpan = xSpan; if (ySpan > maxSpan) { maxSpan = ySpan; dia1 = ymin; dia2 = ymax; } if (zSpan > maxSpan) { dia1 = zmin; dia2 = zmax; } var center = (dia1 + dia2) * 0.5f; var sqRad = (dia2 - center).sqrMagnitude; var radius = Mathf.Sqrt(sqRad); foreach (var p in points) { float d = (p - center).sqrMagnitude; if (d > sqRad) { var r = Mathf.Sqrt(d); radius = (radius + r) * 0.5f; sqRad = radius * radius; var offset = r - radius; center = (radius * center + offset * p) / r; } } return new Sphere(center, radius); } } return new Sphere(); }
public static Sphere FromMesh(Mesh mesh, BoundingSphereAlgorithm algorithm) { if (mesh == null) return new Sphere(); if (algorithm != BoundingSphereAlgorithm.FromBounds) { var arr = mesh.vertices; if (arr.Length > 0) { return FromPoints(arr, algorithm); } else { return new Sphere(); } } else { var bounds = mesh.bounds; return new Sphere(bounds.center, bounds.extents.magnitude); } }
public static Sphere FromMesh(Mesh mesh, BoundingSphereAlgorithm algorithm, Trans transform) { if (mesh == null) return new Sphere(); var arr = mesh.vertices; if (arr.Length > 0) { for (int i = 0; i < arr.Length; i++) { arr[i] = transform.TransformPoint(arr[i]); } return FromPoints(arr, algorithm); } else { return new Sphere(); } }
public static Sphere FromCollider(Collider c, BoundingSphereAlgorithm algorithm, bool local = false) { if (c is SphereCollider) { return FromCollider(c as SphereCollider, local); } else if (c is CapsuleCollider) { return FromCollider(c as CapsuleCollider, local); } else if (algorithm != BoundingSphereAlgorithm.FromBounds && c is MeshCollider) { return FromMesh((c as MeshCollider).sharedMesh, algorithm, Trans.GetGlobal(c.transform)); } else { var bounds = AABBox.FromCollider(c, local); return new Sphere(bounds.Center, bounds.Extents.magnitude); } }
public static Sphere GetLocalBoundingSphere(this Collider c, BoundingSphereAlgorithm algorithm) { return(Sphere.FromCollider(c, algorithm, true)); }
public static Sphere GetGlobalBoundingSphere(this Collider c, BoundingSphereAlgorithm algorithm) { return(Sphere.FromCollider(c, algorithm, false)); }
public static Sphere FromPoints(Vector3[] points, BoundingSphereAlgorithm algorithm) { switch (algorithm) { case BoundingSphereAlgorithm.FromBounds: { var bounds = AABBox.FromPoints(points); return(new Sphere(bounds.Center, bounds.Extents.magnitude)); } case BoundingSphereAlgorithm.Average: { Vector3 sum = Vector3.zero; foreach (var v in points) { sum += v; } sum /= points.Length; float dist = 0f; float d; foreach (var v in points) { d = (v - sum).sqrMagnitude; if (d > dist) { dist = d; } } dist = Mathf.Sqrt(dist); return(new Sphere(sum, dist)); } case BoundingSphereAlgorithm.Ritter: { Vector3 xmin, xmax, ymin, ymax, zmin, zmax; xmin = ymin = zmin = Vector3.one * float.PositiveInfinity; xmax = ymax = zmax = Vector3.one * float.NegativeInfinity; foreach (var p in points) { if (p.x < xmin.x) { xmin = p; } if (p.x > xmax.x) { xmax = p; } if (p.y < ymin.y) { ymin = p; } if (p.y > ymax.y) { ymax = p; } if (p.z < zmin.z) { zmin = p; } if (p.z > zmax.z) { zmax = p; } } var xSpan = (xmax - xmin).sqrMagnitude; var ySpan = (ymax - ymin).sqrMagnitude; var zSpan = (zmax - zmin).sqrMagnitude; var dia1 = xmin; var dia2 = xmax; var maxSpan = xSpan; if (ySpan > maxSpan) { maxSpan = ySpan; dia1 = ymin; dia2 = ymax; } if (zSpan > maxSpan) { dia1 = zmin; dia2 = zmax; } var center = (dia1 + dia2) * 0.5f; var sqRad = (dia2 - center).sqrMagnitude; var radius = Mathf.Sqrt(sqRad); foreach (var p in points) { float d = (p - center).sqrMagnitude; if (d > sqRad) { var r = Mathf.Sqrt(d); radius = (radius + r) * 0.5f; sqRad = radius * radius; var offset = r - radius; center = (radius * center + offset * p) / r; } } return(new Sphere(center, radius)); } } return(new Sphere()); }
public static Sphere FromPoints(IEnumerable <Vector3> points, BoundingSphereAlgorithm algorithm) { return(FromPoints(points.ToArray(), algorithm)); }