当前位置: 首页>>代码示例>>C++>>正文


C++ rcGetCon函数代码示例

本文整理汇总了C++中rcGetCon函数的典型用法代码示例。如果您正苦于以下问题:C++ rcGetCon函数的具体用法?C++ rcGetCon怎么用?C++ rcGetCon使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了rcGetCon函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: boxBlur

static unsigned short* boxBlur(rcCompactHeightfield& chf, int thr,
                               unsigned short* src, unsigned short* dst)
{
    const int w = chf.width;
    const int h = chf.height;
    
    thr *= 2;
    
    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)
            {
                const rcCompactSpan& s = chf.spans[i];
                const unsigned short cd = src[i];
                if (cd <= thr)
                {
                    dst[i] = cd;
                    continue;
                }

                int d = (int)cd;
                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);
                        d += (int)src[ai];
                        
                        const rcCompactSpan& as = chf.spans[ai];
                        const int dir2 = (dir+1) & 0x3;
                        if (rcGetCon(as, dir2) != RC_NOT_CONNECTED)
                        {
                            const int ax2 = ax + rcGetDirOffsetX(dir2);
                            const int ay2 = ay + rcGetDirOffsetY(dir2);
                            const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2);
                            d += (int)src[ai2];
                        }
                        else
                        {
                            d += cd;
                        }
                    }
                    else
                    {
                        d += cd*2;
                    }
                }
                dst[i] = (unsigned short)((d+5)/9);
            }
        }
    }
    return dst;
}
开发者ID:Frankenhooker,项目名称:OpenWoW541,代码行数:58,代码来源:RecastRegion.cpp

示例2: isSolidEdge

static bool isSolidEdge(rcCompactHeightfield& chf, unsigned short* srcReg, int x, int y, int i, int dir)
{
	const rcCompactSpan& s = chf.spans[i];
	unsigned short r = 0;
	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*chf.width].index + rcGetCon(s, dir);
		r = srcReg[ai];
	}
	if (r == srcReg[i])
		return false;
	return true;
}
开发者ID:xiangyuan,项目名称:Unreal4,代码行数:15,代码来源:RecastLayers.cpp

示例3: CollectLayerRegionsMonotone

static bool CollectLayerRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize,
										unsigned short* srcReg, rcLayerRegionMonotone*& regs, int& nregs)
{
	const int w = chf.width;
	const int h = chf.height;

	const int nsweeps = chf.width;
	rcScopedDelete<rcLayerSweepSpan> sweeps = (rcLayerSweepSpan*)rcAlloc(sizeof(rcLayerSweepSpan)*nsweeps, RC_ALLOC_TEMP);
	if (!sweeps)
	{
		ctx->log(RC_LOG_ERROR, "CollectLayerRegionsMonotone: Out of memory 'sweeps' (%d).", nsweeps);
		return false;
	}

	// Partition walkable area into monotone regions.
	rcIntArray prev(256);
	unsigned short regId = 0;

	for (int y = borderSize; y < h-borderSize; ++y)
	{
		prev.resize(regId+1);
		memset(&prev[0],0,sizeof(int)*regId);
		unsigned short sweepId = 0;

		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)
			{
				const rcCompactSpan& s = chf.spans[i];
				if (chf.areas[i] == RC_NULL_AREA) continue;

				unsigned short sid = 0xffff;

				// -x
				if (rcGetCon(s, 0) != RC_NOT_CONNECTED)
				{
					const int ax = x + rcGetDirOffsetX(0);
					const int ay = y + rcGetDirOffsetY(0);
					const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0);
					if (chf.areas[ai] != RC_NULL_AREA && srcReg[ai] != 0xffff)
						sid = srcReg[ai];
				}

				if (sid == 0xffff)
				{
					sid = sweepId++;
					sweeps[sid].nei = 0xffff;
					sweeps[sid].ns = 0;
				}

				// -y
				if (rcGetCon(s,3) != RC_NOT_CONNECTED)
				{
					const int ax = x + rcGetDirOffsetX(3);
					const int ay = y + rcGetDirOffsetY(3);
					const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3);
					const unsigned short nr = srcReg[ai];
					if (nr != 0xffff)
					{
						// Set neighbour when first valid neighbour is encoutered.
						if (sweeps[sid].ns == 0)
							sweeps[sid].nei = nr;

						if (sweeps[sid].nei == nr)
						{
							// Update existing neighbour
							sweeps[sid].ns++;
							prev[nr]++;
						}
						else
						{
							// This is hit if there is nore than one neighbour.
							// Invalidate the neighbour.
							sweeps[sid].nei = 0xffff;
						}
					}
				}

				srcReg[i] = sid;
			}
		}

		// Create unique ID.
		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.
//.........这里部分代码省略.........
开发者ID:xiangyuan,项目名称:Unreal4,代码行数:101,代码来源:RecastLayers.cpp

示例4: getHeightData

static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf,
						  const unsigned short* poly, const int npoly,
						  const unsigned short* verts, const int bs,
						  rcHeightPatch& hp, rcIntArray& queue,
						  int region)
{
	// Note: Reads to the compact heightfield are offset by border size (bs)
	// since border size offset is already removed from the polymesh vertices.
	
	queue.resize(0);
	// Set all heights to RC_UNSET_HEIGHT.
	memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);

	bool empty = true;
	
	// We cannot sample from this poly if it was created from polys
	// of different regions. If it was then it could potentially be overlapping
	// with polys of that region and the heights sampled here could be wrong.
	if (region != RC_MULTIPLE_REGS)
	{
		// Copy the height from the same region, and mark region borders
		// as seed points to fill the rest.
		for (int hy = 0; hy < hp.height; hy++)
		{
			int y = hp.ymin + hy + bs;
			for (int hx = 0; hx < hp.width; hx++)
			{
				int x = hp.xmin + hx + bs;
				const rcCompactCell& c = chf.cells[x + y*chf.width];
				for (int i = (int)c.index, ni = (int)(c.index + c.count); i < ni; ++i)
				{
					const rcCompactSpan& s = chf.spans[i];
					if (s.reg == region)
					{
						// Store height
						hp.data[hx + hy*hp.width] = s.y;
						empty = false;

						// If any of the neighbours is not in same region,
						// add the current location as flood fill start
						bool border = false;
						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*chf.width].index + rcGetCon(s, dir);
								const rcCompactSpan& as = chf.spans[ai];
								if (as.reg != region)
								{
									border = true;
									break;
								}
							}
						}
						if (border)
							push3(queue, x, y, i);
						break;
					}
				}
			}
		}
	}
	
	// if the polygon does not contain any points from the current region (rare, but happens)
	// or if it could potentially be overlapping polygons of the same region,
	// then use the center as the seed point.
	if (empty)
		seedArrayWithPolyCenter(ctx, chf, poly, npoly, verts, bs, hp, queue);
	
	static const int RETRACT_SIZE = 256;
	int head = 0;
	
	// We assume the seed is centered in the polygon, so a BFS to collect
	// height data will ensure we do not move onto overlapping polygons and
	// sample wrong heights.
	while (head*3 < queue.size())
	{
		int cx = queue[head*3+0];
		int cy = queue[head*3+1];
		int ci = queue[head*3+2];
		head++;
		if (head >= RETRACT_SIZE)
		{
			head = 0;
			if (queue.size() > RETRACT_SIZE*3)
				memmove(&queue[0], &queue[RETRACT_SIZE*3], sizeof(int)*(queue.size()-RETRACT_SIZE*3));
			queue.resize(queue.size()-RETRACT_SIZE*3);
		}
		
		const rcCompactSpan& cs = chf.spans[ci];
		for (int dir = 0; dir < 4; ++dir)
		{
			if (rcGetCon(cs, dir) == RC_NOT_CONNECTED) continue;
			
			const int ax = cx + rcGetDirOffsetX(dir);
			const int ay = cy + rcGetDirOffsetY(dir);
			const int hx = ax - hp.xmin - bs;
			const int hy = ay - hp.ymin - bs;
//.........这里部分代码省略.........
开发者ID:090809,项目名称:TrinityCore,代码行数:101,代码来源:RecastMeshDetail.cpp

示例5: expandRegions

static unsigned short* expandRegions(int maxIter, unsigned short level,
                                     rcCompactHeightfield& chf,
                                     unsigned short* srcReg, unsigned short* srcDist,
                                     unsigned short* dstReg, unsigned short* dstDist, 
                                     rcIntArray& stack)
{
    const int w = chf.width;
    const int h = chf.height;

    // Find cells revealed by the raised level.
    stack.resize(0);
    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)
                {
                    stack.push(x);
                    stack.push(y);
                    stack.push(i);
                }
            }
        }
    }
    
    int iter = 0;
    while (stack.size() > 0)
    {
        int failed = 0;
        
        memcpy(dstReg, srcReg, sizeof(unsigned short)*chf.spanCount);
        memcpy(dstDist, srcDist, sizeof(unsigned short)*chf.spanCount);
        
        for (int j = 0; j < stack.size(); j += 3)
        {
            int x = stack[j+0];
            int y = stack[j+1];
            int i = stack[j+2];
            if (i < 0)
            {
                failed++;
                continue;
            }
            
            unsigned short r = srcReg[i];
            unsigned short d2 = 0xffff;
            const unsigned char area = chf.areas[i];
            const rcCompactSpan& s = chf.spans[i];
            for (int dir = 0; dir < 4; ++dir)
            {
                if (rcGetCon(s, dir) == RC_NOT_CONNECTED) continue;
                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);
                if (chf.areas[ai] != area) continue;
                if (srcReg[ai] > 0 && (srcReg[ai] & RC_BORDER_REG) == 0)
                {
                    if ((int)srcDist[ai]+2 < (int)d2)
                    {
                        r = srcReg[ai];
                        d2 = srcDist[ai]+2;
                    }
                }
            }
            if (r)
            {
                stack[j+2] = -1; // mark as used
                dstReg[i] = r;
                dstDist[i] = d2;
            }
            else
            {
                failed++;
            }
        }
        
        // rcSwap source and dest.
        rcSwap(srcReg, dstReg);
        rcSwap(srcDist, dstDist);
        
        if (failed*3 == stack.size())
            break;
        
        if (level > 0)
        {
            ++iter;
            if (iter >= maxIter)
                break;
        }
    }
    
    return srcReg;
}
开发者ID:Frankenhooker,项目名称:OpenWoW541,代码行数:96,代码来源:RecastRegion.cpp

示例6: floodRegion

static bool floodRegion(int x, int y, int i,
                        unsigned short level, unsigned short r,
                        rcCompactHeightfield& chf,
                        unsigned short* srcReg, unsigned short* srcDist,
                        rcIntArray& stack)
{
    const int w = chf.width;
    
    const unsigned char area = chf.areas[i];
    
    // Flood fill mark region.
    stack.resize(0);
    stack.push((int)x);
    stack.push((int)y);
    stack.push((int)i);
    srcReg[i] = r;
    srcDist[i] = 0;
    
    unsigned short lev = level >= 2 ? level-2 : 0;
    int count = 0;
    
    while (stack.size() > 0)
    {
        int ci = stack.pop();
        int cy = stack.pop();
        int cx = stack.pop();
        
        const rcCompactSpan& cs = chf.spans[ci];
        
        // Check if any of the neighbours already have a valid region set.
        unsigned short ar = 0;
        for (int dir = 0; dir < 4; ++dir)
        {
            // 8 connected
            if (rcGetCon(cs, dir) != RC_NOT_CONNECTED)
            {
                const int ax = cx + rcGetDirOffsetX(dir);
                const int ay = cy + rcGetDirOffsetY(dir);
                const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir);
                if (chf.areas[ai] != area)
                    continue;
                unsigned short nr = srcReg[ai];
                if (nr & RC_BORDER_REG) // Do not take borders into account.
                    continue;
                if (nr != 0 && nr != r)
                    ar = nr;
                
                const rcCompactSpan& as = chf.spans[ai];
                
                const int dir2 = (dir+1) & 0x3;
                if (rcGetCon(as, dir2) != RC_NOT_CONNECTED)
                {
                    const int ax2 = ax + rcGetDirOffsetX(dir2);
                    const int ay2 = ay + rcGetDirOffsetY(dir2);
                    const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2);
                    if (chf.areas[ai2] != area)
                        continue;
                    unsigned short nr2 = srcReg[ai2];
                    if (nr2 != 0 && nr2 != r)
                        ar = nr2;
                }                
            }
        }
        if (ar != 0)
        {
            srcReg[ci] = 0;
            continue;
        }
        count++;
        
        // Expand neighbours.
        for (int dir = 0; dir < 4; ++dir)
        {
            if (rcGetCon(cs, dir) != RC_NOT_CONNECTED)
            {
                const int ax = cx + rcGetDirOffsetX(dir);
                const int ay = cy + rcGetDirOffsetY(dir);
                const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir);
                if (chf.areas[ai] != area)
                    continue;
                if (chf.dist[ai] >= lev && srcReg[ai] == 0)
                {
                    srcReg[ai] = r;
                    srcDist[ai] = 0;
                    stack.push(ax);
                    stack.push(ay);
                    stack.push(ai);
                }
            }
        }
    }
    
    return count > 0;
}
开发者ID:Frankenhooker,项目名称:OpenWoW541,代码行数:94,代码来源:RecastRegion.cpp

示例7: rcBuildRegionsMonotone

/// @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.
/// 
/// Partitioning can result in smaller than necessary regions. @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 rcBuildRegionsMonotone(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;
    unsigned short id = 1;
    
    rcScopedDelete<unsigned short> srcReg = (unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_TEMP);
    if (!srcReg)
    {
        ctx->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'src' (%d).", chf.spanCount);
        return false;
    }
    memset(srcReg,0,sizeof(unsigned short)*chf.spanCount);

    const int nsweeps = rcMax(chf.width,chf.height);
    rcScopedDelete<rcSweepSpan> sweeps = (rcSweepSpan*)rcAlloc(sizeof(rcSweepSpan)*nsweeps, RC_ALLOC_TEMP);
    if (!sweeps)
    {
        ctx->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'sweeps' (%d).", nsweeps);
        return false;
    }
    
    
    // Mark border regions.
    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, id|RC_BORDER_REG, chf, srcReg); id++;
        paintRectRegion(w-bw, w, 0, h, id|RC_BORDER_REG, chf, srcReg); id++;
        paintRectRegion(0, w, 0, bh, id|RC_BORDER_REG, chf, srcReg); id++;
        paintRectRegion(0, w, h-bh, h, id|RC_BORDER_REG, chf, srcReg); id++;
        
        chf.borderSize = borderSize;
    }
    
    rcIntArray prev(256);

    // Sweep one line at a time.
    for (int y = borderSize; y < h-borderSize; ++y)
    {
        // Collect spans from this row.
        prev.resize(id+1);
        memset(&prev[0],0,sizeof(int)*id);
        unsigned short rid = 1;
        
        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)
            {
                const rcCompactSpan& s = chf.spans[i];
                if (chf.areas[i] == RC_NULL_AREA) continue;
                
                // -x
                unsigned short previd = 0;
                if (rcGetCon(s, 0) != RC_NOT_CONNECTED)
                {
                    const int ax = x + rcGetDirOffsetX(0);
                    const int ay = y + rcGetDirOffsetY(0);
                    const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0);
                    if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
                        previd = srcReg[ai];
                }
                
                if (!previd)
                {
                    previd = rid++;
                    sweeps[previd].rid = previd;
                    sweeps[previd].ns = 0;
                    sweeps[previd].nei = 0;
                }

//.........这里部分代码省略.........
开发者ID:Frankenhooker,项目名称:OpenWoW541,代码行数:101,代码来源:RecastRegion.cpp

示例8: rcMedianFilterWalkableArea

bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf)
{
    rcAssert(ctx);
    
    const int w = chf.width;
    const int h = chf.height;
    
    ctx->startTimer(RC_TIMER_MEDIAN_AREA);
    
    unsigned char* areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
    if (!areas)
    {
        ctx->log(RC_LOG_ERROR, "medianFilterWalkableArea: Out of memory 'areas' (%d).", chf.spanCount);
        return false;
    }
    
    // Init distance.
    memset(areas, 0xff, sizeof(unsigned char)*chf.spanCount);
    
    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)
            {
                const rcCompactSpan& s = chf.spans[i];
                if (chf.areas[i] == RC_NULL_AREA)
                {
                    areas[i] = chf.areas[i];
                    continue;
                }
                
                unsigned char nei[9];
                for (int j = 0; j < 9; ++j)
                    nei[j] = chf.areas[i];
                
                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);
                        if (chf.areas[ai] != RC_NULL_AREA)
                            nei[dir*2+0] = chf.areas[ai];
                        
                        const rcCompactSpan& as = chf.spans[ai];
                        const int dir2 = (dir+1) & 0x3;
                        if (rcGetCon(as, dir2) != RC_NOT_CONNECTED)
                        {
                            const int ax2 = ax + rcGetDirOffsetX(dir2);
                            const int ay2 = ay + rcGetDirOffsetY(dir2);
                            const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2);
                            if (chf.areas[ai2] != RC_NULL_AREA)
                                nei[dir*2+1] = chf.areas[ai2];
                        }
                    }
                }
                insertSort(nei, 9);
                areas[i] = nei[4];
            }
        }
    }
    
    memcpy(chf.areas, areas, sizeof(unsigned char)*chf.spanCount);
    
    rcFree(areas);

    ctx->stopTimer(RC_TIMER_MEDIAN_AREA);
    
    return true;
}
开发者ID:Blumfield,项目名称:ptc,代码行数:73,代码来源:RecastArea.cpp

示例9: getHeightDataSeedsFromVertices

static void getHeightDataSeedsFromVertices(const rcCompactHeightfield& chf,
										   const unsigned short* poly, const int npoly,
										   const unsigned short* verts, const int bs,
										   rcHeightPatch& hp, rcIntArray& stack)
{
	// Floodfill the heightfield to get 2D height data,
	// starting at vertex locations as seeds.
	
	// Note: Reads to the compact heightfield are offset by border size (bs)
	// since border size offset is already removed from the polymesh vertices.
	
	memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height);
	
	stack.resize(0);
	
	static const int offset[9*2] =
	{
		0,0, -1,-1, 0,-1, 1,-1, 1,0, 1,1, 0,1, -1,1, -1,0,
	};
	
	// Use poly vertices as seed points for the flood fill.
	for (int j = 0; j < npoly; ++j)
	{
		int cx = 0, cz = 0, ci =-1;
		int dmin = RC_UNSET_HEIGHT;
		for (int k = 0; k < 9; ++k)
		{
			const int ax = (int)verts[poly[j]*3+0] + offset[k*2+0];
			const int ay = (int)verts[poly[j]*3+1];
			const int az = (int)verts[poly[j]*3+2] + offset[k*2+1];
			if (ax < hp.xmin || ax >= hp.xmin+hp.width ||
				az < hp.ymin || az >= hp.ymin+hp.height)
				continue;
			
			const rcCompactCell& c = chf.cells[(ax+bs)+(az+bs)*chf.width];
			for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
			{
				const rcCompactSpan& s = chf.spans[i];
				int d = rcAbs(ay - (int)s.y);
				if (d < dmin)
				{
					cx = ax;
					cz = az;
					ci = i;
					dmin = d;
				}
			}
		}
		if (ci != -1)
		{
			stack.push(cx);
			stack.push(cz);
			stack.push(ci);
		}
	}
	
	// Find center of the polygon using flood fill.
	int pcx = 0, pcz = 0;
	for (int j = 0; j < npoly; ++j)
	{
		pcx += (int)verts[poly[j]*3+0];
		pcz += (int)verts[poly[j]*3+2];
	}
	pcx /= npoly;
	pcz /= npoly;
	
	for (int i = 0; i < stack.size(); i += 3)
	{
		int cx = stack[i+0];
		int cy = stack[i+1];
		int idx = cx-hp.xmin+(cy-hp.ymin)*hp.width;
		hp.data[idx] = 1;
	}
	
	while (stack.size() > 0)
	{
		int ci = stack.pop();
		int cy = stack.pop();
		int cx = stack.pop();
		
		// Check if close to center of the polygon.
		if (rcAbs(cx-pcx) <= 1 && rcAbs(cy-pcz) <= 1)
		{
			stack.resize(0);
			stack.push(cx);
			stack.push(cy);
			stack.push(ci);
			break;
		}
		
		const rcCompactSpan& cs = chf.spans[ci];
		
		for (int dir = 0; dir < 4; ++dir)
		{
			if (rcGetCon(cs, dir) == RC_NOT_CONNECTED) continue;
			
			const int ax = cx + rcGetDirOffsetX(dir);
			const int ay = cy + rcGetDirOffsetY(dir);
			
			if (ax < hp.xmin || ax >= (hp.xmin+hp.width) ||
//.........这里部分代码省略.........
开发者ID:madisodr,项目名称:legacy-core,代码行数:101,代码来源:RecastMeshDetail.cpp

示例10: walkContour

static void walkContour(int x, int y, int i,
						rcCompactHeightfield& chf,
						unsigned char* flags, rcIntArray& points)
{
	// Choose the first non-connected edge
	unsigned char dir = 0;
	while ((flags[i] & (1 << dir)) == 0)
		dir++;
	
	unsigned char startDir = dir;
	int starti = i;
	
	const navAreaMask area = chf.areaMasks[ i ];
	
	int iter = 0;
	while (++iter < 40000)
	{
		if (flags[i] & (1 << dir))
		{
			// Choose the edge corner
			bool isBorderVertex = false;
			bool isAreaBorder = false;
			int px = x;
			int py = getCornerHeight(x, y, i, dir, chf, isBorderVertex);
			int pz = y;
			switch(dir)
			{
				case 0: pz++; break;
				case 1: px++; pz++; break;
				case 2: px++; break;
			}
			int r = 0;
			const rcCompactSpan& s = chf.spans[i];
			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*chf.width].index + rcGetCon(s, dir);
				r = (int)chf.spans[ai].regionID;
				if (area != chf.areaMasks[ai])
					isAreaBorder = true;
			}
			if (isBorderVertex)
				r |= RC_BORDER_VERTEX;
			if (isAreaBorder)
				r |= RC_AREA_BORDER;
			points.push(px);
			points.push(py);
			points.push(pz);
			points.push(r);
			
			flags[i] &= ~(1 << dir); // Remove visited edges
			dir = (dir+1) & 0x3;  // Rotate CW
		}
		else
		{
			int ni = -1;
			const int nx = x + rcGetDirOffsetX(dir);
			const int ny = y + rcGetDirOffsetY(dir);
			const rcCompactSpan& s = chf.spans[i];
			if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
			{
				const rcCompactCell& nc = chf.cells[nx+ny*chf.width];
				ni = (int)nc.index + rcGetCon(s, dir);
			}
			if (ni == -1)
			{
				// Should not happen.
				return;
			}
			x = nx;
			y = ny;
			i = ni;
			dir = (dir+3) & 0x3;	// Rotate CCW
		}
		
		if (starti == i && startDir == dir)
		{
			break;
		}
	}
}
开发者ID:rwindegger,项目名称:recastnavigation,代码行数:82,代码来源:RecastContour.cpp

示例11: floodRegion

static bool floodRegion(int x, int y, int i,
						unsigned short level, unsigned short minLevel, unsigned short r,
						rcCompactHeightfield& chf,
						unsigned short* src,
						rcIntArray& stack)
{
	const int w = chf.width;
	
	// Flood fill mark region.
	stack.resize(0);
	stack.push((int)x);
	stack.push((int)y);
	stack.push((int)i);
	src[i*2] = r;
	src[i*2+1] = 0;
	
	unsigned short lev = level >= minLevel+2 ? level-2 : minLevel;
	int count = 0;
	
	while (stack.size() > 0)
	{
		int ci = stack.pop();
		int cy = stack.pop();
		int cx = stack.pop();
		
		const rcCompactSpan& cs = chf.spans[ci];
		
		// Check if any of the neighbours already have a valid region set.
		unsigned short ar = 0;
		for (int dir = 0; dir < 4; ++dir)
		{
			// 8 connected
			if (rcGetCon(cs, dir) != 0xf)
			{
				const int ax = cx + rcGetDirOffsetX(dir);
				const int ay = cy + rcGetDirOffsetY(dir);
				const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir);
				unsigned short nr = src[ai*2];
				if (nr != 0 && nr != r)
					ar = nr;
				
				const rcCompactSpan& as = chf.spans[ai];
				
				const int dir2 = (dir+1) & 0x3;
				if (rcGetCon(as, dir2) != 0xf)
				{
					const int ax2 = ax + rcGetDirOffsetX(dir2);
					const int ay2 = ay + rcGetDirOffsetY(dir2);
					const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2);
					
					unsigned short nr = src[ai2*2];
					if (nr != 0 && nr != r)
						ar = nr;
				}				
			}
		}
		if (ar != 0)
		{
			src[ci*2] = 0;
			continue;
		}
		count++;
		
		// Expand neighbours.
		for (int dir = 0; dir < 4; ++dir)
		{
			if (rcGetCon(cs, dir) != 0xf)
			{
				const int ax = cx + rcGetDirOffsetX(dir);
				const int ay = cy + rcGetDirOffsetY(dir);
				const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(cs, dir);
				if (chf.spans[ai].dist >= lev)
				{
					if (src[ai*2] == 0)
					{
						src[ai*2] = r;
						src[ai*2+1] = 0;
						stack.push(ax);
						stack.push(ay);
						stack.push(ai);
					}
				}
			}
		}
	}
	
	return count > 0;
}
开发者ID:Entropy-Soldier,项目名称:ges-legacy-code,代码行数:88,代码来源:RecastRegion.cpp

