278 lines
9.8 KiB
C#
278 lines
9.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace ProBuilder2.Common
|
|
{
|
|
// Token: 0x02000026 RID: 38
|
|
public static class pb_HandleUtility
|
|
{
|
|
// Token: 0x060000BB RID: 187 RVA: 0x000100A5 File Offset: 0x0000E4A5
|
|
public static bool FaceRaycast(Ray InWorldRay, pb_Object mesh, out pb_RaycastHit hit, HashSet<pb_Face> ignore = null)
|
|
{
|
|
return pb_HandleUtility.FaceRaycast(InWorldRay, mesh, out hit, float.PositiveInfinity, Culling.Front, ignore);
|
|
}
|
|
|
|
// Token: 0x060000BC RID: 188 RVA: 0x000100B8 File Offset: 0x0000E4B8
|
|
public static bool FaceRaycast(Ray InWorldRay, pb_Object mesh, out pb_RaycastHit hit, float distance, Culling cullingMode, HashSet<pb_Face> ignore = null)
|
|
{
|
|
InWorldRay.origin -= mesh.transform.position;
|
|
InWorldRay.origin = mesh.transform.worldToLocalMatrix * InWorldRay.origin;
|
|
InWorldRay.direction = mesh.transform.worldToLocalMatrix * InWorldRay.direction;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float num = 0f;
|
|
Vector3 zero = Vector3.zero;
|
|
float num2 = float.PositiveInfinity;
|
|
int num3 = -1;
|
|
Vector3 vector = Vector3.zero;
|
|
for (int i = 0; i < mesh.faces.Length; i++)
|
|
{
|
|
if (ignore == null || !ignore.Contains(mesh.faces[i]))
|
|
{
|
|
int[] indices = mesh.faces[i].indices;
|
|
for (int j = 0; j < indices.Length; j += 3)
|
|
{
|
|
Vector3 vector2 = vertices[indices[j]];
|
|
Vector3 vector3 = vertices[indices[j + 1]];
|
|
Vector3 vector4 = vertices[indices[j + 2]];
|
|
Vector3 vector5 = Vector3.Cross(vector3 - vector2, vector4 - vector2);
|
|
float num4 = Vector3.Dot(InWorldRay.direction, vector5);
|
|
bool flag = false;
|
|
if (cullingMode != Culling.Front)
|
|
{
|
|
if (cullingMode == Culling.Back)
|
|
{
|
|
if (num4 < 0f)
|
|
{
|
|
flag = true;
|
|
}
|
|
}
|
|
}
|
|
else if (num4 > 0f)
|
|
{
|
|
flag = true;
|
|
}
|
|
if (!flag && pb_Math.RayIntersectsTriangle(InWorldRay, vector2, vector3, vector4, out num, out zero))
|
|
{
|
|
if (num <= num2 && num <= distance)
|
|
{
|
|
vector = vector5;
|
|
num3 = i;
|
|
num2 = num;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
hit = new pb_RaycastHit(num2, InWorldRay.GetPoint(num2), vector, num3);
|
|
return num3 > -1;
|
|
}
|
|
|
|
// Token: 0x060000BD RID: 189 RVA: 0x000102B8 File Offset: 0x0000E6B8
|
|
public static bool FaceRaycast(Ray InWorldRay, pb_Object mesh, out List<pb_RaycastHit> hits, float distance, Culling cullingMode, HashSet<pb_Face> ignore = null)
|
|
{
|
|
InWorldRay.origin -= mesh.transform.position;
|
|
InWorldRay.origin = mesh.transform.worldToLocalMatrix * InWorldRay.origin;
|
|
InWorldRay.direction = mesh.transform.worldToLocalMatrix * InWorldRay.direction;
|
|
Vector3[] vertices = mesh.vertices;
|
|
float num = 0f;
|
|
Vector3 zero = Vector3.zero;
|
|
hits = new List<pb_RaycastHit>();
|
|
for (int i = 0; i < mesh.faces.Length; i++)
|
|
{
|
|
if (ignore == null || !ignore.Contains(mesh.faces[i]))
|
|
{
|
|
int[] indices = mesh.faces[i].indices;
|
|
for (int j = 0; j < indices.Length; j += 3)
|
|
{
|
|
Vector3 vector = vertices[indices[j]];
|
|
Vector3 vector2 = vertices[indices[j + 1]];
|
|
Vector3 vector3 = vertices[indices[j + 2]];
|
|
if (pb_Math.RayIntersectsTriangle(InWorldRay, vector, vector2, vector3, out num, out zero))
|
|
{
|
|
Vector3 vector4 = Vector3.Cross(vector2 - vector, vector3 - vector);
|
|
if (cullingMode != Culling.Front)
|
|
{
|
|
if (cullingMode != Culling.Back)
|
|
{
|
|
if (cullingMode == Culling.FrontBack)
|
|
{
|
|
goto IL_199;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float num2 = Vector3.Dot(InWorldRay.direction, vector4);
|
|
if (num2 > 0f)
|
|
{
|
|
goto IL_199;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float num2 = Vector3.Dot(InWorldRay.direction, -vector4);
|
|
if (num2 > 0f)
|
|
{
|
|
goto IL_199;
|
|
}
|
|
}
|
|
goto IL_1BC;
|
|
IL_199:
|
|
hits.Add(new pb_RaycastHit(num, InWorldRay.GetPoint(num), vector4, i));
|
|
}
|
|
IL_1BC:;
|
|
}
|
|
}
|
|
}
|
|
return hits.Count > 0;
|
|
}
|
|
|
|
// Token: 0x060000BE RID: 190 RVA: 0x000104B4 File Offset: 0x0000E8B4
|
|
public static Ray InverseTransformRay(this Transform transform, Ray InWorldRay)
|
|
{
|
|
Vector3 vector = InWorldRay.origin;
|
|
vector -= transform.position;
|
|
vector = transform.worldToLocalMatrix * vector;
|
|
Vector3 vector2 = transform.worldToLocalMatrix.MultiplyVector(InWorldRay.direction);
|
|
return new Ray(vector, vector2);
|
|
}
|
|
|
|
// Token: 0x060000BF RID: 191 RVA: 0x0001050C File Offset: 0x0000E90C
|
|
public static bool WorldRaycast(Ray InWorldRay, Transform transform, Vector3[] vertices, int[] triangles, out pb_RaycastHit hit, float distance = float.PositiveInfinity, Culling cullingMode = Culling.Front)
|
|
{
|
|
Ray ray = transform.InverseTransformRay(InWorldRay);
|
|
return pb_HandleUtility.MeshRaycast(ray, vertices, triangles, out hit, distance, cullingMode);
|
|
}
|
|
|
|
// Token: 0x060000C0 RID: 192 RVA: 0x00010530 File Offset: 0x0000E930
|
|
public static bool MeshRaycast(Ray InRay, Vector3[] vertices, int[] triangles, out pb_RaycastHit hit, float distance = float.PositiveInfinity, Culling cullingMode = Culling.Front)
|
|
{
|
|
float num = float.PositiveInfinity;
|
|
Vector3 vector = new Vector3(0f, 0f, 0f);
|
|
int num2 = -1;
|
|
Vector3 origin = InRay.origin;
|
|
Vector3 direction = InRay.direction;
|
|
for (int i = 0; i < triangles.Length; i += 3)
|
|
{
|
|
Vector3 vector2 = vertices[triangles[i]];
|
|
Vector3 vector3 = vertices[triangles[i + 1]];
|
|
Vector3 vector4 = vertices[triangles[i + 2]];
|
|
if (pb_Math.RayIntersectsTriangle2(origin, direction, vector2, vector3, vector4, ref distance, ref vector))
|
|
{
|
|
num2 = i / 3;
|
|
num = distance;
|
|
break;
|
|
}
|
|
}
|
|
hit = new pb_RaycastHit(num, InRay.GetPoint(num), vector, num2);
|
|
return num2 > -1;
|
|
}
|
|
|
|
// Token: 0x060000C1 RID: 193 RVA: 0x000105F8 File Offset: 0x0000E9F8
|
|
public static bool EdgeRaycast(Camera cam, Vector2 mousePosition, pb_Object mesh, pb_Edge[] edges, Vector3[] verticesInWorldSpace, out pb_Edge edge)
|
|
{
|
|
float num = float.PositiveInfinity;
|
|
edge = null;
|
|
GameObject gameObject = pb_HandleUtility.ObjectRaycast(cam, mousePosition, (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject)));
|
|
if (gameObject == null || gameObject != mesh.gameObject)
|
|
{
|
|
int width = Screen.width;
|
|
int height = Screen.height;
|
|
for (int i = 0; i < edges.Length; i++)
|
|
{
|
|
Vector3 vector = verticesInWorldSpace[edges[i].x];
|
|
Vector3 vector2 = verticesInWorldSpace[edges[i].y];
|
|
float num2 = pb_HandleUtility.DistancePoint2DToLine(cam, mousePosition, vector, vector2);
|
|
if (num2 < num && num2 < 20f)
|
|
{
|
|
Vector3 vector3 = cam.WorldToScreenPoint(vector);
|
|
if (vector3.z > 0f && vector3.x >= 0f && vector3.y >= 0f && vector3.x <= (float)width && vector3.y <= (float)height)
|
|
{
|
|
Vector3 vector4 = cam.WorldToScreenPoint(vector2);
|
|
if (vector4.z > 0f && vector4.x >= 0f && vector4.y >= 0f && vector4.x <= (float)width && vector4.y <= (float)height)
|
|
{
|
|
num = num2;
|
|
edge = edges[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Ray ray = cam.ScreenPointToRay(mousePosition);
|
|
List<pb_RaycastHit> list;
|
|
if (pb_HandleUtility.FaceRaycast(ray, mesh, out list, float.PositiveInfinity, Culling.FrontBack, null))
|
|
{
|
|
list.Sort((pb_RaycastHit x, pb_RaycastHit y) => x.distance.CompareTo(y.distance));
|
|
Vector3[] vertices = mesh.vertices;
|
|
for (int j = 0; j < list.Count; j++)
|
|
{
|
|
if (!pb_HandleUtility.PointIsOccluded(cam, mesh, mesh.transform.TransformPoint(list[j].point)))
|
|
{
|
|
foreach (pb_Edge pb_Edge in mesh.faces[list[j].face].GetAllEdges())
|
|
{
|
|
float num3 = pb_Math.DistancePointLineSegment(list[j].point, vertices[pb_Edge.x], vertices[pb_Edge.y]);
|
|
if (num3 < num)
|
|
{
|
|
num = num3;
|
|
edge = pb_Edge;
|
|
}
|
|
}
|
|
if (Vector3.Dot(ray.direction, mesh.transform.TransformDirection(list[j].normal)) < 0f)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (edge != null && pb_HandleUtility.DistancePoint2DToLine(cam, mousePosition, mesh.transform.TransformPoint(vertices[edge.x]), mesh.transform.TransformPoint(vertices[edge.y])) > 20f)
|
|
{
|
|
edge = null;
|
|
}
|
|
}
|
|
}
|
|
return edge != null;
|
|
}
|
|
|
|
// Token: 0x060000C2 RID: 194 RVA: 0x00010940 File Offset: 0x0000ED40
|
|
public static GameObject ObjectRaycast(Camera cam, Vector2 mousePosition, GameObject[] objects)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x060000C3 RID: 195 RVA: 0x00010944 File Offset: 0x0000ED44
|
|
public static float DistancePoint2DToLine(Camera cam, Vector2 mousePosition, Vector3 worldPosition1, Vector3 worldPosition2)
|
|
{
|
|
Vector2 vector = cam.WorldToScreenPoint(worldPosition1);
|
|
Vector2 vector2 = cam.WorldToScreenPoint(worldPosition2);
|
|
return pb_Math.DistancePointLineSegment(mousePosition, vector, vector2);
|
|
}
|
|
|
|
// Token: 0x060000C4 RID: 196 RVA: 0x00010974 File Offset: 0x0000ED74
|
|
public static bool PointIsOccluded(Camera cam, pb_Object pb, Vector3 worldPoint)
|
|
{
|
|
Vector3 normalized = (cam.transform.position - worldPoint).normalized;
|
|
Ray ray = new Ray(worldPoint + normalized * 0.0001f, normalized);
|
|
pb_RaycastHit pb_RaycastHit;
|
|
return pb_HandleUtility.FaceRaycast(ray, pb, out pb_RaycastHit, Vector3.Distance(cam.transform.position, worldPoint), Culling.Back, null);
|
|
}
|
|
|
|
// Token: 0x060000C5 RID: 197 RVA: 0x000109D0 File Offset: 0x0000EDD0
|
|
public static bool IsOccluded(Camera cam, pb_Object pb, pb_Face face)
|
|
{
|
|
Vector3 vector = Vector3.zero;
|
|
int num = face.distinctIndices.Length;
|
|
for (int i = 0; i < num; i++)
|
|
{
|
|
vector += pb.vertices[face.distinctIndices[i]];
|
|
}
|
|
vector *= 1f / (float)num;
|
|
return pb_HandleUtility.PointIsOccluded(cam, pb, pb.transform.TransformPoint(vector));
|
|
}
|
|
|
|
// Token: 0x0400010E RID: 270
|
|
private const float MAX_EDGE_SELECT_DISTANCE = 20f;
|
|
}
|
|
}
|