forked from bit/DotRecastNetSim
refactor: aligned the parameter order of RasterizeTriangles() to match that of rcRasterizeTriangles() in the recastnavigation project.
This commit is contained in:
parent
48a1e18101
commit
507e3548ef
|
@ -62,8 +62,8 @@ namespace DotRecast.Detour.Dynamic.Colliders
|
||||||
{
|
{
|
||||||
for (int i = 0; i < triangles.Length; i += 3)
|
for (int i = 0; i < triangles.Length; i += 3)
|
||||||
{
|
{
|
||||||
RcRasterizations.RasterizeTriangle(hf, vertices, triangles[i], triangles[i + 1], triangles[i + 2], area,
|
RcRasterizations.RasterizeTriangle(telemetry, vertices, triangles[i], triangles[i + 1], triangles[i + 2], area,
|
||||||
(int)MathF.Floor(flagMergeThreshold / hf.ch), telemetry);
|
hf, (int)MathF.Floor(flagMergeThreshold / hf.ch));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,31 +229,35 @@ namespace DotRecast.Recast
|
||||||
/// @param[in] inverseCellHeight 1 / cellHeight
|
/// @param[in] inverseCellHeight 1 / cellHeight
|
||||||
/// @param[in] flagMergeThreshold The threshold in which area flags will be merged
|
/// @param[in] flagMergeThreshold The threshold in which area flags will be merged
|
||||||
/// @returns true if the operation completes successfully. false if there was an error adding spans to the heightfield.
|
/// @returns true if the operation completes successfully. false if there was an error adding spans to the heightfield.
|
||||||
private static void RasterizeTri(float[] verts, int v0, int v1, int v2, int area, RcHeightfield heightfield,
|
private static bool RasterizeTri(float[] verts, int v0, int v1, int v2,
|
||||||
|
int areaID, RcHeightfield heightfield,
|
||||||
RcVec3f heightfieldBBMin, RcVec3f heightfieldBBMax,
|
RcVec3f heightfieldBBMin, RcVec3f heightfieldBBMax,
|
||||||
float cellSize, float inverseCellSize, float inverseCellHeight,
|
float cellSize, float inverseCellSize, float inverseCellHeight,
|
||||||
int flagMergeThreshold)
|
int flagMergeThreshold)
|
||||||
{
|
{
|
||||||
float by = heightfieldBBMax.Y - heightfieldBBMin.Y;
|
|
||||||
|
|
||||||
// Calculate the bounding box of the triangle.
|
// Calculate the bounding box of the triangle.
|
||||||
RcVec3f tmin = RcVecUtils.Create(verts, v0 * 3);
|
RcVec3f triBBMin = RcVecUtils.Create(verts, v0 * 3);
|
||||||
RcVec3f tmax = RcVecUtils.Create(verts, v0 * 3);
|
triBBMin = RcVecUtils.Min(triBBMin, verts, v1 * 3);
|
||||||
tmin = RcVecUtils.Min(tmin, verts, v1 * 3);
|
triBBMin = RcVecUtils.Min(triBBMin, verts, v2 * 3);
|
||||||
tmin = RcVecUtils.Min(tmin, verts, v2 * 3);
|
|
||||||
tmax = RcVecUtils.Max(tmax, verts, v1 * 3);
|
|
||||||
tmax = RcVecUtils.Max(tmax, verts, v2 * 3);
|
|
||||||
|
|
||||||
// If the triangle does not touch the bbox of the heightfield, skip the triagle.
|
RcVec3f triBBMax = RcVecUtils.Create(verts, v0 * 3);
|
||||||
if (!OverlapBounds(heightfieldBBMin, heightfieldBBMax, tmin, tmax))
|
triBBMax = RcVecUtils.Max(triBBMax, verts, v1 * 3);
|
||||||
return;
|
triBBMax = RcVecUtils.Max(triBBMax, verts, v2 * 3);
|
||||||
|
|
||||||
// Calculate the footprint of the triangle on the grid's y-axis
|
// If the triangle does not touch the bounding box of the heightfield, skip the triangle.
|
||||||
int z0 = (int)((tmin.Z - heightfieldBBMin.Z) * inverseCellSize);
|
if (!OverlapBounds(triBBMin, triBBMax, heightfieldBBMin, heightfieldBBMax))
|
||||||
int z1 = (int)((tmax.Z - heightfieldBBMin.Z) * inverseCellSize);
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int w = heightfield.width;
|
int w = heightfield.width;
|
||||||
int h = heightfield.height;
|
int h = heightfield.height;
|
||||||
|
float by = heightfieldBBMax.Y - heightfieldBBMin.Y;
|
||||||
|
|
||||||
|
// Calculate the footprint of the triangle on the grid's y-axis
|
||||||
|
int z0 = (int)((triBBMin.Z - heightfieldBBMin.Z) * inverseCellSize);
|
||||||
|
int z1 = (int)((triBBMax.Z - heightfieldBBMin.Z) * inverseCellSize);
|
||||||
|
|
||||||
// use -1 rather than 0 to cut the polygon properly at the start of the tile
|
// use -1 rather than 0 to cut the polygon properly at the start of the tile
|
||||||
z0 = Math.Clamp(z0, -1, h - 1);
|
z0 = Math.Clamp(z0, -1, h - 1);
|
||||||
z1 = Math.Clamp(z1, 0, h - 1);
|
z1 = Math.Clamp(z1, 0, h - 1);
|
||||||
|
@ -268,7 +272,8 @@ namespace DotRecast.Recast
|
||||||
RcVecUtils.Copy(buf, 0, verts, v0 * 3);
|
RcVecUtils.Copy(buf, 0, verts, v0 * 3);
|
||||||
RcVecUtils.Copy(buf, 3, verts, v1 * 3);
|
RcVecUtils.Copy(buf, 3, verts, v1 * 3);
|
||||||
RcVecUtils.Copy(buf, 6, verts, v2 * 3);
|
RcVecUtils.Copy(buf, 6, verts, v2 * 3);
|
||||||
int nvRow, nvIn = 3;
|
int nvRow;
|
||||||
|
int nvIn = 3;
|
||||||
|
|
||||||
for (int z = z0; z <= z1; ++z)
|
for (int z = z0; z <= z1; ++z)
|
||||||
{
|
{
|
||||||
|
@ -278,15 +283,18 @@ namespace DotRecast.Recast
|
||||||
(@in, p1) = (p1, @in);
|
(@in, p1) = (p1, @in);
|
||||||
|
|
||||||
if (nvRow < 3)
|
if (nvRow < 3)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (z < 0)
|
if (z < 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the horizontal bounds in the row
|
// find X-axis bounds of the row
|
||||||
float minX = buf[inRow], maxX = buf[inRow];
|
float minX = buf[inRow];
|
||||||
|
float maxX = buf[inRow];
|
||||||
for (int i = 1; i < nvRow; ++i)
|
for (int i = 1; i < nvRow; ++i)
|
||||||
{
|
{
|
||||||
float v = buf[inRow + i * 3];
|
float v = buf[inRow + i * 3];
|
||||||
|
@ -304,7 +312,8 @@ namespace DotRecast.Recast
|
||||||
x0 = Math.Clamp(x0, -1, w - 1);
|
x0 = Math.Clamp(x0, -1, w - 1);
|
||||||
x1 = Math.Clamp(x1, 0, w - 1);
|
x1 = Math.Clamp(x1, 0, w - 1);
|
||||||
|
|
||||||
int nv, nv2 = nvRow;
|
int nv;
|
||||||
|
int nv2 = nvRow;
|
||||||
for (int x = x0; x <= x1; ++x)
|
for (int x = x0; x <= x1; ++x)
|
||||||
{
|
{
|
||||||
// Clip polygon to column. store the remaining polygon as well
|
// Clip polygon to column. store the remaining polygon as well
|
||||||
|
@ -313,7 +322,9 @@ namespace DotRecast.Recast
|
||||||
(inRow, p2) = (p2, inRow);
|
(inRow, p2) = (p2, inRow);
|
||||||
|
|
||||||
if (nv < 3)
|
if (nv < 3)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
{
|
{
|
||||||
|
@ -331,78 +342,87 @@ namespace DotRecast.Recast
|
||||||
|
|
||||||
spanMin -= heightfieldBBMin.Y;
|
spanMin -= heightfieldBBMin.Y;
|
||||||
spanMax -= heightfieldBBMin.Y;
|
spanMax -= heightfieldBBMin.Y;
|
||||||
|
|
||||||
// Skip the span if it is outside the heightfield bbox
|
// Skip the span if it is outside the heightfield bbox
|
||||||
if (spanMax < 0.0f)
|
if (spanMax < 0.0f)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (spanMin > by)
|
if (spanMin > by)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Clamp the span to the heightfield bbox.
|
// Clamp the span to the heightfield bbox.
|
||||||
if (spanMin < 0.0f)
|
if (spanMin < 0.0f)
|
||||||
|
{
|
||||||
spanMin = 0;
|
spanMin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (spanMax > by)
|
if (spanMax > by)
|
||||||
|
{
|
||||||
spanMax = by;
|
spanMax = by;
|
||||||
|
}
|
||||||
|
|
||||||
// Snap the span to the heightfield height grid.
|
// Snap the span to the heightfield height grid.
|
||||||
int spanMinCellIndex = Math.Clamp((int)MathF.Floor(spanMin * inverseCellHeight), 0, RC_SPAN_MAX_HEIGHT);
|
int spanMinCellIndex = Math.Clamp((int)MathF.Floor(spanMin * inverseCellHeight), 0, RC_SPAN_MAX_HEIGHT);
|
||||||
int spanMaxCellIndex = Math.Clamp((int)MathF.Ceiling(spanMax * inverseCellHeight), spanMinCellIndex + 1, RC_SPAN_MAX_HEIGHT);
|
int spanMaxCellIndex = Math.Clamp((int)MathF.Ceiling(spanMax * inverseCellHeight), spanMinCellIndex + 1, RC_SPAN_MAX_HEIGHT);
|
||||||
|
|
||||||
AddSpan(heightfield, x, z, spanMinCellIndex, spanMaxCellIndex, area, flagMergeThreshold);
|
AddSpan(heightfield, x, z, spanMinCellIndex, spanMaxCellIndex, areaID, flagMergeThreshold);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return true;
|
||||||
* Rasterizes a single triangle into the specified heightfield. Calling this for each triangle in a mesh is less
|
}
|
||||||
* efficient than calling rasterizeTriangles. No spans will be added if the triangle does not overlap the
|
|
||||||
* heightfield grid.
|
/// Rasterizes a single triangle into the specified heightfield.
|
||||||
*
|
///
|
||||||
* @param heightfield
|
/// Calling this for each triangle in a mesh is less efficient than calling rcRasterizeTriangles
|
||||||
* An initialized heightfield.
|
///
|
||||||
* @param verts
|
/// No spans will be added if the triangle does not overlap the heightfield grid.
|
||||||
* An array with vertex coordinates [(x, y, z) * N]
|
///
|
||||||
* @param v0
|
/// @see rcHeightfield
|
||||||
* Index of triangle vertex 0, will be multiplied by 3 to get vertex coordinates
|
/// @ingroup recast
|
||||||
* @param v1
|
/// @param[in,out] context The build context to use during the operation.
|
||||||
* Triangle vertex 1 index
|
/// @param[in] v0 Triangle vertex 0 [(x, y, z)]
|
||||||
* @param v2
|
/// @param[in] v1 Triangle vertex 1 [(x, y, z)]
|
||||||
* Triangle vertex 2 index
|
/// @param[in] v2 Triangle vertex 2 [(x, y, z)]
|
||||||
* @param areaId
|
/// @param[in] areaID The area id of the triangle. [Limit: <= #RC_WALKABLE_AREA]
|
||||||
* The area id of the triangle. [Limit: <= WALKABLE_AREA)
|
/// @param[in,out] heightfield An initialized heightfield.
|
||||||
* @param flagMergeThreshold
|
/// @param[in] flagMergeThreshold The distance where the walkable flag is favored over the non-walkable flag.
|
||||||
* The distance where the walkable flag is favored over the non-walkable flag. [Limit: >= 0] [Units: vx]
|
/// [Limit: >= 0] [Units: vx]
|
||||||
* @see Heightfield
|
/// @returns True if the operation completed successfully.
|
||||||
*/
|
public static void RasterizeTriangle(RcTelemetry context, float[] verts, int v0, int v1, int v2, int areaID,
|
||||||
public static void RasterizeTriangle(RcHeightfield heightfield, float[] verts, int v0, int v1, int v2, int area,
|
RcHeightfield heightfield, int flagMergeThreshold)
|
||||||
int flagMergeThreshold, RcTelemetry ctx)
|
|
||||||
{
|
{
|
||||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
using var timer = context.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
||||||
|
|
||||||
|
// Rasterize the single triangle.
|
||||||
float inverseCellSize = 1.0f / heightfield.cs;
|
float inverseCellSize = 1.0f / heightfield.cs;
|
||||||
float inverseCellHeight = 1.0f / heightfield.ch;
|
float inverseCellHeight = 1.0f / heightfield.ch;
|
||||||
RasterizeTri(verts, v0, v1, v2, area, heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs, inverseCellSize,
|
RasterizeTri(verts, v0, v1, v2, areaID, heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs, inverseCellSize,
|
||||||
inverseCellHeight, flagMergeThreshold);
|
inverseCellHeight, flagMergeThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Rasterizes an indexed triangle mesh into the specified heightfield.
|
||||||
* Rasterizes an indexed triangle mesh into the specified heightfield. Spans will only be added for triangles that
|
///
|
||||||
* overlap the heightfield grid.
|
/// Spans will only be added for triangles that overlap the heightfield grid.
|
||||||
*
|
///
|
||||||
* @param heightfield
|
/// @see rcHeightfield
|
||||||
* An initialized heightfield.
|
/// @ingroup recast
|
||||||
* @param verts
|
/// @param[in,out] context The build context to use during the operation.
|
||||||
* The vertices. [(x, y, z) * N]
|
/// @param[in] verts The vertices. [(x, y, z) * @p nv]
|
||||||
* @param tris
|
/// @param[in] numVerts The number of vertices. (unused) TODO (graham): Remove in next major release
|
||||||
* The triangle indices. [(vertA, vertB, vertC) * nt]
|
/// @param[in] tris The triangle indices. [(vertA, vertB, vertC) * @p nt]
|
||||||
* @param areaIds
|
/// @param[in] triAreaIDs The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt]
|
||||||
* The area id's of the triangles. [Limit: <= WALKABLE_AREA] [Size: numTris]
|
/// @param[in] numTris The number of triangles.
|
||||||
* @param numTris
|
/// @param[in,out] heightfield An initialized heightfield.
|
||||||
* The number of triangles.
|
/// @param[in] flagMergeThreshold The distance where the walkable flag is favored over the non-walkable flag.
|
||||||
* @param flagMergeThreshold
|
/// [Limit: >= 0] [Units: vx]
|
||||||
* The distance where the walkable flag is favored over the non-walkable flag. [Limit: >= 0] [Units: vx]
|
/// @returns True if the operation completed successfully.
|
||||||
* @see Heightfield
|
public static void RasterizeTriangles(RcTelemetry ctx, float[] verts, int[] tris, int[] triAreaIDs, int numTris,
|
||||||
*/
|
RcHeightfield heightfield, int flagMergeThreshold)
|
||||||
public static void RasterizeTriangles(RcHeightfield heightfield, float[] verts, int[] tris, int[] areaIds, int numTris,
|
|
||||||
int flagMergeThreshold, RcTelemetry ctx)
|
|
||||||
{
|
{
|
||||||
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
using var timer = ctx.ScopedTimer(RcTimerLabel.RC_TIMER_RASTERIZE_TRIANGLES);
|
||||||
|
|
||||||
|
@ -413,7 +433,7 @@ namespace DotRecast.Recast
|
||||||
int v0 = tris[triIndex * 3 + 0];
|
int v0 = tris[triIndex * 3 + 0];
|
||||||
int v1 = tris[triIndex * 3 + 1];
|
int v1 = tris[triIndex * 3 + 1];
|
||||||
int v2 = tris[triIndex * 3 + 2];
|
int v2 = tris[triIndex * 3 + 2];
|
||||||
RasterizeTri(verts, v0, v1, v2, areaIds[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs,
|
RasterizeTri(verts, v0, v1, v2, triAreaIDs[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs,
|
||||||
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
inverseCellSize, inverseCellHeight, flagMergeThreshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace DotRecast.Recast
|
||||||
int[] tris = node.tris;
|
int[] tris = node.tris;
|
||||||
int ntris = tris.Length / 3;
|
int ntris = tris.Length / 3;
|
||||||
int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
||||||
RcRasterizations.RasterizeTriangles(solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, ctx);
|
RcRasterizations.RasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.WalkableClimb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -67,7 +67,7 @@ namespace DotRecast.Recast
|
||||||
int[] tris = geom.GetTris();
|
int[] tris = geom.GetTris();
|
||||||
int ntris = tris.Length / 3;
|
int ntris = tris.Length / 3;
|
||||||
int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
int[] m_triareas = RcCommons.MarkWalkableTriangles(ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
||||||
RcRasterizations.RasterizeTriangles(solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, ctx);
|
RcRasterizations.RasterizeTriangles(ctx, verts, tris, m_triareas, ntris, solid, cfg.WalkableClimb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class RecastSoloMeshTest
|
||||||
// If your input data is multiple meshes, you can transform them here, calculate
|
// If your input data is multiple meshes, you can transform them here, calculate
|
||||||
// the are type for each of the meshes and rasterize them.
|
// the are type for each of the meshes and rasterize them.
|
||||||
int[] m_triareas = RcCommons.MarkWalkableTriangles(m_ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
int[] m_triareas = RcCommons.MarkWalkableTriangles(m_ctx, cfg.WalkableSlopeAngle, verts, tris, ntris, cfg.WalkableAreaMod);
|
||||||
RcRasterizations.RasterizeTriangles(m_solid, verts, tris, m_triareas, ntris, cfg.WalkableClimb, m_ctx);
|
RcRasterizations.RasterizeTriangles(m_ctx, verts, tris, m_triareas, ntris, m_solid, cfg.WalkableClimb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue