Merge branch 'master' of https://github.com/memononen/recastnavigation
thrown away the fix I made to Recast/Source/RecastMeshDetail.cpp in favor of the upstream code.
This commit is contained in:
commit
f60468abcb
3
.gitignore
vendored
3
.gitignore
vendored
@ -14,6 +14,9 @@ RecastDemo/Bin/RecastDemo
|
|||||||
# Build directory
|
# Build directory
|
||||||
RecastDemo/Build
|
RecastDemo/Build
|
||||||
|
|
||||||
|
# Ignore some meshes based on name
|
||||||
|
RecastDemo/Bin/Meshes/_*
|
||||||
|
|
||||||
## Logs and databases #
|
## Logs and databases #
|
||||||
*.log
|
*.log
|
||||||
*.sql
|
*.sql
|
||||||
|
@ -751,158 +751,55 @@ static void getHeightData(const rcCompactHeightfield& chf,
|
|||||||
// since border size offset is already removed from the polymesh vertices.
|
// since border size offset is already removed from the polymesh vertices.
|
||||||
|
|
||||||
stack.resize(0);
|
stack.resize(0);
|
||||||
|
memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);
|
||||||
|
|
||||||
static const int offset[9*2] =
|
// 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++)
|
||||||
{
|
{
|
||||||
0,0, -1,0, 0,1, 1,0, 0,-1, -1,-1, -1,1, 1,1, 1,-1
|
int y = hp.ymin + hy + bs;
|
||||||
};
|
for (int hx = 0; hx < hp.width; hx++)
|
||||||
|
|
||||||
// find the center of the polygon
|
|
||||||
int pcx = 0, pcz = 0;
|
|
||||||
for (int j = 0; j < npoly; ++j)
|
|
||||||
{
|
{
|
||||||
pcx += (int)verts[poly[j]*3+0];
|
int x = hp.xmin + hx + bs;
|
||||||
pcz += (int)verts[poly[j]*3+2];
|
const rcCompactCell& c = chf.cells[x+y*chf.width];
|
||||||
}
|
|
||||||
pcx /= npoly;
|
|
||||||
pcz /= npoly;
|
|
||||||
|
|
||||||
// find a span with the right region around this point
|
|
||||||
// No need to check for connectivity because the region ensures it
|
|
||||||
for (int dir = 0; dir < 9; ++dir)
|
|
||||||
{
|
|
||||||
int ax = pcx + offset[dir*2+0];
|
|
||||||
int az = pcz + offset[dir*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)
|
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
|
||||||
{
|
{
|
||||||
const rcCompactSpan& s = chf.spans[i];
|
const rcCompactSpan& s = chf.spans[i];
|
||||||
if (s.reg == region)
|
if (s.reg == region)
|
||||||
{
|
{
|
||||||
stack.push(ax);
|
// Store height
|
||||||
stack.push(az);
|
hp.data[hx + hy*hp.width] = s.y;
|
||||||
stack.push(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stack.size() > 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// in some rare dense cases the polygon simplification moves the polygon to a point where the center
|
|
||||||
// is very far from the region. So we search the span in flood-fill fashion from the vertices
|
|
||||||
if (stack.size() == 0)
|
|
||||||
{
|
|
||||||
memset(hp.data, 0, sizeof(unsigned short)*hp.width*hp.height);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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];
|
|
||||||
|
|
||||||
|
// 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)
|
for (int dir = 0; dir < 4; ++dir)
|
||||||
{
|
{
|
||||||
if (rcGetCon(cs, dir) == RC_NOT_CONNECTED) continue;
|
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
|
||||||
|
|
||||||
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] != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const int ai = (int)chf.cells[(ax+bs)+(ay+bs)*chf.width].index + rcGetCon(cs, dir);
|
|
||||||
|
|
||||||
int idx = ax-hp.xmin+(ay-hp.ymin)*hp.width;
|
|
||||||
hp.data[idx] = 1;
|
|
||||||
|
|
||||||
stack.push(ax);
|
|
||||||
stack.push(ay);
|
|
||||||
stack.push(ai);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Floodfill the heightfield to get 2D height data,
|
|
||||||
// starting at center location found above as seed.
|
|
||||||
|
|
||||||
memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height);
|
|
||||||
|
|
||||||
// Mark start locations.
|
|
||||||
for (int i = 0; i < stack.size(); i += 3)
|
|
||||||
{
|
{
|
||||||
int cx = stack[i+0];
|
const int ax = x + rcGetDirOffsetX(dir);
|
||||||
int cy = stack[i+1];
|
const int ay = y + rcGetDirOffsetY(dir);
|
||||||
int ci = stack[i+2];
|
const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir);
|
||||||
int idx = cx-hp.xmin+(cy-hp.ymin)*hp.width;
|
const rcCompactSpan& as = chf.spans[ai];
|
||||||
const rcCompactSpan& cs = chf.spans[ci];
|
if (as.reg != region)
|
||||||
hp.data[idx] = cs.y;
|
{
|
||||||
|
border = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (border)
|
||||||
|
{
|
||||||
|
stack.push(x);
|
||||||
|
stack.push(y);
|
||||||
|
stack.push(i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const int RETRACT_SIZE = 256;
|
static const int RETRACT_SIZE = 256;
|
||||||
int head = 0;
|
int head = 0;
|
||||||
@ -928,19 +825,19 @@ static void getHeightData(const rcCompactHeightfield& chf,
|
|||||||
|
|
||||||
const int ax = cx + rcGetDirOffsetX(dir);
|
const int ax = cx + rcGetDirOffsetX(dir);
|
||||||
const int ay = cy + rcGetDirOffsetY(dir);
|
const int ay = cy + rcGetDirOffsetY(dir);
|
||||||
|
const int hx = ax - hp.xmin - bs;
|
||||||
|
const int hy = ay - hp.ymin - bs;
|
||||||
|
|
||||||
if (ax < hp.xmin || ax >= (hp.xmin+hp.width) ||
|
if (hx < 0 || hx >= hp.width || hy < 0 || hy >= hp.height)
|
||||||
ay < hp.ymin || ay >= (hp.ymin+hp.height))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hp.data[ax-hp.xmin+(ay-hp.ymin)*hp.width] != RC_UNSET_HEIGHT)
|
if (hp.data[hx + hy*hp.width] != RC_UNSET_HEIGHT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int ai = (int)chf.cells[(ax+bs)+(ay+bs)*chf.width].index + rcGetCon(cs, dir);
|
const int ai = (int)chf.cells[ax + ay*chf.width].index + rcGetCon(cs, dir);
|
||||||
|
|
||||||
const rcCompactSpan& as = chf.spans[ai];
|
const rcCompactSpan& as = chf.spans[ai];
|
||||||
int idx = ax-hp.xmin+(ay-hp.ymin)*hp.width;
|
|
||||||
hp.data[idx] = as.y;
|
hp.data[hx + hy*hp.width] = as.y;
|
||||||
|
|
||||||
stack.push(ax);
|
stack.push(ax);
|
||||||
stack.push(ay);
|
stack.push(ay);
|
||||||
|
@ -170,17 +170,17 @@ void rcAddSpan(rcContext* /*ctx*/, rcHeightfield& hf, const int x, const int y,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// divides a convex polygons into two convex polygons on both sides of a line
|
// divides a convex polygons into two convex polygons on both sides of a line
|
||||||
static void dividePoly(const float* in, int nbIn,
|
static void dividePoly(const float* in, int nin,
|
||||||
float* out1, int* nb1,
|
float* out1, int* nout1,
|
||||||
float* out2, int* nb2,
|
float* out2, int* nout2,
|
||||||
float x, int axis)
|
float x, int axis)
|
||||||
{
|
{
|
||||||
float d[12];
|
float d[12];
|
||||||
for (int i = 0; i < nbIn; ++i)
|
for (int i = 0; i < nin; ++i)
|
||||||
d[i] = x - in[i*3+axis];
|
d[i] = x - in[i*3+axis];
|
||||||
|
|
||||||
int m = 0, n = 0;
|
int m = 0, n = 0;
|
||||||
for (int i = 0, j = nbIn-1; i < nbIn; j=i, ++i)
|
for (int i = 0, j = nin-1; i < nin; j=i, ++i)
|
||||||
{
|
{
|
||||||
bool ina = d[j] >= 0;
|
bool ina = d[j] >= 0;
|
||||||
bool inb = d[i] >= 0;
|
bool inb = d[i] >= 0;
|
||||||
@ -211,8 +211,8 @@ static void dividePoly(const float* in, int nbIn,
|
|||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*nb1 = m;
|
*nout1 = m;
|
||||||
*nb2 = n;
|
*nout2 = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public:
|
|||||||
}
|
}
|
||||||
m_size = n;
|
m_size = n;
|
||||||
}
|
}
|
||||||
inline void push(int item) { resize(m_size+1); m_data[m_size-1] = item; }
|
inline void push(dtPolyRef item) { resize(m_size+1); m_data[m_size-1] = item; }
|
||||||
inline dtPolyRef pop() { if (m_size > 0) m_size--; return m_data[m_size]; }
|
inline dtPolyRef pop() { if (m_size > 0) m_size--; return m_data[m_size]; }
|
||||||
inline const dtPolyRef& operator[](int i) const { return m_data[i]; }
|
inline const dtPolyRef& operator[](int i) const { return m_data[i]; }
|
||||||
inline dtPolyRef& operator[](int i) { return m_data[i]; }
|
inline dtPolyRef& operator[](int i) { return m_data[i]; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user