You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.9 KiB
93 lines
2.9 KiB
using System.Collections.Generic; |
|
using UnityEngine; |
|
|
|
namespace UDE_HAND_INTERACTION |
|
{ |
|
public interface ISurface |
|
{ |
|
Transform Transform { get; } |
|
|
|
bool Raycast(in Ray ray, out SurfaceHit hit, float maxDistance = 0); |
|
|
|
bool ClosestSurfacePoint(in Vector3 point, out SurfaceHit hit, float maxDistance = 0); |
|
} |
|
|
|
public struct SurfaceHit |
|
{ |
|
public Vector3 Point { get; set; } |
|
|
|
public Vector3 Normal { get; set; } |
|
|
|
public float Distance { get; set; } |
|
} |
|
|
|
public interface ISurfacePatch : ISurface |
|
{ |
|
ISurface BackingSurface { get; } |
|
} |
|
public static class SurfaceUtils |
|
{ |
|
|
|
public static float ComputeDistanceAbove(ISurfacePatch surfacePatch, Vector3 point, float radius) |
|
{ |
|
surfacePatch.BackingSurface.ClosestSurfacePoint(point, out SurfaceHit hit); |
|
Vector3 surfaceToPoint = point - hit.Point; |
|
return Vector3.Dot(surfaceToPoint, hit.Normal) - radius; |
|
} |
|
|
|
public static float ComputeTangentDistance(ISurfacePatch surfacePatch, Vector3 point, float radius) |
|
{ |
|
surfacePatch.ClosestSurfacePoint(point, out SurfaceHit patchHit); |
|
surfacePatch.BackingSurface.ClosestSurfacePoint(point, out SurfaceHit backingHit); |
|
Vector3 proximityToPoint = point - patchHit.Point; |
|
Vector3 projOnNormal = Vector3.Dot(proximityToPoint, backingHit.Normal) * |
|
backingHit.Normal; |
|
Vector3 lateralVec = proximityToPoint - projOnNormal; |
|
return lateralVec.magnitude - radius; |
|
} |
|
|
|
public static float ComputeDepth(ISurfacePatch surfacePatch, Vector3 point, float radius) |
|
{ |
|
return Mathf.Max(0f, -ComputeDistanceAbove(surfacePatch, point, radius)); |
|
} |
|
|
|
public static float ComputeDistanceFrom(ISurfacePatch surfacePatch, Vector3 point, float radius) |
|
{ |
|
surfacePatch.ClosestSurfacePoint(point, out SurfaceHit hit); |
|
Vector3 surfaceToPoint = point - hit.Point; |
|
return surfaceToPoint.magnitude - radius; |
|
} |
|
|
|
public static bool Clip(this Bounds bounds, |
|
in Bounds clipper, out Bounds result) |
|
{ |
|
result = new Bounds(); |
|
Vector3 min = Vector3.Max(bounds.min, clipper.min); |
|
Vector3 max = Vector3.Min(bounds.max, clipper.max); |
|
|
|
if (min.x > max.x || |
|
min.y > max.y || |
|
min.z > max.z) |
|
{ |
|
return false; |
|
} |
|
|
|
result.SetMinMax(min, max); |
|
return true; |
|
} |
|
} |
|
public interface IBounds |
|
{ |
|
Bounds Bounds { get; } |
|
} |
|
|
|
public interface IBoundsClipper |
|
{ |
|
public bool GetLocalBounds(Transform localTo, out Bounds bounds); |
|
} |
|
public interface IClippedSurface<TClipper> : ISurfacePatch |
|
{ |
|
IEnumerable<TClipper> GetClippers(); |
|
} |
|
} |
|
|
|
|