// // Copyright (c) 2009 Mikko Mononen memon@inside.org // // This software is provided 'as-is', without any express or implied // warranty. In no event will the authors be held liable for any damages // arising from the use of this software. // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it // freely, subject to the following restrictions: // 1. The origin of this software must not be misrepresented; you must not // claim that you wrote the original software. If you use this software // in a product, an acknowledgment in the product documentation would be // appreciated but is not required. // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // 3. This notice may not be removed or altered from any source distribution. // #define _USE_MATH_DEFINES #include #include "DebugDraw.h" inline int bit(int a, int b) { return (a & (1 << b)) >> b; } unsigned int duIntToCol(int i, int a) { int r = bit(i, 0) + bit(i, 3) * 2 + 1; int g = bit(i, 1) + bit(i, 4) * 2 + 1; int b = bit(i, 2) + bit(i, 5) * 2 + 1; return duRGBA(r*63,g*63,b*63,a); } void duIntToCol(int i, float* col) { int r = bit(i, 0) + bit(i, 3) * 2 + 1; int g = bit(i, 1) + bit(i, 4) * 2 + 1; int b = bit(i, 2) + bit(i, 5) * 2 + 1; col[0] = 1 - r*63.0f/255.0f; col[1] = 1 - g*63.0f/255.0f; col[2] = 1 - b*63.0f/255.0f; } inline unsigned int multCol(const unsigned int col, const unsigned int d) { const unsigned int r = col & 0xff; const unsigned int g = (col >> 8) & 0xff; const unsigned int b = (col >> 16) & 0xff; const unsigned int a = (col >> 24) & 0xff; return duRGBA((r*d) >> 8, (g*d) >> 8, (b*d) >> 8, a); } void duCalcBoxColors(unsigned int* colors, unsigned int colTop, unsigned int colSide) { colors[0] = multCol(colTop, 250); colors[1] = multCol(colSide, 140); colors[2] = multCol(colSide, 165); colors[3] = multCol(colSide, 217); colors[4] = multCol(colSide, 165); colors[5] = multCol(colSide, 217); } void duDebugDrawCylinderWire(struct duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, unsigned int col, const float lineWidth) { dd->begin(DU_DRAW_LINES, lineWidth); duAppendCylinderWire(dd, minx,miny,minz, maxx,maxy,maxz, col); dd->end(); } void duDebugDrawBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, unsigned int col, const float lineWidth) { dd->begin(DU_DRAW_LINES, lineWidth); duAppendBoxWire(dd, minx,miny,minz, maxx,maxy,maxz, col); dd->end(); } void duDebugDrawArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0, const float x1, const float y1, const float z1, const float h, unsigned int col, const float lineWidth) { dd->begin(DU_DRAW_LINES, lineWidth); duAppendArc(dd, x0,y0,z0, x1,y1,z1, h, col); dd->end(); } void duDebugDrawCircle(struct duDebugDraw* dd, const float x, const float y, const float z, const float r, unsigned int col, const float lineWidth) { dd->begin(DU_DRAW_LINES, lineWidth); duAppendCircle(dd, x,y,z, r, col); dd->end(); } void duDebugDrawCross(struct duDebugDraw* dd, const float x, const float y, const float z, const float size, unsigned int col, const float lineWidth) { dd->begin(DU_DRAW_LINES, lineWidth); duAppendCross(dd, x,y,z, size, col); dd->end(); } void duDebugDrawBox(struct duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, const unsigned int* fcol) { dd->begin(DU_DRAW_TRIS); duAppendBox(dd, minx,miny,minz, maxx,maxy,maxz, fcol); dd->end(); } void duDebugDrawGridXZ(struct duDebugDraw* dd, const float ox, const float oy, const float oz, const int w, const int h, const float size, const unsigned int col, const float lineWidth) { dd->begin(DU_DRAW_LINES, lineWidth); for (int i = 0; i <= h; ++i) { dd->vertex(ox,oy,oz+i*size, col); dd->vertex(ox+w*size,oy,oz+i*size, col); } for (int i = 0; i <= w; ++i) { dd->vertex(ox+i*size,oy,oz, col); dd->vertex(ox+i*size,oy,oz+h*size, col); } dd->end(); } void duAppendCylinderWire(struct duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, unsigned int col) { static const int NUM_SEG = 16; static float dir[NUM_SEG*2]; static bool init = false; if (!init) { init = true; for (int i = 0; i < NUM_SEG; ++i) { const float a = (float)i/(float)NUM_SEG*(float)M_PI*2; dir[i*2] = cosf(a); dir[i*2+1] = sinf(a); } } const float cx = (maxx + minx)/2; const float cz = (maxz + minz)/2; const float rx = (maxx - minx)/2; const float rz = (maxz - minz)/2; for (int i = 0, j = NUM_SEG-1; i < NUM_SEG; j = i++) { dd->vertex(cx+dir[j*2+0]*rx, miny, cz+dir[j*2+1]*rz, col); dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col); dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, col); dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, col); } for (int i = 0; i < NUM_SEG; i += NUM_SEG/4) { dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, col); dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, col); } } void duAppendBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, unsigned int col) { // Top dd->vertex(minx, miny, minz, col); dd->vertex(maxx, miny, minz, col); dd->vertex(maxx, miny, minz, col); dd->vertex(maxx, miny, maxz, col); dd->vertex(maxx, miny, maxz, col); dd->vertex(minx, miny, maxz, col); dd->vertex(minx, miny, maxz, col); dd->vertex(minx, miny, minz, col); // bottom dd->vertex(minx, maxy, minz, col); dd->vertex(maxx, maxy, minz, col); dd->vertex(maxx, maxy, minz, col); dd->vertex(maxx, maxy, maxz, col); dd->vertex(maxx, maxy, maxz, col); dd->vertex(minx, maxy, maxz, col); dd->vertex(minx, maxy, maxz, col); dd->vertex(minx, maxy, minz, col); // Sides dd->vertex(minx, miny, minz, col); dd->vertex(minx, maxy, minz, col); dd->vertex(maxx, miny, minz, col); dd->vertex(maxx, maxy, minz, col); dd->vertex(maxx, miny, maxz, col); dd->vertex(maxx, maxy, maxz, col); dd->vertex(minx, miny, maxz, col); dd->vertex(minx, maxy, maxz, col); } void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, const unsigned int* fcol) { const float verts[8*3] = { minx, miny, minz, maxx, miny, minz, maxx, miny, maxz, minx, miny, maxz, minx, maxy, minz, maxx, maxy, minz, maxx, maxy, maxz, minx, maxy, maxz, }; static const unsigned char inds[6*4] = { 7, 6, 5, 4, 0, 1, 2, 3, 1, 5, 6, 2, 3, 7, 4, 0, 2, 6, 7, 3, 0, 4, 5, 1, }; const unsigned char* in = inds; for (int i = 0; i < 6; ++i) { dd->vertex(&verts[*in*3], fcol[i]); in++; dd->vertex(&verts[*in*3], fcol[i]); in++; dd->vertex(&verts[*in*3], fcol[i]); in++; dd->vertex(&verts[*in*3], fcol[i]); in++; } } void duAppendArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0, const float x1, const float y1, const float z1, const float h, unsigned int col) { static const int NUM_ARC_PTS = 8; static const float ARC_PTS_SCALE = 1.0f / (float)NUM_ARC_PTS; const float dx = x1 - x0; const float dy = y1 - y0; const float dz = z1 - z0; const float len = sqrtf(dx*dx + dy*dy + dz*dz); float px = x0, py = y0, pz = z0; for (int i = 1; i <= NUM_ARC_PTS; ++i) { const float u = i * ARC_PTS_SCALE; const float x = x0 + dx * u; const float y = y0 + dy * u + (len*h) * (1-(u*2-1)*(u*2-1)); const float z = z0 + dz * u; dd->vertex(px,py,pz, col); dd->vertex(x,y,z, col); px = x; py = y; pz = z; } } void duAppendCircle(struct duDebugDraw* dd, const float x, const float y, const float z, const float r, unsigned int col) { static const int NUM_SEG = 40; static float dir[40*2]; static bool init = false; if (!init) { init = true; for (int i = 0; i < NUM_SEG; ++i) { const float a = (float)i/(float)NUM_SEG*(float)M_PI*2; dir[i*2] = cosf(a); dir[i*2+1] = sinf(a); } } for (int i = 0, j = NUM_SEG-1; i < NUM_SEG; j = i++) { dd->vertex(x+dir[j*2+0]*r, y, z+dir[j*2+1]*r, col); dd->vertex(x+dir[i*2+0]*r, y, z+dir[i*2+1]*r, col); } } void duAppendCross(struct duDebugDraw* dd, const float x, const float y, const float z, const float s, unsigned int col) { dd->vertex(x-s,y,z, col); dd->vertex(x+s,y,z, col); dd->vertex(x,y-s,z, col); dd->vertex(x,y+s,z, col); dd->vertex(x,y,z-s, col); dd->vertex(x,y,z+s, col); }