示例12: rcErodeArea

bool rcErodeArea(unsigned char areaId, int radius, rcCompactHeightfield& chf)
{
        const int w = chf.width;
        const int h = chf.height;
        
        rcTimeVal startTime = rcGetPerformanceTimer();
        
        unsigned char* dist = new unsigned char[chf.spanCount];
        if (!dist)
                return false;
        
        // Init distance.
        memset(dist, 0xff, sizeof(unsigned char)*chf.spanCount);
        
        // Mark boundary cells.
        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.areas[i] != RC_NULL_AREA)
                                {
                                        const rcCompactSpan& s = chf.spans[i];
                                        int nc = 0;
                                        for (int dir = 0; dir < 4; ++dir)
                                        {
                                                if (rcGetCon(s, dir) != 0xf)
                                                {
                                                        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);
                                                        if (chf.areas[ai] == areaId)
                                                                nc++;
                                                }
                                        }
                                        // At least one missing neighbour.
                                        if (nc != 4)
                                                dist[i] = 0;
                                }
                        }
                }
        }
        
        unsigned char nd;
        
        // Pass 1
        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)
                        {
                                const rcCompactSpan& s = chf.spans[i];
                                
                                if (rcGetCon(s, 0) != 0xf)
                                {
                                        // (-1,0)
                                        const int ax = x + rcGetDirOffsetX(0);
                                        const int ay = y + rcGetDirOffsetY(0);
                                        const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0);
                                        const rcCompactSpan& as = chf.spans[ai];
                                        nd = (unsigned char)rcMin((int)dist[ai]+2, 255);
                                        if (nd < dist[i])
                                                dist[i] = nd;
                                        
                                        // (-1,-1)
                                        if (rcGetCon(as, 3) != 0xf)
                                        {
                                                const int aax = ax + rcGetDirOffsetX(3);
                                                const int aay = ay + rcGetDirOffsetY(3);
                                                const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 3);
                                                nd = (unsigned char)rcMin((int)dist[aai]+3, 255);
                                                if (nd < dist[i])
                                                        dist[i] = nd;
                                        }
                                }
                                if (rcGetCon(s, 3) != 0xf)
                                {
                                        // (0,-1)
                                        const int ax = x + rcGetDirOffsetX(3);
                                        const int ay = y + rcGetDirOffsetY(3);
                                        const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3);
                                        const rcCompactSpan& as = chf.spans[ai];
                                        nd = (unsigned char)rcMin((int)dist[ai]+2, 255);
                                        if (nd < dist[i])
                                                dist[i] = nd;
                                        
                                        // (1,-1)
                                        if (rcGetCon(as, 2) != 0xf)
                                        {
                                                const int aax = ax + rcGetDirOffsetX(2);
                                                const int aay = ay + rcGetDirOffsetY(2);
                                                const int aai = (int)chf.cells[aax+aay*w].index + rcGetCon(as, 2);
                                                nd = (unsigned char)rcMin((int)dist[aai]+3, 255);
                                                if (nd < dist[i])
                                                        dist[i] = nd;
                                        }
