Make sure all cross sections on the convex hull.
parent
68cb7d499f
commit
2f022b337c
|
@ -57,3 +57,12 @@ void arrayDestroy(array *arr) {
|
||||||
free(arr);
|
free(arr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *arrayNewItem(array *arr) {
|
||||||
|
int newIndex = arrayGetLength(arr);
|
||||||
|
if (0 != arraySetLength(arr, newIndex + 1)) {
|
||||||
|
fprintf(stderr, "%s:arraySetLength.\n", __FUNCTION__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return arrayGetItem(arr, newIndex);
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ array *arrayCreate(int nodeSize);
|
||||||
void *arrayGetItem(array *arr, int index);
|
void *arrayGetItem(array *arr, int index);
|
||||||
int arrayGetLength(array *arr);
|
int arrayGetLength(array *arr);
|
||||||
int arraySetLength(array *arr, int length);
|
int arraySetLength(array *arr, int length);
|
||||||
|
void *arrayNewItem(array *arr);
|
||||||
void arrayDestroy(array *arr);
|
void arrayDestroy(array *arr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
254
src/bmesh.c
254
src/bmesh.c
|
@ -10,7 +10,6 @@
|
||||||
#include "convexhull.h"
|
#include "convexhull.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
#define BMESH_STEP_DISTANCE 0.2
|
|
||||||
#define BMESH_MAX_PARENT_BALL_DEPTH 1000
|
#define BMESH_MAX_PARENT_BALL_DEPTH 1000
|
||||||
|
|
||||||
typedef struct bmeshBallIndex {
|
typedef struct bmeshBallIndex {
|
||||||
|
@ -92,6 +91,7 @@ int bmeshAddBall(bmesh *bm, bmeshBall *ball) {
|
||||||
ball->index = index;
|
ball->index = index;
|
||||||
ball->firstChildIndex = -1;
|
ball->firstChildIndex = -1;
|
||||||
ball->childrenIndices = 0;
|
ball->childrenIndices = 0;
|
||||||
|
ball->notFitHull = 0;
|
||||||
if (0 != arraySetLength(bm->ballArray, index + 1)) {
|
if (0 != arraySetLength(bm->ballArray, index + 1)) {
|
||||||
fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__);
|
fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -235,12 +235,11 @@ static int bmeshGenerateInbetweenBallsBetween(bmesh *bm,
|
||||||
bmeshBall *firstBall = bmeshGetBall(bm, firstBallIndex);
|
bmeshBall *firstBall = bmeshGetBall(bm, firstBallIndex);
|
||||||
bmeshBall *secondBall = bmeshGetBall(bm, secondBallIndex);
|
bmeshBall *secondBall = bmeshGetBall(bm, secondBallIndex);
|
||||||
bmeshBall *newBall;
|
bmeshBall *newBall;
|
||||||
|
float intvalDist;
|
||||||
if (secondBall->roundColor == bm->roundColor) {
|
if (secondBall->roundColor == bm->roundColor) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
step = BMESH_STEP_DISTANCE;
|
|
||||||
|
|
||||||
vec3Sub(&firstBall->position, &secondBall->position, &boneDirection);
|
vec3Sub(&firstBall->position, &secondBall->position, &boneDirection);
|
||||||
normalizedBoneDirection = boneDirection;
|
normalizedBoneDirection = boneDirection;
|
||||||
vec3Normalize(&normalizedBoneDirection);
|
vec3Normalize(&normalizedBoneDirection);
|
||||||
|
@ -261,15 +260,17 @@ static int bmeshGenerateInbetweenBallsBetween(bmesh *bm,
|
||||||
boneDirection.z);
|
boneDirection.z);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
intvalDist = (firstBall->radius + secondBall->radius) / 3;
|
||||||
|
step = intvalDist;
|
||||||
distance = vec3Length(&boneDirection);
|
distance = vec3Length(&boneDirection);
|
||||||
if (distance > BMESH_STEP_DISTANCE) {
|
if (distance > intvalDist) {
|
||||||
float offset;
|
float offset;
|
||||||
int calculatedStepCount = (int)(distance / BMESH_STEP_DISTANCE);
|
int calculatedStepCount = (int)(distance / intvalDist);
|
||||||
float remaining = distance - BMESH_STEP_DISTANCE * calculatedStepCount;
|
float remaining = distance - intvalDist * calculatedStepCount;
|
||||||
step += remaining / calculatedStepCount;
|
step += remaining / calculatedStepCount;
|
||||||
offset = step;
|
offset = step;
|
||||||
if (offset < distance) {
|
if (offset < distance) {
|
||||||
while (offset < distance && offset + BMESH_STEP_DISTANCE <= distance) {
|
while (offset < distance && offset + intvalDist <= distance) {
|
||||||
float frac = offset / distance;
|
float frac = offset / distance;
|
||||||
parentBallIndex = bmeshAddInbetweenBallBetween(bm,
|
parentBallIndex = bmeshAddInbetweenBallBetween(bm,
|
||||||
firstBall, secondBall, frac, parentBallIndex);
|
firstBall, secondBall, frac, parentBallIndex);
|
||||||
|
@ -508,7 +509,7 @@ int bmeshSweep(bmesh *bm) {
|
||||||
static int isDistanceEnoughForConvexHull(bmeshBall *root,
|
static int isDistanceEnoughForConvexHull(bmeshBall *root,
|
||||||
bmeshBall *ball) {
|
bmeshBall *ball) {
|
||||||
float distance = vec3Distance(&root->position, &ball->position);
|
float distance = vec3Distance(&root->position, &ball->position);
|
||||||
if (distance >= root->radius + BMESH_STEP_DISTANCE) {
|
if (distance >= root->radius) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -518,14 +519,13 @@ static bmeshBall *bmeshFindChildBallForConvexHull(bmesh *bm, bmeshBall *root,
|
||||||
bmeshBall *ball) {
|
bmeshBall *ball) {
|
||||||
bmeshBallIterator iterator;
|
bmeshBallIterator iterator;
|
||||||
bmeshBall *child;
|
bmeshBall *child;
|
||||||
if (isDistanceEnoughForConvexHull(root, ball)) {
|
if (!ball->notFitHull && isDistanceEnoughForConvexHull(root, ball)) {
|
||||||
return ball;
|
return ball;
|
||||||
}
|
}
|
||||||
child = bmeshGetBallFirstChild(bm, ball, &iterator);
|
child = bmeshGetBallFirstChild(bm, ball, &iterator);
|
||||||
if (!child) {
|
if (!child) {
|
||||||
return ball;
|
return ball;
|
||||||
}
|
}
|
||||||
ball->radius = 0;
|
|
||||||
return bmeshFindChildBallForConvexHull(bm, root, child);
|
return bmeshFindChildBallForConvexHull(bm, root, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,15 +534,14 @@ static bmeshBall *bmeshFindParentBallForConvexHull(bmesh *bm, bmeshBall *root,
|
||||||
if (depth <= 0) {
|
if (depth <= 0) {
|
||||||
return ball;
|
return ball;
|
||||||
}
|
}
|
||||||
if (isDistanceEnoughForConvexHull(root, ball)) {
|
if (!ball->notFitHull && isDistanceEnoughForConvexHull(root, ball)) {
|
||||||
return ball;
|
return ball;
|
||||||
}
|
}
|
||||||
ball->radius = 0;
|
|
||||||
return bmeshFindParentBallForConvexHull(bm, root, depth - 1,
|
return bmeshFindParentBallForConvexHull(bm, root, depth - 1,
|
||||||
bm->parentBallStack[depth - 1]);
|
bm->parentBallStack[depth - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull,
|
static int addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull,
|
||||||
bmeshBall **outmostBall, int *outmostBallFirstVertexIndex) {
|
bmeshBall **outmostBall, int *outmostBallFirstVertexIndex) {
|
||||||
vec3 z, y;
|
vec3 z, y;
|
||||||
quad q;
|
quad q;
|
||||||
|
@ -560,10 +559,19 @@ static void addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull,
|
||||||
vec3Add(&ballForConvexHull->position, &y, &q.pt[3]);
|
vec3Add(&ballForConvexHull->position, &y, &q.pt[3]);
|
||||||
vec3Add(&q.pt[3], &z, &q.pt[3]);
|
vec3Add(&q.pt[3], &z, &q.pt[3]);
|
||||||
|
|
||||||
vertexIndex[0] = convexHullAddVertex(hull, &q.pt[0], ballForConvexHull->index, 0);
|
vertexIndex[0] = convexHullAddVertex(hull, &q.pt[0],
|
||||||
vertexIndex[1] = convexHullAddVertex(hull, &q.pt[1], ballForConvexHull->index, 1);
|
ballForConvexHull->index, 0);
|
||||||
vertexIndex[2] = convexHullAddVertex(hull, &q.pt[2], ballForConvexHull->index, 2);
|
vertexIndex[1] = convexHullAddVertex(hull, &q.pt[1],
|
||||||
vertexIndex[3] = convexHullAddVertex(hull, &q.pt[3], ballForConvexHull->index, 3);
|
ballForConvexHull->index, 1);
|
||||||
|
vertexIndex[2] = convexHullAddVertex(hull, &q.pt[2],
|
||||||
|
ballForConvexHull->index, 2);
|
||||||
|
vertexIndex[3] = convexHullAddVertex(hull, &q.pt[3],
|
||||||
|
ballForConvexHull->index, 3);
|
||||||
|
if (-1 == vertexIndex[0] || -1 == vertexIndex[1] || -1 == vertexIndex[2] ||
|
||||||
|
-1 == vertexIndex[3]) {
|
||||||
|
fprintf(stderr, "%s:convexHullAddVertex failed.\n", __FUNCTION__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (*outmostBall) {
|
if (*outmostBall) {
|
||||||
if (ballForConvexHull->radius > (*outmostBall)->radius) {
|
if (ballForConvexHull->radius > (*outmostBall)->radius) {
|
||||||
|
@ -576,17 +584,162 @@ static void addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull,
|
||||||
*outmostBall = ballForConvexHull;
|
*outmostBall = ballForConvexHull;
|
||||||
*outmostBallFirstVertexIndex = vertexIndex[0];
|
*outmostBallFirstVertexIndex = vertexIndex[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "osutil.h"
|
#include "osutil.h"
|
||||||
int showFaceIndex = 10000000;
|
int showFaceIndex = 10000000;
|
||||||
static long long lastShowFaceIndexIncTime = 0;
|
static long long lastShowFaceIndexIncTime = 0;
|
||||||
|
|
||||||
static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
static convexHull *createConvexHullForBall(bmesh *bm, int depth,
|
||||||
int result = 0;
|
bmeshBall *ball, int *needRetry) {
|
||||||
|
convexHull *hull;
|
||||||
bmeshBallIterator iterator;
|
bmeshBallIterator iterator;
|
||||||
bmeshBall *child;
|
bmeshBall *child;
|
||||||
bmeshBall *ballForConvexHull;
|
bmeshBall *ballForConvexHull;
|
||||||
|
bmeshBall *outmostBall = 0;
|
||||||
|
int outmostBallFirstVertexIndex = 0;
|
||||||
|
array *ballPtrArray;
|
||||||
|
bmeshBall **ballPtr;
|
||||||
|
int i;
|
||||||
|
int hasVertexNotFitOnHull = 0;
|
||||||
|
|
||||||
|
*needRetry = 0;
|
||||||
|
|
||||||
|
ballPtrArray = arrayCreate(sizeof(bmeshBall *));
|
||||||
|
if (!ballPtrArray) {
|
||||||
|
fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
hull = convexHullCreate();
|
||||||
|
if (!hull) {
|
||||||
|
fprintf(stderr, "%s:convexHullCreate failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (child = bmeshGetBallFirstChild(bm, ball, &iterator);
|
||||||
|
child;
|
||||||
|
child = bmeshGetBallNextChild(bm, ball, &iterator)) {
|
||||||
|
ballForConvexHull = bmeshFindChildBallForConvexHull(bm, ball, child);
|
||||||
|
ballPtr = (bmeshBall **)arrayNewItem(ballPtrArray);
|
||||||
|
if (!ballPtr) {
|
||||||
|
fprintf(stderr, "%s:arrayNewItem failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*ballPtr = ballForConvexHull;
|
||||||
|
if (-1 == addBallToHull(hull, ballForConvexHull,
|
||||||
|
&outmostBall, &outmostBallFirstVertexIndex)) {
|
||||||
|
fprintf(stderr, "%s:addBallToHull failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (depth > 0 && depth - 1 < BMESH_MAX_PARENT_BALL_DEPTH) {
|
||||||
|
ballForConvexHull = bmeshFindParentBallForConvexHull(bm, ball, depth - 1,
|
||||||
|
bm->parentBallStack[depth - 1]);
|
||||||
|
ballPtr = (bmeshBall **)arrayNewItem(ballPtrArray);
|
||||||
|
if (!ballPtr) {
|
||||||
|
fprintf(stderr, "%s:arrayNewItem failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*ballPtr = ballForConvexHull;
|
||||||
|
if (-1 == addBallToHull(hull, ballForConvexHull,
|
||||||
|
&outmostBall, &outmostBallFirstVertexIndex)) {
|
||||||
|
fprintf(stderr, "%s:addBallToHull failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (outmostBall) {
|
||||||
|
if (-1 == convexHullAddTodo(hull, outmostBallFirstVertexIndex + 0,
|
||||||
|
outmostBallFirstVertexIndex + 1, outmostBallFirstVertexIndex + 2)) {
|
||||||
|
fprintf(stderr, "%s:convexHullAddTodo failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < arrayGetLength(ballPtrArray); ++i) {
|
||||||
|
bmeshBall *ballItem = *((bmeshBall **)arrayGetItem(ballPtrArray, i));
|
||||||
|
ballItem->flagForHull = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == convexHullGenerate(hull)) {
|
||||||
|
fprintf(stderr, "%s:convexHullGenerate failed.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
convexHullUnifyNormals(hull, &ball->position);
|
||||||
|
convexHullMergeTriangles(hull);
|
||||||
|
|
||||||
|
for (i = 0; i < convexHullGetFaceNum(hull); ++i) {
|
||||||
|
convexHullFace *f = (convexHullFace *)convexHullGetFace(hull, i);
|
||||||
|
if (-1 != f->plane) {
|
||||||
|
bmeshBall *ballItem = (bmeshBall *)arrayGetItem(bm->ballArray, f->plane);
|
||||||
|
ballItem->flagForHull = 1;
|
||||||
|
f->vertexNum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < arrayGetLength(ballPtrArray); ++i) {
|
||||||
|
bmeshBall *ballItem = *((bmeshBall **)arrayGetItem(ballPtrArray, i));
|
||||||
|
if (!ballItem->flagForHull) {
|
||||||
|
hasVertexNotFitOnHull = 1;
|
||||||
|
if (!ballItem->notFitHull) {
|
||||||
|
*needRetry = 1;
|
||||||
|
ballItem->notFitHull = 1;
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!hasVertexNotFitOnHull) {
|
||||||
|
for (i = 0; i < arrayGetLength(ballPtrArray); ++i) {
|
||||||
|
bmeshBall *ballItem = *((bmeshBall **)arrayGetItem(ballPtrArray, i));
|
||||||
|
if (-1 == ballItem->countsForHull[0] ||
|
||||||
|
ballItem->countsForHull[0] != ballItem->countsForHull[1] ||
|
||||||
|
ballItem->countsForHull[1] != ballItem->countsForHull[2] ||
|
||||||
|
ballItem->countsForHull[2] != ballItem->countsForHull[3]) {
|
||||||
|
hasVertexNotFitOnHull = 1;
|
||||||
|
if (!ballItem->notFitHull) {
|
||||||
|
*needRetry = 1;
|
||||||
|
ballItem->notFitHull = 1;
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (hasVertexNotFitOnHull) {
|
||||||
|
fprintf(stderr, "%s:hasVertexNotFitOnHull.\n", __FUNCTION__);
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
arrayDestroy(ballPtrArray);
|
||||||
|
return hull;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
||||||
|
bmeshBallIterator iterator;
|
||||||
|
bmeshBall *child;
|
||||||
|
int result = 0;
|
||||||
if (bm->roundColor == ball->roundColor) {
|
if (bm->roundColor == ball->roundColor) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -594,38 +747,20 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
||||||
bm->parentBallStack[depth] = ball;
|
bm->parentBallStack[depth] = ball;
|
||||||
}
|
}
|
||||||
ball->roundColor = bm->roundColor;
|
ball->roundColor = bm->roundColor;
|
||||||
if (BMESH_BALL_TYPE_ROOT == ball->type) {
|
if (BMESH_BALL_TYPE_ROOT == ball->type/* && 2 == ball->index*/) {
|
||||||
convexHull *hull;
|
convexHull *hull = 0;
|
||||||
bmeshBall *outmostBall = 0;
|
|
||||||
int outmostBallFirstVertexIndex = 0;
|
for (;;) {
|
||||||
hull = convexHullCreate();
|
int needRetry = 0;
|
||||||
if (!hull) {
|
hull = createConvexHullForBall(bm, depth, ball, &needRetry);
|
||||||
fprintf(stderr, "%s:convexHullCreate failed.\n", __FUNCTION__);
|
if (hull) {
|
||||||
return -1;
|
break;
|
||||||
|
}
|
||||||
|
if (!needRetry) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
glColor3f(0.0, 0.0, 0.0);
|
|
||||||
drawDebugPrintf("root <%f,%f,%f>", ball->position.x,
|
|
||||||
ball->position.y, ball->position.z);
|
|
||||||
for (child = bmeshGetBallFirstChild(bm, ball, &iterator);
|
|
||||||
child;
|
|
||||||
child = bmeshGetBallNextChild(bm, ball, &iterator)) {
|
|
||||||
ballForConvexHull = bmeshFindChildBallForConvexHull(bm, ball, child);
|
|
||||||
addBallToHull(hull, ballForConvexHull,
|
|
||||||
&outmostBall, &outmostBallFirstVertexIndex);
|
|
||||||
}
|
|
||||||
if (depth > 0 && depth - 1 < BMESH_MAX_PARENT_BALL_DEPTH) {
|
|
||||||
ballForConvexHull = bmeshFindParentBallForConvexHull(bm, ball, depth - 1,
|
|
||||||
bm->parentBallStack[depth - 1]);
|
|
||||||
addBallToHull(hull, ballForConvexHull,
|
|
||||||
&outmostBall, &outmostBallFirstVertexIndex);
|
|
||||||
}
|
|
||||||
if (outmostBall) {
|
|
||||||
convexHullAddTodo(hull, outmostBallFirstVertexIndex + 0,
|
|
||||||
outmostBallFirstVertexIndex + 1, outmostBallFirstVertexIndex + 2);
|
|
||||||
}
|
|
||||||
convexHullGenerate(hull);
|
|
||||||
convexHullUnifyNormals(hull, &ball->position);
|
|
||||||
convexHullMergeTriangles(hull);
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -649,6 +784,7 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
if (hull)
|
||||||
{
|
{
|
||||||
int triIndex;
|
int triIndex;
|
||||||
for (triIndex = 0; triIndex < convexHullGetFaceNum(hull);
|
for (triIndex = 0; triIndex < convexHullGetFaceNum(hull);
|
||||||
|
@ -658,9 +794,9 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
||||||
if (3 == face->vertexNum) {
|
if (3 == face->vertexNum) {
|
||||||
triangle tri;
|
triangle tri;
|
||||||
int j;
|
int j;
|
||||||
tri.pt[0] = *convexHullGetVertex(hull, face->u.t.indices[0]);
|
tri.pt[0] = convexHullGetVertex(hull, face->u.t.indices[0])->pt;
|
||||||
tri.pt[1] = *convexHullGetVertex(hull, face->u.t.indices[1]);
|
tri.pt[1] = convexHullGetVertex(hull, face->u.t.indices[1])->pt;
|
||||||
tri.pt[2] = *convexHullGetVertex(hull, face->u.t.indices[2]);
|
tri.pt[2] = convexHullGetVertex(hull, face->u.t.indices[2])->pt;
|
||||||
|
|
||||||
if (triIndex >= showFaceIndex) {
|
if (triIndex >= showFaceIndex) {
|
||||||
break;
|
break;
|
||||||
|
@ -680,10 +816,10 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
||||||
quad q;
|
quad q;
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
int j;
|
int j;
|
||||||
q.pt[0] = *convexHullGetVertex(hull, face->u.q.indices[0]);
|
q.pt[0] = convexHullGetVertex(hull, face->u.q.indices[0])->pt;
|
||||||
q.pt[1] = *convexHullGetVertex(hull, face->u.q.indices[1]);
|
q.pt[1] = convexHullGetVertex(hull, face->u.q.indices[1])->pt;
|
||||||
q.pt[2] = *convexHullGetVertex(hull, face->u.q.indices[2]);
|
q.pt[2] = convexHullGetVertex(hull, face->u.q.indices[2])->pt;
|
||||||
q.pt[3] = *convexHullGetVertex(hull, face->u.q.indices[3]);
|
q.pt[3] = convexHullGetVertex(hull, face->u.q.indices[3])->pt;
|
||||||
|
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
@ -788,7 +924,9 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
convexHullDestroy(hull);
|
if (hull) {
|
||||||
|
convexHullDestroy(hull);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (child = bmeshGetBallFirstChild(bm, ball, &iterator);
|
for (child = bmeshGetBallFirstChild(bm, ball, &iterator);
|
||||||
child;
|
child;
|
||||||
|
|
|
@ -26,6 +26,8 @@ typedef struct {
|
||||||
vec3 localYaxis;
|
vec3 localYaxis;
|
||||||
vec3 localZaxis;
|
vec3 localZaxis;
|
||||||
int roundColor;
|
int roundColor;
|
||||||
|
int notFitHull;
|
||||||
|
int flagForHull;
|
||||||
} bmeshBall;
|
} bmeshBall;
|
||||||
|
|
||||||
typedef int bmeshBallIterator;
|
typedef int bmeshBallIterator;
|
||||||
|
|
|
@ -14,19 +14,14 @@
|
||||||
#define FACE3_HASHTABLE_SIZE 100
|
#define FACE3_HASHTABLE_SIZE 100
|
||||||
#define EDGE_HASHTABLE_SIZE 100
|
#define EDGE_HASHTABLE_SIZE 100
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
vec3 pt;
|
|
||||||
int plane;
|
|
||||||
int orderOnPlane;
|
|
||||||
} convexHullVertex;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int p1;
|
int p1;
|
||||||
int p2;
|
int p2;
|
||||||
int hill1;
|
int hill1;
|
||||||
int hill2;
|
int hill2;
|
||||||
vec3 hill1Normal;
|
vec3 hill1Normal;
|
||||||
int score;
|
int angleBetweenFaces;
|
||||||
|
int angleWithLevel;
|
||||||
int face1;
|
int face1;
|
||||||
int face2;
|
int face2;
|
||||||
} edge;
|
} edge;
|
||||||
|
@ -265,13 +260,17 @@ int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex,
|
||||||
convexHullVertex *vtx2;
|
convexHullVertex *vtx2;
|
||||||
convexHullVertex *vtx3;
|
convexHullVertex *vtx3;
|
||||||
int newTri;
|
int newTri;
|
||||||
|
int facePlane = -1;
|
||||||
|
|
||||||
vtx1 = (convexHullVertex *)arrayGetItem(hull->vertexArray, firstVertex);
|
vtx1 = (convexHullVertex *)arrayGetItem(hull->vertexArray, firstVertex);
|
||||||
vtx2 = (convexHullVertex *)arrayGetItem(hull->vertexArray, secondVertex);
|
vtx2 = (convexHullVertex *)arrayGetItem(hull->vertexArray, secondVertex);
|
||||||
vtx3 = (convexHullVertex *)arrayGetItem(hull->vertexArray, thirdVertex);
|
vtx3 = (convexHullVertex *)arrayGetItem(hull->vertexArray, thirdVertex);
|
||||||
|
|
||||||
if (vtx1->plane == vtx2->plane && vtx1->plane == vtx3->plane) {
|
if (vtx1->plane == vtx2->plane && vtx1->plane == vtx3->plane) {
|
||||||
return 0;
|
facePlane = vtx1->plane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (vtx1->plane == vtx2->plane) {
|
if (vtx1->plane == vtx2->plane) {
|
||||||
if (!isInAdjacentOrder(vtx1->orderOnPlane, vtx2->orderOnPlane)) {
|
if (!isInAdjacentOrder(vtx1->orderOnPlane, vtx2->orderOnPlane)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -286,7 +285,7 @@ int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex,
|
||||||
if (!isInAdjacentOrder(vtx2->orderOnPlane, vtx3->orderOnPlane)) {
|
if (!isInAdjacentOrder(vtx2->orderOnPlane, vtx3->orderOnPlane)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
memset(&hull->findFace3, 0, sizeof(hull->findFace3));
|
memset(&hull->findFace3, 0, sizeof(hull->findFace3));
|
||||||
hull->findFace3.indices[0] = firstVertex;
|
hull->findFace3.indices[0] = firstVertex;
|
||||||
|
@ -302,6 +301,7 @@ int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex,
|
||||||
}
|
}
|
||||||
tri = (face3 *)arrayGetItem(hull->faceArray, newTri);
|
tri = (face3 *)arrayGetItem(hull->faceArray, newTri);
|
||||||
((convexHullFace *)tri)->vertexNum = 3;
|
((convexHullFace *)tri)->vertexNum = 3;
|
||||||
|
((convexHullFace *)tri)->plane = facePlane;
|
||||||
*tri = hull->findFace3;
|
*tri = hull->findFace3;
|
||||||
if (0 != hashtableInsert(hull->face3Hashtable,
|
if (0 != hashtableInsert(hull->face3Hashtable,
|
||||||
(char *)0 + newTri + 1)) {
|
(char *)0 + newTri + 1)) {
|
||||||
|
@ -486,9 +486,13 @@ int convexHullUnifyNormals(convexHull *hull, vec3 *origin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sortEdgeByScore(const void *first, const void *second) {
|
static int sortEdgeByScore(const void *first, const void *second) {
|
||||||
edge *e1 = (edge *)first;
|
edge *e1 = (edge *)first;
|
||||||
edge *e2 = (edge *)second;
|
edge *e2 = (edge *)second;
|
||||||
return e1->score - e2->score;
|
int result = e1->angleBetweenFaces - e2->angleBetweenFaces;
|
||||||
|
if (0 == result) {
|
||||||
|
result = e2->angleWithLevel - e1->angleWithLevel;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rollTriangleIndices(face3 *face) {
|
static void rollTriangleIndices(face3 *face) {
|
||||||
|
@ -512,7 +516,7 @@ int convexHullMergeTriangles(convexHull *hull) {
|
||||||
//face3 *f2 = (face3 *)arrayGetItem(hull->faceArray, e->face2);
|
//face3 *f2 = (face3 *)arrayGetItem(hull->faceArray, e->face2);
|
||||||
vec3 f1normal;
|
vec3 f1normal;
|
||||||
vec3 f2normal;
|
vec3 f2normal;
|
||||||
float angle;
|
const vec3 yAxis = {0, 1, 0};
|
||||||
/*
|
/*
|
||||||
convexHullVertex *f1p1 = (convexHullVertex *)arrayGetItem(
|
convexHullVertex *f1p1 = (convexHullVertex *)arrayGetItem(
|
||||||
hull->vertexArray, f1->indices[0]);
|
hull->vertexArray, f1->indices[0]);
|
||||||
|
@ -533,15 +537,12 @@ int convexHullMergeTriangles(convexHull *hull) {
|
||||||
vec3 *v2 = (vec3 *)arrayGetItem(hull->vertexArray, e->p2);
|
vec3 *v2 = (vec3 *)arrayGetItem(hull->vertexArray, e->p2);
|
||||||
vec3 *vHill1 = (vec3 *)arrayGetItem(hull->vertexArray, e->hill1);
|
vec3 *vHill1 = (vec3 *)arrayGetItem(hull->vertexArray, e->hill1);
|
||||||
vec3 *vHill2 = (vec3 *)arrayGetItem(hull->vertexArray, e->hill2);
|
vec3 *vHill2 = (vec3 *)arrayGetItem(hull->vertexArray, e->hill2);
|
||||||
|
vec3 v12;
|
||||||
|
vec3Sub(v1, v2, &v12);
|
||||||
vec3Normal(v1, vHill1, v2, &f1normal);
|
vec3Normal(v1, vHill1, v2, &f1normal);
|
||||||
vec3Normal(v2, vHill2, v1, &f2normal);
|
vec3Normal(v2, vHill2, v1, &f2normal);
|
||||||
angle = (int)vec3Angle(&f1normal, &f2normal);
|
e->angleBetweenFaces = (int)vec3Angle(&f1normal, &f2normal);
|
||||||
e->score = (int)angle;
|
e->angleWithLevel = (int)vec3Angle(&v12, (vec3 *)&yAxis);
|
||||||
//if (edgeIndex >= 12 && edgeIndex <= 12) {
|
|
||||||
// angle = (int)vec3Angle(&f1normal, &f2normal);
|
|
||||||
drawDebugPrintf("edgeIndex:%d angle:%f",
|
|
||||||
edgeIndex, angle);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +564,8 @@ int convexHullMergeTriangles(convexHull *hull) {
|
||||||
convexHullFace *f2 = (convexHullFace *)arrayGetItem(hull->faceArray,
|
convexHullFace *f2 = (convexHullFace *)arrayGetItem(hull->faceArray,
|
||||||
e->face2);
|
e->face2);
|
||||||
if (3 == f1->vertexNum && 3 == f2->vertexNum) {
|
if (3 == f1->vertexNum && 3 == f2->vertexNum) {
|
||||||
if (e->score <= 40) {
|
if (e->angleBetweenFaces <= 40 &&
|
||||||
|
f1->plane == f2->plane) {
|
||||||
while (e->p1 == f1->u.t.indices[0] || e->p2 == f1->u.t.indices[0]) {
|
while (e->p1 == f1->u.t.indices[0] || e->p2 == f1->u.t.indices[0]) {
|
||||||
rollTriangleIndices((face3 *)f1);
|
rollTriangleIndices((face3 *)f1);
|
||||||
}
|
}
|
||||||
|
@ -595,10 +597,10 @@ convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex) {
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex) {
|
convexHullVertex *convexHullGetVertex(convexHull *hull, int vertexIndex) {
|
||||||
convexHullVertex *vertex = (convexHullVertex *)arrayGetItem(
|
convexHullVertex *vertex = (convexHullVertex *)arrayGetItem(
|
||||||
hull->vertexArray, vertexIndex);
|
hull->vertexArray, vertexIndex);
|
||||||
return &vertex->pt;
|
return vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
int convexHullGetFaceNum(convexHull *hull) {
|
int convexHullGetFaceNum(convexHull *hull) {
|
||||||
|
|
|
@ -3,14 +3,22 @@
|
||||||
#include "3dstruct.h"
|
#include "3dstruct.h"
|
||||||
|
|
||||||
typedef struct convexHull convexHull;
|
typedef struct convexHull convexHull;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
union {
|
union {
|
||||||
face4 q;
|
face4 q;
|
||||||
face3 t;
|
face3 t;
|
||||||
} u;
|
} u;
|
||||||
int vertexNum;
|
int vertexNum;
|
||||||
|
int plane;
|
||||||
} convexHullFace;
|
} convexHullFace;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
vec3 pt;
|
||||||
|
int plane;
|
||||||
|
int orderOnPlane;
|
||||||
|
} convexHullVertex;
|
||||||
|
|
||||||
convexHull *convexHullCreate(void);
|
convexHull *convexHullCreate(void);
|
||||||
int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane,
|
int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane,
|
||||||
int orderOnPlane);
|
int orderOnPlane);
|
||||||
|
@ -20,7 +28,7 @@ int convexHullUnifyNormals(convexHull *hull, vec3 *origin);
|
||||||
int convexHullMergeTriangles(convexHull *hull);
|
int convexHullMergeTriangles(convexHull *hull);
|
||||||
int convexHullGetFaceNum(convexHull *hull);
|
int convexHullGetFaceNum(convexHull *hull);
|
||||||
convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex);
|
convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex);
|
||||||
vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex);
|
convexHullVertex *convexHullGetVertex(convexHull *hull, int vertexIndex);
|
||||||
int convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, int vertex3);
|
int convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, int vertex3);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -213,7 +213,7 @@ void Render::initializeGL() {
|
||||||
drawInit();
|
drawInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../data/bmesh_test_1.h"
|
#include "../data/bmesh_test_2.h"
|
||||||
|
|
||||||
void Render::paintGL() {
|
void Render::paintGL() {
|
||||||
bmesh *bm = 0;
|
bmesh *bm = 0;
|
||||||
|
@ -237,6 +237,7 @@ void Render::paintGL() {
|
||||||
|
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
|
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
subdivModel *input = subdivCreateModel();
|
subdivModel *input = subdivCreateModel();
|
||||||
subdivModel *output;
|
subdivModel *output;
|
||||||
|
@ -245,8 +246,9 @@ void Render::paintGL() {
|
||||||
subdivDestroyModel(input);
|
subdivDestroyModel(input);
|
||||||
subdivDestroyModel(output);
|
subdivDestroyModel(output);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (0 && 0 == bm) {
|
if (0 == bm) {
|
||||||
bmeshBall ball;
|
bmeshBall ball;
|
||||||
bmeshBone bone;
|
bmeshBone bone;
|
||||||
int i;
|
int i;
|
||||||
|
@ -272,7 +274,7 @@ void Render::paintGL() {
|
||||||
bmeshGenerateInbetweenBalls(bm);
|
bmeshGenerateInbetweenBalls(bm);
|
||||||
bmeshSweep(bm);
|
bmeshSweep(bm);
|
||||||
bmeshStitch(bm);
|
bmeshStitch(bm);
|
||||||
bmeshGenerateInbetweenMesh(bm);
|
//bmeshGenerateInbetweenMesh(bm);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bm) {
|
if (bm) {
|
||||||
|
|
Loading…
Reference in New Issue