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


C++ rcGetDirOffsetY函数代码示例

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


在下文中一共展示了rcGetDirOffsetY函数的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: rcFilterUnwalkableLedgeSpans

void	rcFilterUnwalkableLedgeSpans( rcContext* ctx, const int /*walkableHeight*/, const int walkableClimb, rcHeightfield& solid )
{
	rcAssert( ctx );

	ctx->startTimer( RC_TIMER_TEMPORARY );

	const int w = solid.width;
	const int h = solid.height;

	for( int y = 0; y < h; ++y ) {
		for( int x = 0; x < w; ++x ) {
			for( rcSpan* s = solid.spans[x + y*w]; s != NULL; s = s->next ) {
				if( !rcCanMovableArea( s->area ) || !rcIsObjectArea( s->area ) ) {
					continue;
				}

				const int smax = static_cast<int>( s->smax );
				int connectedEdgeCount = 0;

				for( int dir = 0; dir < 4; ++dir ) {
					int dx = x + rcGetDirOffsetX(dir);
					int dy = y + rcGetDirOffsetY(dir);
					if( dx < 0 || dy < 0 || dx >= w || dy >= h ) {
						++connectedEdgeCount;
						continue;
					}

					for( rcSpan* ns = solid.spans[dx + dy*w]; ns != NULL; ns = ns->next ) {
						const int nsmax = static_cast<int>( ns->smax );
						if( rcAbs( smax - nsmax ) <= walkableClimb*0.25f ) {
							++connectedEdgeCount;
						}
					}
				}

				if( connectedEdgeCount < 2 ) {
					s->area = RC_NULL_AREA;
				}
			}
		}
	}

	ctx->stopTimer( RC_TIMER_TEMPORARY );
}
开发者ID:infini,项目名称:_task,代码行数:44,代码来源:Recast.cpp

示例4: rcMarkSideLedgeSpans

void	rcMarkSideLedgeSpans( rcContext* ctx, const int walkableClimb, rcHeightfield& solid )
{
	rcAssert( ctx );

	ctx->startTimer( RC_TIMER_TEMPORARY );

	const int w = solid.width;
	const int h = solid.height;

	for( int y = 0; y < h; ++y ) {
		for( int x = 0; x < w; ++x ) {
			for( rcSpan* s = solid.spans[x + y*w]; s != NULL; s = s->next ) {
				if( !rcIsObjectArea( s->area ) || !rcIsWalkableObjectArea( s->area ) ) {
					continue;
				}
				for( int dir = 0; dir < 4; ++dir ) {
					const int dx = x + rcGetDirOffsetX(dir);
					const int dy = y + rcGetDirOffsetY(dir);
					if( dx < 0 || dy < 0 || dx >= w || dy >= h ) {
						continue;
					}
					for( rcSpan* ns = solid.spans[dx + dy*w]; ns != NULL; ns = ns->next ) {
						if( (ns->area & RC_UNWALKABLE_AREA) == RC_UNWALKABLE_AREA ) {
							const int gap = rcAbs( static_cast<int>(s->smax) - static_cast<int>(ns->smax) );
							if( gap <= walkableClimb ) {
								s->area |= RC_CLIMBABLE_AREA;
							}
						}
					}
				}
			}
		}
	}

	ctx->stopTimer( RC_TIMER_TEMPORARY );
}
开发者ID:infini,项目名称:_task,代码行数:36,代码来源:Recast.cpp

示例5: 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

示例6: walkContour

static void walkContour(int x, int y, int i, int dir,
                        rcCompactHeightfield& chf,
                        unsigned short* srcReg,
                        rcIntArray& cont)
{
    int startDir = dir;
    int starti = i;

    const rcCompactSpan& ss = chf.spans[i];
    unsigned short curReg = 0;
    if (rcGetCon(ss, 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(ss, dir);
        curReg = srcReg[ai];
    }
    cont.push(curReg);
            
    int iter = 0;
    while (++iter < 40000)
    {
        const rcCompactSpan& s = chf.spans[i];
        
        if (isSolidEdge(chf, srcReg, x, y, i, dir))
        {
            // Choose the edge corner
            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 != curReg)
            {
                curReg = r;
                cont.push(curReg);
            }
            
            dir = (dir+1) & 0x3;  // Rotate CW
        }
        else
        {
            int ni = -1;
            const int nx = x + rcGetDirOffsetX(dir);
            const int ny = y + rcGetDirOffsetY(dir);
            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;
        }
    }

    // Remove adjacent duplicates.
    if (cont.size() > 1)
    {
        for (int j = 0; j < cont.size(); )
        {
            int nj = (j+1) % cont.size();
            if (cont[j] == cont[nj])
            {
                for (int k = j; k < cont.size()-1; ++k)
                    cont[k] = cont[k+1];
                cont.pop();
            }
            else
                ++j;
        }
    }
}
开发者ID:Frankenhooker,项目名称:OpenWoW541,代码行数:87,代码来源:RecastRegion.cpp

