LethalCompany/Lethal Company/ExportedProject/Assets/Scripts/Assembly-CSharp/DigitalRuby/ThunderAndLightning/MeshHelper.cs
2023-12-22 18:30:10 -05:00

120 lines
3.5 KiB
C#

using UnityEngine;
namespace DigitalRuby.ThunderAndLightning
{
public class MeshHelper
{
private Mesh mesh;
private int[] triangles;
private Vector3[] vertices;
private Vector3[] normals;
private float[] normalizedAreaWeights;
public Mesh Mesh => mesh;
public int[] Triangles => triangles;
public Vector3[] Vertices => vertices;
public Vector3[] Normals => normals;
public MeshHelper(Mesh mesh)
{
this.mesh = mesh;
triangles = mesh.triangles;
vertices = mesh.vertices;
normals = mesh.normals;
CalculateNormalizedAreaWeights();
}
public void GenerateRandomPoint(ref RaycastHit hit, out int triangleIndex)
{
triangleIndex = SelectRandomTriangle();
GetRaycastFromTriangleIndex(triangleIndex, ref hit);
}
public void GetRaycastFromTriangleIndex(int triangleIndex, ref RaycastHit hit)
{
Vector3 barycentricCoordinate = GenerateRandomBarycentricCoordinates();
Vector3 vector = vertices[triangles[triangleIndex]];
Vector3 vector2 = vertices[triangles[triangleIndex + 1]];
Vector3 vector3 = vertices[triangles[triangleIndex + 2]];
hit.barycentricCoordinate = barycentricCoordinate;
hit.point = vector * barycentricCoordinate.x + vector2 * barycentricCoordinate.y + vector3 * barycentricCoordinate.z;
if (normals == null)
{
hit.normal = Vector3.Cross(vector3 - vector2, vector - vector2).normalized;
return;
}
vector = normals[triangles[triangleIndex]];
vector2 = normals[triangles[triangleIndex + 1]];
vector3 = normals[triangles[triangleIndex + 2]];
hit.normal = vector * barycentricCoordinate.x + vector2 * barycentricCoordinate.y + vector3 * barycentricCoordinate.z;
}
private float[] CalculateSurfaceAreas(out float totalSurfaceArea)
{
int num = 0;
totalSurfaceArea = 0f;
float[] array = new float[triangles.Length / 3];
for (int i = 0; i < triangles.Length; i += 3)
{
Vector3 vector = vertices[triangles[i]];
Vector3 vector2 = vertices[triangles[i + 1]];
Vector3 vector3 = vertices[triangles[i + 2]];
float sqrMagnitude = (vector - vector2).sqrMagnitude;
float sqrMagnitude2 = (vector - vector3).sqrMagnitude;
float sqrMagnitude3 = (vector2 - vector3).sqrMagnitude;
float num2 = PathGenerator.SquareRoot((2f * sqrMagnitude * sqrMagnitude2 + 2f * sqrMagnitude2 * sqrMagnitude3 + 2f * sqrMagnitude3 * sqrMagnitude - sqrMagnitude * sqrMagnitude - sqrMagnitude2 * sqrMagnitude2 - sqrMagnitude3 * sqrMagnitude3) / 16f);
array[num++] = num2;
totalSurfaceArea += num2;
}
return array;
}
private void CalculateNormalizedAreaWeights()
{
normalizedAreaWeights = CalculateSurfaceAreas(out var totalSurfaceArea);
if (normalizedAreaWeights.Length != 0)
{
float num = 0f;
for (int i = 0; i < normalizedAreaWeights.Length; i++)
{
float num2 = normalizedAreaWeights[i] / totalSurfaceArea;
normalizedAreaWeights[i] = num;
num += num2;
}
}
}
private int SelectRandomTriangle()
{
float value = Random.value;
int num = 0;
int num2 = normalizedAreaWeights.Length - 1;
while (num < num2)
{
int num3 = (num + num2) / 2;
if (normalizedAreaWeights[num3] < value)
{
num = num3 + 1;
}
else
{
num2 = num3;
}
}
return num * 3;
}
private Vector3 GenerateRandomBarycentricCoordinates()
{
Vector3 vector = new Vector3(Random.Range(Mathf.Epsilon, 1f), Random.Range(Mathf.Epsilon, 1f), Random.Range(Mathf.Epsilon, 1f));
return vector / (vector.x + vector.y + vector.z);
}
}
}