diff --git a/src/bmesh.c b/src/bmesh.c index e35b4013..7c75cfa7 100644 --- a/src/bmesh.c +++ b/src/bmesh.c @@ -537,6 +537,7 @@ static bmeshBall *bmeshFindParentBallForConvexHull(bmesh *bm, bmeshBall *root, if (isDistanceEnoughForConvexHull(root, ball)) { return ball; } + ball->radius = 0; return bmeshFindParentBallForConvexHull(bm, root, depth - 1, bm->parentBallStack[depth - 1]); } @@ -593,7 +594,7 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) { bm->parentBallStack[depth] = ball; } ball->roundColor = bm->roundColor; - if (BMESH_BALL_TYPE_ROOT == ball->type/* && 4 == ball->index*/) { + if (BMESH_BALL_TYPE_ROOT == ball->type) { convexHull *hull; bmeshBall *outmostBall = 0; int outmostBallFirstVertexIndex = 0; @@ -805,3 +806,84 @@ int bmeshStitch(bmesh *bm) { bm->roundColor++; return bmeshStichFrom(bm, 0, bmeshGetRootBall(bm)); } + +void calculateBallQuad(bmeshBall *ball, quad *q) { + vec3 z, y; + vec3Scale(&ball->localYaxis, ball->radius, &y); + vec3Scale(&ball->localZaxis, ball->radius, &z); + vec3Sub(&ball->position, &y, &q->pt[0]); + vec3Add(&q->pt[0], &z, &q->pt[0]); + vec3Sub(&ball->position, &y, &q->pt[1]); + vec3Sub(&q->pt[1], &z, &q->pt[1]); + vec3Add(&ball->position, &y, &q->pt[2]); + vec3Sub(&q->pt[2], &z, &q->pt[2]); + vec3Add(&ball->position, &y, &q->pt[3]); + vec3Add(&q->pt[3], &z, &q->pt[3]); +} + +static void drawWallsBetweenQuads(quad *q1, quad *q2) { + int i; + for (i = 0; i < 4; ++i) { + quad wall = {{q1->pt[i], q2->pt[i], + q2->pt[(i + 1) % 4], q1->pt[(i + 1) % 4]}}; + drawQuad(&wall); + } +} + +static int bmeshGenerateInbetweenMeshFrom(bmesh *bm, bmeshBall *parent, + bmeshBall *ball) { + int result = 0; + bmeshBallIterator iterator; + bmeshBall *child = 0; + if (bm->roundColor == ball->roundColor) { + return 0; + } + ball->roundColor = bm->roundColor; + if (ball->radius > 0) { + quad currentFace; + calculateBallQuad(ball, ¤tFace); + if (parent && parent->radius > 0) { + quad parentFace; + calculateBallQuad(parent, &parentFace); + drawWallsBetweenQuads(&parentFace, ¤tFace); + child = bmeshGetBallFirstChild(bm, ball, &iterator); + if (!child) { + bmeshBall fakeParentParent = *parent; + bmeshBall fakeParent = *ball; + bmeshBall fakeBall; + for (;;) { + quad childFace; + fakeBall = fakeParent; + vec3Lerp(&fakeParentParent.position, &fakeParent.position, 2, + &fakeBall.position); + calculateBallQuad(&fakeBall, &childFace); + drawWallsBetweenQuads(¤tFace, &childFace); + if (vec3Distance(&ball->position, &fakeBall.position) >= + ball->radius) { + drawQuad(&childFace); + break; + } + fakeParentParent = fakeParent; + fakeParent = fakeBall; + } + } + } + } + for (child = bmeshGetBallFirstChild(bm, ball, &iterator); + child; + child = bmeshGetBallNextChild(bm, ball, &iterator)) { + result = bmeshGenerateInbetweenMeshFrom(bm, ball, child); + if (0 != result) { + fprintf(stderr, "%s:bmeshGenerateInbetweenMeshFrom failed.\n", + __FUNCTION__); + return result; + } + } + return result; +} + +int bmeshGenerateInbetweenMesh(bmesh *bm) { + bm->roundColor++; + return bmeshGenerateInbetweenMeshFrom(bm, 0, bmeshGetRootBall(bm)); +} + diff --git a/src/bmesh.h b/src/bmesh.h index 329e804f..86ac25b2 100644 --- a/src/bmesh.h +++ b/src/bmesh.h @@ -55,6 +55,7 @@ quad *bmeshGetQuad(bmesh *bm, int index); int bmeshAddQuad(bmesh *bm, quad *q); int bmeshSweep(bmesh *bm); int bmeshStitch(bmesh *bm); +int bmeshGenerateInbetweenMesh(bmesh *bm); #ifdef __cplusplus } diff --git a/src/draw.cpp b/src/draw.cpp index 54399fb2..c0ac49ef 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -35,6 +35,18 @@ void drawTriangle(triangle *poly) { glEnd(); } +void drawQuad(quad *poly) { + vec3 normal; + int i; + glBegin(GL_QUADS); + vec3Normal(&poly->pt[0], &poly->pt[1], &poly->pt[2], &normal); + for (i = 0; i < 4; ++i) { + glNormal3f(normal.x, normal.y, normal.z); + glVertex3f(poly->pt[i].x, poly->pt[i].y, poly->pt[i].z); + } + glEnd(); +} + int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices, int stacks) { vec3 zAxis = {0, 0, 1}; diff --git a/src/draw.h b/src/draw.h index 2300bc25..742f3c9e 100644 --- a/src/draw.h +++ b/src/draw.h @@ -14,6 +14,7 @@ extern "C" { int drawInit(void); int drawSphere(vec3 *origin, float radius, int slices, int stacks); void drawTriangle(triangle *poly); +void drawQuad(quad *poly); int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices, int stacks); int drawGrid(float size, float step); diff --git a/src/render.cpp b/src/render.cpp index 34580b5e..381d763d 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -42,7 +42,7 @@ static int drawBmeshBall(bmesh *bm, bmeshBall *ball) { static void drawBmeshBallRecursively(bmesh *bm, bmeshBall *ball) { bmeshBallIterator iterator; bmeshBall *child; - drawBmeshBall(bm, ball); + //drawBmeshBall(bm, ball); for (child = bmeshGetBallFirstChild(bm, ball, &iterator); child; child = bmeshGetBallNextChild(bm, ball, &iterator)) { @@ -50,7 +50,7 @@ static void drawBmeshBallRecursively(bmesh *bm, bmeshBall *ball) { } } -static int drawBmeshBallQuad(bmeshBall *ball) { +static void drawBmeshBallQuad(bmeshBall *ball) { vec3 normal; int j; vec3 z, y; @@ -262,6 +262,7 @@ void Render::paintGL() { bmeshGenerateInbetweenBalls(bm); bmeshSweep(bm); bmeshStitch(bm); + bmeshGenerateInbetweenMesh(bm); } drawBmeshBallRecursively(bm, bmeshGetRootBall(bm)); @@ -280,7 +281,7 @@ void Render::paintGL() { for (index = 0; index < bmeshGetBoneNum(bm); ++index) { bmeshBone *bone = bmeshGetBone(bm, index); - drawBmeshBone(bm, bone); + //drawBmeshBone(bm, bone); } /* glColor4f(1.0f, 1.0f, 1.0f, 0.5);