Files
plugin-library/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs

152 lines
4.3 KiB
C#
Raw Normal View History

2025-09-02 10:42:11 +08:00
using UnityEngine;
using System.Collections.Generic;
[RequireComponent(typeof(MeshCollider))]
public class MeshColliderGizmo : MonoBehaviour
{
[Tooltip("Gizmo显示颜色")]
public Color lineColor = new Color(0, 1, 1, 0.8f);
[Tooltip("线框宽度")]
public float lineWidth = 1.0f;
[Tooltip("是否在运行时显示")]
public bool showInPlayMode = true;
[Tooltip("是否只显示边缘")]
public bool showEdgesOnly = true;
private MeshCollider _meshCollider;
private Mesh _mesh;
private List<Vector3> _vertices = new List<Vector3>();
private List<int> _triangles = new List<int>();
private List<Vector3> _linePoints = new List<Vector3>();
private Material _glMaterial;
private Matrix4x4 _localToWorldMatrix;
private void Awake()
{
_meshCollider = GetComponent<MeshCollider>();
InitializeMeshData();
InitializeGLMaterial();
}
private void InitializeMeshData()
{
// 尝试获取网格数据
MeshFilter meshFilter = GetComponent<MeshFilter>();
if (meshFilter != null && meshFilter.sharedMesh != null)
{
_mesh = meshFilter.sharedMesh;
}
else if (_meshCollider.sharedMesh != null)
{
_mesh = _meshCollider.sharedMesh;
}
if (_mesh != null)
{
_vertices.Clear();
_triangles.Clear();
_mesh.GetVertices(_vertices);
_mesh.GetTriangles(_triangles, 0);
GenerateLinePoints();
}
else
{
Debug.LogWarning("未找到有效的Mesh资源", this);
}
}
private void InitializeGLMaterial()
{
// 创建用于GL绘制的材质
_glMaterial = new Material(Shader.Find("Hidden/Internal-Colored"));
_glMaterial.hideFlags = HideFlags.HideAndDontSave;
_glMaterial.SetInt("ZWrite", 0);
_glMaterial.SetInt("ZTest", (int)UnityEngine.Rendering.CompareFunction.Always);
}
private void GenerateLinePoints()
{
if (showEdgesOnly)
{
// 只显示边缘线(去重处理)
HashSet<long> edgeSet = new HashSet<long>();
_linePoints.Clear();
for (int i = 0; i < _triangles.Count; i += 3)
{
AddEdge(_triangles[i], _triangles[i + 1], edgeSet);
AddEdge(_triangles[i + 1], _triangles[i + 2], edgeSet);
AddEdge(_triangles[i + 2], _triangles[i], edgeSet);
}
}
else
{
// 显示所有三角形线
_linePoints.Clear();
for (int i = 0; i < _triangles.Count; i += 3)
{
_linePoints.Add(_vertices[_triangles[i]]);
_linePoints.Add(_vertices[_triangles[i + 1]]);
_linePoints.Add(_vertices[_triangles[i + 1]]);
_linePoints.Add(_vertices[_triangles[i + 2]]);
_linePoints.Add(_vertices[_triangles[i + 2]]);
_linePoints.Add(_vertices[_triangles[i]]);
}
}
}
private void AddEdge(int v1, int v2, HashSet<long> edgeSet)
{
// 创建唯一的边ID避免重复
long edgeId = (long)Mathf.Min(v1, v2) << 32 | Mathf.Max(v1, v2);
if (edgeSet.Contains(edgeId)) return;
edgeSet.Add(edgeId);
_linePoints.Add(_vertices[v1]);
_linePoints.Add(_vertices[v2]);
}
private void Update()
{
_localToWorldMatrix = transform.localToWorldMatrix;
}
private void OnRenderObject()
{
if (!showInPlayMode || _mesh == null || _linePoints.Count == 0 || _glMaterial == null)
return;
// 设置材质和颜色
_glMaterial.SetPass(0);
GL.PushMatrix();
GL.MultMatrix(_localToWorldMatrix);
GL.Color(lineColor);
// 设置线宽
GL.Begin(GL.LINES);
for (int i = 0; i < _linePoints.Count; i++)
{
GL.Vertex(_linePoints[i]);
}
GL.End();
GL.PopMatrix();
}
// 编辑器下的Gizmo预览
#if UNITY_EDITOR
private void OnDrawGizmos()
{
if (!Application.isPlaying && _mesh != null)
{
Gizmos.color = lineColor;
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawWireMesh(_mesh);
}
}
#endif
}