fix(physics): enforce retail step-down support radius (#273)
This commit is contained in:
parent
4dd40ad8fe
commit
c24bc571cf
9 changed files with 2117 additions and 24 deletions
|
|
@ -284,28 +284,46 @@ public static class BSPQuery
|
|||
CollisionSphere sphere,
|
||||
Vector3 up,
|
||||
bool small)
|
||||
=> CheckWalkableSupport(
|
||||
poly.Plane,
|
||||
poly.Vertices,
|
||||
sphere.Center,
|
||||
small ? sphere.Radius * 0.5f : sphere.Radius,
|
||||
up);
|
||||
|
||||
/// <summary>
|
||||
/// Retail <c>CPolygon::check_walkable</c> against an already resolved
|
||||
/// polygon. The caller supplies the effective support radius; retail's
|
||||
/// <c>SPHEREPATH::check_walkables</c> halves its saved sphere before
|
||||
/// entering this routine.
|
||||
/// </summary>
|
||||
internal static bool CheckWalkableSupport(
|
||||
Plane plane,
|
||||
ReadOnlySpan<Vector3> vertices,
|
||||
Vector3 center,
|
||||
float supportRadius,
|
||||
Vector3 up)
|
||||
{
|
||||
float angleUp = Vector3.Dot(poly.Plane.Normal, up);
|
||||
float angleUp = Vector3.Dot(plane.Normal, up);
|
||||
if (angleUp < PhysicsGlobals.EPSILON) return false;
|
||||
|
||||
float angle = (Vector3.Dot(poly.Plane.Normal, sphere.Center) + poly.Plane.D) / angleUp;
|
||||
var center = sphere.Center - up * angle;
|
||||
float angle = (Vector3.Dot(plane.Normal, center) + plane.D) / angleUp;
|
||||
center -= up * angle;
|
||||
|
||||
float radsum = sphere.Radius * sphere.Radius;
|
||||
if (small) radsum *= 0.25f;
|
||||
float radsum = supportRadius * supportRadius;
|
||||
|
||||
int n = poly.Vertices.Length;
|
||||
int n = vertices.Length;
|
||||
int prevIdx = n - 1;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
var v = poly.Vertices[i];
|
||||
var lv = poly.Vertices[prevIdx];
|
||||
var v = vertices[i];
|
||||
var lv = vertices[prevIdx];
|
||||
prevIdx = i;
|
||||
|
||||
var edge = v - lv;
|
||||
var disp = center - lv;
|
||||
var cross = Vector3.Cross(poly.Plane.Normal, edge);
|
||||
var cross = Vector3.Cross(plane.Normal, edge);
|
||||
float diff = Vector3.Dot(disp, cross);
|
||||
|
||||
if (diff < 0f)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue