- Added rcOffsetPoly() helper function to expand polygon areas
This commit is contained in:
parent
17fae045a2
commit
d2b4b09e16
@ -935,6 +935,16 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
|
|||||||
const float hmin, const float hmax, unsigned char areaId,
|
const float hmin, const float hmax, unsigned char areaId,
|
||||||
rcCompactHeightfield& chf);
|
rcCompactHeightfield& chf);
|
||||||
|
|
||||||
|
/// Helper function to offset voncex polygons for rcMarkConvexPolyArea.
|
||||||
|
/// @ingroup recast
|
||||||
|
/// @param[in] verts The vertices of the polygon [Form: (x, y, z) * @p nverts]
|
||||||
|
/// @param[in] nverts The number of vertices in the polygon.
|
||||||
|
/// @param[out] outVerts The offset vertices (should hold up to 2 * @p nverts) [Form: (x, y, z) * return value]
|
||||||
|
/// @param[in] maxOutVerts The max number of vertices that can be stored to @p outVerts.
|
||||||
|
/// @returns Number of vertices in the offset polygon or 0 if too few vertices in @p outVerts.
|
||||||
|
int rcOffsetPoly(const float* verts, const int nverts, const float offset,
|
||||||
|
float* outVerts, const int maxOutVerts);
|
||||||
|
|
||||||
/// Applies the area id to all spans within the specified cylinder.
|
/// Applies the area id to all spans within the specified cylinder.
|
||||||
/// @ingroup recast
|
/// @ingroup recast
|
||||||
/// @param[in,out] ctx The build context to use during the operation.
|
/// @param[in,out] ctx The build context to use during the operation.
|
||||||
|
@ -452,6 +452,84 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts,
|
|||||||
ctx->stopTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
|
ctx->stopTimer(RC_TIMER_MARK_CONVEXPOLY_AREA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rcOffsetPoly(const float* verts, const int nverts, const float offset,
|
||||||
|
float* outVerts, const int maxOutVerts)
|
||||||
|
{
|
||||||
|
const float MITER_LIMIT = 1.20f;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < nverts; i++)
|
||||||
|
{
|
||||||
|
const int a = (i+nverts-1) % nverts;
|
||||||
|
const int b = i;
|
||||||
|
const int c = (i+1) % nverts;
|
||||||
|
const float* va = &verts[a*3];
|
||||||
|
const float* vb = &verts[b*3];
|
||||||
|
const float* vc = &verts[c*3];
|
||||||
|
float dx0 = vb[0] - va[0];
|
||||||
|
float dy0 = vb[2] - va[2];
|
||||||
|
float d0 = dx0*dx0 + dy0*dy0;
|
||||||
|
if (d0 > 1e-6f)
|
||||||
|
{
|
||||||
|
d0 = 1.0f/rcSqrt(d0);
|
||||||
|
dx0 *= d0;
|
||||||
|
dy0 *= d0;
|
||||||
|
}
|
||||||
|
float dx1 = vc[0] - vb[0];
|
||||||
|
float dy1 = vc[2] - vb[2];
|
||||||
|
float d1 = dx1*dx1 + dy1*dy1;
|
||||||
|
if (d1 > 1e-6f)
|
||||||
|
{
|
||||||
|
d1 = 1.0f/rcSqrt(d1);
|
||||||
|
dx1 *= d1;
|
||||||
|
dy1 *= d1;
|
||||||
|
}
|
||||||
|
const float dlx0 = -dy0;
|
||||||
|
const float dly0 = dx0;
|
||||||
|
const float dlx1 = -dy1;
|
||||||
|
const float dly1 = dx1;
|
||||||
|
float cross = dx1*dy0 - dx0*dy1;
|
||||||
|
float dmx = (dlx0 + dlx1) * 0.5f;
|
||||||
|
float dmy = (dly0 + dly1) * 0.5f;
|
||||||
|
float dmr2 = dmx*dmx + dmy*dmy;
|
||||||
|
bool bevel = dmr2 * MITER_LIMIT*MITER_LIMIT < 1.0f;
|
||||||
|
if (dmr2 > 1e-6f)
|
||||||
|
{
|
||||||
|
const float scale = 1.0f / dmr2;
|
||||||
|
dmx *= scale;
|
||||||
|
dmy *= scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bevel && cross < 0.0f)
|
||||||
|
{
|
||||||
|
if (n+2 >= maxOutVerts)
|
||||||
|
return 0;
|
||||||
|
float d = (1.0f - (dx0*dx1 + dy0*dy1))*0.5f;
|
||||||
|
outVerts[n*3+0] = vb[0] + (-dlx0+dx0*d)*offset;
|
||||||
|
outVerts[n*3+1] = vb[1];
|
||||||
|
outVerts[n*3+2] = vb[2] + (-dly0+dy0*d)*offset;
|
||||||
|
n++;
|
||||||
|
outVerts[n*3+0] = vb[0] + (-dlx1-dx1*d)*offset;
|
||||||
|
outVerts[n*3+1] = vb[1];
|
||||||
|
outVerts[n*3+2] = vb[2] + (-dly1-dy1*d)*offset;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (n+1 >= maxOutVerts)
|
||||||
|
return 0;
|
||||||
|
outVerts[n*3+0] = vb[0] - dmx*offset;
|
||||||
|
outVerts[n*3+1] = vb[1];
|
||||||
|
outVerts[n*3+2] = vb[2] - dmy*offset;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// The value of spacial parameters are in world units.
|
/// The value of spacial parameters are in world units.
|
||||||
|
@ -27,6 +27,7 @@ class ConvexVolumeTool : public SampleTool
|
|||||||
{
|
{
|
||||||
Sample* m_sample;
|
Sample* m_sample;
|
||||||
int m_areaType;
|
int m_areaType;
|
||||||
|
float m_polyOffset;
|
||||||
float m_boxHeight;
|
float m_boxHeight;
|
||||||
float m_boxDescent;
|
float m_boxDescent;
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ static int pointInPoly(int nvert, const float* verts, const float* p)
|
|||||||
ConvexVolumeTool::ConvexVolumeTool() :
|
ConvexVolumeTool::ConvexVolumeTool() :
|
||||||
m_sample(0),
|
m_sample(0),
|
||||||
m_areaType(SAMPLE_POLYAREA_GRASS),
|
m_areaType(SAMPLE_POLYAREA_GRASS),
|
||||||
|
m_polyOffset(0.0f),
|
||||||
m_boxHeight(6.0f),
|
m_boxHeight(6.0f),
|
||||||
m_boxDescent(1.0f),
|
m_boxDescent(1.0f),
|
||||||
m_npts(0),
|
m_npts(0),
|
||||||
@ -127,6 +128,7 @@ void ConvexVolumeTool::handleMenu()
|
|||||||
{
|
{
|
||||||
imguiSlider("Shape Height", &m_boxHeight, 0.1f, 20.0f, 0.1f);
|
imguiSlider("Shape Height", &m_boxHeight, 0.1f, 20.0f, 0.1f);
|
||||||
imguiSlider("Shape Descent", &m_boxDescent, 0.1f, 20.0f, 0.1f);
|
imguiSlider("Shape Descent", &m_boxDescent, 0.1f, 20.0f, 0.1f);
|
||||||
|
imguiSlider("Poly Offset", &m_polyOffset, 0.0f, 10.0f, 0.1f);
|
||||||
|
|
||||||
imguiSeparator();
|
imguiSeparator();
|
||||||
|
|
||||||
@ -196,7 +198,17 @@ void ConvexVolumeTool::handleClick(const float* /*s*/, const float* p, bool shif
|
|||||||
minh -= m_boxDescent;
|
minh -= m_boxDescent;
|
||||||
maxh = minh + m_boxHeight;
|
maxh = minh + m_boxHeight;
|
||||||
|
|
||||||
geom->addConvexVolume(verts, m_nhull, minh, maxh, (unsigned char)m_areaType);
|
if (m_polyOffset > 0.01f)
|
||||||
|
{
|
||||||
|
float offset[MAX_PTS*2*3];
|
||||||
|
int noffset = rcOffsetPoly(verts, m_nhull, m_polyOffset, offset, MAX_PTS*2);
|
||||||
|
if (noffset > 0)
|
||||||
|
geom->addConvexVolume(offset, noffset, minh, maxh, (unsigned char)m_areaType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
geom->addConvexVolume(verts, m_nhull, minh, maxh, (unsigned char)m_areaType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_npts = 0;
|
m_npts = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user