BITFALL/Assets/GSpawn - Level Designer/Scripts/Math/Triangle.cs

155 lines
5.0 KiB
C#
Raw Normal View History

2024-01-27 04:09:57 +08:00
#if UNITY_EDITOR
using UnityEngine;
namespace GSpawn
{
public static class Triangle3D
{
public static bool raycast(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2)
{
t = 0.0f;
float rayEnter;
Plane trianglePlane = new Plane(p0, p1, p2);
if (trianglePlane.Raycast(ray, out rayEnter) &&
containsPoint(ray.GetPoint(rayEnter), false, p0, p1, p2))
{
t = rayEnter;
return true;
}
return false;
}
public static bool raycast(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 normal)
{
t = 0.0f;
float rayEnter;
Plane trianglePlane = new Plane(normal, p0);
if (trianglePlane.Raycast(ray, out rayEnter) &&
containsPoint(ray.GetPoint(rayEnter), false, p0, p1, p2, normal))
{
t = rayEnter;
return true;
}
return false;
}
public static bool raycast(Ray ray, out float t, Vector3[] pts, Vector3 normal)
{
t = 0.0f;
float rayEnter;
Plane trianglePlane = new Plane(normal, pts[0]);
if (trianglePlane.Raycast(ray, out rayEnter))
{
Vector3 point = ray.GetPoint(rayEnter);
Vector3 edge0 = pts[1] - pts[0];
Vector3 edge1 = pts[2] - pts[1];
Vector3 edge2 = pts[0] - pts[2];
Vector3 edgeNormal = Vector3.Cross(edge0, normal).normalized;
if (Vector3.Dot(point - pts[0], edgeNormal) > 0.0f) return false;
edgeNormal = Vector3.Cross(edge1, normal).normalized;
if (Vector3.Dot(point - pts[1], edgeNormal) > 0.0f) return false;
edgeNormal = Vector3.Cross(edge2, normal).normalized;
if (Vector3.Dot(point - pts[2], edgeNormal) > 0.0f) return false;
t = rayEnter;
return true;
}
return false;
}
public static bool raycastWire(Ray ray, out float t, Vector3 p0, Vector3 p1, Vector3 p2, float wireEps)
{
t = 0.0f;
float rayEnter;
Plane trianglePlane = new Plane(p0, p1, p2);
if (trianglePlane.Raycast(ray, out rayEnter))
{
Vector3 intersectPt = ray.GetPoint(rayEnter);
float distToSegment = intersectPt.getDistanceToSegment(p0, p1);
if (distToSegment <= wireEps)
{
t = rayEnter;
return true;
}
distToSegment = intersectPt.getDistanceToSegment(p1, p2);
if (distToSegment <= wireEps)
{
t = rayEnter;
return true;
}
distToSegment = intersectPt.getDistanceToSegment(p2, p0);
if (distToSegment <= wireEps)
{
t = rayEnter;
return true;
}
}
return false;
}
public static bool containsPoint(Vector3 point, bool checkOnPlane, Vector3 p0, Vector3 p1, Vector3 p2)
{
Vector3 edge0 = p1 - p0;
Vector3 edge1 = p2 - p1;
Vector3 edge2 = p0 - p2;
Vector3 normal = Vector3.Cross(edge0, -edge2).normalized;
if (checkOnPlane)
{
float distanceToPt = Vector3.Dot(point - p0, normal);
if (Mathf.Abs(distanceToPt) > 1e-5f) return false;
}
Vector3 edgeNormal = Vector3.Cross(edge0, normal).normalized;
if (Vector3.Dot(point - p0, edgeNormal) > 0.0f) return false;
edgeNormal = Vector3.Cross(edge1, normal).normalized;
if (Vector3.Dot(point - p1, edgeNormal) > 0.0f) return false;
edgeNormal = Vector3.Cross(edge2, normal).normalized;
if (Vector3.Dot(point - p2, edgeNormal) > 0.0f) return false;
return true;
}
public static bool containsPoint(Vector3 point, bool checkOnPlane, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 normal)
{
Vector3 edge0 = p1 - p0;
Vector3 edge1 = p2 - p1;
Vector3 edge2 = p0 - p2;
if (checkOnPlane)
{
float distanceToPt = Vector3.Dot(point - p0, normal);
if (Mathf.Abs(distanceToPt) > 1e-5f) return false;
}
Vector3 edgeNormal = Vector3.Cross(edge0, normal).normalized;
if (Vector3.Dot(point - p0, edgeNormal) > 0.0f) return false;
edgeNormal = Vector3.Cross(edge1, normal).normalized;
if (Vector3.Dot(point - p1, edgeNormal) > 0.0f) return false;
edgeNormal = Vector3.Cross(edge2, normal).normalized;
if (Vector3.Dot(point - p2, edgeNormal) > 0.0f) return false;
return true;
}
}
}
#endif