133 lines
3.9 KiB
C#
133 lines
3.9 KiB
C#
#if UNITY_EDITOR
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
namespace O3DWB
|
|
{
|
|
public struct Sphere
|
|
{
|
|
#region Private Variables
|
|
private float _radius;
|
|
private Vector3 _center;
|
|
#endregion
|
|
|
|
#region Constructors
|
|
public Sphere(Vector3 center)
|
|
{
|
|
_radius = 1.0f;
|
|
_center = center;
|
|
}
|
|
|
|
public Sphere(float radius)
|
|
{
|
|
_radius = radius;
|
|
_center = Vector3.zero;
|
|
}
|
|
|
|
public Sphere(Vector3 center, float radius)
|
|
{
|
|
_radius = radius;
|
|
_center = center;
|
|
}
|
|
|
|
public Sphere(Sphere source)
|
|
{
|
|
_radius = source._radius;
|
|
_center = source._center;
|
|
}
|
|
#endregion
|
|
|
|
#region Public Properties
|
|
public float Radius { get { return _radius; } set { _radius = value; } }
|
|
public Vector3 Center { get { return _center; } set { _center = value; } }
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
public bool Raycast(Ray ray)
|
|
{
|
|
float t;
|
|
return Raycast(ray, out t);
|
|
}
|
|
|
|
public bool Raycast(Ray ray, out float t)
|
|
{
|
|
t = 0.0f;
|
|
|
|
// Calculate the coefficients of the quadratic equation
|
|
Vector3 sphereCenterToRayOrigin = ray.origin - _center;
|
|
float a = Vector3.SqrMagnitude(ray.direction);
|
|
float b = 2.0f * Vector3.Dot(ray.direction, sphereCenterToRayOrigin);
|
|
float c = Vector3.SqrMagnitude(sphereCenterToRayOrigin) - _radius * _radius;
|
|
|
|
// If we have a solution to the equation, the ray most likely intersects the sphere.
|
|
float t1, t2;
|
|
if (Equation.SolveQuadratic(a, b, c, out t1, out t2))
|
|
{
|
|
// Make sure the ray doesn't intersect the sphere only from behind
|
|
if (t1 < 0.0f && t2 < 0.0f) return false;
|
|
|
|
// Make sure we are using the smallest positive t value
|
|
if (t1 < 0.0f)
|
|
{
|
|
float temp = t1;
|
|
t1 = t2;
|
|
t2 = temp;
|
|
}
|
|
t = t1;
|
|
|
|
return true;
|
|
}
|
|
|
|
// If we reach this point it means the ray does not intersect the sphere in any way
|
|
return false;
|
|
}
|
|
|
|
public float GetDistanceBetweenCenters(Sphere sphere)
|
|
{
|
|
return (_center - sphere.Center).magnitude;
|
|
}
|
|
|
|
public float GetDistanceBetweenCentersSq(Sphere sphere)
|
|
{
|
|
return (Center - sphere.Center).sqrMagnitude;
|
|
}
|
|
|
|
public bool FullyOverlaps(Sphere sphere)
|
|
{
|
|
return GetDistanceBetweenCenters(sphere) + sphere.Radius <= _radius;
|
|
}
|
|
|
|
public bool OverlapsFullyOrPartially(Sphere sphere)
|
|
{
|
|
float distanceBetweenCenters = GetDistanceBetweenCenters(sphere);
|
|
|
|
// Fully?
|
|
if (distanceBetweenCenters + sphere.Radius <= _radius) return true;
|
|
|
|
// Partially?
|
|
return distanceBetweenCenters - sphere.Radius <= _radius;
|
|
}
|
|
|
|
public bool OverlapsFullyOrPartially(OrientedBox orientedBox)
|
|
{
|
|
Vector3 closestPointToSphereCenter = orientedBox.GetClosestPointToPoint(_center);
|
|
return (closestPointToSphereCenter - _center).sqrMagnitude <= _radius * _radius;
|
|
}
|
|
|
|
public Sphere Encapsulate(Sphere sphere)
|
|
{
|
|
float distanceBetweenCenters = GetDistanceBetweenCenters(sphere);
|
|
|
|
float newDiameter = distanceBetweenCenters + _radius + sphere.Radius;
|
|
float newRadius = newDiameter * 0.5f;
|
|
|
|
Vector3 fromThisToOther = sphere.Center - Center;
|
|
fromThisToOther.Normalize();
|
|
Vector3 newCenter = Center - fromThisToOther * _radius + fromThisToOther * newRadius;
|
|
|
|
return new Sphere(newCenter, newRadius);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
#endif |