本文整理汇总了C++中rcMin函数的典型用法代码示例。如果您正苦于以下问题:C++ rcMin函数的具体用法?C++ rcMin怎么用?C++ rcMin使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了rcMin函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: rcMax
void Visualization::updateCameraVelocity(float dt, bool forward, bool backward, bool left, bool right, bool fast)
{
float cameraKeySpeed = 22.0f;
if (fast)
{
cameraKeySpeed *= 4.0f;
}
float cameraKeyAcceleration = 100.f;
if (forward) //Forward
{
m_cameraVelocity[2] -= dt * cameraKeyAcceleration;
m_cameraVelocity[2] = rcMax(m_cameraVelocity[2],-cameraKeySpeed);
}
else if (backward) // Backward
{
m_cameraVelocity[2] += dt * cameraKeyAcceleration;
m_cameraVelocity[2] = rcMin(m_cameraVelocity[2],cameraKeySpeed);
}
else if (m_cameraVelocity[2] > 0)
{
m_cameraVelocity[2] -= dt * cameraKeyAcceleration;
m_cameraVelocity[2] = rcMax(m_cameraVelocity[2],0.f);
}
else
{
m_cameraVelocity[2] += dt * cameraKeyAcceleration;
m_cameraVelocity[2] = rcMin(m_cameraVelocity[2],0.f);
}
if (right) // Right
{
m_cameraVelocity[0] += dt * cameraKeyAcceleration;
m_cameraVelocity[0] = rcMin(m_cameraVelocity[0],cameraKeySpeed);
}
else if (left) // Left
{
m_cameraVelocity[0] -= dt * cameraKeyAcceleration;
m_cameraVelocity[0] = rcMax(m_cameraVelocity[0],-cameraKeySpeed);
}
else if (m_cameraVelocity[0] > 0)
{
m_cameraVelocity[0] -= dt * cameraKeyAcceleration;
m_cameraVelocity[0] = rcMax(m_cameraVelocity[0],0.f);
}
else
{
m_cameraVelocity[0] += dt * cameraKeyAcceleration;
m_cameraVelocity[0] = rcMin(m_cameraVelocity[0],0.f);
}
}
示例2: rcMin
void ConvexVolumeTool::handleRender()
{
DebugDrawGL dd;
// Find height extents of the shape.
float minh = FLT_MAX, maxh = 0;
for (int i = 0; i < m_npts; ++i)
minh = rcMin(minh, m_pts[i*3+1]);
minh -= m_boxDescent;
maxh = minh + m_boxHeight;
dd.begin(DU_DRAW_POINTS, 4.0f);
for (int i = 0; i < m_npts; ++i)
{
unsigned int col = duRGBA(255,255,255,255);
if (i == m_npts-1)
col = duRGBA(240,32,16,255);
dd.vertex(m_pts[i*3+0],m_pts[i*3+1]+0.1f,m_pts[i*3+2], col);
}
dd.end();
dd.begin(DU_DRAW_LINES, 2.0f);
for (int i = 0, j = m_nhull-1; i < m_nhull; j = i++)
{
const float* vi = &m_pts[m_hull[j]*3];
const float* vj = &m_pts[m_hull[i]*3];
dd.vertex(vj[0],minh,vj[2], duRGBA(255,255,255,64));
dd.vertex(vi[0],minh,vi[2], duRGBA(255,255,255,64));
dd.vertex(vj[0],maxh,vj[2], duRGBA(255,255,255,64));
dd.vertex(vi[0],maxh,vi[2], duRGBA(255,255,255,64));
dd.vertex(vj[0],minh,vj[2], duRGBA(255,255,255,64));
dd.vertex(vj[0],maxh,vj[2], duRGBA(255,255,255,64));
}
dd.end();
}
示例3: distToPoly
static float distToPoly(int nvert, const float* verts, const float* p)
{
float dmin = FLT_MAX;
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++)
{
const float* vi = &verts[i*3];
const float* vj = &verts[j*3];
if (((vi[2] > p[2]) != (vj[2] > p[2])) &&
(p[0] < (vj[0]-vi[0]) * (p[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) )
c = !c;
dmin = rcMin(dmin, distancePtSeg2d(p, vj, vi));
}
return c ? -dmin : dmin;
}
示例4: distToPoly
static float distToPoly(int nvert, const dtCoordinates* verts, const dtCoordinates& p)
{
float dmin = FLT_MAX;
int i, j, c = 0;
for (i = 0, j = nvert-1; i < nvert; j = i++)
{
const dtCoordinates vi( verts[i] );
const dtCoordinates vj( verts[j] );
if (((vi.Z() > p.Z()) != (vj.Z() > p.Z())) &&
(p.X() < (vj.X()-vi.X()) * (p.Z()-vi.Z()) / (vj.Z()-vi.Z()) + vi.X()) )
c = !c;
dmin = rcMin(dmin, distancePtSeg2d(p, vj, vi));
}
return c ? -dmin : dmin;
}
示例5: fixupCorridor
static int fixupCorridor(dtPolyRef* path, const int npath, const int maxPath,
const dtPolyRef* visited, const int nvisited)
{
int furthestPath = -1;
int furthestVisited = -1;
// Find furthest common polygon.
for (int i = npath-1; i >= 0; --i)
{
bool found = false;
for (int j = nvisited-1; j >= 0; --j)
{
if (path[i] == visited[j])
{
furthestPath = i;
furthestVisited = j;
found = true;
}
}
if (found)
break;
}
// If no intersection found just return current path.
if (furthestPath == -1 || furthestVisited == -1)
return npath;
// Concatenate paths.
// Adjust beginning of the buffer to include the visited.
const int req = nvisited - furthestVisited;
const int orig = rcMin(furthestPath+1, npath);
int size = rcMax(0, npath-orig);
if (req+size > maxPath)
size = maxPath-req;
if (size)
memmove(path+req, path+orig, size*sizeof(dtPolyRef));
// Store visited
for (int i = 0; i < req; ++i)
path[i] = visited[(nvisited-1)-i];
return req+size;
}
示例6: polyMinExtent
// Calculate minimum extend of the polygon.
static float polyMinExtent(const float* verts, const int nverts)
{
float minDist = FLT_MAX;
for (int i = 0; i < nverts; i++)
{
const int ni = (i+1) % nverts;
const float* p1 = &verts[i*3];
const float* p2 = &verts[ni*3];
float maxEdgeDist = 0;
for (int j = 0; j < nverts; j++)
{
if (j == i || j == ni) continue;
float d = distancePtSeg2d(&verts[j*3], p1,p2);
maxEdgeDist = rcMax(maxEdgeDist, d);
}
minDist = rcMin(minDist, maxEdgeDist);
}
return rcSqrt(minDist);
}
示例7: rcCalcGridSize
unsigned char* RecastTileBuilder::build(float x, float y, const AABB& lastTileBounds, int& dataSize) {
int gw = 0, gh = 0;
float bmin[3];
float bmax[3];
bmin[0] = bounds.getXMin();
bmin[1] = bounds.getYMin();
bmin[2] = bounds.getZMin();
bmax[0] = bounds.getXMax();
bmax[1] = bounds.getYMax();
bmax[2] = bounds.getZMax();
rcCalcGridSize(bmin, bmax, settings.m_cellSize, &gw, &gh);
const int ts = (int) settings.m_tileSize;
const int tw = (gw + ts - 1) / ts;
const int th = (gh + ts - 1) / ts;
// Max tiles and max polys affect how the tile IDs are caculated.
// There are 22 bits available for identifying a tile and a polygon.
int tileBits = rcMin((int) ilog2(nextPow2(tw * th)), 14);
int polyBits = 22 - tileBits;
m_maxTiles = 1<<tileBits;
m_maxPolysPerTile = 1<<polyBits;
dtNavMeshParams params;
params.orig[0] = bounds.getXMin();
params.orig[1] = bounds.getYMin();
params.orig[2] = bounds.getZMin();
//rcVcopy(params.orig, m_geom->getNavMeshBoundsMin());
params.tileWidth = settings.m_tileSize * settings.m_cellSize;
params.tileHeight = settings.m_tileSize * settings.m_cellSize;
params.maxTiles = m_maxTiles;
params.maxPolys = m_maxPolysPerTile;
dtStatus status;
this->lastTileBounds = lastTileBounds;
return buildTileMesh(x, y, dataSize);
}
示例8: rcMin
void BuildContext::doLog(const rcLogCategory category, const char* msg, const int len)
{
if (!len) return;
if (m_messageCount >= MAX_MESSAGES)
return;
char* dst = &m_textPool[m_textPoolSize];
int n = TEXT_POOL_SIZE - m_textPoolSize;
if (n < 2)
return;
char* cat = dst;
char* text = dst+1;
const int maxtext = n-1;
// Store category
*cat = (char)category;
// Store message
const int count = rcMin(len+1, maxtext);
memcpy(text, msg, count);
text[count-1] = '\0';
m_textPoolSize += 1 + count;
m_messages[m_messageCount++] = dst;
}
示例9: rcBuildPolyMeshDetail
/// @par
///
/// See the #rcConfig documentation for more information on the configuration parameters.
///
/// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig
bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf,
const float sampleDist, const float sampleMaxError,
rcPolyMeshDetail& dmesh)
{
rcAssert(ctx);
ctx->startTimer(RC_TIMER_BUILD_POLYMESHDETAIL);
if (mesh.nverts == 0 || mesh.npolys == 0)
return true;
const int nvp = mesh.nvp;
const float cs = mesh.cs;
const float ch = mesh.ch;
const float* orig = mesh.bmin;
const int borderSize = mesh.borderSize;
rcIntArray edges(64);
rcIntArray tris(512);
rcIntArray stack(512);
rcIntArray samples(512);
float verts[256*3];
rcHeightPatch hp;
int nPolyVerts = 0;
int maxhw = 0, maxhh = 0;
rcScopedDelete<int> bounds = (int*)rcAlloc(sizeof(int)*mesh.npolys*4, RC_ALLOC_TEMP);
if (!bounds)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4);
return false;
}
rcScopedDelete<float> poly = (float*)rcAlloc(sizeof(float)*nvp*3, RC_ALLOC_TEMP);
if (!poly)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'poly' (%d).", nvp*3);
return false;
}
// Find max size for a polygon area.
for (int i = 0; i < mesh.npolys; ++i)
{
const unsigned short* p = &mesh.polys[i*nvp*2];
int& xmin = bounds[i*4+0];
int& xmax = bounds[i*4+1];
int& ymin = bounds[i*4+2];
int& ymax = bounds[i*4+3];
xmin = chf.width;
xmax = 0;
ymin = chf.height;
ymax = 0;
for (int j = 0; j < nvp; ++j)
{
if(p[j] == RC_MESH_NULL_IDX) break;
const unsigned short* v = &mesh.verts[p[j]*3];
xmin = rcMin(xmin, (int)v[0]);
xmax = rcMax(xmax, (int)v[0]);
ymin = rcMin(ymin, (int)v[2]);
ymax = rcMax(ymax, (int)v[2]);
nPolyVerts++;
}
xmin = rcMax(0,xmin-1);
xmax = rcMin(chf.width,xmax+1);
ymin = rcMax(0,ymin-1);
ymax = rcMin(chf.height,ymax+1);
if (xmin >= xmax || ymin >= ymax) continue;
maxhw = rcMax(maxhw, xmax-xmin);
maxhh = rcMax(maxhh, ymax-ymin);
}
hp.data = (unsigned short*)rcAlloc(sizeof(unsigned short)*maxhw*maxhh, RC_ALLOC_TEMP);
if (!hp.data)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh);
return false;
}
dmesh.nmeshes = mesh.npolys;
dmesh.nverts = 0;
dmesh.ntris = 0;
dmesh.meshes = (unsigned int*)rcAlloc(sizeof(unsigned int)*dmesh.nmeshes*4, RC_ALLOC_PERM);
if (!dmesh.meshes)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4);
return false;
}
int vcap = nPolyVerts+nPolyVerts/2;
int tcap = vcap*2;
dmesh.nverts = 0;
dmesh.verts = (float*)rcAlloc(sizeof(float)*vcap*3, RC_ALLOC_PERM);
if (!dmesh.verts)
{
ctx->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3);
//.........这里部分代码省略.........
示例10: rcBuildRegions
/// @par
///
/// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour.
/// Contours will form simple polygons.
///
/// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be
/// re-assigned to the zero (null) region.
///
/// Watershed partitioning can result in smaller than necessary regions, especially in diagonal corridors.
/// @p mergeRegionArea helps reduce unecessarily small regions.
///
/// See the #rcConfig documentation for more information on the configuration parameters.
///
/// The region data will be available via the rcCompactHeightfield::maxRegions
/// and rcCompactSpan::reg fields.
///
/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions.
///
/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig
bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int minRegionArea, const int mergeRegionArea)
{
rcAssert(ctx);
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
const int w = chf.width;
const int h = chf.height;
rcScopedDelete<unsigned short> buf = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*4, RC_ALLOC_TEMP);
if (!buf)
{
ctx->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4);
return false;
}
ctx->startTimer(RC_TIMER_BUILD_REGIONS_WATERSHED);
const int LOG_NB_STACKS = 3;
const int NB_STACKS = 1 << LOG_NB_STACKS;
rcIntArray lvlStacks[NB_STACKS];
for (int i=0; i<NB_STACKS; ++i)
lvlStacks[i].resize(1024);
rcIntArray stack(1024);
rcIntArray visited(1024);
unsigned short* srcReg = buf;
unsigned short* srcDist = buf+chf.spanCount;
unsigned short* dstReg = buf+chf.spanCount*2;
unsigned short* dstDist = buf+chf.spanCount*3;
memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount);
memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount);
unsigned short regionId = 1;
unsigned short level = (chf.maxDistance+1) & ~1;
// TODO: Figure better formula, expandIters defines how much the
// watershed "overflows" and simplifies the regions. Tying it to
// agent radius was usually good indication how greedy it could be.
// const int expandIters = 4 + walkableRadius * 2;
const int expandIters = 8;
if (borderSize > 0)
{
// Make sure border will not overflow.
const int bw = rcMin(w, borderSize);
const int bh = rcMin(h, borderSize);
// Paint regions
paintRectRegion(0, bw, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(w-bw, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(0, w, 0, bh, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(0, w, h-bh, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
chf.borderSize = borderSize;
}
int sId = -1;
while (level > 0)
{
level = level >= 2 ? level-2 : 0;
sId = (sId+1) & (NB_STACKS-1);
// ctx->startTimer(RC_TIMER_DIVIDE_TO_LEVELS);
if (sId == 0)
sortCellsByLevel(level, chf, srcReg, NB_STACKS, lvlStacks, 1);
else
appendStacks(lvlStacks[sId-1], lvlStacks[sId], srcReg); // copy left overs from last level
// ctx->stopTimer(RC_TIMER_DIVIDE_TO_LEVELS);
ctx->startTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
// Expand current regions until no empty connected cells found.
if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, lvlStacks[sId], false) != srcReg)
{
rcSwap(srcReg, dstReg);
rcSwap(srcDist, dstDist);
//.........这里部分代码省略.........
示例11: imguiLabel
void Sample_TileMesh::handleSettings()
{
Sample::handleCommonSettings();
if (imguiCheck("Keep Itermediate Results", m_keepInterResults))
m_keepInterResults = !m_keepInterResults;
if (imguiCheck("Build All Tiles", m_buildAll))
m_buildAll = !m_buildAll;
imguiLabel("Tiling");
imguiSlider("TileSize", &m_tileSize, 16.0f, 1024.0f, 16.0f);
if (m_geom)
{
char text[64];
int gw = 0, gh = 0;
const float* bmin = m_geom->getNavMeshBoundsMin();
const float* bmax = m_geom->getNavMeshBoundsMax();
rcCalcGridSize(bmin, bmax, m_cellSize, &gw, &gh);
const int ts = (int)m_tileSize;
const int tw = (gw + ts-1) / ts;
const int th = (gh + ts-1) / ts;
snprintf(text, 64, "Tiles %d x %d", tw, th);
imguiValue(text);
// Max tiles and max polys affect how the tile IDs are caculated.
// There are 22 bits available for identifying a tile and a polygon.
int tileBits = rcMin((int)ilog2(nextPow2(tw*th)), 14);
if (tileBits > 14) tileBits = 14;
int polyBits = 22 - tileBits;
m_maxTiles = 1 << tileBits;
m_maxPolysPerTile = 1 << polyBits;
snprintf(text, 64, "Max Tiles %d", m_maxTiles);
imguiValue(text);
snprintf(text, 64, "Max Polys %d", m_maxPolysPerTile);
imguiValue(text);
}
else
{
m_maxTiles = 0;
m_maxPolysPerTile = 0;
}
imguiSeparator();
imguiIndent();
imguiIndent();
if (imguiButton("Save"))
{
Sample::saveAll("all_tiles_navmesh.bin", m_navMesh);
}
if (imguiButton("Load"))
{
dtFreeNavMesh(m_navMesh);
m_navMesh = Sample::loadAll("all_tiles_navmesh.bin");
m_navQuery->init(m_navMesh, 2048);
}
imguiUnindent();
imguiUnindent();
char msg[64];
snprintf(msg, 64, "Build Time: %.1fms", m_totalBuildTimeMs);
imguiLabel(msg);
imguiSeparator();
imguiSeparator();
}
示例12: rcBuildRegions
/// @par
///
/// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour.
/// Contours will form simple polygons.
///
/// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be
/// re-assigned to the zero (null) region.
///
/// Watershed partitioning can result in smaller than necessary regions, especially in diagonal corridors.
/// @p mergeRegionArea helps reduce unecessarily small regions.
///
/// See the #rcConfig documentation for more information on the configuration parameters.
///
/// The region data will be available via the rcCompactHeightfield::maxRegions
/// and rcCompactSpan::reg fields.
///
/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions.
///
/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig
bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int minRegionArea, const int mergeRegionArea)
{
rcAssert(ctx);
ctx->startTimer(RC_TIMER_BUILD_REGIONS);
const int w = chf.width;
const int h = chf.height;
rcScopedDelete<unsigned short> buf = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*4, RC_ALLOC_TEMP);
if (!buf)
{
ctx->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4);
return false;
}
ctx->startTimer(RC_TIMER_BUILD_REGIONS_WATERSHED);
rcIntArray stack(1024);
rcIntArray visited(1024);
unsigned short* srcReg = buf;
unsigned short* srcDist = buf+chf.spanCount;
unsigned short* dstReg = buf+chf.spanCount*2;
unsigned short* dstDist = buf+chf.spanCount*3;
memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount);
memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount);
unsigned short regionId = 1;
unsigned short level = (chf.maxDistance+1) & ~1;
// TODO: Figure better formula, expandIters defines how much the
// watershed "overflows" and simplifies the regions. Tying it to
// agent radius was usually good indication how greedy it could be.
// const int expandIters = 4 + walkableRadius * 2;
const int expandIters = 8;
if (borderSize > 0)
{
// Make sure border will not overflow.
const int bw = rcMin(w, borderSize);
const int bh = rcMin(h, borderSize);
// Paint regions
paintRectRegion(0, bw, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(w-bw, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(0, w, 0, bh, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(0, w, h-bh, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
chf.borderSize = borderSize;
}
while (level > 0)
{
level = level >= 2 ? level-2 : 0;
ctx->startTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
// Expand current regions until no empty connected cells found.
if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, stack) != srcReg)
{
rcSwap(srcReg, dstReg);
rcSwap(srcDist, dstDist);
}
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_EXPAND);
ctx->startTimer(RC_TIMER_BUILD_REGIONS_FLOOD);
// Mark new regions with IDs.
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
const rcCompactCell& c = chf.cells[x+y*w];
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
{
if (chf.dist[i] < level || srcReg[i] != 0 || chf.areas[i] == RC_NULL_AREA)
continue;
if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack))
//.........这里部分代码省略.........
示例13: rcFilterLedgeSpans
void rcFilterLedgeSpans(const int walkableHeight,
const int walkableClimb,
rcHeightfield& solid)
{
rcTimeVal startTime = rcGetPerformanceTimer();
const int w = solid.width;
const int h = solid.height;
const int MAX_HEIGHT = 0xffff;
// Mark border spans.
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next)
{
// Skip non walkable spans.
if ((s->flags & RC_WALKABLE) == 0)
continue;
const int bot = (int)(s->smax);
const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT;
// Find neighbours minimum height.
int minh = MAX_HEIGHT;
// Min and max height of accessible neighbours.
int asmin = s->smax;
int asmax = s->smax;
for (int dir = 0; dir < 4; ++dir)
{
int dx = x + rcGetDirOffsetX(dir);
int dy = y + rcGetDirOffsetY(dir);
// Skip neighbours which are out of bounds.
if (dx < 0 || dy < 0 || dx >= w || dy >= h)
{
minh = rcMin(minh, -walkableClimb - bot);
continue;
}
// From minus infinity to the first span.
rcSpan* ns = solid.spans[dx + dy*w];
int nbot = -walkableClimb;
int ntop = ns ? (int)ns->smin : MAX_HEIGHT;
// Skip neightbour if the gap between the spans is too small.
if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight)
minh = rcMin(minh, nbot - bot);
// Rest of the spans.
for (ns = solid.spans[dx + dy*w]; ns; ns = ns->next)
{
nbot = (int)ns->smax;
ntop = ns->next ? (int)ns->next->smin : MAX_HEIGHT;
// Skip neightbour if the gap between the spans is too small.
if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight)
{
minh = rcMin(minh, nbot - bot);
// Find min/max accessible neighbour height.
if (rcAbs(nbot - bot) <= walkableClimb)
{
if (nbot < asmin) asmin = nbot;
if (nbot > asmax) asmax = nbot;
}
}
}
}
// The current span is close to a ledge if the drop to any
// neighbour span is less than the walkableClimb.
if (minh < -walkableClimb)
s->flags |= RC_LEDGE;
// If the difference between all neighbours is too large,
// we are at steep slope, mark the span as ledge.
if ((asmax - asmin) > walkableClimb)
{
s->flags |= RC_LEDGE;
}
}
}
}
rcTimeVal endTime = rcGetPerformanceTimer();
// if (rcGetLog())
// rcGetLog()->log(RC_LOG_PROGRESS, "Filter border: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
if (rcGetBuildTimes())
rcGetBuildTimes()->filterBorder += rcGetDeltaTimeUsec(startTime, endTime);
}
示例14: CollectLayerRegionsMonotone
//.........这里部分代码省略.........
for (int i = 0; i < sweepId; ++i)
{
// If the neighbour is set and there is only one continuous connection to it,
// the sweep will be merged with the previous one, else new region is created.
if (sweeps[i].nei != 0xffff && prev[sweeps[i].nei] == sweeps[i].ns)
{
sweeps[i].id = sweeps[i].nei;
}
else
{
sweeps[i].id = regId++;
}
}
// Remap local sweep ids to region ids.
for (int x = borderSize; x < w-borderSize; ++x)
{
const rcCompactCell& c = chf.cells[x+y*w];
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
{
if (srcReg[i] != 0xffff)
srcReg[i] = sweeps[srcReg[i]].id;
}
}
}
// Allocate and init layer regions.
nregs = (int)regId;
regs = (rcLayerRegionMonotone*)rcAlloc(sizeof(rcLayerRegionMonotone)*nregs, RC_ALLOC_TEMP);
if (!regs)
{
ctx->log(RC_LOG_ERROR, "CollectLayerRegionsMonotone: Out of memory 'regs' (%d).", nregs);
return false;
}
memset(regs, 0, sizeof(rcLayerRegionMonotone)*nregs);
for (int i = 0; i < nregs; ++i)
{
regs[i].layerId = 0xffff;
regs[i].ymin = 0xffff;
regs[i].ymax = 0;
}
rcIntArray lregs(64);
// Find region neighbours and overlapping regions.
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
const rcCompactCell& c = chf.cells[x+y*w];
lregs.resize(0);
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
{
const rcCompactSpan& s = chf.spans[i];
const unsigned short ri = srcReg[i];
if (ri == 0xffff) continue;
regs[ri].ymin = rcMin(regs[ri].ymin, s.y);
regs[ri].ymax = rcMax(regs[ri].ymax, s.y);
// Collect all region layers.
lregs.push(ri);
// Update neighbours
for (int dir = 0; dir < 4; ++dir)
{
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
{
const int ax = x + rcGetDirOffsetX(dir);
const int ay = y + rcGetDirOffsetY(dir);
const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
const unsigned short rai = srcReg[ai];
if (rai != 0xffff && rai != ri)
addUnique(regs[ri].neis, rai);
}
}
}
// Update overlapping regions.
const int nlregs = lregs.size();
for (int i = 0; i < nlregs-1; ++i)
{
for (int j = i+1; j < nlregs; ++j)
{
if (lregs[i] != lregs[j])
{
rcLayerRegionMonotone& ri = regs[lregs[i]];
rcLayerRegionMonotone& rj = regs[lregs[j]];
addUnique(ri.layers, lregs[j]);
addUnique(rj.layers, lregs[i]);
}
}
}
}
}
return true;
}
示例15: SplitAndStoreLayerRegions
static bool SplitAndStoreLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int walkableHeight,
unsigned short* srcReg, rcLayerRegionMonotone* regs, const int nregs,
rcHeightfieldLayerSet& lset)
{
// Create 2D layers from regions.
unsigned short layerId = 0;
rcIntArray stack(64);
stack.resize(0);
for (int i = 0; i < nregs; ++i)
{
rcLayerRegionMonotone& root = regs[i];
// Skip already visited.
if (root.layerId != 0xffff)
continue;
// Start search.
root.layerId = layerId;
root.base = 1;
stack.push(i);
while (stack.size())
{
// Pop front
rcLayerRegionMonotone& reg = regs[stack[0]];
for (int j = 1; j < stack.size(); ++j)
stack[j - 1] = stack[j];
stack.pop();
const int nneis = (int)reg.neis.size();
for (int j = 0; j < nneis; ++j)
{
const int nei = reg.neis[j];
rcLayerRegionMonotone& regn = regs[nei];
// Skip already visited.
if (regn.layerId != 0xffff)
continue;
// Skip if the neighbour is overlapping root region.
if (root.layers.contains(nei))
continue;
// Skip if the height range would become too large.
const int ymin = rcMin(root.ymin, regn.ymin);
const int ymax = rcMin(root.ymax, regn.ymax);
if ((ymax - ymin) >= 255)
continue;
// Deepen
stack.push(nei);
// Mark layer id
regn.layerId = layerId;
// Merge current layers to root.
for (int k = 0; k < regn.layers.size(); ++k)
addUnique(root.layers, regn.layers[k]);
root.ymin = rcMin(root.ymin, regn.ymin);
root.ymax = rcMax(root.ymax, regn.ymax);
}
}
layerId++;
}
// Merge non-overlapping regions that are close in height.
const unsigned short mergeHeight = (unsigned short)walkableHeight * 4;
for (int i = 0; i < nregs; ++i)
{
rcLayerRegionMonotone& ri = regs[i];
if (!ri.base) continue;
unsigned short newId = ri.layerId;
for (;;)
{
unsigned short oldId = 0xffff;
for (int j = 0; j < nregs; ++j)
{
if (i == j) continue;
rcLayerRegionMonotone& rj = regs[j];
if (!rj.base) continue;
// Skip if the regions are not close to each other.
if (!overlapRange(ri.ymin,ri.ymax+mergeHeight, rj.ymin,rj.ymax+mergeHeight))
continue;
// Skip if the height range would become too large.
const int ymin = rcMin(ri.ymin, rj.ymin);
const int ymax = rcMin(ri.ymax, rj.ymax);
if ((ymax - ymin) >= 255)
continue;
// Make sure that there is no overlap when mergin 'ri' and 'rj'.
bool overlap = false;
// Iterate over all regions which have the same layerId as 'rj'
for (int k = 0; k < nregs; ++k)
{
if (regs[k].layerId != rj.layerId)
continue;
//.........这里部分代码省略.........