void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int /*nverts*/, const int* tris, const float* normals, int ntris, const float walkableSlopeAngle) { if (!dd) return; if (!verts) return; if (!tris) return; if (!normals) return; const float walkableThr = cosf(walkableSlopeAngle/180.0f*(float)M_PI); dd->begin(DU_DRAW_TRIS); for (int i = 0; i < ntris*3; i += 3) { const float* norm = &normals[i]; unsigned int color; unsigned char a = (unsigned char)(255*(2+normals[i+0]+normals[i+1])/4); if (norm[1] < walkableThr) color = duRGBA(a,a/4,a/16,255); else color = duRGBA(a,a,a,255); dd->vertex(&verts[tris[i+0]*3], color); dd->vertex(&verts[tris[i+1]*3], color); dd->vertex(&verts[tris[i+2]*3], color); } dd->end(); }
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 = 64; unsigned int data[TSIZE*TSIZE]; glGenTextures(1, &m_texId); glBindTexture(GL_TEXTURE_2D, m_texId); int level = 0; int size = TSIZE; while (size > 0) { for (int y = 0; y < size; ++y) for (int x = 0; x < size; ++x) data[x+y*size] = (x==0 || y==0) ? col0 : col1; glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size,size, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); size /= 2; level++; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { glBindTexture(GL_TEXTURE_2D, m_texId); } }
void duDebugDrawTriMesh(duDebugDraw* dd, const float* verts, int /*nverts*/, const int* tris, const float* normals, int ntris, const unsigned char* flags) { if (!dd) return; if (!verts) return; if (!tris) return; if (!normals) return; dd->begin(DU_DRAW_TRIS); for (int i = 0; i < ntris*3; i += 3) { unsigned int color; unsigned char a = (unsigned char)(150*(2+normals[i+0]+normals[i+1])/4); if (flags && !flags[i/3]) color = duRGBA(a,a/4,a/16,255); else color = duRGBA(a,a,a,255); dd->vertex(&verts[tris[i+0]*3], color); dd->vertex(&verts[tris[i+1]*3], color); dd->vertex(&verts[tris[i+2]*3], color); } dd->end(); }
void duDebugDrawHeightfieldSolid(duDebugDraw* dd, const rcHeightfield& hf) { if (!dd) return; const float* orig = hf.bmin; const float cs = hf.cs; const float ch = hf.ch; const int w = hf.width; const int h = hf.height; unsigned int fcol[6]; duCalcBoxColors(fcol, duRGBA(255,255,255,255), duRGBA(255,255,255,255)); dd->begin(DU_DRAW_QUADS); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { float fx = orig[0] + x*cs; float fz = orig[2] + y*cs; const rcSpan* s = hf.spans[x + y*w]; while (s) { duAppendBox(dd, fx, orig[1]+s->smin*ch, fz, fx+cs, orig[1] + s->smax*ch, fz+cs, fcol); s = s->next; } } } dd->end(); }
void RecastMapRenderer::DrawAgents(duDebugDraw* dd) { for (int i = 0; i < m_RecastMap->GetCrowd()->getAgentCount(); ++i) { const dtCrowdAgent* ag = m_RecastMap->GetCrowd()->getAgent(i); if (!ag->active) continue; const float height = ag->params.height; const float radius = ag->params.radius; const float* pos = ag->npos; unsigned int col = duRGBA(220,220,220,128); if (ag->targetState == DT_CROWDAGENT_TARGET_REQUESTING || ag->targetState == DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE) col = duLerpCol(col, duRGBA(128,0,255,128), 32); else if (ag->targetState == DT_CROWDAGENT_TARGET_WAITING_FOR_PATH) col = duLerpCol(col, duRGBA(128,0,255,128), 128); else if (ag->targetState == DT_CROWDAGENT_TARGET_FAILED) col = duRGBA(255,32,16,128); else if (ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY) col = duLerpCol(col, duRGBA(64,255,0,128), 128); duDebugDrawCylinder(dd, pos[0]-radius, pos[1]+radius*0.1f, pos[2]-radius, pos[0]+radius, pos[1]+height, pos[2]+radius, col); } }
void cocos2d::NavMesh::drawOffMeshConnections() { unsigned int conColor = duRGBA(192, 0, 128, 192); unsigned int baseColor = duRGBA(0, 0, 0, 64); _debugDraw.begin(DU_DRAW_LINES, 2.0f); for (int i = 0; i < _geomData->offMeshConCount; ++i) { float* v = &_geomData->offMeshConVerts[i * 3 * 2]; _debugDraw.vertex(v[0], v[1], v[2], baseColor); _debugDraw.vertex(v[0], v[1] + 0.2f, v[2], baseColor); _debugDraw.vertex(v[3], v[4], v[5], baseColor); _debugDraw.vertex(v[3], v[4] + 0.2f, v[5], baseColor); duAppendCircle(&_debugDraw, v[0], v[1] + 0.1f, v[2], _geomData->offMeshConRads[i], baseColor); duAppendCircle(&_debugDraw, v[3], v[4] + 0.1f, v[5], _geomData->offMeshConRads[i], baseColor); if (/*hilight*/true) { duAppendArc(&_debugDraw, v[0], v[1], v[2], v[3], v[4], v[5], 0.25f, (_geomData->offMeshConDirs[i] & 1) ? 0.6f : 0.0f, 0.6f, conColor); } } _debugDraw.end(); }
void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool hilight) { unsigned int conColor = duRGBA(192,0,128,192); unsigned int baseColor = duRGBA(0,0,0,64); dd->depthMask(false); dd->begin(DU_DRAW_LINES, 2.0f); for (int i = 0; i < m_offMeshConCount; ++i) { float* v = &m_offMeshConVerts[i*3*2]; dd->vertex(v[0],v[1],v[2], baseColor); dd->vertex(v[0],v[1]+0.2f,v[2], baseColor); dd->vertex(v[3],v[4],v[5], baseColor); dd->vertex(v[3],v[4]+0.2f,v[5], baseColor); duAppendCircle(dd, v[0],v[1]+0.1f,v[2], m_offMeshConRads[i], baseColor); duAppendCircle(dd, v[3],v[4]+0.1f,v[5], m_offMeshConRads[i], baseColor); if (hilight) { duAppendArc(dd, v[0],v[1],v[2], v[3],v[4],v[5], 0.25f, (m_offMeshConDirs[i]&1) ? 0.6f : 0.0f, 0.6f, conColor); } } dd->end(); dd->depthMask(true); }
void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int /*nverts*/, const int* tris, const float* normals, int ntris, const float walkableSlopeAngle, const float texScale) { if (!dd) return; if (!verts) return; if (!tris) return; if (!normals) return; 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); for (int i = 0; i < ntris*3; i += 3) { const float* norm = &normals[i]; unsigned int color; unsigned char a = (unsigned char)(220*(2+norm[0]+norm[1])/4); if (norm[1] < walkableThr) color = duLerpCol(duRGBA(a,a,a,255), unwalkable, 64); else color = duRGBA(a,a,a,255); const float* va = &verts[tris[i+0]*3]; const float* vb = &verts[tris[i+1]*3]; 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->texture(false); }
void duDebugDrawHeightfieldLayer(duDebugDraw* dd, const struct rcHeightfieldLayer& layer, const int idx) { const float cs = layer.cs; const float ch = layer.ch; const int w = layer.width; const int h = layer.height; unsigned int color = duIntToCol(idx+1, 255); // Layer bounds float bmin[3], bmax[3]; bmin[0] = layer.bmin[0] + layer.minx*cs; bmin[1] = layer.bmin[1]; bmin[2] = layer.bmin[2] + layer.miny*cs; bmax[0] = layer.bmin[0] + (layer.maxx+1)*cs; bmax[1] = layer.bmax[1]; bmax[2] = layer.bmin[2] + (layer.maxy+1)*cs; duDebugDrawBoxWire(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duTransCol(color,128), 2.0f); // Layer height dd->begin(DU_DRAW_QUADS); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { const int lidx = x+y*w; const int lh = (int)layer.heights[lidx]; if (h == 0xff) continue; const unsigned char area = layer.areas[lidx]; unsigned int col; if (area == RC_WALKABLE_AREA) col = duLerpCol(color, duRGBA(0,192,255,64), 32); else if (area == RC_NULL_AREA) col = duLerpCol(color, duRGBA(0,0,0,64), 32); else col = duLerpCol(color, duIntToCol(area, 255), 32); const float fx = layer.bmin[0] + x*cs; const float fy = layer.bmin[1] + (lh+1)*ch; const float fz = layer.bmin[2] + y*cs; dd->vertex(fx, fy, fz, col); dd->vertex(fx, fy, fz+cs, col); dd->vertex(fx+cs, fy, fz+cs, col); dd->vertex(fx+cs, fy, fz, col); } } dd->end(); // Portals drawLayerPortals(dd, &layer); }
void Visualization::renderDebugInfoOverlay() { GraphParams gp; gp.setRect(10, 10, 500, 200, 8); gp.setValueRange(0.0f, 2.0f, 4, "ms"); drawGraphBackground(&gp); drawGraph(&gp, &m_debugInfo->m_crowdTotalTime, 1, "Crowd update", duRGBA(255,128,0,255)); gp.setRect(10, 10, 500, 200, 8); gp.setValueRange(0.0f, 2000.0f, 1, ""); drawGraph(&gp, &m_debugInfo->m_crowdSampleCount, 0, "Sample Count", duRGBA(96,96,96,128)); }
void ConvexVolumeTool::handleRender() { DebugDrawGL dd; // Find height extents of the shape. float minh = FLT_MAX, maxh = 0; for (int i = 0; i < m_npts; ++i) minh = rcMin(minh, m_pts[i*3+1]); minh -= m_boxDescent; maxh = minh + m_boxHeight; dd.begin(DU_DRAW_POINTS, 4.0f); for (int i = 0; i < m_npts; ++i) { unsigned int col = duRGBA(255,255,255,255); if (i == m_npts-1) col = duRGBA(240,32,16,255); dd.vertex(m_pts[i*3+0],m_pts[i*3+1]+0.1f,m_pts[i*3+2], col); } dd.end(); dd.begin(DU_DRAW_LINES, 2.0f); for (int i = 0, j = m_nhull-1; i < m_nhull; j = i++) { const float* vi = &m_pts[m_hull[j]*3]; const float* vj = &m_pts[m_hull[i]*3]; dd.vertex(vj[0],minh,vj[2], duRGBA(255,255,255,64)); dd.vertex(vi[0],minh,vi[2], duRGBA(255,255,255,64)); dd.vertex(vj[0],maxh,vj[2], duRGBA(255,255,255,64)); dd.vertex(vi[0],maxh,vi[2], duRGBA(255,255,255,64)); dd.vertex(vj[0],minh,vj[2], duRGBA(255,255,255,64)); dd.vertex(vj[0],maxh,vj[2], duRGBA(255,255,255,64)); } dd.end(); }
void RecastMapRenderer::Render() { if (!m_RecastMap->GetGeometry() || !m_RecastMap->GetGeometry()->getMesh()) return; // ========================================== setup glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); DebugDrawGL dd; const float texScale = 1.0f / (RECAST_CELL_SIZE * 10.0f); duDebugDrawTriMeshSlope(&dd, m_RecastMap->GetGeometry()->getMesh()->getVerts(), m_RecastMap->GetGeometry()->getMesh()->getVertCount(), m_RecastMap->GetGeometry()->getMesh()->getTris(), m_RecastMap->GetGeometry()->getMesh()->getNormals(), m_RecastMap->GetGeometry()->getMesh()->getTriCount(), RECAST_AGENT_MAX_SLOPE, texScale); DrawAgents(&dd); glDepthMask(GL_FALSE); // Draw bounds const float* bmin = m_RecastMap->GetGeometry()->getMeshBoundsMin(); const float* bmax = m_RecastMap->GetGeometry()->getMeshBoundsMax(); duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f); // Tiling grid. int gw = 0, gh = 0; rcCalcGridSize(bmin, bmax, RECAST_CELL_SIZE, &gw, &gh); const int tw = (gw + RECAST_TILE_SIZE - 1) / RECAST_TILE_SIZE; const int th = (gh + RECAST_TILE_SIZE - 1) / RECAST_TILE_SIZE; const float s = RECAST_TILE_SIZE*RECAST_CELL_SIZE; duDebugDrawGridXZ(&dd, bmin[0],bmin[1],bmin[2], tw,th, s, duRGBA(0,0,0,64), 1.0f); if(m_RecastMap->GetMesh() && m_RecastMap->GetQuery()) { duDebugDrawNavMesh(&dd, *(m_RecastMap->GetMesh()), DU_DRAWNAVMESH_COLOR_TILES|DU_DRAWNAVMESH_CLOSEDLIST|DU_DRAWNAVMESH_OFFMESHCONS); duDebugDrawNavMeshPolysWithFlags(&dd, *(m_RecastMap->GetMesh()), POLY_ABILITY_DISABLED, duRGBA(0,0,0,128)); } if (m_RecastMap->GetTileCache()) //DrawTiles(&dd, m_RecastMap->GetTileCache()); if (m_RecastMap->GetTileCache()) DrawObstacles(&dd, m_RecastMap->GetTileCache()); if (m_RecastMap->GetGeometry()) DrawConvexVolumes(&dd, m_RecastMap->GetGeometry()); }
void Sample_TileMesh::buildTile(const float* pos) { if (!m_geom) return; if (!m_navMesh) return; const float* bmin = m_geom->getMeshBoundsMin(); const float* bmax = m_geom->getMeshBoundsMax(); const float ts = m_tileSize*m_cellSize; const int tx = (int)((pos[0] - bmin[0]) / ts); const int ty = (int)((pos[2] - bmin[2]) / ts); m_tileBmin[0] = bmin[0] + tx*ts; m_tileBmin[1] = bmin[1]; m_tileBmin[2] = bmin[2] + ty*ts; m_tileBmax[0] = bmin[0] + (tx+1)*ts; m_tileBmax[1] = bmax[1]; m_tileBmax[2] = bmin[2] + (ty+1)*ts; m_tileCol = duRGBA(77,204,0,255); int dataSize = 0; unsigned char* data = buildTileMesh(tx, ty, m_tileBmin, m_tileBmax, dataSize); if (data) { // Remove any previous data (navmesh owns and deletes the data). m_navMesh->removeTile(m_navMesh->getTileRefAt(tx,ty),0,0); // Let the navmesh own the data. if (!m_navMesh->addTile(data,dataSize,DT_TILE_FREE_DATA)) dtFree(data); } }
Sample_TileMesh::Sample_TileMesh() : m_keepInterResults(false), m_buildAll(true), m_totalBuildTimeMs(0), m_triareas(0), m_solid(0), m_chf(0), m_cset(0), m_pmesh(0), m_dmesh(0), m_drawMode(DRAWMODE_NAVMESH), m_maxTiles(0), m_maxPolysPerTile(0), m_tileSize(32), m_tileCol(duRGBA(0,0,0,32)), m_tileBuildTime(0), m_tileMemUsage(0), m_tileTriCount(0) { resetCommonSettings(); memset(m_lastBuiltTileBmin, 0, sizeof(m_lastBuiltTileBmin)); memset(m_lastBuiltTileBmax, 0, sizeof(m_lastBuiltTileBmax)); setTool(new NavMeshTileTool); }
unsigned int duIntToCol(int i, int a) { int r = bit(i, 1) + bit(i, 3) * 2 + 1; int g = bit(i, 2) + bit(i, 4) * 2 + 1; int b = bit(i, 0) + bit(i, 5) * 2 + 1; return duRGBA(r*63,g*63,b*63,a); }
CMaNGOS_Map::CMaNGOS_Map() : m_drawMode(DRAWMODE_NAVMESH), m_navMeshDrawFlags(DU_DRAWNAVMESH_OFFMESHCONS | DU_DRAWNAVMESH_COLOR_TILES), m_maxTiles(0), m_maxPolysPerTile(0), m_tileSize(32), m_tileCol(duRGBA(11, 243, 229, 200)), m_tileBuildTime(0), m_tileMemUsage(0), m_tileTriCount(0), m_isBuilded(false), m_bigBaseUnit(false), m_mapID(0), m_showLevelOld(false), m_DrawVMapMesh(true), m_DrawMapMesh(true), m_showLevel(SHOW_LEVEL_NONE), m_GeomChanged(false), m_tool(NULL), m_SelectedTile(NULL) { for (int i = 0; i < MAX_TOOLS; i++) m_toolStates[i] = NULL; for (int i = 0; i < 3; i++) m_LastClick[i] = 0.0f; }
void CrowdTool::handleRenderOverlay(double* proj, double* model, int* view) { GLdouble x, y, z; // Draw start and end point labels if (m_targetRef && gluProject((GLdouble)m_targetPos[0], (GLdouble)m_targetPos[1], (GLdouble)m_targetPos[2], model, proj, view, &x, &y, &z)) { imguiDrawText((int)x, (int)(y+25), IMGUI_ALIGN_CENTER, "TARGET", imguiRGBA(0,0,0,220)); } if (m_showLabels) { char label[32]; for (int i = 0; i < m_crowd.getAgentCount(); ++i) { const Agent* ag = m_crowd.getAgent(i); if (!ag->active) continue; const float* pos = ag->npos; const float h = ag->height; if (gluProject((GLdouble)pos[0], (GLdouble)pos[1]+h, (GLdouble)pos[2], model, proj, view, &x, &y, &z)) { snprintf(label, 32, "%d", i); imguiDrawText((int)x, (int)y+15, IMGUI_ALIGN_CENTER, label, imguiRGBA(0,0,0,220)); } } } if (m_showPerfGraph) { GraphParams gp; gp.setRect(300, 10, 500, 200, 8); gp.setValueRange(0.0f, 2.0f, 4, "ms"); drawGraphBackground(&gp); drawGraph(&gp, &m_crowdRvoTime, 0, "RVO Sampling", duRGBA(255,0,128,255)); drawGraph(&gp, &m_crowdTotalTime, 1, "Total", duRGBA(128,255,0,255)); gp.setRect(300, 10, 500, 50, 8); gp.setValueRange(0.0f, 2000.0f, 1, "0"); drawGraph(&gp, &m_crowdSampleCount, 0, "Sample Count", duRGBA(255,255,255,255)); } }
void NavPath::renderSimple(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat) { if(overrideMat) return; if(state->isReflectPass() || !(isSelected() || mAlwaysRender)) return; GFXDrawUtil *drawer = GFX->getDrawUtil(); GFXStateBlockDesc desc; desc.setZReadWrite(true, false); desc.setBlend(true); desc.setCullMode(GFXCullNone); if(isSelected()) { drawer->drawCube(desc, getWorldBox(), ColorI(136, 255, 228, 5)); desc.setFillModeWireframe(); drawer->drawCube(desc, getWorldBox(), ColorI::BLACK); } desc.setZReadWrite(!mXray, false); ColorI pathColour(255, 0, 255); if(!mIsLooping) { desc.setFillModeSolid(); if(mFromSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mFrom, pathColour); if(mToSet) drawer->drawCube(desc, Point3F(0.2f, 0.2f, 0.2f), mTo, pathColour); } GFXStateBlockRef sb = GFX->createStateBlock(desc); GFX->setStateBlock(sb); PrimBuild::color3i(pathColour.red, pathColour.green, pathColour.blue); PrimBuild::begin(GFXLineStrip, mPoints.size()); for (U32 i = 0; i < mPoints.size(); i++) PrimBuild::vertex3fv(mPoints[i]); PrimBuild::end(); if(mRenderSearch && getServerObject()) { NavPath *np = static_cast<NavPath*>(getServerObject()); if(np->mQuery && !dtStatusSucceed(np->mStatus)) { duDebugDrawTorque dd; dd.overrideColor(duRGBA(250, 20, 20, 255)); duDebugDrawNavMeshNodes(&dd, *np->mQuery); dd.render(); } } }
void RecastMapRenderer::DrawObstacles(duDebugDraw* dd, const dtTileCache* tc) { for (int i = 0; i < tc->getObstacleCount(); ++i) { const dtTileCacheObstacle* ob = tc->getObstacle(i); if (ob->state == DT_OBSTACLE_EMPTY) continue; float bmin[3], bmax[3]; tc->getObstacleBounds(ob, bmin,bmax); unsigned int col = 0; if (ob->state == DT_OBSTACLE_PROCESSING) col = duRGBA(255,255,0,128); else if (ob->state == DT_OBSTACLE_PROCESSED) col = duRGBA(255,192,0,192); else if (ob->state == DT_OBSTACLE_REMOVING) col = duRGBA(220,0,0,128); duDebugDrawCylinder(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], col); duDebugDrawCylinderWire(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duDarkenCol(col), 2); } }
void OffMeshConnectionTool::handleRender() { DebugDrawGL dd; const float s = m_sample->getAgentRadius(); if (m_hitPosSet) duDebugDrawCross(&dd, m_hitPos[0],m_hitPos[1]+0.1f,m_hitPos[2], s, duRGBA(0,0,0,128), 2.0f); InputGeom* geom = m_sample->getInputGeom(); if (geom) geom->drawOffMeshConnections(&dd, true); }
void duDebugDrawHeightfieldWalkable(duDebugDraw* dd, const rcHeightfield& hf) { if (!dd) return; const float* orig = hf.bmin; const float cs = hf.cs; const float ch = hf.ch; const int w = hf.width; const int h = hf.height; unsigned int fcol[6]; duCalcBoxColors(fcol, duRGBA(255,255,255,255), duRGBA(217,217,217,255)); dd->begin(DU_DRAW_QUADS); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { float fx = orig[0] + x*cs; float fz = orig[2] + y*cs; const rcSpan* s = hf.spans[x + y*w]; while (s) { if (s->area == RC_WALKABLE_AREA) fcol[0] = duRGBA(64,128,160,255); else if (s->area == RC_NULL_AREA) fcol[0] = duRGBA(64,64,64,255); else fcol[0] = duMultCol(duIntToCol(s->area, 255), 200); duAppendBox(dd, fx, orig[1]+s->smin*ch, fz, fx+cs, orig[1] + s->smax*ch, fz+cs, fcol); s = s->next; } } } dd->end(); }
void duDebugDrawRegionConnections(duDebugDraw* dd, const rcContourSet& cset, const float alpha) { if (!dd) return; const float* orig = cset.bmin; const float cs = cset.cs; const float ch = cset.ch; // Draw centers float pos[3], pos2[3]; unsigned int color = duRGBA(0,0,0,196); dd->begin(DU_DRAW_LINES, 2.0f); for (int i = 0; i < cset.nconts; ++i) { const rcContour* cont = &cset.conts[i]; getContourCenter(cont, orig, cs, ch, pos); for (int j = 0; j < cont->nverts; ++j) { const int* v = &cont->verts[j*4]; if(v[3] < 65500) { const unsigned short a = v[3]; if (a == 0 || a < cont->reg) continue; const rcContour* cont2 = findContourFromSet(cset, a); if (cont2) { getContourCenter(cont2, orig, cs, ch, pos2); duAppendArc(dd, pos[0],pos[1],pos[2], pos2[0],pos2[1],pos2[2], 0.25f, 0.6f, 0.6f, color); } } } } dd->end(); unsigned char a = (unsigned char)(alpha * 255.0f); dd->begin(DU_DRAW_POINTS, 7.0f); for (int i = 0; i < cset.nconts; ++i) { const rcContour* cont = &cset.conts[i]; unsigned int col = duDarkenCol(duIntToCol(cont->reg,a)); getContourCenter(cont, orig, cs, ch, pos); dd->vertex(pos, col); } dd->end(); }
void duDebugDrawCompactHeightfieldSolid(duDebugDraw* dd, const rcCompactHeightfield& chf) { if (!dd) return; const float cs = chf.cs; const float ch = chf.ch; dd->begin(DU_DRAW_QUADS); for (int y = 0; y < chf.height; ++y) { for (int x = 0; x < chf.width; ++x) { const float fx = chf.bmin[0] + x*cs; const float fz = chf.bmin[2] + y*cs; const rcCompactCell& c = chf.cells[x+y*chf.width]; for (unsigned i = c.index, ni = c.index+c.count; i < ni; ++i) { const rcCompactSpan& s = chf.spans[i]; unsigned int color; if (chf.areas[i] == RC_WALKABLE_AREA) color = duRGBA(0,192,255,64); else if (chf.areas[i] == RC_NULL_AREA) color = duRGBA(0,0,0,64); else color = duIntToCol(chf.areas[i], 255); const float fy = chf.bmin[1] + (s.y+1)*ch; dd->vertex(fx, fy, fz, color); dd->vertex(fx, fy, fz+cs, color); dd->vertex(fx+cs, fy, fz+cs, color); dd->vertex(fx+cs, fy, fz, color); } } } dd->end(); }
void NavmeshPruneTool::handleRender() { DebugDrawGL dd; if (m_hitPosSet) { const float s = m_sample->getAgentRadius(); const unsigned int col = duRGBA(255,255,255,255); dd.begin(DU_DRAW_LINES); dd.vertex(m_hitPos[0]-s,m_hitPos[1],m_hitPos[2], col); dd.vertex(m_hitPos[0]+s,m_hitPos[1],m_hitPos[2], col); dd.vertex(m_hitPos[0],m_hitPos[1]-s,m_hitPos[2], col); dd.vertex(m_hitPos[0],m_hitPos[1]+s,m_hitPos[2], col); dd.vertex(m_hitPos[0],m_hitPos[1],m_hitPos[2]-s, col); dd.vertex(m_hitPos[0],m_hitPos[1],m_hitPos[2]+s, col); dd.end(); } const dtNavMesh* nav = m_sample->getNavMesh(); if (m_flags && nav) { for (int i = 0; i < nav->getMaxTiles(); ++i) { const dtMeshTile* tile = nav->getTile(i); if (!tile->header) continue; const dtPolyRef base = nav->getPolyRefBase(tile); for (int j = 0; j < tile->header->polyCount; ++j) { const dtPolyRef ref = base | (unsigned int)j; if (m_flags->getFlags(ref)) { duDebugDrawNavMeshPoly(&dd, *nav, ref, duRGBA(255,255,255,128)); } } } } }
void NavMeshTesterTool::drawAgent(const float* pos, float r, float h, float c, const unsigned int col) { DebugDrawGL dd; dd.depthMask(false); // Agent dimensions. duDebugDrawCylinderWire(&dd, pos[0]-r, pos[1]+0.02f, pos[2]-r, pos[0]+r, pos[1]+h, pos[2]+r, col, 2.0f); duDebugDrawCircle(&dd, pos[0],pos[1]+c,pos[2],r,duRGBA(0,0,0,64),1.0f); unsigned int colb = duRGBA(0,0,0,196); dd.begin(DU_DRAW_LINES); dd.vertex(pos[0], pos[1]-c, pos[2], colb); dd.vertex(pos[0], pos[1]+c, pos[2], colb); dd.vertex(pos[0]-r/2, pos[1]+0.02f, pos[2], colb); dd.vertex(pos[0]+r/2, pos[1]+0.02f, pos[2], colb); dd.vertex(pos[0], pos[1]+0.02f, pos[2]-r/2, colb); dd.vertex(pos[0], pos[1]+0.02f, pos[2]+r/2, colb); dd.end(); dd.depthMask(true); }
void Visualization::renderScene() { if (m_scene) { DebugDrawGL dd; // Draw mesh duDebugDrawTriMesh(&dd, m_scene->getMesh()->getVerts(), m_scene->getMesh()->getVertCount(), m_scene->getMesh()->getTris(), m_scene->getMesh()->getNormals(), m_scene->getMesh()->getTriCount(), 0, 1.0f); // Draw bounds const float* bmin = m_scene->getMeshBoundsMin(); const float* bmax = m_scene->getMeshBoundsMax(); duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f); } }
void cocos2d::NavMesh::drawObstacles() { // Draw obstacles for (auto iter : _obstacleList) { if (iter){ const dtTileCacheObstacle* ob = _tileCache->getObstacleByRef(iter->_obstacleID); if (ob->state == DT_OBSTACLE_EMPTY) continue; float bmin[3], bmax[3]; _tileCache->getObstacleBounds(ob, bmin, bmax); unsigned int col = 0; if (ob->state == DT_OBSTACLE_PROCESSING) col = duRGBA(255, 255, 0, 128); else if (ob->state == DT_OBSTACLE_PROCESSED) col = duRGBA(255, 192, 0, 192); else if (ob->state == DT_OBSTACLE_REMOVING) col = duRGBA(220, 0, 0, 128); duDebugDrawCylinder(&_debugDraw, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], col); duDebugDrawCylinderWire(&_debugDraw, bmin[0], bmin[1], bmin[2], bmax[0], bmax[1], bmax[2], duDarkenCol(col), 2); } } }
void Sample::handleRender() { if (!m_geom) return; DebugDrawGL dd; // 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, 1.0f); // Draw bounds const dtCoordinates bmin( m_geom->getMeshBoundsMin() ); const dtCoordinates bmax( m_geom->getMeshBoundsMax() ); duDebugDrawBoxWire(&dd, bmin.X(),bmin.Y(),bmin.Z(), bmax.X(),bmax.Y(),bmax.Z(), duRGBA(255,255,255,128), 1.0f); }
void Sample::handleRender() { if (!m_geom) return; DebugDrawGL dd; // 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, 1.0f); // Draw bounds const float* bmin = m_geom->getMeshBoundsMin(); const float* bmax = m_geom->getMeshBoundsMax(); duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f); }
void duDebugDrawLiquidTriMesh(duDebugDraw* dd, const float* verts, int /*nverts*/, const int* tris, const float* normals, int ntris, const float texScale) { if (!dd) return; if (!verts) return; if (!tris) return; if (!normals) return; float uva[2]; float uvb[2]; float uvc[2]; dd->texture(true); dd->begin(DU_DRAW_TRIS); for (int i = 0; i < ntris * 3; i += 3) { const float* norm = &normals[i]; unsigned int color; color = duRGBA(0, 183, 205, 255); const float* va = &verts[tris[i + 0] * 3]; const float* vb = &verts[tris[i + 1] * 3]; 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->texture(false); }