示例7: calculateDistanceField

static void calculateDistanceField(rcCompactHeightfield& chf, unsigned short* src, unsigned short& maxDist)
{
    const int w = chf.width;
    const int h = chf.height;
    
    // Init distance and points.
    for (int i = 0; i < chf.spanCount; ++i)
        src[i] = 0xffff;
    
    // 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)
            {
                const rcCompactSpan& s = chf.spans[i];
                const unsigned char area = chf.areas[i];
                
                int nc = 0;
                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 (area == chf.areas[ai])
                            nc++;
                    }
                }
                if (nc != 4)
                    src[i] = 0;
            }
        }
    }
    
            
    // 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) != RC_NOT_CONNECTED)
                {
                    // (-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];
                    if (src[ai]+2 < src[i])
                        src[i] = src[ai]+2;
                    
                    // (-1,-1)
                    if (rcGetCon(as, 3) != RC_NOT_CONNECTED)
                    {
                        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);
                        if (src[aai]+3 < src[i])
                            src[i] = src[aai]+3;
                    }
                }
                if (rcGetCon(s, 3) != RC_NOT_CONNECTED)
                {
                    // (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];
                    if (src[ai]+2 < src[i])
                        src[i] = src[ai]+2;
                    
                    // (1,-1)
                    if (rcGetCon(as, 2) != RC_NOT_CONNECTED)
                    {
                        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);
                        if (src[aai]+3 < src[i])
                            src[i] = src[aai]+3;
                    }
                }
            }
        }
    }
    
    // Pass 2
    for (int y = h-1; y >= 0; --y)
    {
        for (int x = w-1; x >= 0; --x)
        {
            const rcCompactCell& c = chf.cells[x+y*w];
            for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
//.........这里部分代码省略.........
开发者ID:Frankenhooker,项目名称:OpenWoW541,代码行数:101,代码来源:RecastRegion.cpp

示例8: rcErodeWalkableArea

bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf)
{
    rcAssert(ctx);
    
    const int w = chf.width;
    const int h = chf.height;
    
    ctx->startTimer(RC_TIMER_ERODE_AREA);
    
    unsigned char* dist = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
    if (!dist)
    {
        ctx->log(RC_LOG_ERROR, "erodeWalkableArea: Out of memory 'dist' (%d).", chf.spanCount);
        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) != RC_NOT_CONNECTED)
                            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) != RC_NOT_CONNECTED)
                {
                    // (-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) != RC_NOT_CONNECTED)
                    {
                        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) != RC_NOT_CONNECTED)
                {
                    // (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) != RC_NOT_CONNECTED)
                    {
                        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:Blumfield,项目名称:ptc,代码行数:101,代码来源:RecastArea.cpp

示例9: getHeightData

static void getHeightData(const rcCompactHeightfield& chf,
						  const unsigned short* poly, const int npoly,
						  const unsigned short* verts, const int bs,
						  rcHeightPatch& hp, rcIntArray& stack,
						  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.
	
	stack.resize(0);
	memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);
	
	bool empty = true;
	
	// 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)
					{
						stack.push(x);
						stack.push(y);
						stack.push(i);
					}
					break;
				}
			}
		}
	}
	
	// if the polygon does not contian any points from the current region (rare, but happens)
	// then use the cells closest to the polygon vertices as seeds to fill the height field
	if (empty)
		getHeightDataSeedsFromVertices(chf, poly, npoly, verts, bs, hp, stack);
	
	static const int RETRACT_SIZE = 256;
	int head = 0;
	
	while (head*3 < stack.size())
	{
		int cx = stack[head*3+0];
		int cy = stack[head*3+1];
		int ci = stack[head*3+2];
		head++;
		if (head >= RETRACT_SIZE)
		{
			head = 0;
			if (stack.size() > RETRACT_SIZE*3)
				memmove(&stack[0], &stack[RETRACT_SIZE*3], sizeof(int)*(stack.size()-RETRACT_SIZE*3));
			stack.resize(stack.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;
			
			if (hx < 0 || hx >= hp.width || hy < 0 || hy >= hp.height)
				continue;
			
			if (hp.data[hx + hy*hp.width] != RC_UNSET_HEIGHT)
				continue;
			
//.........这里部分代码省略.........
开发者ID:madisodr,项目名称:legacy-core,代码行数:101,代码来源:RecastMeshDetail.cpp

示例10: rcBuildHeightfieldLayers

/// @par
/// 
/// See the #rcConfig documentation for more information on the configuration parameters.
/// 
/// @see rcAllocHeightfieldLayerSet, rcCompactHeightfield, rcHeightfieldLayerSet, rcConfig
bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
							  const int borderSize, const int walkableHeight,
							  rcHeightfieldLayerSet& lset)
{
	rcAssert(ctx);
	
	rcScopedTimer timer(ctx, RC_TIMER_BUILD_LAYERS);
	
	const int w = chf.width;
	const int h = chf.height;
	
	rcScopedDelete<unsigned char> srcReg((unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP));
	if (!srcReg)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'srcReg' (%d).", chf.spanCount);
		return false;
	}
	memset(srcReg,0xff,sizeof(unsigned char)*chf.spanCount);
	
	const int nsweeps = chf.width;
	rcScopedDelete<rcLayerSweepSpan> sweeps((rcLayerSweepSpan*)rcAlloc(sizeof(rcLayerSweepSpan)*nsweeps, RC_ALLOC_TEMP));
	if (!sweeps)
	{
		ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'sweeps' (%d).", nsweeps);
		return false;
	}
	
	
	// Partition walkable area into monotone regions.
	int prevCount[256];
	unsigned char regId = 0;

	for (int y = borderSize; y < h-borderSize; ++y)
	{
		memset(prevCount,0,sizeof(int)*regId);
		unsigned char 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 char sid = 0xff;

				// -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] != 0xff)
						sid = srcReg[ai];
				}
				
				if (sid == 0xff)
				{
					sid = sweepId++;
					sweeps[sid].nei = 0xff;
					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 char nr = srcReg[ai];
					if (nr != 0xff)
					{
						// 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++;
							prevCount[nr]++;
						}
						else
						{
							// This is hit if there is nore than one neighbour.
							// Invalidate the neighbour.
							sweeps[sid].nei = 0xff;
						}
					}
				}
				
				srcReg[i] = sid;
			}
