Added boxmapped texturing to input mesh, helps visualize it better. Added polymesh generation for layered heighfields.

This commit is contained in:
Mikko Mononen 2011-03-06 15:40:33 +00:00
parent 6cb0413cc7
commit e84d563bfe
16 changed files with 1612 additions and 193 deletions

View File

@ -37,6 +37,8 @@ struct duDebugDraw
virtual void depthMask(bool state) = 0; virtual void depthMask(bool state) = 0;
virtual void texture(bool state) = 0;
// Begin drawing primitives. // Begin drawing primitives.
// Params: // Params:
// prim - (in) primitive type to draw, one of rcDebugDrawPrimitives. // prim - (in) primitive type to draw, one of rcDebugDrawPrimitives.
@ -56,6 +58,18 @@ struct duDebugDraw
// color - (in) color of the verts. // color - (in) color of the verts.
virtual void vertex(const float x, const float y, const float z, unsigned int color) = 0; virtual void vertex(const float x, const float y, const float z, unsigned int color) = 0;
// Submit a vertex
// Params:
// pos - (in) position of the verts.
// color - (in) color of the verts.
virtual void vertex(const float* pos, unsigned int color, const float* uv) = 0;
// Submit a vertex
// Params:
// x,y,z - (in) position of the verts.
// color - (in) color of the verts.
virtual void vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v) = 0;
// End drawing primitives. // End drawing primitives.
virtual void end() = 0; virtual void end() = 0;
}; };

View File

@ -19,8 +19,8 @@
#ifndef RECAST_DEBUGDRAW_H #ifndef RECAST_DEBUGDRAW_H
#define RECAST_DEBUGDRAW_H #define RECAST_DEBUGDRAW_H
void duDebugDrawTriMesh(struct duDebugDraw* dd, const float* verts, int nverts, const int* tris, const float* normals, int ntris, const unsigned char* flags); void duDebugDrawTriMesh(struct duDebugDraw* dd, const float* verts, int nverts, const int* tris, const float* normals, int ntris, const unsigned char* flags, const float texScale);
void duDebugDrawTriMeshSlope(struct duDebugDraw* dd, const float* verts, int nverts, const int* tris, const float* normals, int ntris, const float walkableSlopeAngle); void duDebugDrawTriMeshSlope(struct duDebugDraw* dd, const float* verts, int nverts, const int* tris, const float* normals, int ntris, const float walkableSlopeAngle, const float texScale);
void duDebugDrawHeightfieldSolid(struct duDebugDraw* dd, const struct rcHeightfield& hf); void duDebugDrawHeightfieldSolid(struct duDebugDraw* dd, const struct rcHeightfield& hf);
void duDebugDrawHeightfieldWalkable(struct duDebugDraw* dd, const struct rcHeightfield& hf); void duDebugDrawHeightfieldWalkable(struct duDebugDraw* dd, const struct rcHeightfield& hf);
@ -35,6 +35,7 @@ void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLay
void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset); void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset);
void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& lcset); void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& lcset);
void duDebugDrawLayerPolyMesh(duDebugDraw* dd, const struct rcLayerPolyMesh& lmesh);
void duDebugDrawRegionConnections(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f); void duDebugDrawRegionConnections(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f);

View File

