我已经遍历了Triangle.NET的每个问题和资源,试图找到如何将顶点插入现有三角剖分的答案。我得到的最接近的是Traingle.Net的讨论档案,那里有人问了类似的问题(讨论ID 632458),但不幸的是,答案不是我想要的。
我的目标是在Unity中创建一个可破坏的墙,当玩家射击墙时,它将在墙中创建一个洞(就像在《彩虹六号:围攻》中一样。]]
这是我为原始实现所做的:
如您所见,步骤2
因为每次玩家击中墙时都会重新对整个网格进行三角剖分,所以玩家触及墙壁的次数越多,随着顶点数量的增加,三角剖分的速度就越慢。我想这可能很好,但我希望可破坏的墙在我的游戏中起主要作用,所以这是不可接受的。
因此,通过浏览Triangle.Net源代码,我找到了一个称为InsertVertex
的内部方法。此方法的摘要指出:
将顶点插入Delaunay三角剖分,并根据需要执行翻转以保持Delaunay属性。
这意味着我不必在每次射击时都重新三角化!
所以我开始实现此方法,并且...不起作用。我收到类似以下的错误:
时就一直被这个问题困扰,我无法终生解决!如果有人对Triangle.NET库有足够的了解,愿意帮助我,我将非常感激!除此之外,如果我使用的实现或库有更好的选择(出于上面概述的目的),那也很棒![当前,我如何设置场景非常简单,我只有一个四边形,我按比例放大并将下面的脚本作为组件添加到其中。然后,我将该组件链接到附加到主摄像机的Shoot raycast脚本:NullReferenceException:对象引用未设置为对象的实例TriangleNet.TriangleLocator.PreciseLocate(TriangleNet.Geometry.Point搜索点,TriangleNet.Topology.Otri&searchtri,System.Boolean stopatsubsegment)(位于Assets / Triangle.NET / TriangleLocator.cs:146)
我在[[days
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的每个问题和资源,试图找到如何将顶点插入现有三角剖分的答案。我最近得到的是...
InsertVertex()
实际上不会将新顶点添加到顶点列表中!因此,这意味着当它尝试进行三角剖分时,它试图指向新的顶点,但是却无法指向(因为该顶点不在列表中)。因此,要解决此问题,我只需将我的新顶点手动添加到网格中的顶点列表中,before