(SOLVED)Triangle.NET-如何将顶点添加到现有的三角测量?

问题描述 投票:0回答:1

我已经遍历了Triangle.NET的每个问题和资源,试图找到如何将顶点插入现有三角剖分的答案。我得到的最接近的是Traingle.Net的讨论档案,那里有人问了类似的问题(讨论ID 632458),但不幸的是,答案不是我想要的。

我的目标是在Unity中创建一个可破坏的墙,当玩家射击墙时,它将在墙中创建一个洞(就像在《彩虹六号:围攻》中一样。]]

这是我为原始实现所做的:

  1. 使用墙的四个角创建初始三角剖分。
  2. [玩家射击时,执行射线投射,如果射线投射与墙相交,则将相交点添加到多边形变量中,并使用该变量重新三角化整个网格。
  3. 在墙上绘制新的三角剖分作为纹理以可视化正在发生的事情。
  4. 重复。
  5. 如您所见,步骤2

是问题。

因为每次玩家击中墙时都会重新对整个网格进行三角剖分,所以玩家触及墙壁的次数越多,随着顶点数量的增加,三角剖分的速度就越慢。我想这可能很好,但我希望可破坏的墙在我的游戏中起主要作用,所以这是不可接受的。

因此,通过浏览Triangle.Net源代码,我找到了一个称为InsertVertex的内部方法。此方法的摘要指出:

将顶点插入Delaunay三角剖分,并根据需要执行翻转以保持Delaunay属性。

这意味着我不必在每次射击时都重新三角化!

所以我开始实现此方法,并且...不起作用。我收到类似以下的错误:

NullReferenceException:对象引用未设置为对象的实例TriangleNet.TriangleLocator.PreciseLocate(TriangleNet.Geometry.Point搜索点,TriangleNet.Topology.Otri&searchtri,System.Boolean stopatsubsegment)(位于Assets / Triangle.NET / TriangleLocator.cs:146)

我在[[days

时就一直被这个问题困扰,我无法终生解决!如果有人对Triangle.NET库有足够的了解,愿意帮助我,我将非常感激!除此之外,如果我使用的实现或库有更好的选择(出于上面概述的目的),那也很棒![当前,我如何设置场景非常简单,我只有一个四边形,我按比例放大并将下面的脚本作为组件添加到其中。然后,我将该组件链接到附加到主摄像机的Shoot raycast脚本:

How the scene is setup

What it looks like in Play Mode

我克隆的确切Triangle.Net存储库是this one

我的代码发布在下面:

using UnityEngine; using TriangleNet.Geometry; using TriangleNet.Topology; using TriangleNet.Meshing; public class Delaunay : MonoBehaviour { [SerializeField] private int randomPoints = 150; [SerializeField] private int width = 512; [SerializeField] private int height = 512; private TriangleNet.Mesh mesh; Polygon polygon = new Polygon(); Otri otri = default(Otri); Osub osub = default(Osub); ConstraintOptions constraintOptions = new ConstraintOptions() { ConformingDelaunay = true }; QualityOptions qualityOptions = new QualityOptions() { MinimumAngle = 25 }; void Start() { osub.seg = null; Mesh objMesh = GetComponent<MeshFilter>().mesh; // Add four corners of wall (quad in this case) to polygon. //foreach (Vector3 vert in objMesh.vertices) //{ // Vector2 temp = new Vector2(); // temp.x = map(vert.x, -0.5f, 0.5f, 0, 512); // temp.y = map(vert.y, -0.5f, 0.5f, 0, 512); // polygon.Add(new Vertex(temp.x, temp.y)); //} // Generate random points and add to polygon. for (int i = 0; i < randomPoints; i++) { polygon.Add(new Vertex(Random.Range(0.0f, width), Random.Range(0.0f, height))); } // Triangulate polygon. delaunayTriangulation(); } // When left click is pressed, a raycast is sent out. If that raycast hits the wall, updatePoints() is called and is passed in the location of the hit (hit.point). public void updatePoints(Vector3 pos) { // Convert pos to local coords of wall. pos = transform.InverseTransformPoint(pos); Vertex newVert = new Vertex(pos.x, pos.y); //// Give new vertex a unique id. //if (mesh != null) //{ // newVert.id = mesh.NumberOfInputPoints; //} // Insert new vertex into existing triangulation. otri.tri = mesh.dummytri; mesh.InsertVertex(newVert, ref otri, ref osub, false, false); // Draw result as a texture onto the wall so to visualise what is happening. draw(); } private void delaunayTriangulation() { mesh = (TriangleNet.Mesh)polygon.Triangulate(constraintOptions, qualityOptions); draw(); } void draw() { Texture2D tx = new Texture2D(width, height); // Draw triangulation. if (mesh.Edges != null) { foreach (Edge edge in mesh.Edges) { Vertex v0 = mesh.vertices[edge.P0]; Vertex v1 = mesh.vertices[edge.P1]; DrawLine(new Vector2((float)v0.x, (float)v0.y), new Vector2((float)v1.x, (float)v1.y), tx, Color.black); } } tx.Apply(); this.GetComponent<Renderer>().sharedMaterial.mainTexture = tx; } // Bresenham line algorithm private void DrawLine(Vector2 p0, Vector2 p1, Texture2D tx, Color c, int offset = 0) { int x0 = (int)p0.x; int y0 = (int)p0.y; int x1 = (int)p1.x; int y1 = (int)p1.y; int dx = Mathf.Abs(x1 - x0); int dy = Mathf.Abs(y1 - y0); int sx = x0 < x1 ? 1 : -1; int sy = y0 < y1 ? 1 : -1; int err = dx - dy; while (true) { tx.SetPixel(x0 + offset, y0 + offset, c); if (x0 == x1 && y0 == y1) break; int e2 = 2 * err; if (e2 > -dy) { err -= dy; x0 += sx; } if (e2 < dx) { err += dx; y0 += sy; } } } private float map(float from, float fromMin, float fromMax, float toMin, float toMax) { float fromAbs = from - fromMin; float fromMaxAbs = fromMax - fromMin; float normal = fromAbs / fromMaxAbs; float toMaxAbs = toMax - toMin; float toAbs = toMaxAbs * normal; float to = toAbs + toMin; return to; } }

我已经遍历了Triangle.NET的每个问题和资源,试图找到如何将顶点插入现有三角剖分的答案。我最近得到的是...
c# unity3d triangulation delaunay triangle.net
1个回答
0
投票
好消息!我已经解决了这个问题。 InsertVertex()实际上不会将新顶点添加到顶点列表中!因此,这意味着当它尝试进行三角剖分时,它试图指向新的顶点,但是却无法指向(因为该顶点不在列表中)。因此,要解决此问题,我只需将我的新顶点手动添加到网格中的顶点列表中,

before

© www.soinside.com 2019 - 2024. All rights reserved.