@ -24,33 +24,62 @@
void duDebugDrawTriMesh(duDebugDraw* dd, const float* verts, int /*nverts*/, void duDebugDrawTriMesh(duDebugDraw* dd, const float* verts, int /*nverts*/,
const int* tris, const float* normals, int ntris, const int* tris, const float* normals, int ntris,
const unsigned char* flags) const unsigned char* flags, const float texScale)
{ {
if (!dd) return; if (!dd) return;
if (!verts) return; if (!verts) return;
if (!tris) return; if (!tris) return;
if (!normals) return; if (!normals) return;
float uva[2];
float uvb[2];
float uvc[2];
const unsigned int unwalkable = duRGBA(192,128,0,255);
dd->texture(true);
dd->begin(DU_DRAW_TRIS); dd->begin(DU_DRAW_TRIS);
for (int i = 0; i < ntris*3; i += 3) for (int i = 0; i < ntris*3; i += 3)
{ {
const float* norm = &normals[i];
unsigned int color; unsigned int color;
unsigned char a = (unsigned char)(150*(2+normals[i+0]+normals[i+1])/4); unsigned char a = (unsigned char)(220*(2+norm[0]+norm[1])/4);
if (flags && !flags[i/3]) if (flags && !flags[i/3])
color = duRGBA(a,a/4,a/16,255); color = duLerpCol(duRGBA(a,a,a,255), unwalkable, 64);
else else
color = duRGBA(a,a,a,255); color = duRGBA(a,a,a,255);
dd->vertex(&verts[tris[i+0]*3], color); const float* va = &verts[tris[i+0]*3];
dd->vertex(&verts[tris[i+1]*3], color); const float* vb = &verts[tris[i+1]*3];
dd->vertex(&verts[tris[i+2]*3], color); const float* vc = &verts[tris[i+2]*3];
int ax = 0, ay = 0;
if (rcAbs(norm[1]) > rcAbs(norm[ax]))
ax = 1;
if (rcAbs(norm[2]) > rcAbs(norm[ax]))
ax = 2;
ax = (1<<ax)&3; // +1 mod 3
ay = (1<<ax)&3; // +1 mod 3
uva[0] = va[ax]*texScale;
uva[1] = va[ay]*texScale;
uvb[0] = vb[ax]*texScale;
uvb[1] = vb[ay]*texScale;
uvc[0] = vc[ax]*texScale;
uvc[1] = vc[ay]*texScale;
dd->vertex(va, color, uva);
dd->vertex(vb, color, uvb);
dd->vertex(vc, color, uvc);
} }
dd->end(); dd->end();
dd->texture(false);
} }
void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int /*nverts*/, void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int /*nverts*/,
const int* tris, const float* normals, int ntris, const int* tris, const float* normals, int ntris,
const float walkableSlopeAngle) const float walkableSlopeAngle, const float texScale)
{ {
if (!dd) return; if (!dd) return;
if (!verts) return; if (!verts) return;
@ -58,23 +87,52 @@ void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int /*nverts*/
if (!normals) return; if (!normals) return;
const float walkableThr = cosf(walkableSlopeAngle/180.0f*DU_PI); const float walkableThr = cosf(walkableSlopeAngle/180.0f*DU_PI);
float uva[2];
float uvb[2];
float uvc[2];
dd->texture(true);
const unsigned int unwalkable = duRGBA(192,128,0,255);
dd->begin(DU_DRAW_TRIS); dd->begin(DU_DRAW_TRIS);
for (int i = 0; i < ntris*3; i += 3) for (int i = 0; i < ntris*3; i += 3)
{ {
const float* norm = &normals[i]; const float* norm = &normals[i];
unsigned int color; unsigned int color;
unsigned char a = (unsigned char)(255*(2+normals[i+0]+normals[i+1])/4); unsigned char a = (unsigned char)(220*(2+norm[0]+norm[1])/4);
if (norm[1] < walkableThr) if (norm[1] < walkableThr)
color = duRGBA(a,a/4,a/16,255); color = duLerpCol(duRGBA(a,a,a,255), unwalkable, 64);
else else
color = duRGBA(a,a,a,255); color = duRGBA(a,a,a,255);
dd->vertex(&verts[tris[i+0]*3], color); const float* va = &verts[tris[i+0]*3];
dd->vertex(&verts[tris[i+1]*3], color); const float* vb = &verts[tris[i+1]*3];
dd->vertex(&verts[tris[i+2]*3], color); const float* vc = &verts[tris[i+2]*3];
int ax = 0, ay = 0;
if (rcAbs(norm[1]) > rcAbs(norm[ax]))
ax = 1;
if (rcAbs(norm[2]) > rcAbs(norm[ax]))
ax = 2;
ax = (1<<ax)&3; // +1 mod 3
ay = (1<<ax)&3; // +1 mod 3
uva[0] = va[ax]*texScale;
uva[1] = va[ay]*texScale;
uvb[0] = vb[ax]*texScale;
uvb[1] = vb[ay]*texScale;
uvc[0] = vc[ax]*texScale;
uvc[1] = vc[ay]*texScale;
dd->vertex(va, color, uva);
dd->vertex(vb, color, uvb);
dd->vertex(vc, color, uvc);
} }
dd->end(); dd->end();
dd->texture(false);
} }
void duDebugDrawHeightfieldSolid(duDebugDraw* dd, const rcHeightfield& hf) void duDebugDrawHeightfieldSolid(duDebugDraw* dd, const rcHeightfield& hf)
@ -498,7 +556,9 @@ void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& l
{ {
const rcLayerContour& c = lcset.conts[i]; const rcLayerContour& c = lcset.conts[i];
unsigned int color = 0; unsigned int color = 0;
color = duIntToCol(i, a);
for (int j = 0; j < c.nverts; ++j) for (int j = 0; j < c.nverts; ++j)
{ {
const int k = (j+1) % c.nverts; const int k = (j+1) % c.nverts;
@ -510,7 +570,6 @@ void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& l
const float bx = orig[0] + vb[0]*cs; const float bx = orig[0] + vb[0]*cs;
const float by = orig[1] + (vb[1]+1+(i&1))*ch; const float by = orig[1] + (vb[1]+1+(i&1))*ch;
const float bz = orig[2] + vb[2]*cs; const float bz = orig[2] + vb[2]*cs;
color = duIntToCol(vb[3], a);
dd->vertex(ax,ay,az,color); dd->vertex(ax,ay,az,color);
dd->vertex(bx,by,bz,duDarkenCol(color)); dd->vertex(bx,by,bz,duDarkenCol(color));
} }
@ -526,12 +585,10 @@ void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& l
for (int j = 0; j < c.nverts; ++j) for (int j = 0; j < c.nverts; ++j)
{ {
const int k = (j+1) % c.nverts;
const unsigned char* va = &c.verts[j*4]; const unsigned char* va = &c.verts[j*4];
const unsigned char* vb = &c.verts[k*4];
color = duDarkenCol(duIntToCol(va[3], a)); color = duDarkenCol(duIntToCol(i, a));
if (va[3] != vb[3]) if (va[3])
color = duRGBA(255,255,255,a); color = duRGBA(255,255,255,a);
float fx = orig[0] + va[0]*cs; float fx = orig[0] + va[0]*cs;
@ -543,6 +600,118 @@ void duDebugDrawLayerContours(duDebugDraw* dd, const struct rcLayerContourSet& l
dd->end(); dd->end();
} }
void duDebugDrawLayerPolyMesh(duDebugDraw* dd, const struct rcLayerPolyMesh& lmesh)
{
if (!dd) return;
const int nvp = lmesh.nvp;
const float cs = lmesh.cs;
const float ch = lmesh.ch;
const float* orig = lmesh.bmin;
dd->begin(DU_DRAW_TRIS);
for (int i = 0; i < lmesh.npolys; ++i)
{
const unsigned short* p = &lmesh.polys[i*nvp*2];
unsigned int color;
if (lmesh.areas[i] == RC_WALKABLE_AREA)
color = duRGBA(0,192,255,64);
else if (lmesh.areas[i] == RC_NULL_AREA)
color = duRGBA(0,0,0,64);
else
color = duIntToCol(lmesh.areas[i], 255);
unsigned short vi[3];
for (int j = 2; j < nvp; ++j)
{
if (p[j] == RC_MESH_NULL_IDX) break;
vi[0] = p[0];
vi[1] = p[j-1];
vi[2] = p[j];
for (int k = 0; k < 3; ++k)
{
const unsigned short* v = &lmesh.verts[vi[k]*3];
const float x = orig[0] + v[0]*cs;
const float y = orig[1] + (v[1]+1)*ch;
const float z = orig[2] + v[2]*cs;
dd->vertex(x,y,z, color);
}
}
}
dd->end();
// Draw neighbours edges
const unsigned int coln = duRGBA(0,48,64,32);
dd->begin(DU_DRAW_LINES, 1.5f);
for (int i = 0; i < lmesh.npolys; ++i)
{
const unsigned short* p = &lmesh.polys[i*nvp*2];
for (int j = 0; j < nvp; ++j)
{
if (p[j] == RC_MESH_NULL_IDX) break;
if (p[nvp+j] == RC_MESH_NULL_IDX) continue;
int vi[2];
vi[0] = p[j];
if (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX)
vi[1] = p[0];
else
vi[1] = p[j+1];
for (int k = 0; k < 2; ++k)
{
const unsigned short* v = &lmesh.verts[vi[k]*3];
const float x = orig[0] + v[0]*cs;
const float y = orig[1] + (v[1]+1)*ch + 0.1f;
const float z = orig[2] + v[2]*cs;
dd->vertex(x, y, z, coln);
}
}
}
dd->end();
// Draw boundary edges
const unsigned int colb = duRGBA(0,48,64,220);
dd->begin(DU_DRAW_LINES, 2.5f);
for (int i = 0; i < lmesh.npolys; ++i)
{
const unsigned short* p = &lmesh.polys[i*nvp*2];
for (int j = 0; j < nvp; ++j)
{
if (p[j] == RC_MESH_NULL_IDX) break;
if (p[nvp+j] != RC_MESH_NULL_IDX) continue;
int vi[2];
vi[0] = p[j];
if (j+1 >= nvp || p[j+1] == RC_MESH_NULL_IDX)
vi[1] = p[0];
else
vi[1] = p[j+1];
for (int k = 0; k < 2; ++k)
{
const unsigned short* v = &lmesh.verts[vi[k]*3];
const float x = orig[0] + v[0]*cs;
const float y = orig[1] + (v[1]+1)*ch + 0.1f;
const float z = orig[2] + v[2]*cs;
dd->vertex(x, y, z, colb);
}
}
}
dd->end();
dd->begin(DU_DRAW_POINTS, 3.0f);
const unsigned int colv = duRGBA(0,0,0,220);
for (int i = 0; i < lmesh.nverts; ++i)
{
const unsigned short* v = &lmesh.verts[i*3];
const float x = orig[0] + v[0]*cs;
const float y = orig[1] + (v[1]+1)*ch + 0.1f;
const float z = orig[2] + v[2]*cs;
dd->vertex(x,y,z, colv);
}
dd->end();
}
static void getContourCenter(const rcContour* cont, const float* orig, float cs, float ch, float* center) static void getContourCenter(const rcContour* cont, const float* orig, float cs, float ch, float* center)
{ {
center[0] = 0; center[0] = 0;

View File

@ -779,6 +779,28 @@ bool rcBuildLayerContours(rcContext* ctx,
rcLayerContourSet& lcset); rcLayerContourSet& lcset);
struct rcLayerPolyMesh
{
unsigned short* verts; // Vertices of the mesh, 3 elements per vertex.
unsigned short* polys; // Polygons of the mesh, nvp*2 elements per polygon.
unsigned short* flags; // Per polygon flags.
unsigned char* areas; // Area ID of polygons.
int nverts; // Number of vertices.
int npolys; // Number of polygons.
int maxpolys; // Number of allocated polygons.
int nvp; // Max number of vertices per polygon.
float bmin[3], bmax[3]; // Bounding box of the mesh.
float cs, ch; // Cell size and height.
};
rcLayerPolyMesh* rcAllocLayerPolyMesh();
void rcFreeLayerPolyMesh(rcLayerPolyMesh* lmesh);
bool rcBuildLayerPolyMesh(rcContext* ctx,
rcLayerContourSet& lcset,
const int maxVertsPerPoly,
rcLayerPolyMesh& lmesh);
// Builds simplified contours from the regions outlines. // Builds simplified contours from the regions outlines.

View File

@ -132,6 +132,23 @@ void rcFreeLayerContourSet(rcLayerContourSet* cset)
rcFree(cset); rcFree(cset);
} }
rcLayerPolyMesh* rcAllocLayerPolyMesh()
{
rcLayerPolyMesh* lmesh = (rcLayerPolyMesh*)rcAlloc(sizeof(rcLayerPolyMesh), RC_ALLOC_PERM);
memset(lmesh, 0, sizeof(rcLayerPolyMesh));
return lmesh;
}
void rcFreeLayerPolyMesh(rcLayerPolyMesh* lmesh)
{
if (!lmesh) return;
rcFree(lmesh->verts);
rcFree(lmesh->polys);
rcFree(lmesh->flags);
rcFree(lmesh->areas);
rcFree(lmesh);
}
rcContourSet* rcAllocContourSet() rcContourSet* rcAllocContourSet()

File diff suppressed because it is too large Load Diff

View File

@ -195,7 +195,7 @@ inline bool collinear(const int* a, const int* b, const int* c)
// Returns true iff ab properly intersects cd: they share // Returns true iff ab properly intersects cd: they share
// a point interior to both segments. The properness of the // a point interior to both segments. The properness of the
// intersection is ensured by using strict leftness. // intersection is ensured by using strict leftness.
bool intersectProp(const int* a, const int* b, const int* c, const int* d) static bool intersectProp(const int* a, const int* b, const int* c, const int* d)
{ {
// Eliminate improper cases. // Eliminate improper cases.
if (collinear(a,b,c) || collinear(a,b,d) || if (collinear(a,b,c) || collinear(a,b,d) ||
@ -470,6 +470,7 @@ static void mergePolys(unsigned short* pa, unsigned short* pb, int ea, int eb,
memcpy(pa, tmp, sizeof(unsigned short)*nvp); memcpy(pa, tmp, sizeof(unsigned short)*nvp);
} }
static void pushFront(int v, int* arr, int& an) static void pushFront(int v, int* arr, int& an)
{ {
an++; an++;
@ -1165,11 +1166,11 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, int nvp, rcPolyMesh& me
if (mesh.nverts > 0xffff) if (mesh.nverts > 0xffff)
{ {
ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff); ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many vertices %d (max %d). Data can be corrupted.", mesh.nverts, 0xffff);
} }
if (mesh.npolys > 0xffff) if (mesh.npolys > 0xffff)
{ {
ctx->log(RC_LOG_ERROR, "rcMergePolyMeshes: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff); ctx->log(RC_LOG_ERROR, "rcBuildPolyMesh: The resulting mesh has too many polygons %d (max %d). Data can be corrupted.", mesh.npolys, 0xffff);
} }
ctx->stopTimer(RC_TIMER_BUILD_POLYMESH); ctx->stopTimer(RC_TIMER_BUILD_POLYMESH);

View File

@ -65,9 +65,12 @@ class DebugDrawGL : public duDebugDraw
{ {
public: public:
virtual void depthMask(bool state); virtual void depthMask(bool state);
virtual void texture(bool state);
virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f); virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f);
virtual void vertex(const float* pos, unsigned int color); virtual void vertex(const float* pos, unsigned int color);
virtual void vertex(const float x, const float y, const float z, unsigned int color); virtual void vertex(const float x, const float y, const float z, unsigned int color);
virtual void vertex(const float* pos, unsigned int color, const float* uv);
virtual void vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v);
virtual void end(); virtual void end();
}; };

View File

@ -44,6 +44,8 @@ protected:
rcHeightfieldLayerSet* m_lset; rcHeightfieldLayerSet* m_lset;
rcLayerContourSet* m_lcsets[MAX_LAYERS]; rcLayerContourSet* m_lcsets[MAX_LAYERS];
int m_nlcsets; int m_nlcsets;
rcLayerPolyMesh* m_lmeshes[MAX_LAYERS];
int m_nlmeshes;
enum DrawMode enum DrawMode
{ {
@ -68,6 +70,7 @@ protected:
DRAWMODE_HEIGHFIELD_LAYERS, DRAWMODE_HEIGHFIELD_LAYERS,
DRAWMODE_LAYER_CONTOURS, DRAWMODE_LAYER_CONTOURS,
DRAWMODE_LAYER_MESHES,
MAX_DRAWMODE MAX_DRAWMODE
}; };

View File

@ -82,7 +82,7 @@ void Sample::handleRender()
// Draw mesh // Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0); m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0, 1.0f);
// Draw bounds // Draw bounds
const float* bmin = m_geom->getMeshBoundsMin(); const float* bmin = m_geom->getMeshBoundsMin();
const float* bmax = m_geom->getMeshBoundsMax(); const float* bmax = m_geom->getMeshBoundsMax();

View File

@ -139,11 +139,64 @@ const char* BuildContext::getLogText(const int i) const
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
class GLCheckerTexture
{
unsigned int m_texId;
public:
GLCheckerTexture() : m_texId(0)
{
}
~GLCheckerTexture()
{
if (m_texId != 0)
glDeleteTextures(1, &m_texId);
}
void bind()
{
if (m_texId == 0)
{
// Create checker pattern.
const unsigned int col0 = duRGBA(215,215,215,255);
const unsigned int col1 = duRGBA(255,255,255,255);
static const int TSIZE = 32;
unsigned int data[TSIZE*TSIZE];
for (int y = 0; y < TSIZE; ++y)
for (int x = 0; x < TSIZE; ++x)
data[x+y*TSIZE] = (x==0 || y==0) ? col0 : col1;
glGenTextures(1, &m_texId);
glBindTexture(GL_TEXTURE_2D, m_texId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TSIZE,TSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else
{
glBindTexture(GL_TEXTURE_2D, m_texId);
}
}
};
GLCheckerTexture g_tex;
void DebugDrawGL::depthMask(bool state) void DebugDrawGL::depthMask(bool state)
{ {
glDepthMask(state ? GL_TRUE : GL_FALSE); glDepthMask(state ? GL_TRUE : GL_FALSE);
} }
void DebugDrawGL::texture(bool state)
{
if (state)
{
glEnable(GL_TEXTURE_2D);
g_tex.bind();
}
else
{
glDisable(GL_TEXTURE_2D);
}
}
void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size) void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
{ {
switch (prim) switch (prim)
@ -177,6 +230,20 @@ void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned i
glVertex3f(x,y,z); glVertex3f(x,y,z);
} }
void DebugDrawGL::vertex(const float* pos, unsigned int color, const float* uv)
{
glColor4ubv((GLubyte*)&color);
glTexCoord2fv(uv);
glVertex3fv(pos);
}
void DebugDrawGL::vertex(const float x, const float y, const float z, unsigned int color, const float u, const float v)
{
glColor4ubv((GLubyte*)&color);
glTexCoord2f(u,v);
glVertex3f(x,y,z);
}
void DebugDrawGL::end() void DebugDrawGL::end()
{ {
glEnd(); glEnd();

View File

@ -215,19 +215,14 @@ void Sample_SoloMeshSimple::handleRender()
glEnable(GL_FOG); glEnable(GL_FOG);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
if (m_drawMode == DRAWMODE_MESH) const float texScale = 1.0f / (m_cellSize * 10.0f);
if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{ {
// Draw mesh // Draw mesh
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
m_agentMaxSlope); m_agentMaxSlope, texScale);
m_geom->drawOffMeshConnections(&dd);
}
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{
// Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd); m_geom->drawOffMeshConnections(&dd);
} }

View File

@ -347,19 +347,14 @@ void Sample_SoloMeshTiled::handleRender()
glEnable(GL_FOG); glEnable(GL_FOG);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
if (m_drawMode == DRAWMODE_MESH) const float texScale = 1.0f / (m_cellSize * 10.0f);
if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{ {
// Draw mesh // Draw mesh
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
m_agentMaxSlope); m_agentMaxSlope, texScale);
m_geom->drawOffMeshConnections(&dd);
}
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{
// Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd); m_geom->drawOffMeshConnections(&dd);
} }

View File

@ -1460,20 +1460,23 @@ void Sample_TempObstacles::handleRender()
DebugDrawGL dd; DebugDrawGL dd;
const float texScale = 1.0f / (m_cellSize * 10.0f);
// Draw mesh // Draw mesh
if (m_drawMode == DRAWMODE_MESH) if (m_drawMode == DRAWMODE_MESH)
{ {
// Draw mesh // Draw mesh
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
m_agentMaxSlope); m_agentMaxSlope, texScale);
m_geom->drawOffMeshConnections(&dd); m_geom->drawOffMeshConnections(&dd);
} }
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS) else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{ {
// Draw mesh // Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0); m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0,
texScale);
m_geom->drawOffMeshConnections(&dd); m_geom->drawOffMeshConnections(&dd);
} }