//.........这里部分代码省略.........
开发者ID:090809,项目名称:TrinityCore,代码行数:101,代码来源:RecastLayers.cpp

示例11: getCornerHeight

static int getCornerHeight(int x, int y, int i, int dir,
						   const rcCompactHeightfield& chf,
						   bool& isBorderVertex)
{
	const rcCompactSpan& s = chf.spans[i];
	int ch = (int)s.minY;
	int dirp = (dir+1) & 0x3;
	
	struct CornerId
	{
		uint64_t		areaMask;
		unsigned short	region;

		bool No0() const
		{
			return areaMask != 0 && region != 0;
		}

		CornerId( unsigned short reg = 0, uint64_t area = 0 )
			: areaMask( area )
			, region( reg )
		{
		}
	};

	CornerId regs[ 4 ];
	
	// Combine region and area codes in order to prevent
	// border vertices which are in between two areas to be removed. 
	regs[ 0 ] = CornerId( chf.spans[ i ].regionID, chf.areaMasks[ 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);
		const rcCompactSpan& as = chf.spans[ai];
		ch = rcMax(ch, (int)as.minY);
		regs[ 1 ] = CornerId( chf.spans[ ai ].regionID, chf.areaMasks[ ai ] );
		if (rcGetCon(as, dirp) != RC_NOT_CONNECTED)
		{
			const int ax2 = ax + rcGetDirOffsetX(dirp);
			const int ay2 = ay + rcGetDirOffsetY(dirp);
			const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dirp);
			const rcCompactSpan& as2 = chf.spans[ai2];
			ch = rcMax(ch, (int)as2.minY);
			regs[ 2 ] = CornerId( chf.spans[ ai2 ].regionID, chf.areaMasks[ ai2 ] );
		}
	}
	if (rcGetCon(s, dirp) != RC_NOT_CONNECTED)
	{
		const int ax = x + rcGetDirOffsetX(dirp);
		const int ay = y + rcGetDirOffsetY(dirp);
		const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dirp);
		const rcCompactSpan& as = chf.spans[ai];
		ch = rcMax(ch, (int)as.minY);
		regs[ 3 ] = CornerId( chf.spans[ ai ].regionID, chf.areaMasks[ ai ] );
		if (rcGetCon(as, dir) != RC_NOT_CONNECTED)
		{
			const int ax2 = ax + rcGetDirOffsetX(dir);
			const int ay2 = ay + rcGetDirOffsetY(dir);
			const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dir);
			const rcCompactSpan& as2 = chf.spans[ai2];
			ch = rcMax(ch, (int)as2.minY);
			regs[ 2 ] = CornerId( chf.spans[ ai2 ].regionID, chf.areaMasks[ ai2 ] );
		}
	}

	// Check if the vertex is special edge vertex, these vertices will be removed later.
	for (int j = 0; j < 4; ++j)
	{
		const int a = j;
		const int b = (j+1) & 0x3;
		const int c = (j+2) & 0x3;
		const int d = (j+3) & 0x3;
		
		// The vertex is a border vertex there are two same exterior cells in a row,
		// followed by two interior cells and none of the regions are out of bounds.
		const bool twoSameExts = ( regs[ a ].region & regs[ b ].region & RC_BORDER_REG ) != 0 && regs[ a ].region == regs[ b ].region;
		const bool twoInts = ( ( regs[ c ].region | regs[ d ].region ) & RC_BORDER_REG ) == 0;
		const bool intsSameArea = ( regs[ c ].areaMask ) == ( regs[ d ].areaMask );
		const bool noZeros = regs[ a ].No0() && regs[ b ].No0() && regs[ c ].No0() && regs[ d ].No0();
		if (twoSameExts && twoInts && intsSameArea && noZeros)
		{
			isBorderVertex = true;
			break;
		}
	}
	
	return ch;
}
开发者ID:rwindegger,项目名称:recastnavigation,代码行数:91,代码来源:RecastContour.cpp

