该项目的目的是同时测试和演示来自 Unity DOTS 技术堆栈的多个新包。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

115 行
4.0 KiB

using System.Runtime.CompilerServices;
using Unity.Properties;
using UnityEngine;
using static Unity.Mathematics.math;
namespace CollisionLib
{
using Unity.Mathematics;
using Primitives;
public static partial class coll
{
public static bool RayCast(sphere sphere, ray ray, float rayDist, float rayRadius)
{
var rayEnd = ray.origin + ray.direction * rayDist;
var closestPointOnRay = ClosestPointOnLineSegment(ray.origin, rayEnd, sphere.center);
var dist = distance(closestPointOnRay, sphere.center);
return dist < rayRadius + sphere.radius;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ProjectPointToLineSegment(float3 lineStart, float3 lineEnd, float3 point, out float t)
{
var v = lineStart - lineEnd;
t = dot(point - lineStart, v) / dot(v, v);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float3 closest(lineseg lineseg, float3 point)
{
return ClosestPointOnLineSegment(lineseg.start, lineseg.end, point);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float3 ClosestPointOnLineSegment(float3 lineStart, float3 lineEnd, float3 point)
{
var v = lineEnd - lineStart;
var t = dot(point - lineStart, v) / dot(v, v);
t = max(t, 0.0f);
t = min(t, 1.0f);
return lineStart + v * t;
}
public static float DistanceToSegment(float3 lineStart, float3 lineEnd, float3 point, out float3 closest)
{
closest = ClosestPointOnLineSegment(lineStart, lineEnd, point);
return distance(point, closest);
}
public static bool OverlapCapsuleAABB(capsule capsule, box AABB)
{
var closestOnCapsule = ClosestPointOnLineSegment(capsule.p1, capsule.p2, AABB.center);
float sqDist;
float3 closestInBox;
CalculateClosestPointInBox(closestOnCapsule, AABB, out closestInBox, out sqDist);
return math.sqrt(sqDist) < capsule.radius;
}
public static bool OverlapCapsuleBox(capsule capsule, box box)
{
// Transform capsule into box space
var rayCapsule = capsule;
var invBoxRot = math.inverse(box.rotation);
var invBoxPos = -math.mul(invBoxRot, box.center);
rayCapsule = primlib.transform(rayCapsule, invBoxPos, invBoxRot);
var primLocalSpace = box;
primLocalSpace.center = float3.zero;
primLocalSpace.rotation = Quaternion.identity;
var hit = coll.OverlapCapsuleAABB(rayCapsule, primLocalSpace);
return hit;
}
public static void CalculateClosestPointInBox(float3 point, box AABB, out float3 outPoint, out float outSqrDistance)
{
// compute coordinates of point in box coordinate system
float3 closest = point - AABB.center;
float3 halfSize = AABB.size * 0.5f;
// project test point onto box
float fSqrDistance = 0.0f;
float fDelta;
for (int i = 0; i < 3; i++)
{
if (closest[i] < -halfSize[i])
{
fDelta = closest[i] + halfSize[i];
fSqrDistance += fDelta * fDelta;
closest[i] = -halfSize[i];
}
else if (closest[i] > halfSize[i])
{
fDelta = closest[i] - halfSize[i];
fSqrDistance += fDelta * fDelta;
closest[i] = halfSize[i];
}
}
// Inside
if (fSqrDistance == 0.0F)
{
outPoint = point;
outSqrDistance = 0.0F;
}
// Outside
else
{
outPoint = closest + AABB.center;
outSqrDistance = fSqrDistance;
}
}
}
}