//.........这里部分代码省略.........
开发者ID:Zekom,项目名称:NeoCore,代码行数:101,代码来源:RecastArea.cpp

示例13: rcBuildRegionsMonotone

bool rcBuildRegionsMonotone(rcCompactHeightfield& chf,
							int borderSize, int minRegionSize, int mergeRegionSize)
{
	rcTimeVal startTime = rcGetPerformanceTimer();
	
	const int w = chf.width;
	const int h = chf.height;
	unsigned short id = 1;
	
	if (chf.regs)
	{
		delete [] chf.regs;
		chf.regs = 0;
	}
	
	rcScopedDelete<unsigned short> srcReg = new unsigned short[chf.spanCount];
	if (!srcReg)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'src' (%d).", chf.spanCount);
		return false;
	}
	memset(srcReg,0,sizeof(unsigned short)*chf.spanCount);

	rcScopedDelete<rcSweepSpan> sweeps = new rcSweepSpan[rcMax(chf.width,chf.height)];
	if (!sweeps)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'sweeps' (%d).", chf.width);
		return false;
	}
	
	
	// Mark border regions.
	if (borderSize)
	{
		paintRectRegion(0, borderSize, 0, h, id|RC_BORDER_REG, chf, srcReg); id++;
		paintRectRegion(w-borderSize, w, 0, h, id|RC_BORDER_REG, chf, srcReg); id++;
		paintRectRegion(0, w, 0, borderSize, id|RC_BORDER_REG, chf, srcReg); id++;
		paintRectRegion(0, w, h-borderSize, h, id|RC_BORDER_REG, chf, srcReg); id++;
	}
	
	rcIntArray prev(256);

	// Sweep one line at a time.
	for (int y = borderSize; y < h-borderSize; ++y)
	{
		// Collect spans from this row.
		prev.resize(id+1);
		memset(&prev[0],0,sizeof(int)*id);
		unsigned short rid = 1;
		
		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)
			{
				const rcCompactSpan& s = chf.spans[i];
				if (chf.areas[i] == RC_NULL_AREA) continue;
				
				// -x
				unsigned short previd = 0;
				if (rcGetCon(s, 0) != RC_NOT_CONNECTED)
				{
					const int ax = x + rcGetDirOffsetX(0);
					const int ay = y + rcGetDirOffsetY(0);
					const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0);
					if ((srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
						previd = srcReg[ai];
				}
				
				if (!previd)
				{
					previd = rid++;
					sweeps[previd].rid = previd;
					sweeps[previd].ns = 0;
					sweeps[previd].nei = 0;
				}

				// -y
				if (rcGetCon(s,3) != RC_NOT_CONNECTED)
				{
					const int ax = x + rcGetDirOffsetX(3);
					const int ay = y + rcGetDirOffsetY(3);
					const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3);
					if (srcReg[ai] && (srcReg[ai] & RC_BORDER_REG) == 0 && chf.areas[i] == chf.areas[ai])
					{
						unsigned short nr = srcReg[ai];
						if (!sweeps[previd].nei || sweeps[previd].nei == nr)
						{
							sweeps[previd].nei = nr;
							sweeps[previd].ns++;
							prev[nr]++;
						}
						else
						{
							sweeps[previd].nei = RC_NULL_NEI;
						}
					}
//.........这里部分代码省略.........
开发者ID:Jekls,项目名称:PhantomCore,代码行数:101,代码来源:RecastRegion.cpp

示例14: getHeightData

static void getHeightData(const rcCompactHeightfield& chf,
						  const unsigned short* poly, const int npoly,
						  const unsigned short* verts,
						  rcHeightPatch& hp, rcIntArray& stack)
{
	// Floodfill the heightfield to get 2D height data,
	// starting at vertex locations as seeds.
	
	memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);

	stack.resize(0);
	
	// Use poly vertices as seed points for the flood fill.
	for (int j = 0; j < npoly; ++j)
	{
		const int ax = (int)verts[poly[j]*3+0];
		const int ay = (int)verts[poly[j]*3+1];
		const int az = (int)verts[poly[j]*3+2];
		if (ax < hp.xmin || ax >= hp.xmin+hp.width ||
			az < hp.ymin || az >= hp.ymin+hp.height)
			continue;
			
		const rcCompactCell& c = chf.cells[ax+az*chf.width];
		int dmin = 0xffff;
		int ai = -1;
		for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
		{
			const rcCompactSpan& s = chf.spans[i];
			int d = rcAbs(ay - (int)s.y);
			if (d < dmin)
			{
				ai = i;
				dmin = d;
			}
		}
		if (ai != -1)
		{
			stack.push(ax);
			stack.push(az);
			stack.push(ai);
		}
	}

	while (stack.size() > 0)
	{
		int ci = stack.pop();
		int cy = stack.pop();
		int cx = stack.pop();

		// Skip already visited locations.
		int idx = cx-hp.xmin+(cy-hp.ymin)*hp.width;
		if (hp.data[idx] != 0xffff)
			continue;
		
		const rcCompactSpan& cs = chf.spans[ci];
		hp.data[idx] = cs.y;
		
		for (int dir = 0; dir < 4; ++dir)
		{
			if (rcGetCon(cs, dir) == 0xf) continue;
			
			const int ax = cx + rcGetDirOffsetX(dir);
			const int ay = cy + rcGetDirOffsetY(dir);
		
			if (ax < hp.xmin || ax >= (hp.xmin+hp.width) ||
				ay < hp.ymin || ay >= (hp.ymin+hp.height))
				continue;

			if (hp.data[ax-hp.xmin+(ay-hp.ymin)*hp.width] != 0xffff)
				continue;

			const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(cs, dir);
			
			stack.push(ax);
			stack.push(ay);
			stack.push(ai);
		}
	}	
}
开发者ID:Entropy-Soldier,项目名称:ges-legacy-code,代码行数:79,代码来源:RecastMeshDetail.cpp

示例15: seedArrayWithPolyCenter

static void seedArrayWithPolyCenter(rcContext* ctx, const rcCompactHeightfield& chf,
									const unsigned short* poly, const int npoly,
									const unsigned short* verts, const int bs,
									rcHeightPatch& hp, rcIntArray& array)
{
	// Note: Reads to the compact heightfield are offset by border size (bs)
	// since border size offset is already removed from the polymesh vertices.
	
	static const int offset[9*2] =
	{
		0,0, -1,-1, 0,-1, 1,-1, 1,0, 1,1, 0,1, -1,1, -1,0,
	};
	
	// Find cell closest to a poly vertex
	int startCellX = 0, startCellY = 0, startSpanIndex = -1;
	int dmin = RC_UNSET_HEIGHT;
	for (int j = 0; j < npoly && dmin > 0; ++j)
	{
		for (int k = 0; k < 9 && dmin > 0; ++k)
		{
			const int ax = (int)verts[poly[j]*3+0] + offset[k*2+0];
			const int ay = (int)verts[poly[j]*3+1];
			const int az = (int)verts[poly[j]*3+2] + offset[k*2+1];
			if (ax < hp.xmin || ax >= hp.xmin+hp.width ||
				az < hp.ymin || az >= hp.ymin+hp.height)
				continue;
			
			const rcCompactCell& c = chf.cells[(ax+bs)+(az+bs)*chf.width];
			for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni && dmin > 0; ++i)
			{
				const rcCompactSpan& s = chf.spans[i];
				int d = rcAbs(ay - (int)s.y);
				if (d < dmin)
				{
					startCellX = ax;
					startCellY = az;
					startSpanIndex = i;
					dmin = d;
				}
			}
		}
	}
	
	rcAssert(startSpanIndex != -1);
	// Find center of the polygon
	int pcx = 0, pcy = 0;
	for (int j = 0; j < npoly; ++j)
	{
		pcx += (int)verts[poly[j]*3+0];
		pcy += (int)verts[poly[j]*3+2];
	}
	pcx /= npoly;
	pcy /= npoly;
	
	// Use seeds array as a stack for DFS
	array.resize(0);
	array.push(startCellX);
	array.push(startCellY);
	array.push(startSpanIndex);

	int dirs[] = { 0, 1, 2, 3 };
	memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height);
	// DFS to move to the center. Note that we need a DFS here and can not just move
	// directly towards the center without recording intermediate nodes, even though the polygons
	// are convex. In very rare we can get stuck due to contour simplification if we do not
	// record nodes.
	int cx = -1, cy = -1, ci = -1;
	while (true)
	{
		if (array.size() < 3)
		{
			ctx->log(RC_LOG_WARNING, "Walk towards polygon center failed to reach center");
			break;
		}

		ci = array.pop();
		cy = array.pop();
		cx = array.pop();

		if (cx == pcx && cy == pcy)
			break;

		// If we are already at the correct X-position, prefer direction
		// directly towards the center in the Y-axis; otherwise prefer
		// direction in the X-axis
		int directDir;
		if (cx == pcx)
			directDir = rcGetDirForOffset(0, pcy > cy ? 1 : -1);
		else
			directDir = rcGetDirForOffset(pcx > cx ? 1 : -1, 0);

		// Push the direct dir last so we start with this on next iteration
		rcSwap(dirs[directDir], dirs[3]);

		const rcCompactSpan& cs = chf.spans[ci];
		for (int i = 0; i < 4; i++)
		{
			int dir = dirs[i];
			if (rcGetCon(cs, dir) == RC_NOT_CONNECTED)
				continue;
//.........这里部分代码省略.........
开发者ID:090809,项目名称:TrinityCore,代码行数:101,代码来源:RecastMeshDetail.cpp


注:本文中的rcGetCon函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。