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

152 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}