Unity Udexreal开发插件包
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

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();
}
}