示例12: 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

示例13: 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

示例14: rcMarkReachableSpans

bool rcMarkReachableSpans(const int walkableHeight,
						  const int walkableClimb,
						  rcHeightfield& solid)
{
	const int w = solid.width;
	const int h = solid.height;
	const int MAX_HEIGHT = 0xffff;
	
	rcTimeVal startTime = rcGetPerformanceTimer();
	
	// Build navigable space.
	const int MAX_SEEDS = w*h;
	rcReachableSeed* stack = new rcReachableSeed[MAX_SEEDS];
	if (!stack)
	{
		if (rcGetLog())
			rcGetLog()->log(RC_LOG_ERROR, "rcMarkReachableSpans: Out of memory 'stack' (%d).", MAX_SEEDS);
		return false;
	}
	int stackSize = 0;
	
	for (int y = 0; y < h; ++y)
	{
		for (int x = 0; x < w; ++x)
		{
			rcSpan* topSpan = solid.spans[x + y*w];
			if (!topSpan)
				continue;
			while (topSpan->next)
				topSpan = topSpan->next;
			
			// If the span is not walkable, skip it.
			if ((topSpan->flags & RC_WALKABLE) == 0)
				continue;
			// If the span has been visited already, skip it.
			if (topSpan->flags & RC_REACHABLE)
				continue;
			
			// Start flood fill.
			topSpan->flags |= RC_REACHABLE;
			stackSize = 0;
			stack[stackSize].set(x, y, topSpan);
			stackSize++;
			
			while (stackSize)
			{
				// Pop a seed from the stack.
				stackSize--;
				rcReachableSeed cur = stack[stackSize];
				
				const int bot = (int)cur.s->smax;
				const int top = (int)cur.s->next ? (int)cur.s->next->smin : MAX_HEIGHT;
				
				// Visit neighbours in all 4 directions.
				for (int dir = 0; dir < 4; ++dir)
				{
					int dx = (int)cur.x + rcGetDirOffsetX(dir);
					int dy = (int)cur.y + rcGetDirOffsetY(dir);
					// Skip neighbour which are out of bounds.
					if (dx < 0 || dy < 0 || dx >= w || dy >= h)
						continue;
					for (rcSpan* ns = solid.spans[dx + dy*w]; ns; ns = ns->next)
					{
						// Skip neighbour if it is not walkable.
						if ((ns->flags & RC_WALKABLE) == 0)
							continue;
						// Skip the neighbour if it has been visited already.
						if (ns->flags & RC_REACHABLE)
							continue;
						
						const int nbot = (int)ns->smax;
						const int ntop = (int)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)
							continue;
						// Skip neightbour if the climb height to the neighbour is too high.
						if (rcAbs(nbot - bot) >= walkableClimb)
							continue;
						
						// This neighbour has not been visited yet.
						// Mark it as reachable and add it to the seed stack.
						ns->flags |= RC_REACHABLE;
						if (stackSize < MAX_SEEDS)
						{
							stack[stackSize].set(dx, dy, ns);
							stackSize++;
						}
					}
				}
			}
		}
	}
	
	delete [] stack;	
	
	rcTimeVal endTime = rcGetPerformanceTimer();
	
//	if (rcGetLog())
//		rcGetLog()->log(RC_LOG_PROGRESS, "Mark reachable: %.3f ms", rcGetDeltaTimeUsec(startTime, endTime)/1000.0f);
	if (rcGetBuildTimes())
//.........这里部分代码省略.........
开发者ID:Entropy-Soldier,项目名称:ges-legacy-code,代码行数:101,代码来源:RecastFilter.cpp

示例15: 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


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