View File

@ -183,6 +183,7 @@ Sample_TileMesh::Sample_TileMesh() :
m_dmesh(0), m_dmesh(0),
m_lset(0), m_lset(0),
m_nlcsets(0), m_nlcsets(0),
m_nlmeshes(0),
m_drawMode(DRAWMODE_NAVMESH), m_drawMode(DRAWMODE_NAVMESH),
m_maxTiles(0), m_maxTiles(0),
m_maxPolysPerTile(0), m_maxPolysPerTile(0),
@ -197,6 +198,7 @@ Sample_TileMesh::Sample_TileMesh() :
memset(m_tileBmax, 0, sizeof(m_tileBmax)); memset(m_tileBmax, 0, sizeof(m_tileBmax));
memset(m_lcsets, 0, sizeof(m_lcsets)); memset(m_lcsets, 0, sizeof(m_lcsets));
memset(m_lmeshes, 0, sizeof(m_lmeshes));
setTool(new NavMeshTileTool); setTool(new NavMeshTileTool);
} }
@ -225,12 +227,20 @@ void Sample_TileMesh::cleanup()
rcFreeHeightfieldLayerSet(m_lset); rcFreeHeightfieldLayerSet(m_lset);
m_lset = 0; m_lset = 0;
for (int i = 0; i < MAX_LAYERS; ++i) for (int i = 0; i < MAX_LAYERS; ++i)
{ {
rcFreeLayerContourSet(m_lcsets[i]); rcFreeLayerContourSet(m_lcsets[i]);
m_lcsets[i] = 0; m_lcsets[i] = 0;
} }
m_nlcsets = 0; m_nlcsets = 0;
for (int i = 0; i < MAX_LAYERS; ++i)
{
rcFreeLayerPolyMesh(m_lmeshes[i]);
m_lmeshes[i] = 0;
}
m_nlmeshes = 0;
} }
@ -481,6 +491,7 @@ void Sample_TileMesh::handleDebugMode()
valid[DRAWMODE_POLYMESH_DETAIL] = m_dmesh != 0; valid[DRAWMODE_POLYMESH_DETAIL] = m_dmesh != 0;
valid[DRAWMODE_HEIGHFIELD_LAYERS] = m_lset != 0; valid[DRAWMODE_HEIGHFIELD_LAYERS] = m_lset != 0;
valid[DRAWMODE_LAYER_CONTOURS] = m_nlcsets != 0; valid[DRAWMODE_LAYER_CONTOURS] = m_nlcsets != 0;
valid[DRAWMODE_LAYER_MESHES] = m_nlmeshes != 0;
} }
int unavail = 0; int unavail = 0;
@ -528,10 +539,14 @@ void Sample_TileMesh::handleDebugMode()
if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL])) if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL]))
m_drawMode = DRAWMODE_POLYMESH_DETAIL; m_drawMode = DRAWMODE_POLYMESH_DETAIL;
imguiSeparatorLine();
if (imguiCheck("Heighfield Layers", m_drawMode == DRAWMODE_HEIGHFIELD_LAYERS, valid[DRAWMODE_HEIGHFIELD_LAYERS])) if (imguiCheck("Heighfield Layers", m_drawMode == DRAWMODE_HEIGHFIELD_LAYERS, valid[DRAWMODE_HEIGHFIELD_LAYERS]))
m_drawMode = DRAWMODE_HEIGHFIELD_LAYERS; m_drawMode = DRAWMODE_HEIGHFIELD_LAYERS;
if (imguiCheck("Layer Contours", m_drawMode == DRAWMODE_LAYER_CONTOURS, valid[DRAWMODE_LAYER_CONTOURS])) if (imguiCheck("Layer Contours", m_drawMode == DRAWMODE_LAYER_CONTOURS, valid[DRAWMODE_LAYER_CONTOURS]))
m_drawMode = DRAWMODE_LAYER_CONTOURS; m_drawMode = DRAWMODE_LAYER_CONTOURS;
if (imguiCheck("Layer Meshes", m_drawMode == DRAWMODE_LAYER_MESHES, valid[DRAWMODE_LAYER_MESHES]))
m_drawMode = DRAWMODE_LAYER_MESHES;
if (unavail) if (unavail)
{ {
@ -548,23 +563,20 @@ void Sample_TileMesh::handleRender()
DebugDrawGL dd; DebugDrawGL dd;
const float texScale = 1.0f / (m_cellSize * 10.0f);
// Draw mesh // Draw mesh
if (m_drawMode == DRAWMODE_MESH) if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{ {
// Draw mesh // Draw mesh
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
m_agentMaxSlope); m_agentMaxSlope, texScale);
m_geom->drawOffMeshConnections(&dd);
}
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
{
// Draw mesh
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd); m_geom->drawOffMeshConnections(&dd);
} }
/* duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(), /* duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0); m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
m_geom->drawOffMeshConnections(&dd);*/ m_geom->drawOffMeshConnections(&dd);*/
@ -690,6 +702,14 @@ void Sample_TileMesh::handleRender()
duDebugDrawLayerContours(&dd, *m_lcsets[i]); duDebugDrawLayerContours(&dd, *m_lcsets[i]);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
} }
if (m_nlmeshes && m_drawMode == DRAWMODE_LAYER_MESHES)
{
glDepthMask(GL_FALSE);
for (int i = 0; i < m_nlmeshes; ++i)
duDebugDrawLayerPolyMesh(&dd, *m_lmeshes[i]);
glDepthMask(GL_TRUE);
}
m_geom->drawConvexVolumes(&dd); m_geom->drawConvexVolumes(&dd);
@ -1137,6 +1157,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
} }
m_nlcsets = 0; m_nlcsets = 0;
m_nlmeshes = 0;
for (int i = 0; i < m_lset->nlayers; ++i) for (int i = 0; i < m_lset->nlayers; ++i)
{ {
rcBuildLayerRegions(m_ctx, m_lset->layers[i], m_cfg.walkableClimb); rcBuildLayerRegions(m_ctx, m_lset->layers[i], m_cfg.walkableClimb);
@ -1146,7 +1167,16 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_cfg.walkableClimb, m_cfg.maxSimplificationError, m_cfg.walkableClimb, m_cfg.maxSimplificationError,
*m_lcsets[m_nlcsets])) *m_lcsets[m_nlcsets]))
break; break;
m_lmeshes[m_nlmeshes] = rcAllocLayerPolyMesh();
if (!rcBuildLayerPolyMesh(m_ctx, *m_lcsets[m_nlcsets],
m_cfg.maxVertsPerPoly,
*m_lmeshes[m_nlmeshes]))
break;
m_nlcsets++; m_nlcsets++;
m_nlmeshes++;
} }
} }

