File: 0015-Make-detail-mesh-edge-detection-more-robust-657.patch

package info (click to toggle)
recastnavigation 1.6.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,928 kB
  • sloc: cpp: 50,116; ansic: 2,674; xml: 182; makefile: 16
file content (118 lines) | stat: -rw-r--r-- 4,076 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
From c393777d26d2ff6519ac23612abf8af42678c9dd Mon Sep 17 00:00:00 2001
From: Jakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Date: Wed, 20 Dec 2023 06:46:50 +0100
Subject: [PATCH 15/36] Make detail mesh edge detection more robust (#657)

Instead of using a distance check which can fail at large magnitudes due
to low precision we can check whether the edges are actually on the
hull.
---
 Recast/Source/RecastMeshDetail.cpp | 64 ++++++++++++++++++------------
 1 file changed, 38 insertions(+), 26 deletions(-)

diff --git a/Recast/Source/RecastMeshDetail.cpp b/Recast/Source/RecastMeshDetail.cpp
index 479037a..957245c 100644
--- a/Recast/Source/RecastMeshDetail.cpp
+++ b/Recast/Source/RecastMeshDetail.cpp
@@ -634,6 +634,40 @@ inline float getJitterY(const int i)
 	return (((i * 0xd8163841) & 0xffff) / 65535.0f * 2.0f) - 1.0f;
 }
 
+static bool onHull(int a, int b, int nhull, int* hull)
+{
+	// All internal sampled points come after the hull so we can early out for those.
+	if (a >= nhull || b >= nhull)
+		return false;
+
+	for (int j = nhull - 1, i = 0; i < nhull; j = i++)
+	{
+		if (a == hull[j] && b == hull[i])
+			return true;
+	}
+
+	return false;
+}
+
+// Find edges that lie on hull and mark them as such.
+static void setTriFlags(rcIntArray& tris, int nhull, int* hull)
+{
+	// Matches DT_DETAIL_EDGE_BOUNDARY
+	const int DETAIL_EDGE_BOUNDARY = 0x1;
+
+	for (int i = 0; i < tris.size(); i += 4)
+	{
+		int a = tris[i + 0];
+		int b = tris[i + 1];
+		int c = tris[i + 2];
+		unsigned short flags = 0;
+		flags |= (onHull(a, b, nhull, hull) ? DETAIL_EDGE_BOUNDARY : 0) << 0;
+		flags |= (onHull(b, c, nhull, hull) ? DETAIL_EDGE_BOUNDARY : 0) << 2;
+		flags |= (onHull(c, a, nhull, hull) ? DETAIL_EDGE_BOUNDARY : 0) << 4;
+		tris[i + 3] = (int)flags;
+	}
+}
+
 static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
 							const float sampleDist, const float sampleMaxError,
 							const int heightSearchRadius, const rcCompactHeightfield& chf,
@@ -771,6 +805,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
 	if (minExtent < sampleDist*2)
 	{
 		triangulateHull(nverts, verts, nhull, hull, nin, tris);
+		setTriFlags(tris, nhull, hull);
 		return true;
 	}
 	
@@ -875,6 +910,8 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
 		tris.resize(MAX_TRIS*4);
 		ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Shrinking triangle count from %d to max %d.", ntris, MAX_TRIS);
 	}
+
+	setTriFlags(tris, nhull, hull);
 	
 	return true;
 }
@@ -1137,31 +1174,6 @@ static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf,
 	}
 }
 
-static unsigned char getEdgeFlags(const float* va, const float* vb,
-								  const float* vpoly, const int npoly)
-{
-	// The flag returned by this function matches dtDetailTriEdgeFlags in Detour.
-	// Figure out if edge (va,vb) is part of the polygon boundary.
-	static const float thrSqr = rcSqr(0.001f);
-	for (int i = 0, j = npoly-1; i < npoly; j=i++)
-	{
-		if (distancePtSeg2d(va, &vpoly[j*3], &vpoly[i*3]) < thrSqr &&
-			distancePtSeg2d(vb, &vpoly[j*3], &vpoly[i*3]) < thrSqr)
-			return 1;
-	}
-	return 0;
-}
-
-static unsigned char getTriFlags(const float* va, const float* vb, const float* vc,
-								 const float* vpoly, const int npoly)
-{
-	unsigned char flags = 0;
-	flags |= getEdgeFlags(va,vb,vpoly,npoly) << 0;
-	flags |= getEdgeFlags(vb,vc,vpoly,npoly) << 2;
-	flags |= getEdgeFlags(vc,va,vpoly,npoly) << 4;
-	return flags;
-}
-
 /// @par
 ///
 /// See the #rcConfig documentation for more information on the configuration parameters.
@@ -1377,7 +1389,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa
 			dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0];
 			dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1];
 			dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2];
-			dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[1]*3], &verts[t[2]*3], poly, npoly);
+			dmesh.tris[dmesh.ntris*4+3] = (unsigned char)t[3];
 			dmesh.ntris++;
 		}
 	}
-- 
2.43.0