diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 0938389..6d40d02 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -91,13 +91,62 @@ cpVect inflateline(cpVect a, cpVect b, float d) return c; } +cpVect inflatepoint(cpVect a, cpVect b, cpVect c, float d) +{ + cpVect ba = cpvnormalize(cpvsub(a,b)); + cpVect bc = cpvnormalize(cpvsub(c,b)); + cpVect avg = cpvadd(ba, bc); + avg = cpvmult(avg, 0.5); + float dot = cpvdot(ba, bc); + dot /= cpvlength(ba); + dot /= cpvlength(bc); + float mid = acos(dot)/2; + avg = cpvnormalize(avg); + return cpvadd(b, cpvmult(avg, d/sin(mid))); +} + +void inflatepoints(cpVect *r, cpVect *p, float d, int n) +{ if (d == 0) { + for (int i = 0; i < n; i++) + r[i] = p[i]; + + return; + } + + if (cpveql(p[0], p[n-1])) { + r[0] = inflatepoint(p[n-2],p[0],p[1],d); + r[n-1] = r[0]; + } else { + cpVect outdir = cpvmult(cpvnormalize(cpvsub(p[0],p[1])),fabs(d)); + cpVect perp; + if (d > 0) + perp = cpvperp(outdir); + else + perp = cpvrperp(outdir); + r[0] = cpvadd(p[0],cpvadd(outdir,perp)); + + outdir = cpvmult(cpvnormalize(cpvsub(p[n-1],p[n-2])),fabs(d)); + if (d > 0) + perp = cpvrperp(outdir); + else + perp = cpvperp(outdir); + r[n-1] = cpvadd(p[n-1],cpvadd(outdir,perp)); + } + + for (int i = 0; i < n-2; i++) + r[i+1] = inflatepoint(p[i],p[i+1],p[i+2], d); + +} + void draw_edge(cpVect *points, int n, float *color, int thickness) { static_assert(sizeof(cpVect) == 2*sizeof(float)); shader_use(rectShader); shader_setvec3(rectShader, "linecolor", color); + if (thickness <= 1) { + shader_setfloat(rectShader, "alpha", 1.f); glBindBuffer(GL_ARRAY_BUFFER, rectVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * n * 2, points, GL_DYNAMIC_DRAW); glBindVertexArray(rectVAO); @@ -107,6 +156,34 @@ void draw_edge(cpVect *points, int n, float *color, int thickness) shader_setfloat(rectShader, "alpha", 1.f); glDrawArrays(GL_LINE_STRIP, 0, n); } else { + shader_setfloat(rectShader, "alpha", 0.1f); + thickness /= 2; + glBindBuffer(GL_ARRAY_BUFFER, rectVBO); + glBindVertexArray(rectVAO); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL); + + cpVect inflate_out[n]; + cpVect inflate_in[n]; + + inflatepoints(inflate_out, points, thickness, n); + inflatepoints(inflate_in, points, -thickness, n); + cpVect interleaved[n*2]; + for (int i = 0; i < n; i++) { + interleaved[i*2] = inflate_in[i]; + interleaved[i*2+1] = inflate_out[i]; + } + glBufferData(GL_ARRAY_BUFFER, sizeof(interleaved), interleaved, GL_DYNAMIC_DRAW); + glDrawArrays(GL_TRIANGLE_STRIP, 0, n*2); + + shader_setfloat(rectShader, "alpha", 1.f); + + cpVect inlined[n*2]; + for (int i = 0; i < n; i++) + inlined[i] = inflate_out[n-1-i]; + memcpy(inlined+n,inflate_in,sizeof(inflate_in)); + glBufferData(GL_ARRAY_BUFFER,sizeof(inlined),inlined,GL_DYNAMIC_DRAW); + glDrawArrays(GL_LINE_LOOP,0,n*2); } }