Unity中根据平面的多边形点的数据,生成简单的立体网格

您所在的位置:网站首页 unity动态生成网格 Unity中根据平面的多边形点的数据,生成简单的立体网格

Unity中根据平面的多边形点的数据,生成简单的立体网格

2023-08-28 02:02| 来源: 网络整理| 查看: 265

根据平面的多边形点的数据,生成简单的立体网格 1.分析2.用耳切法把多边形三角化3.构造墙壁

最近需要一个功能,就是根据给定的多边形顶点(按照顺时针或者逆时针这样的顺序),然后生成一个具有高度,投影与多边形一样的一个Mesh。 效果如下,比如给定以下的一些顶点的位置, 按顺序给定顶点顺序 生成一个这样的Mesh。 在这里插入图片描述

1.分析

首先肯定就是要生成mesh的这样一个问题。mesh的主要内容包括顶点、三角形、法线(uv的话我用不上,所以就不考虑了,而且感觉不好弄)。 顶点,这个很简单,地面的一圈顶点是给定好的,然后上层的顶点只要加上一个高度就能算出来。 三角形,这个尤为不好弄,如果是一个规规矩矩的矩形,三角形的关系很容易就算出来了。但是问题现在给的多边形可以是任意的。我是真的想不到什么方法。然后经过一番查找,终于找到了我想要的东西——多边形三角化(wiki)。 在这里插入图片描述 里面提到了很多方法,然后在github上找了一下,有同志已经把耳切法的算法实现了,并且也是在Unity里面——耳切法(github)。那我就不客气了。虽然耳切法不适用于带孔的多边形,但是能够处理凹凸多边形对我来说已经足够了。 法线,法线其实也还好,直接用向量差乘算出来就好了。

2.用耳切法把多边形三角化

具体算法我暂时没有去深究,现在的先试着用前面yiwei151写好的代码生成一下。主要的东西就是在Triangulation.cs中。 仿照他原来的测试代码我也写了一个生成mesh的代码。 这个函数是传入一个多边形顶点的List (按照我的需求多边形顶点给的是逆时针为顺序,并且是一个位于xOz平面上的多边形,所以比较轴我也设置的Y轴),然后返回对应三角形的索引。 如果不把三角形反转的话,是会算的z轴的反向为正向,与我的需求不服,所以我这里默认反转以下三角形的顺序。

public static int[] PolygonToTriangles(List polygonVertex, bool filpTriangle = true) { // 存结果的列表 var resultVertexes = new List(); // 转化器 var triangulation = new Triangulation(polygonVertex); // 设置比较轴 triangulation.SetCompareAxle(CompareAxle.Y); // 取得三角形 var triangles = triangulation.GetTriangles(); // 反转三角形 int tempInt; if (filpTriangle) { for (int i = 0; i var resMesh = new Mesh(); // 把多边形数据转换为三角形 var triangles = PolygonToTriangles(polyVerts); // 设置顶点 resMesh.vertices = polyVerts.ToArray(); // 设置三角形 resMesh.triangles = triangles; // 计算法线 resMesh.RecalculateNormals(); return resMesh; }

然后也学着yiwei151用物体的坐标计算几个顶点位置,方便调试。 写了个测试脚本。

using System.Collections.Generic; using UnityEngine; using SimpleObject; using UnityEngine.PlayerLoop; namespace Test { public class TestGenerateSimpleMesh : MonoBehaviour { // 是否实时更新mesh public bool updateMesh = false; // 生成物体的材质 public Material mat; // 生成的高度 public float height = 3; // 用物体的坐标来代替点 public List tList; private GameObject _targetObj; private MeshFilter _targetMeshFilter; private List posList = new List(); private void Start() { // 获取多边形顶点 for (int i = 0; i // 获取多边形顶点 posList.Clear(); for (int i = 0; i // 先添加这个面的四个顶点(顺时针) wallVerts.Add(polyVerts[i]); wallVerts.Add(upperVerts[i]); wallVerts.Add(upperVerts[(i + 1) % polyVerts.Count]); wallVerts.Add(polyVerts[(i + 1) % polyVerts.Count]); // 利用两个向量差乘计算法线 var normal = Vector3.Cross(upperVerts[i] - polyVerts[i], polyVerts[(i + 1) % polyVerts.Count] - polyVerts[i]).normalized; wallNormals.Add(normal); wallNormals.Add(normal); wallNormals.Add(normal); wallNormals.Add(normal); // 计算三角 // 第一个三角 wallTriangles.Add(counter); wallTriangles.Add(counter + 1); wallTriangles.Add(counter + 2); // 第二个三角 wallTriangles.Add(counter); wallTriangles.Add(counter + 2); wallTriangles.Add(counter + 3); // 自增 counter += 4; } // 计算顶部的顶点、法线、三角 // 法线 for (var i = 0; i upperVerts.Add(polyVerts[i] + Vector3.up * height); } // 计算顶层三角形 var upperTriangle = PolygonToTriangles(upperVerts); // 给每一个顶点索引加上长度 /* 因为加上顶层顶点之后,相应的索引应该延后 */ for (var i = 0; i // 四边形中第一个三角形 wallTriangle.Add(i); wallTriangle.Add(i + verts.Count); wallTriangle.Add(i + 1); // 计算四边形中第二个三角形 j = (i + 1) % verts.Count; wallTriangle.Add(j); wallTriangle.Add(j + verts.Count - 1); wallTriangle.Add(j + verts.Count); } // 将顶点相加 verts.AddRange(upperVerts); // 将三角相加 var triangleList = wallTriangle.ToList(); triangleList.AddRange(upperTriangle); // 设置顶点 resMesh.vertices = verts.ToArray(); // 设置三角形 resMesh.triangles = triangleList.ToArray(); // 计算法线 resMesh.RecalculateNormals(); return resMesh; }

把前面测试生成多边面的代码中的mesh生成改成用GenBuildingMesh生成,效果就如下了。 手机上播放可能看到的视频不对,可以到原视频观看。

(当输入的多边形是一个不正确的形状的时候,三角计算会为空,然后后面就会报错,加一个检测其实就行了)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3