• 【Unity3D】绘制物体表面三角形网格


    1 仅绘制三角形网格

            1)创建游戏对象 

            创建一个空对象,重命名为 Grid,并在其下添加需要绘制网格的对象,如下:

             场景显示如下:

            2)添加脚本组件

            GridController.cs

    1. using System;
    2. using UnityEngine;
    3. public class GridController : MonoBehaviour {
    4. private void Start () {
    5. ForAllChildren(transform, RebuildMesh);
    6. }
    7. private void RebuildMesh(Transform transform) {
    8. MeshFilter meshFilter = transform.GetComponent();
    9. if (meshFilter != null && meshFilter.mesh != null) {
    10. int[] indices = MakeIndices(meshFilter.mesh.triangles);
    11. meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
    12. }
    13. }
    14. private int[] MakeIndices(int[] triangles) {
    15. int[] indices = new int[2 * triangles.Length];
    16. for( int i = 0; i < triangles.Length; i += 3 ) {
    17. for (int j = 0; j < 6; j++) {
    18. // 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
    19. indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
    20. }
    21. }
    22. return indices;
    23. }
    24. private void ForAllChildren(Transform transform, Action action) {
    25. action.Invoke(transform);
    26. for (int i = 0; i < transform.childCount; i++) {
    27. ForAllChildren(transform.GetChild(i), action);
    28. }
    29. }
    30. }

            说明: GridController 脚本组件挂在 Grid 对象上。

            运行效果:

            3)给网格添加新材质

            GridController.cs

    1. using System;
    2. using UnityEngine;
    3. public class GridController : MonoBehaviour {
    4. public Material material;
    5. private void Start () {
    6. ForAllChildren(transform, RebuildMesh);
    7. }
    8. private void RebuildMesh(Transform transform) {
    9. MeshFilter meshFilter = transform.GetComponent();
    10. MeshRenderer meshRenderer = transform.GetComponent();
    11. if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
    12. meshRenderer.material = material;
    13. int[] indices = MakeIndices(meshFilter.mesh.triangles);
    14. meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
    15. }
    16. }
    17. private int[] MakeIndices(int[] triangles) {
    18. int[] indices = new int[2 * triangles.Length];
    19. for( int i = 0; i < triangles.Length; i += 3 ) {
    20. for (int j = 0; j < 6; j++) {
    21. // 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
    22. indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
    23. }
    24. }
    25. return indices;
    26. }
    27. private void ForAllChildren(Transform transform, Action action) {
    28. action.Invoke(transform);
    29. for (int i = 0; i < transform.childCount; i++) {
    30. ForAllChildren(transform.GetChild(i), action);
    31. }
    32. }
    33. }

            运行效果:

    2 绘制表面和三角形网格

            场景中所有对象同第 1 节,脚本组件如下:

            GridController.cs

    1. using System;
    2. using UnityEngine;
    3. using UnityEngine.Rendering;
    4. public class GridController : MonoBehaviour {
    5. public Material material;
    6. private void Start () {
    7. ForAllChildren(transform, RebuildMesh);
    8. }
    9. private void RebuildMesh(Transform transform) {
    10. MeshFilter meshFilter = transform.GetComponent();
    11. MeshRenderer meshRenderer = transform.GetComponent();
    12. if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
    13. InitMaterials(meshRenderer);
    14. int[] indices = MakeIndices(meshFilter.mesh.triangles);
    15. InitSubMesh(meshFilter.mesh, indices, indices.Length / 3);
    16. }
    17. }
    18. private void InitMaterials(MeshRenderer meshRenderer) {
    19. Material[] materials = new Material[meshRenderer.materials.Length + 1];
    20. meshRenderer.materials.CopyTo(materials, 0);
    21. materials[materials.Length - 1] = material;
    22. meshRenderer.materials = materials;
    23. }
    24. private void InitSubMesh(Mesh mesh, int[] indices, int divide) {
    25. mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt32);
    26. mesh.SetIndexBufferData(indices, 0, 0, indices.Length);
    27. mesh.subMeshCount = 2; // 设置2个子网格
    28. // 第一部分绘制三角形内部
    29. SubMeshDescriptor subMeshDescriptor1 = new SubMeshDescriptor(0, divide, MeshTopology.Triangles);
    30. mesh.SetSubMesh(0, subMeshDescriptor1);
    31. // 第二部分绘制线段
    32. SubMeshDescriptor subMeshDescriptor2 = new SubMeshDescriptor(divide, indices.Length - divide, MeshTopology.Lines);
    33. mesh.SetSubMesh(1, subMeshDescriptor2);
    34. }
    35. private int[] MakeIndices(int[] triangles) {
    36. int[] indices = new int[3 * triangles.Length];
    37. triangles.CopyTo(indices, 0);
    38. for( int i = 0; i < triangles.Length; i += 3 ) {
    39. for (int j = 0; j < 6; j++) {
    40. // 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
    41. indices[triangles.Length + 2 * i + j] = triangles[i + (j + 1) % 6 / 2];
    42. }
    43. }
    44. return indices;
    45. }
    46. private void ForAllChildren(Transform transform, Action action) {
    47. action.Invoke(transform);
    48. for (int i = 0; i < transform.childCount; i++) {
    49. ForAllChildren(transform.GetChild(i), action);
    50. }
    51. }
    52. }

            运行效果:

  • 相关阅读:
    8-1插入排序-直接插入排序
    Flask在线部署ChatGLM2大模型
    linux操作Yum
    net基于asp.net的二手商品的交易系统-二手网站-计算机毕业设计
    解决nacos集群搭建,服务注册失败
    java-net-php-python-java机场航班调度管理系统计算机毕业设计程序
    轻松玩转树莓派Pico之四、Ubuntu下在线debug环境搭建
    nginx配置https详细过程
    【LeetCode】899.有序队列
    微信整合CRM系统的好处
  • 原文地址:https://blog.csdn.net/m0_37602827/article/details/128177762