diff --git a/src/DotRecast.Detour.Extras/Unity/Astar/GraphMeshDataReader.cs b/src/DotRecast.Detour.Extras/Unity/Astar/GraphMeshDataReader.cs index 140134f..e08b984 100644 --- a/src/DotRecast.Detour.Extras/Unity/Astar/GraphMeshDataReader.cs +++ b/src/DotRecast.Detour.Extras/Unity/Astar/GraphMeshDataReader.cs @@ -97,11 +97,11 @@ namespace DotRecast.Detour.Extras.Unity.Astar ymax = Math.Max(ymax, verts[nodes[i].verts[0] * 3 + 1]); ymax = Math.Max(ymax, verts[nodes[i].verts[1] * 3 + 1]); ymax = Math.Max(ymax, verts[nodes[i].verts[2] * 3 + 1]); - detailNodes[i] = new DtPolyDetail(); - detailNodes[i].vertBase = 0; - detailNodes[i].vertCount = 0; - detailNodes[i].triBase = i; - detailNodes[i].triCount = 1; + int vertBase = 0; + int vertCount = 0; + int triBase = i; + int triCount = 1; + detailNodes[i] = new DtPolyDetail(vertBase, triBase, vertCount, triCount); detailTris[4 * i] = 0; detailTris[4 * i + 1] = 1; detailTris[4 * i + 2] = 2; diff --git a/src/DotRecast.Detour/DtNavMesh.cs b/src/DotRecast.Detour/DtNavMesh.cs index 556a8e4..a521ead 100644 --- a/src/DotRecast.Detour/DtNavMesh.cs +++ b/src/DotRecast.Detour/DtNavMesh.cs @@ -1137,7 +1137,7 @@ namespace DotRecast.Detour if (tile.data.detailMeshes != null) { - DtPolyDetail pd = tile.data.detailMeshes[ip]; + ref DtPolyDetail pd = ref tile.data.detailMeshes[ip]; for (int i = 0; i < pd.triCount; i++) { int ti = (pd.triBase + i) * 4; @@ -1248,7 +1248,7 @@ namespace DotRecast.Detour // Find height at the location. if (tile.data.detailMeshes != null) { - DtPolyDetail pd = tile.data.detailMeshes[ip]; + ref DtPolyDetail pd = ref tile.data.detailMeshes[ip]; for (int j = 0; j < pd.triCount; ++j) { int t = (pd.triBase + j) * 4; diff --git a/src/DotRecast.Detour/DtNavMeshBuilder.cs b/src/DotRecast.Detour/DtNavMeshBuilder.cs index fef9a98..eb37a5e 100644 --- a/src/DotRecast.Detour/DtNavMeshBuilder.cs +++ b/src/DotRecast.Detour/DtNavMeshBuilder.cs @@ -545,15 +545,14 @@ namespace DotRecast.Detour int vbase = 0; for (int i = 0; i < option.polyCount; ++i) { - DtPolyDetail dtl = new DtPolyDetail(); - navDMeshes[i] = dtl; int vb = option.detailMeshes[i * 4 + 0]; int ndv = option.detailMeshes[i * 4 + 1]; int nv = navPolys[i].vertCount; - dtl.vertBase = vbase; - dtl.vertCount = (ndv - nv); - dtl.triBase = option.detailMeshes[i * 4 + 2]; - dtl.triCount = option.detailMeshes[i * 4 + 3]; + int vertBase = vbase; + int vertCount = (ndv - nv); + int triBase = option.detailMeshes[i * 4 + 2]; + int triCount = option.detailMeshes[i * 4 + 3]; + navDMeshes[i] = new DtPolyDetail(vertBase, triBase, vertCount, triCount); // Copy vertices except the first 'nv' verts which are equal to // nav poly verts. if (ndv - nv != 0) @@ -572,13 +571,12 @@ namespace DotRecast.Detour int tbase = 0; for (int i = 0; i < option.polyCount; ++i) { - DtPolyDetail dtl = new DtPolyDetail(); - navDMeshes[i] = dtl; int nv = navPolys[i].vertCount; - dtl.vertBase = 0; - dtl.vertCount = 0; - dtl.triBase = tbase; - dtl.triCount = (nv - 2); + int vertBase = 0; + int vertCount = 0; + int triBase = tbase; + int triCount = (nv - 2); + navDMeshes[i] = new DtPolyDetail(vertBase, triBase, vertCount, triCount); // Triangulate polygon (local indices). for (int j = 2; j < nv; ++j) { diff --git a/src/DotRecast.Detour/DtNavMeshRaycast.cs b/src/DotRecast.Detour/DtNavMeshRaycast.cs index 3c9865d..ac1aaca 100644 --- a/src/DotRecast.Detour/DtNavMeshRaycast.cs +++ b/src/DotRecast.Detour/DtNavMeshRaycast.cs @@ -56,40 +56,33 @@ namespace DotRecast.Detour continue; } - DtPolyDetail pd = tile.data.detailMeshes[i]; + ref DtPolyDetail pd = ref tile.data.detailMeshes[i]; - if (pd != null) + RcVec3f[] verts = new RcVec3f[3]; + for (int j = 0; j < pd.triCount; ++j) { - RcVec3f[] verts = new RcVec3f[3]; - for (int j = 0; j < pd.triCount; ++j) + int t = (pd.triBase + j) * 4; + for (int k = 0; k < 3; ++k) { - int t = (pd.triBase + j) * 4; - for (int k = 0; k < 3; ++k) + int v = tile.data.detailTris[t + k]; + if (v < p.vertCount) { - int v = tile.data.detailTris[t + k]; - if (v < p.vertCount) - { - verts[k].X = tile.data.verts[p.verts[v] * 3]; - verts[k].Y = tile.data.verts[p.verts[v] * 3 + 1]; - verts[k].Z = tile.data.verts[p.verts[v] * 3 + 2]; - } - else - { - verts[k].X = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3]; - verts[k].Y = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1]; - verts[k].Z = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2]; - } + verts[k].X = tile.data.verts[p.verts[v] * 3]; + verts[k].Y = tile.data.verts[p.verts[v] * 3 + 1]; + verts[k].Z = tile.data.verts[p.verts[v] * 3 + 2]; } - - if (RcIntersections.IntersectSegmentTriangle(sp, sq, verts[0], verts[1], verts[2], out hitTime)) + else { - return true; + verts[k].X = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3]; + verts[k].Y = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1]; + verts[k].Z = tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2]; } } - } - else - { - // FIXME: Use Poly if PolyDetail is unavailable + + if (RcIntersections.IntersectSegmentTriangle(sp, sq, verts[0], verts[1], verts[2], out hitTime)) + { + return true; + } } } diff --git a/src/DotRecast.Detour/DtPolyDetail.cs b/src/DotRecast.Detour/DtPolyDetail.cs index db8411d..cd813a4 100644 --- a/src/DotRecast.Detour/DtPolyDetail.cs +++ b/src/DotRecast.Detour/DtPolyDetail.cs @@ -21,18 +21,26 @@ freely, subject to the following restrictions: namespace DotRecast.Detour { /** Defines the location of detail sub-mesh data within a dtMeshTile. */ - public class DtPolyDetail + public readonly struct DtPolyDetail { /** The offset of the vertices in the MeshTile::detailVerts array. */ - public int vertBase; + public readonly int vertBase; /** The offset of the triangles in the MeshTile::detailTris array. */ - public int triBase; + public readonly int triBase; /** The number of vertices in the sub-mesh. */ - public int vertCount; + public readonly int vertCount; /** The number of triangles in the sub-mesh. */ - public int triCount; + public readonly int triCount; + + public DtPolyDetail(int vertBase, int triBase, int vertCount, int triCount) + { + this.vertBase = vertBase; + this.triBase = triBase; + this.vertCount = vertCount; + this.triCount = triCount; + } } } \ No newline at end of file diff --git a/src/DotRecast.Detour/Io/DtMeshDataReader.cs b/src/DotRecast.Detour/Io/DtMeshDataReader.cs index 0cf339e..32a98c0 100644 --- a/src/DotRecast.Detour/Io/DtMeshDataReader.cs +++ b/src/DotRecast.Detour/Io/DtMeshDataReader.cs @@ -169,11 +169,11 @@ namespace DotRecast.Detour.Io DtPolyDetail[] polys = new DtPolyDetail[header.detailMeshCount]; for (int i = 0; i < polys.Length; i++) { - polys[i] = new DtPolyDetail(); - polys[i].vertBase = buf.GetInt(); - polys[i].triBase = buf.GetInt(); - polys[i].vertCount = buf.Get() & 0xFF; - polys[i].triCount = buf.Get() & 0xFF; + int vertBase = buf.GetInt(); + int triBase = buf.GetInt(); + int vertCount = buf.Get() & 0xFF; + int triCount = buf.Get() & 0xFF; + polys[i] = new DtPolyDetail(vertBase, triBase, vertCount, triCount); if (cCompatibility) { buf.GetShort(); // C struct padding diff --git a/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs b/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs index 82bf288..8c9fca9 100644 --- a/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs +++ b/src/DotRecast.Recast.Demo/Draw/RecastDebugDraw.cs @@ -255,26 +255,23 @@ public class RecastDebugDraw : DebugDraw DtPoly p = tile.data.polys[index]; if (tile.data.detailMeshes != null) { - DtPolyDetail pd = tile.data.detailMeshes[index]; - if (pd != null) + ref DtPolyDetail pd = ref tile.data.detailMeshes[index]; + for (int j = 0; j < pd.triCount; ++j) { - for (int j = 0; j < pd.triCount; ++j) + int t = (pd.triBase + j) * 4; + for (int k = 0; k < 3; ++k) { - int t = (pd.triBase + j) * 4; - for (int k = 0; k < 3; ++k) + int v = tile.data.detailTris[t + k]; + if (v < p.vertCount) { - int v = tile.data.detailTris[t + k]; - if (v < p.vertCount) - { - Vertex(tile.data.verts[p.verts[v] * 3], tile.data.verts[p.verts[v] * 3 + 1], - tile.data.verts[p.verts[v] * 3 + 2], col); - } - else - { - Vertex(tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3], - tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1], - tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2], col); - } + Vertex(tile.data.verts[p.verts[v] * 3], tile.data.verts[p.verts[v] * 3 + 1], + tile.data.verts[p.verts[v] * 3 + 2], col); + } + else + { + Vertex(tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3], + tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 1], + tile.data.detailVerts[(pd.vertBase + v - p.vertCount) * 3 + 2], col); } } } @@ -367,7 +364,7 @@ public class RecastDebugDraw : DebugDraw // This is really slow. if (tile.data.detailMeshes != null) { - DtPolyDetail pd = tile.data.detailMeshes[i]; + ref DtPolyDetail pd = ref tile.data.detailMeshes[i]; for (int k = 0; k < pd.triCount; ++k) { int t = (pd.triBase + k) * 4;