Files
Fishing2/Assets/ECM2/Source/Utils/MeshUtility.cs
2025-05-16 23:31:59 +08:00

100 lines
3.2 KiB
C#

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace ECM2
{
public static class MeshUtility
{
private const int kMaxVertices = 1024;
private const int kMaxTriangles = kMaxVertices * 3;
private static readonly List<Vector3> _vertices = new List<Vector3>(kMaxVertices);
private static readonly List<ushort> _triangles16 = new List<ushort>(kMaxTriangles);
private static readonly List<int> _triangles32 = new List<int>();
private static readonly List<ushort> _scratchBuffer16 = new List<ushort>(kMaxTriangles);
private static readonly List<int> _scratchBuffer32 = new List<int>();
public static Vector3 FindMeshOpposingNormal(Mesh sharedMesh, ref RaycastHit inHit)
{
Vector3 v0, v1, v2;
if (sharedMesh.indexFormat == IndexFormat.UInt16)
{
_triangles16.Clear();
int subMeshCount = sharedMesh.subMeshCount;
if (subMeshCount == 1)
sharedMesh.GetTriangles(_triangles16, 0);
else
{
for (int i = 0; i < subMeshCount; i++)
{
sharedMesh.GetTriangles(_scratchBuffer16, i);
_triangles16.AddRange(_scratchBuffer16);
}
}
sharedMesh.GetVertices(_vertices);
v0 = _vertices[_triangles16[inHit.triangleIndex * 3 + 0]];
v1 = _vertices[_triangles16[inHit.triangleIndex * 3 + 1]];
v2 = _vertices[_triangles16[inHit.triangleIndex * 3 + 2]];
}
else
{
_triangles32.Clear();
int subMeshCount = sharedMesh.subMeshCount;
if (subMeshCount == 1)
sharedMesh.GetTriangles(_triangles32, 0);
else
{
for (int i = 0; i < subMeshCount; i++)
{
sharedMesh.GetTriangles(_scratchBuffer32, i);
_triangles32.AddRange(_scratchBuffer32);
}
}
sharedMesh.GetVertices(_vertices);
v0 = _vertices[_triangles32[inHit.triangleIndex * 3 + 0]];
v1 = _vertices[_triangles32[inHit.triangleIndex * 3 + 1]];
v2 = _vertices[_triangles32[inHit.triangleIndex * 3 + 2]];
}
Matrix4x4 mtx = inHit.transform.localToWorldMatrix;
Vector3 p0 = mtx.MultiplyPoint3x4(v0);
Vector3 p1 = mtx.MultiplyPoint3x4(v1);
Vector3 p2 = mtx.MultiplyPoint3x4(v2);
Vector3 u = p1 - p0;
Vector3 v = p2 - p0;
Vector3 worldNormal = Vector3.Cross(u, v).normalized;
if (Vector3.Dot(worldNormal, inHit.normal) < 0.0f)
worldNormal = Vector3.Cross(v, u).normalized;
return worldNormal;
}
public static void FlushBuffers()
{
_vertices.Clear();
_scratchBuffer16.Clear();
_scratchBuffer32.Clear();
_triangles16.Clear();
_triangles32.Clear();
}
}
}