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.
94 lines
2.9 KiB
94 lines
2.9 KiB
|
1 month ago
|
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();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|