本文整理汇总了C++中rcSqr函数的典型用法代码示例。如果您正苦于以下问题:C++ rcSqr函数的具体用法?C++ rcSqr怎么用?C++ rcSqr使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了rcSqr函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: sqrtf
bool Visualization::initializeCamera()
{
if (m_scene)
{
const float* max = m_scene->getMeshBoundsMax();
const float* min = m_scene->getMeshBoundsMin();
m_zFar = sqrtf(rcSqr(max[0]-min[0]) + rcSqr(max[1]-min[1]) + rcSqr(max[2]-min[2]));
m_cameraPosition[0] = (max[0] + min[0]) / 2.f;
m_cameraPosition[1] = (max[1] + min[1]) / 2.f + m_zFar;
m_cameraPosition[2] = (max[2] + min[2]) / 2.f;
m_zFar *= 2.f;
m_cameraOrientation[0] = 90.f;
m_cameraOrientation[1] = 0.f;
m_cameraOrientation[2] = 0.f;
}
else
{
m_cameraPosition[0] = m_cameraPosition[1] = m_cameraPosition[2] = 0.f;
m_cameraOrientation[0] = 45.f;
m_cameraOrientation[1] = -45.f;
m_cameraOrientation[2] = 0.f;
}
m_cameraVelocity[0] = m_cameraVelocity[1] = m_cameraVelocity[2] = 0.f;
return true;
}
示例2: if
void RecastToolKit::ResetCameraAndFog(const std::unique_ptr<InputGeom>& geom, const std::shared_ptr<Sample>& sample, float & camx, float & camy, float & camz, float & camr, float & rx, float & ry)
{
if (geom || sample)
{
const float* bmin = 0;
const float* bmax = 0;
if (sample)
{
bmin = sample->getBoundsMin();
bmax = sample->getBoundsMax();
}
else if (geom)
{
bmin = geom->getMeshBoundsMin();
bmax = geom->getMeshBoundsMax();
}
// Reset camera and fog to match the mesh bounds.
if (bmin && bmax)
{
camr = sqrtf(rcSqr(bmax[0] - bmin[0]) +
rcSqr(bmax[1] - bmin[1]) +
rcSqr(bmax[2] - bmin[2])) / 2;
camx = (bmax[0] + bmin[0]) / 2 + camr;
camy = (bmax[1] + bmin[1]) / 2 + camr;
camz = (bmax[2] + bmin[2]) / 2 + camr;
camr *= 3;
}
rx = 45;
ry = -45;
glFogf(GL_FOG_START, camr*0.1f);
glFogf(GL_FOG_END, camr*1.25f);
}
}
示例3: World
TileBuilder::TileBuilder(ContinentBuilder* _cBuilder, std::string world, int x, int y, uint32 mapId) :
World(world), X(x), Y(y), MapId(mapId), _Geometry(NULL), DataSize(0), cBuilder(_cBuilder)
{
/*
Test, non-working values
// Cell Size = TileSize / TileVoxelSize
// 1800 = TileVoxelSize
Config.cs = Constants::TileSize / 1800;
// Cell Height
Config.ch = 0.4f;
// Min Region Area = 20^2
Config.minRegionArea = 20*20;
// Merge Region Area = 40^2
Config.mergeRegionArea = 40*40;
Config.tileSize = Constants::TileSize / 4;
Config.walkableSlopeAngle = 50.0f;
Config.detailSampleDist = 3.0f;
Config.detailSampleMaxError = 1.25f;
Config.walkableClimb = floorf(1.0f / Config.ch);
Config.walkableHeight = ceilf(1.652778f / Config.ch);
Config.walkableRadius = ceilf(0.2951389f / Config.cs);
Config.maxEdgeLen = Config.walkableRadius * 8;
Config.borderSize = Config.walkableRadius + 4;
Config.width = 1800 + Config.borderSize * 2;
Config.height = 1800 + Config.borderSize * 2;
Config.maxVertsPerPoly = 6;
Config.maxSimplificationError = 1.3f;
*/
// All are in UNIT metrics!
memset(&Config, 0, sizeof(rcConfig));
Config.maxVertsPerPoly = DT_VERTS_PER_POLYGON;
Config.cs = Constants::BaseUnitDim;
Config.ch = Constants::BaseUnitDim;
Config.walkableSlopeAngle = 60.0f;
Config.tileSize = Constants::VertexPerTile;
Config.walkableRadius = 1;
Config.borderSize = Config.walkableRadius + 3;
Config.maxEdgeLen = Constants::VertexPerTile + 1; //anything bigger than tileSize
Config.walkableHeight = 3;
Config.walkableClimb = 2; // keep less than walkableHeight
Config.minRegionArea = rcSqr(60);
Config.mergeRegionArea = rcSqr(50);
Config.maxSimplificationError = 2.0f; // eliminates most jagged edges (tinny polygons)
Config.detailSampleDist = Config.cs * 64;
Config.detailSampleMaxError = Config.ch * 2;
Context = new rcContext;
}
示例4: m_keepInterResults
RecastTileBuilder::RecastTileBuilder(float waterTableHeight, float x, float y, const AABB& bounds,
const rcChunkyTriMesh* mesh, const RecastSettings& settings) :
m_keepInterResults(false),
m_buildAll(true),
m_totalBuildTimeMs(0),
m_triareas(0),
m_solid(0),
m_chf(0),
m_cset(0),
m_pmesh(0),
m_dmesh(0),
m_maxTiles(0),
m_maxPolysPerTile(0),
bounds(Vector3(0, 0, 0), Vector3(0, 0, 0)),
m_tileTriCount(0),
waterTableHeight(waterTableHeight),
lastTileBounds(bounds) {
this->settings = settings;
// Init build configuration from GUI
memset(&m_cfg, 0, sizeof(m_cfg));
m_cfg.cs = settings.m_cellSize;
m_cfg.ch = settings.m_cellHeight;
m_cfg.walkableSlopeAngle = settings.m_agentMaxSlope;
m_cfg.walkableHeight = (int) ceilf(settings.m_agentHeight / m_cfg.ch);
m_cfg.walkableClimb = (int) floorf(settings.m_agentMaxClimb / m_cfg.ch);
m_cfg.walkableRadius = (int) ceilf(settings.m_agentRadius / m_cfg.cs);
m_cfg.maxEdgeLen = (int) (settings.m_edgeMaxLen / settings.m_cellSize);
m_cfg.maxSimplificationError = settings.m_edgeMaxError;
m_cfg.minRegionArea = (int) rcSqr(settings.m_regionMinSize); // Note: area = size*size
m_cfg.mergeRegionArea = (int) rcSqr(settings.m_regionMergeSize); // Note: area = size*size
m_cfg.maxVertsPerPoly = (int) settings.m_vertsPerPoly;
m_cfg.tileSize = (int) settings.m_tileSize;
m_cfg.borderSize = m_cfg.walkableRadius + 3; // Reserve enough padding.
m_cfg.width = m_cfg.tileSize + m_cfg.borderSize * 2;
m_cfg.height = m_cfg.tileSize + m_cfg.borderSize * 2;
m_cfg.detailSampleDist = settings.m_detailSampleDist < 0.9f ? 0 : settings.m_cellSize * settings.m_detailSampleDist;
m_cfg.detailSampleMaxError = settings.m_cellHeight * settings.m_detailSampleMaxError;
tileX = x;
tileY = y;
m_ctx = new rcContext();
chunkyMesh = mesh;
}
示例5: getEdgeFlags
static unsigned char getEdgeFlags(const float* va, const float* vb,
const float* vpoly, const int npoly)
{
// Return true if edge (va,vb) is part of the polygon.
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;
}
示例6: buildPolyDetail
static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
const float sampleDist, const float sampleMaxError,
const rcCompactHeightfield& chf, const rcHeightPatch& hp,
float* verts, int& nverts, rcIntArray& tris,
rcIntArray& edges, rcIntArray& samples)
{
static const int MAX_VERTS = 127;
static const int MAX_TRIS = 255; // Max tris for delaunay is 2n-2-k (n=num verts, k=num hull verts).
static const int MAX_VERTS_PER_EDGE = 32;
float edge[(MAX_VERTS_PER_EDGE+1)*3];
int hull[MAX_VERTS];
int nhull = 0;
nverts = 0;
for (int i = 0; i < nin; ++i)
rcVcopy(&verts[i*3], &in[i*3]);
nverts = nin;
edges.resize(0);
tris.resize(0);
const float cs = chf.cs;
const float ics = 1.0f/cs;
// Calculate minimum extents of the polygon based on input data.
float minExtent = polyMinExtent(verts, nverts);
// Tessellate outlines.
// This is done in separate pass in order to ensure
// seamless height values across the ply boundaries.
if (sampleDist > 0)
{
for (int i = 0, j = nin-1; i < nin; j=i++)
{
const float* vj = &in[j*3];
const float* vi = &in[i*3];
bool swapped = false;
// Make sure the segments are always handled in same order
// using lexological sort or else there will be seams.
if (fabsf(vj[0]-vi[0]) < 1e-6f)
{
if (vj[2] > vi[2])
{
rcSwap(vj,vi);
swapped = true;
}
}
else
{
if (vj[0] > vi[0])
{
rcSwap(vj,vi);
swapped = true;
}
}
// Create samples along the edge.
float dx = vi[0] - vj[0];
float dy = vi[1] - vj[1];
float dz = vi[2] - vj[2];
float d = sqrtf(dx*dx + dz*dz);
int nn = 1 + (int)floorf(d/sampleDist);
if (nn >= MAX_VERTS_PER_EDGE) nn = MAX_VERTS_PER_EDGE-1;
if (nverts+nn >= MAX_VERTS)
nn = MAX_VERTS-1-nverts;
for (int k = 0; k <= nn; ++k)
{
float u = (float)k/(float)nn;
float* pos = &edge[k*3];
pos[0] = vj[0] + dx*u;
pos[1] = vj[1] + dy*u;
pos[2] = vj[2] + dz*u;
pos[1] = getHeight(pos[0],pos[1],pos[2], cs, ics, chf.ch, hp)*chf.ch;
}
// Simplify samples.
int idx[MAX_VERTS_PER_EDGE] = {0,nn};
int nidx = 2;
for (int k = 0; k < nidx-1; )
{
const int a = idx[k];
const int b = idx[k+1];
const float* va = &edge[a*3];
const float* vb = &edge[b*3];
// Find maximum deviation along the segment.
float maxd = 0;
int maxi = -1;
for (int m = a+1; m < b; ++m)
{
float dev = distancePtSeg(&edge[m*3],va,vb);
if (dev > maxd)
{
maxd = dev;
maxi = m;
}
}
// If the max deviation is larger than accepted error,
// add new point, else continue to next segment.
if (maxi != -1 && maxd > rcSqr(sampleMaxError))
{
//.........这里部分代码省略.........
示例7: handleClick
void ConvexVolumeTool::handleClick(const float* /*s*/, const float* p, bool shift)
{
if (!m_sample) return;
InputGeom* geom = m_sample->getInputGeom();
if (!geom) return;
if (shift)
{
// Delete
int nearestIndex = -1;
const ConvexVolume* vols = geom->getConvexVolumes();
for (int i = 0; i < geom->getConvexVolumeCount(); ++i)
{
if (pointInPoly(vols[i].nverts, vols[i].verts, p) &&
p[1] >= vols[i].hmin && p[1] <= vols[i].hmax)
{
nearestIndex = i;
}
}
// If end point close enough, delete it.
if (nearestIndex != -1)
{
geom->deleteConvexVolume(nearestIndex);
}
}
else
{
// Create
// If clicked on that last pt, create the shape.
if (m_npts && rcVdistSqr(p, &m_pts[(m_npts-1)*3]) < rcSqr(0.2f))
{
if (m_nhull > 2)
{
// Create shape.
float verts[MAX_PTS*3];
for (int i = 0; i < m_nhull; ++i)
rcVcopy(&verts[i*3], &m_pts[m_hull[i]*3]);
float minh = FLT_MAX, maxh = 0;
for (int i = 0; i < m_nhull; ++i)
minh = rcMin(minh, verts[i*3+1]);
minh -= m_boxDescent;
maxh = minh + m_boxHeight;
geom->addConvexVolume(verts, m_nhull, minh, maxh, (unsigned char)m_areaType);
}
m_npts = 0;
m_nhull = 0;
}
else
{
// Add new point
if (m_npts < MAX_PTS)
{
rcVcopy(&m_pts[m_npts*3], p);
m_npts++;
// Update hull.
if (m_npts > 1)
m_nhull = convexhull(m_pts, m_npts, m_hull);
else
m_nhull = 0;
}
}
}
}
示例8: cleanup
bool Sample_SoloMesh::handleBuild()
{
if (!m_geom || !m_geom->getMesh())
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
return false;
}
cleanup();
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
const float* verts = m_geom->getMesh()->getVerts();
const int nverts = m_geom->getMesh()->getVertCount();
const int* tris = m_geom->getMesh()->getTris();
const int ntris = m_geom->getMesh()->getTriCount();
//
// Step 1. Initialize build config.
//
// Init build configuration from GUI
memset(&m_cfg, 0, sizeof(m_cfg));
m_cfg.cs = m_cellSize;
m_cfg.ch = m_cellHeight;
m_cfg.walkableSlopeAngle = m_agentMaxSlope;
m_cfg.walkableHeight = (int)ceilf(m_agentHeight / m_cfg.ch);
m_cfg.walkableClimb = (int)floorf(m_agentMaxClimb / m_cfg.ch);
m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs);
m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
m_cfg.maxSimplificationError = m_edgeMaxError;
m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist;
m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
// Set the area where the navigation will be build.
// Here the bounds of the input mesh are used, but the
// area could be specified by an user defined box, etc.
rcVcopy(m_cfg.bmin, bmin);
rcVcopy(m_cfg.bmax, bmax);
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
// Reset build times gathering.
m_ctx->resetTimers();
// Start the build process.
m_ctx->startTimer(RC_TIMER_TOTAL);
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
m_ctx->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
//
// Step 2. Rasterize input polygon soup.
//
// Allocate voxel heightfield where we rasterize our input data to.
m_solid = rcAllocHeightfield();
if (!m_solid)
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
return false;
}
if (!rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
return false;
}
// Allocate array that can hold triangle area types.
// If you have multiple meshes you need to process, allocate
// and array which can hold the max number of triangles you need to process.
m_triareas = new unsigned char[ntris];
if (!m_triareas)
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris);
return false;
}
// Find triangles which are walkable based on their slope and rasterize them.
// If your input data is multiple meshes, you can transform them here, calculate
// the are type for each of the meshes and rasterize them.
memset(m_triareas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas);
rcRasterizeTriangles(m_ctx, verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
if (!m_keepInterResults)
{
delete [] m_triareas;
m_triareas = 0;
}
//
// Step 3. Filter walkables surfaces.
//
// Once all geoemtry is rasterized, we do initial pass of filtering to
// remove unwanted overhangs caused by the conservative rasterization
//.........这里部分代码省略.........
示例9: imguiLabel
void CMaNGOS_Map::handleSettings()
{
if (m_MapInfos->IsEmpty())
return;
if (m_SelectedTile)
{
bool tileFound = false;
imguiLabel("Tile commands");
std::string bText;
if (m_MapInfos->GetTileRef(m_SelectedTile->tx, m_SelectedTile->ty))
{
tileFound = true;
bText = "Clear selected tile navmesh";
if (imguiButton(bText.c_str()))
{
setTool(NULL);
m_MapInfos->ClearNavMeshOfTile(m_SelectedTile->tx, m_SelectedTile->ty);
}
}
else
{
bText = "Load selected tile navmesh";
if (imguiButton(bText.c_str()))
{
if (m_MapInfos->LoadNavMeshOfTile(m_SelectedTile->tx, m_SelectedTile->ty))
setTool(new NavMeshTesterTool);
}
bText = "Build navmesh for selected tile";
if (imguiButton(bText.c_str()))
{
rcConfig cfg;
cfg.cs = m_cellSize;
cfg.ch = m_cellHeight;
cfg.walkableSlopeAngle = m_agentMaxSlope;
cfg.walkableHeight = (int)ceilf(m_agentHeight);// (int)ceilf(m_agentHeight / m_cfg.ch);
cfg.walkableClimb = (int)floorf(m_agentMaxClimb);// (int)floorf(m_agentMaxClimb / m_cfg.ch);
cfg.walkableRadius = (int)ceilf(m_agentRadius);// (int)ceilf(m_agentRadius / m_cfg.cs);
cfg.maxEdgeLen = (int)m_edgeMaxLen;// (int)(m_edgeMaxLen / m_cellSize);
cfg.maxSimplificationError = m_edgeMaxError;
cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
cfg.tileSize = (int)m_tileSize;
cfg.borderSize = cfg.walkableRadius + 3; // Reserve enough padding.
cfg.detailSampleDist = m_cellSize * m_detailSampleDist;
cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
m_MapInfos->BuildNavMeshOfTile(m_SelectedTile->tx, m_SelectedTile->ty, &cfg, m_partitionType);
setTool(new NavMeshTesterTool);
}
}
if (tileFound)
return;
char tmpStr[50];
imguiLabel("Rasterization");
snprintf(tmpStr, sizeof(tmpStr), "Cell Size = %4.3f", m_cellSize);
imguiValue(tmpStr);
snprintf(tmpStr, sizeof(tmpStr), "Cell Height = %4.3f", m_cellHeight);
imguiValue(tmpStr);
if (!m_MapInfos->GetGeomsMap()->empty())
{
int gw = 0, gh = 0;
rcCalcGridSize(m_MapInfos->BMin(), m_MapInfos->BMax(), m_cellSize, &gw, &gh);
char text[64];
snprintf(text, 64, "Voxels %d x %d", gw, gh);
imguiValue(text);
}
imguiSeparator();
imguiLabel("Agent");
imguiSlider("Height", &m_agentHeight, 0.1f, 5.0f, 0.1f);
imguiSlider("Radius", &m_agentRadius, 0.0f, 5.0f, 0.1f);
imguiSlider("Max Climb", &m_agentMaxClimb, 0.1f, 5.0f, 0.1f);
imguiSlider("Max Slope", &m_agentMaxSlope, 0.0f, 90.0f, 1.0f);
imguiSeparator();
imguiLabel("Region");
imguiSlider("Min Region Size", &m_regionMinSize, 0.0f, 150.0f, 1.0f);
imguiSlider("Merged Region Size", &m_regionMergeSize, 0.0f, 150.0f, 1.0f);
imguiSeparator();
imguiLabel("Partitioning");
if (imguiCheck("Watershed", m_partitionType == SAMPLE_PARTITION_WATERSHED))
m_partitionType = SAMPLE_PARTITION_WATERSHED;
if (imguiCheck("Monotone", m_partitionType == SAMPLE_PARTITION_MONOTONE))
m_partitionType = SAMPLE_PARTITION_MONOTONE;
if (imguiCheck("Layers", m_partitionType == SAMPLE_PARTITION_LAYERS))
m_partitionType = SAMPLE_PARTITION_LAYERS;
imguiSeparator();
imguiLabel("Polygonization");
imguiSlider("Max Edge Length", &m_edgeMaxLen, 0.0f, 100.0f, 1.0f);
imguiSlider("Max Edge Error", &m_edgeMaxError, 0.1f, 3.0f, 0.1f);
imguiSlider("Verts Per Poly", &m_vertsPerPoly, 3.0f, 12.0f, 1.0f);
imguiSeparator();
//.........这里部分代码省略.........
示例10: rcCalcGridSize
bool NavMesh::BuildMesh()
{
dtStatus status;
if (!m_geom || !m_geom->getMesh()) return false;
m_tmproc->init(m_geom);
// Init cache
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
int gw = 0, gh = 0;
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;
// Generation params.
rcConfig cfg;
memset(&cfg, 0, sizeof(cfg));
cfg.cs = m_cellSize;
cfg.ch = m_cellHeight;
cfg.walkableSlopeAngle = m_agentMaxSlope;
cfg.walkableHeight = (int)ceilf(m_agentHeight / cfg.ch);
cfg.walkableClimb = (int)floorf(m_agentMaxClimb / cfg.ch);
cfg.walkableRadius = (int)ceilf(m_agentRadius / cfg.cs);
cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
cfg.maxSimplificationError = m_edgeMaxError;
cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
cfg.tileSize = (int)m_tileSize;
cfg.borderSize = cfg.walkableRadius + 3; // Reserve enough padding.
cfg.width = cfg.tileSize + cfg.borderSize*2;
cfg.height = cfg.tileSize + cfg.borderSize*2;
cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist;
cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
rcVcopy(cfg.bmin, bmin);
rcVcopy(cfg.bmax, bmax);
// Tile cache params.
dtTileCacheParams tcparams;
memset(&tcparams, 0, sizeof(tcparams));
rcVcopy(tcparams.orig, bmin);
tcparams.cs = m_cellSize;
tcparams.ch = m_cellHeight;
tcparams.width = (int)m_tileSize;
tcparams.height = (int)m_tileSize;
tcparams.walkableHeight = m_agentHeight;
tcparams.walkableRadius = m_agentRadius;
tcparams.walkableClimb = m_agentMaxClimb;
tcparams.maxSimplificationError = m_edgeMaxError;
tcparams.maxTiles = tw*th*EXPECTED_LAYERS_PER_TILE;
tcparams.maxObstacles = 128;
dtFreeTileCache(m_tileCache);
m_tileCache = dtAllocTileCache();
if (!m_tileCache) return false;
status = m_tileCache->init(&tcparams, m_talloc, m_tcomp, m_tmproc);
if (dtStatusFailed(status)) return false;
dtFreeNavMesh(m_navMesh);
m_navMesh = dtAllocNavMesh();
if (!m_navMesh) return false;
dtNavMeshParams params;
memset(¶ms, 0, sizeof(params));
rcVcopy(params.orig, m_geom->getMeshBoundsMin());
params.tileWidth = m_tileSize*m_cellSize;
params.tileHeight = m_tileSize*m_cellSize;
params.maxTiles = m_maxTiles;
params.maxPolys = m_maxPolysPerTile;
status = m_navMesh->init(¶ms);
if (dtStatusFailed(status)) return false;
status = m_navQuery->init(m_navMesh, 2048);
if (dtStatusFailed(status)) return false;
for (int y = 0; y < th; ++y)
{
for (int x = 0; x < tw; ++x)
{
TileCacheData tiles[MAX_LAYERS];
memset(tiles, 0, sizeof(tiles));
int n = rasterizeTileLayers(m_geom, x, y, cfg, tiles, MAX_LAYERS);
for (int i = 0; i < n; ++i)
{
TileCacheData* tile = &tiles[i];
status = m_tileCache->addTile(tile->data, tile->dataSize, DT_COMPRESSEDTILE_FREE_DATA, 0);
if (dtStatusFailed(status))
{
dtFree(tile->data);
tile->data = 0;
continue;
}
}
}
}
for (int y = 0; y < th; ++y)
for (int x = 0; x < tw; ++x)
m_tileCache->buildNavMeshTilesAt(x,y, m_navMesh);
}
示例11: cleanup
bool NavMesher::Build()
{
// ******* Only for OBJ Loading ****
cleanup();
const char * filepath = "../../media/models/";
if (!m_geom || !m_geom->loadMesh(filepath))
{
delete m_geom;
m_geom = 0;
m_ctx->log(RC_LOG_ERROR, "Geom load log %s:");
}
assert(m_geom);
if (!m_geom || !m_geom->getMesh())
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
return false;
}
if(m_geom->getMesh()->getTriCount() <= 0 || m_geom->getMesh()->getVertCount()<=0)
Ogre::Exception(0,Ogre::String("Bad verts or Triangle count. Verts: "+
StringConverter::toString( m_geom->getMesh()->getVertCount()) + "/n"
+ "Triangles :" +StringConverter::toString(m_geom->getMesh()->getTriCount())),"NavMesher::Build");
//reset timer
Ogre::Timer tm;
tm.reset();
unsigned long stime = tm.getMicroseconds();
//clear existing
Clear();
// ******* Only for OBJ Loading ****
const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax();
const float* verts = m_geom->getMesh()->getVerts();
const int nverts = m_geom->getMesh()->getVertCount();
const int *tris = m_geom->getMesh()->getTris();
const int ntris = m_geom->getMesh()->getTriCount();
if(sizeof(tris) <= 0 || ntris <= 0) {
return false;
}
//
// Step 1. Initialize build config.
//
// Init build configuration from GUI
memset(&m_cfg, 0, sizeof(m_cfg));
m_cfg.cs = m_cellSize;
m_cfg.ch = m_cellHeight;
m_cfg.walkableSlopeAngle = m_agentMaxSlope;
m_cfg.walkableHeight = (int)ceilf(m_agentHeight / m_cfg.ch);
m_cfg.walkableClimb = (int)floorf(m_agentMaxClimb / m_cfg.ch);
m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs);
m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
m_cfg.maxSimplificationError = m_edgeMaxError;
m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist;
m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
// Set the area where the navigation will be build.
// Here the bounds of the input mesh are used, but the
// area could be specified by an user defined box, etc.
rcVcopy(m_cfg.bmin, bmin);
rcVcopy(m_cfg.bmax, bmax);
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
// Reset build times gathering.
m_ctx->resetTimers();
// Start the build process.
m_ctx->startTimer(RC_TIMER_TOTAL);
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
m_ctx->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
//
// Step 2. Rasterize input polygon soup.
//
// Allocate voxel heightfield where we rasterize our input data to.
m_solid = rcAllocHeightfield();
if (!m_solid)
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
return false;
}
if (!rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
return false;
}
// Allocate array that can hold triangle area types.
// If you have multiple meshes you need to process, allocate
// and array which can hold the max number of triangles you need to process.
m_triareas = new unsigned char[ntris];
if (!m_triareas)
{
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris);
return false;
//.........这里部分代码省略.........
示例12: NAVIGATION_build
/*!
Build a NAVIGATION mesh from an OBJ mesh index. Usually this OBJMESH is either a collision map
or a mesh that have been built especially for navigation.
\param[in,out] navigation A valid NAVIGATION structure pointer.
\param[in] obj A valid OBJ structure pointer.
\param[in] mesh_index The mesh index of the OBJMESH to use to create the NAVIGATION mesh.
\return Return 1 if the NAVIGATION mesh have been generated successfully, else this function will return 0.
*/
unsigned char NAVIGATION_build( NAVIGATION *navigation, OBJ *obj, unsigned int mesh_index )
{
unsigned int i = 0,
j = 0,
k = 0,
triangle_count = 0;
int *indices = NULL;
OBJMESH *objmesh = &obj->objmesh[ mesh_index ];
vec3 *vertex_array = ( vec3 * ) malloc( objmesh->n_objvertexdata * sizeof( vec3 ) ),
*vertex_start = vertex_array;
rcHeightfield *rcheightfield;
rcCompactHeightfield *rccompactheightfield;
rcContourSet *rccontourset;
rcPolyMesh *rcpolymesh;
rcPolyMeshDetail *rcpolymeshdetail;
while( i != objmesh->n_objvertexdata )
{
memcpy( vertex_array,
&obj->indexed_vertex[ objmesh->objvertexdata[ i ].vertex_index ],
sizeof( vec3 ) );
vec3_to_recast( vertex_array );
++vertex_array;
++i;
}
i = 0;
while( i != objmesh->n_objtrianglelist )
{
triangle_count += objmesh->objtrianglelist[ i ].n_indice_array;
indices = ( int * ) realloc( indices, triangle_count * sizeof( int ) );
j = 0;
while( j != objmesh->objtrianglelist[ i ].n_indice_array )
{
indices[ k ] = objmesh->objtrianglelist[ i ].indice_array[ j ];
++k;
++j;
}
++i;
}
triangle_count /= 3;
rcConfig rcconfig;
memset( &rcconfig, 0, sizeof( rcConfig ) );
rcconfig.cs = navigation->navigationconfiguration.cell_size;
rcconfig.ch = navigation->navigationconfiguration.cell_height;
rcconfig.walkableHeight = ( int )ceilf ( navigation->navigationconfiguration.agent_height / rcconfig.ch );
rcconfig.walkableRadius = ( int )ceilf ( navigation->navigationconfiguration.agent_radius / rcconfig.cs );
rcconfig.walkableClimb = ( int )floorf( navigation->navigationconfiguration.agent_max_climb / rcconfig.ch );
rcconfig.walkableSlopeAngle = navigation->navigationconfiguration.agent_max_slope;
rcconfig.minRegionSize = ( int )rcSqr( navigation->navigationconfiguration.region_min_size );
rcconfig.mergeRegionSize = ( int )rcSqr( navigation->navigationconfiguration.region_merge_size );
rcconfig.maxEdgeLen = ( int )( navigation->navigationconfiguration.edge_max_len / rcconfig.cs );
rcconfig.maxSimplificationError = navigation->navigationconfiguration.edge_max_error;
rcconfig.maxVertsPerPoly = ( int )navigation->navigationconfiguration.vert_per_poly;
rcconfig.detailSampleDist = rcconfig.cs * navigation->navigationconfiguration.detail_sample_dst;
rcconfig.detailSampleMaxError = rcconfig.ch * navigation->navigationconfiguration.detail_sample_max_error;
rcCalcBounds( ( float * )vertex_start,
objmesh->n_objvertexdata,
rcconfig.bmin,
rcconfig.bmax );
rcCalcGridSize( rcconfig.bmin,
rcconfig.bmax,
rcconfig.cs,
&rcconfig.width,
&rcconfig.height );
//.........这里部分代码省略.........
示例13: buildPolyDetail
static bool buildPolyDetail(const float* in, const int nin, unsigned short reg,
const float sampleDist, const float sampleMaxError,
const rcCompactHeightfield& chf, const rcHeightPatch& hp,
float* verts, int& nverts, rcIntArray& tris,
rcIntArray& edges, rcIntArray& idx, rcIntArray& samples)
{
static const int MAX_VERTS = 256;
static const int MAX_EDGE = 64;
float edge[(MAX_EDGE+1)*3];
nverts = 0;
for (int i = 0; i < nin; ++i)
vcopy(&verts[i*3], &in[i*3]);
nverts = nin;
const float ics = 1.0f/chf.cs;
// Tesselate outlines.
// This is done in separate pass in order to ensure
// seamless height values across the ply boundaries.
if (sampleDist > 0)
{
for (int i = 0, j = nin-1; i < nin; j=i++)
{
const float* vj = &in[j*3];
const float* vi = &in[i*3];
// Make sure the segments are always handled in same order
// using lexological sort or else there will be seams.
if (fabsf(vj[0]-vi[0]) < 1e-6f)
{
if (vj[2] > vi[2])
rcSwap(vj,vi);
}
else
{
if (vj[0] > vi[0])
rcSwap(vj,vi);
}
// Create samples along the edge.
float dx = vi[0] - vj[0];
float dy = vi[1] - vj[1];
float dz = vi[2] - vj[2];
float d = sqrtf(dx*dx + dz*dz);
int nn = 1 + (int)floorf(d/sampleDist);
if (nn > MAX_EDGE) nn = MAX_EDGE;
if (nverts+nn >= MAX_VERTS)
nn = MAX_VERTS-1-nverts;
for (int k = 0; k <= nn; ++k)
{
float u = (float)k/(float)nn;
float* pos = &edge[k*3];
pos[0] = vj[0] + dx*u;
pos[1] = vj[1] + dy*u;
pos[2] = vj[2] + dz*u;
pos[1] = chf.bmin[1] + getHeight(pos, chf.bmin, ics, hp)*chf.ch;
}
// Simplify samples.
int idx[MAX_EDGE] = {0,nn};
int nidx = 2;
for (int k = 0; k < nidx-1; )
{
const int a = idx[k];
const int b = idx[k+1];
const float* va = &edge[a*3];
const float* vb = &edge[b*3];
// Find maximum deviation along the segment.
float maxd = 0;
int maxi = -1;
for (int m = a+1; m < b; ++m)
{
float d = distancePtSeg(&edge[m*3],va,vb);
if (d > maxd)
{
maxd = d;
maxi = m;
}
}
// If the max deviation is larger than accepted error,
// add new point, else continue to next segment.
if (maxi != -1 && maxd > rcSqr(sampleMaxError))
{
for (int m = nidx; m > k; --m)
idx[m] = idx[m-1];
idx[k+1] = maxi;
nidx++;
}
else
{
++k;
}
}
// Add new vertices.
for (int k = 1; k < nidx-1; ++k)
{
vcopy(&verts[nverts*3], &edge[idx[k]*3]);
nverts++;
}
}
}
//.........这里部分代码省略.........
示例14: delaunay
// Based on Paul Bourke's triangulate.c
// http://astronomy.swin.edu.au/~pbourke/terrain/triangulate/triangulate.c
static void delaunay(const int nv, float *verts, rcIntArray& idx, rcIntArray& tris, rcIntArray& edges)
{
// Sort vertices
idx.resize(nv);
for (int i = 0; i < nv; ++i)
idx[i] = i;
#ifdef WIN32
qsort_s(&idx[0], idx.size(), sizeof(int), ptcmp, verts);
#else
qsort_r(&idx[0], idx.size(), sizeof(int), verts, ptcmp);
#endif
// Find the maximum and minimum vertex bounds.
// This is to allow calculation of the bounding triangle
float xmin = verts[0];
float ymin = verts[2];
float xmax = xmin;
float ymax = ymin;
for (int i = 1; i < nv; ++i)
{
xmin = rcMin(xmin, verts[i*3+0]);
xmax = rcMax(xmax, verts[i*3+0]);
ymin = rcMin(ymin, verts[i*3+2]);
ymax = rcMax(ymax, verts[i*3+2]);
}
float dx = xmax - xmin;
float dy = ymax - ymin;
float dmax = (dx > dy) ? dx : dy;
float xmid = (xmax + xmin) / 2.0f;
float ymid = (ymax + ymin) / 2.0f;
// Set up the supertriangle
// This is a triangle which encompasses all the sample points.
// The supertriangle coordinates are added to the end of the
// vertex list. The supertriangle is the first triangle in
// the triangle list.
float sv[3*3];
sv[0] = xmid - 20 * dmax;
sv[1] = 0;
sv[2] = ymid - dmax;
sv[3] = xmid;
sv[4] = 0;
sv[5] = ymid + 20 * dmax;
sv[6] = xmid + 20 * dmax;
sv[7] = 0;
sv[8] = ymid - dmax;
tris.push(-3);
tris.push(-2);
tris.push(-1);
tris.push(0); // not completed
for (int i = 0; i < nv; ++i)
{
const float xp = verts[idx[i]*3+0];
const float yp = verts[idx[i]*3+2];
edges.resize(0);
// Set up the edge buffer.
// If the point (xp,yp) lies inside the circumcircle then the
// three edges of that triangle are added to the edge buffer
// and that triangle is removed.
for (int j = 0; j < tris.size()/4; ++j)
{
int* t = &tris[j*4];
if (t[3]) // completed?
continue;
const float* v1 = t[0] < 0 ? &sv[(t[0]+3)*3] : &verts[idx[t[0]]*3];
const float* v2 = t[1] < 0 ? &sv[(t[1]+3)*3] : &verts[idx[t[1]]*3];
const float* v3 = t[2] < 0 ? &sv[(t[2]+3)*3] : &verts[idx[t[2]]*3];
float xc,yc,rsqr;
int inside = circumCircle(xp,yp, v1[0],v1[2], v2[0],v2[2], v3[0],v3[2], xc,yc,rsqr);
if (xc < xp && rcSqr(xp-xc) > rsqr)
t[3] = 1;
if (inside)
{
// Collect triangle edges.
edges.push(t[0]);
edges.push(t[1]);
edges.push(t[1]);
edges.push(t[2]);
edges.push(t[2]);
edges.push(t[0]);
// Remove triangle j.
t[0] = tris[tris.size()-4];
t[1] = tris[tris.size()-3];
t[2] = tris[tris.size()-2];
t[3] = tris[tris.size()-1];
tris.resize(tris.size()-4);
j--;
}
}
// Remove duplicate edges.
//.........这里部分代码省略.........
示例15: PDT_NAV_MESH
PDT_NAV_MESH gkRecast::createNavMesh(PMESHDATA meshData, const Config& config)
{
if (!meshData.get())
return PDT_NAV_MESH(0);
rcConfig cfg;
cfg.cs = config.CELL_SIZE;
cfg.ch = config.CELL_HEIGHT;
GK_ASSERT(cfg.ch && "cfg.ch cannot be zero");
GK_ASSERT(cfg.ch && "cfg.ch cannot be zero");
cfg.walkableSlopeAngle = config.AGENT_MAX_SLOPE;
cfg.walkableHeight = (int)ceilf(config.AGENT_HEIGHT / cfg.ch);
cfg.walkableClimb = (int)ceilf(config.AGENT_MAX_CLIMB / cfg.ch);
cfg.walkableRadius = (int)ceilf(config.AGENT_RADIUS / cfg.cs);
cfg.maxEdgeLen = (int)(config.EDGE_MAX_LEN / cfg.cs);
cfg.maxSimplificationError = config.EDGE_MAX_ERROR;
cfg.minRegionSize = (int)rcSqr(config.REGION_MIN_SIZE);
cfg.mergeRegionSize = (int)rcSqr(config.REGION_MERGE_SIZE);
cfg.maxVertsPerPoly = gkMin(config.VERTS_PER_POLY, DT_VERTS_PER_POLYGON);
cfg.tileSize = config.TILE_SIZE;
cfg.borderSize = cfg.walkableRadius + 4; // Reserve enough padding.
cfg.detailSampleDist = config.DETAIL_SAMPLE_DIST < 0.9f ? 0 : cfg.cs * config.DETAIL_SAMPLE_DIST;
cfg.detailSampleMaxError = cfg.ch * config.DETAIL_SAMPLE_ERROR;
if (!meshData->getVertCount())
return PDT_NAV_MESH(0);
gkScalar bmin[3], bmax[3];
const gkScalar* verts = meshData->getVerts();
int nverts = meshData->getVertCount();
const int* tris = meshData->getTris();
const gkScalar* trinorms = meshData->getNormals();
int ntris = meshData->getTriCount();
rcCalcBounds(verts, nverts, bmin, bmax);
//
// Step 1. Initialize build config.
//
// Set the area where the navigation will be build.
// Here the bounds of the input mesh are used, but the
// area could be specified by an user defined box, etc.
rcVcopy(cfg.bmin, bmin);
rcVcopy(cfg.bmax, bmax);
rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
rcBuildTimes m_buildTimes;
// Reset build times gathering.
memset(&m_buildTimes, 0, sizeof(m_buildTimes));
rcSetBuildTimes(&m_buildTimes);
// Start the build process.
rcTimeVal totStartTime = rcGetPerformanceTimer();
//gkPrintf("Building navigation:");
//gkPrintf(" - %d x %d cells", cfg.width, cfg.height);
//gkPrintf(" - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
//
// Step 2. Rasterize input polygon soup.
//
// Allocate voxel heighfield where we rasterize our input data to.
rcHeightfield heightField;
if (!rcCreateHeightfield(heightField, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch))
{
gkPrintf("buildNavigation: Could not create solid heightfield.");
return PDT_NAV_MESH(0);
}
{
// Allocate array that can hold triangle flags.
// If you have multiple meshes you need to process, allocate
// and array which can hold the max number of triangles you need to process.
utArray<unsigned char> triflags;
triflags.resize(ntris);
// Find triangles which are walkable based on their slope and rasterize them.
// If your input data is multiple meshes, you can transform them here, calculate
// the flags for each of the meshes and rasterize them.
memset(triflags.ptr(), 0, ntris * sizeof(unsigned char));
rcMarkWalkableTriangles(cfg.walkableSlopeAngle, verts, nverts, tris, ntris, triflags.ptr());
rcRasterizeTriangles(verts, nverts, tris, triflags.ptr(), ntris, heightField);
}
//
// Step 3. Filter walkables surfaces.
//
// Once all geoemtry is rasterized, we do initial pass of filtering to
// remove unwanted overhangs caused by the conservative rasterization
// as well as filter spans where the character cannot possibly stand.
rcFilterLedgeSpans(cfg.walkableHeight, cfg.walkableClimb, heightField);
//.........这里部分代码省略.........