View File

@ -162,10 +162,10 @@ int main(int /*argc*/, char** /*argv*/)
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
float fogCol[4] = { 0.32f,0.25f,0.25f,1 }; float fogCol[4] = { 0.32f, 0.31f, 0.30f, 1.0f };
glEnable(GL_FOG); glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_LINEAR); glFogi(GL_FOG_MODE, GL_LINEAR);
glFogf(GL_FOG_START, camr*0.2f); glFogf(GL_FOG_START, camr*0.1f);
glFogf(GL_FOG_END, camr*1.25f); glFogf(GL_FOG_END, camr*1.25f);
glFogfv(GL_FOG_COLOR, fogCol); glFogfv(GL_FOG_COLOR, fogCol);
@ -667,7 +667,7 @@ int main(int /*argc*/, char** /*argv*/)
} }
rx = 45; rx = 45;
ry = -45; ry = -45;
glFogf(GL_FOG_START, camr*0.2f); glFogf(GL_FOG_START, camr*0.1f);
glFogf(GL_FOG_END, camr*1.25f); glFogf(GL_FOG_END, camr*1.25f);
} }
@ -743,7 +743,7 @@ int main(int /*argc*/, char** /*argv*/)
} }
rx = 45; rx = 45;
ry = -45; ry = -45;
glFogf(GL_FOG_START, camr*0.2f); glFogf(GL_FOG_START, camr*0.1f);
glFogf(GL_FOG_END, camr*1.25f); glFogf(GL_FOG_END, camr*1.25f);
} }
} }
@ -857,7 +857,7 @@ int main(int /*argc*/, char** /*argv*/)
} }
rx = 45; rx = 45;
ry = -45; ry = -45;
glFogf(GL_FOG_START, camr*0.2f); glFogf(GL_FOG_START, camr*0.1f);
glFogf(GL_FOG_END, camr*1.25f); glFogf(GL_FOG_END, camr*1.25f);
} }