Add merge triangles inside implementation of convex hull.
parent
1c305d5ef9
commit
06e584ac1c
82
src/bmesh.c
82
src/bmesh.c
|
@ -596,6 +596,7 @@ static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) {
|
||||||
}
|
}
|
||||||
convexHullGenerate(hull);
|
convexHullGenerate(hull);
|
||||||
convexHullUnifyNormals(hull, &ball->position);
|
convexHullUnifyNormals(hull, &ball->position);
|
||||||
|
convexHullMergeTriangles(hull);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -619,41 +620,84 @@ static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) {
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
|
||||||
{
|
{
|
||||||
int triIndex;
|
int triIndex;
|
||||||
for (triIndex = 0; triIndex < convexHullGetFace3Num(hull);
|
for (triIndex = 0; triIndex < convexHullGetFaceNum(hull);
|
||||||
++triIndex) {
|
++triIndex) {
|
||||||
|
convexHullFace *face = (convexHullFace *)convexHullGetFace(hull,
|
||||||
|
triIndex);
|
||||||
|
if (3 == face->vertexNum) {
|
||||||
triangle tri;
|
triangle tri;
|
||||||
face3 *face = (face3 *)convexHullGetFace3(hull, triIndex);
|
int j;
|
||||||
tri.pt[0] = *convexHullGetVertex(hull, face->indices[0]);
|
tri.pt[0] = *convexHullGetVertex(hull, face->u.t.indices[0]);
|
||||||
tri.pt[1] = *convexHullGetVertex(hull, face->indices[1]);
|
tri.pt[1] = *convexHullGetVertex(hull, face->u.t.indices[1]);
|
||||||
tri.pt[2] = *convexHullGetVertex(hull, face->indices[2]);
|
tri.pt[2] = *convexHullGetVertex(hull, face->u.t.indices[2]);
|
||||||
|
|
||||||
if (triIndex >= showFaceIndex) {
|
if (triIndex >= showFaceIndex) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
drawTriangle(&tri);
|
drawTriangle(&tri);
|
||||||
}
|
|
||||||
}
|
|
||||||
glColor3f(0.0f, 0.0f, 0.0f);
|
|
||||||
{
|
|
||||||
int triIndex;
|
|
||||||
int j;
|
|
||||||
for (triIndex = 0; triIndex < convexHullGetFace3Num(hull);
|
|
||||||
++triIndex) {
|
|
||||||
triangle tri;
|
|
||||||
face3 *face = (face3 *)convexHullGetFace3(hull, triIndex);
|
|
||||||
tri.pt[0] = *convexHullGetVertex(hull, face->indices[0]);
|
|
||||||
tri.pt[1] = *convexHullGetVertex(hull, face->indices[1]);
|
|
||||||
tri.pt[2] = *convexHullGetVertex(hull, face->indices[2]);
|
|
||||||
glBegin(GL_LINE_STRIP);
|
glBegin(GL_LINE_STRIP);
|
||||||
for (j = 0; j < 3; ++j) {
|
for (j = 0; j < 3; ++j) {
|
||||||
glVertex3f(tri.pt[j].x, tri.pt[j].y, tri.pt[j].z);
|
glVertex3f(tri.pt[j].x, tri.pt[j].y, tri.pt[j].z);
|
||||||
}
|
}
|
||||||
glVertex3f(tri.pt[0].x, tri.pt[0].y, tri.pt[0].z);
|
glVertex3f(tri.pt[0].x, tri.pt[0].y, tri.pt[0].z);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
} else if (4 == face->vertexNum) {
|
||||||
|
quad q;
|
||||||
|
vec3 normal;
|
||||||
|
int j;
|
||||||
|
q.pt[0] = *convexHullGetVertex(hull, face->u.q.indices[0]);
|
||||||
|
q.pt[1] = *convexHullGetVertex(hull, face->u.q.indices[1]);
|
||||||
|
q.pt[2] = *convexHullGetVertex(hull, face->u.q.indices[2]);
|
||||||
|
q.pt[3] = *convexHullGetVertex(hull, face->u.q.indices[3]);
|
||||||
|
|
||||||
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
vec3Normal(&q.pt[0], &q.pt[1], &q.pt[2], &normal);
|
||||||
|
for (j = 0; j < 4; ++j) {
|
||||||
|
glNormal3f(normal.x, normal.y, normal.z);
|
||||||
|
glVertex3f(q.pt[j].x, q.pt[j].y, q.pt[j].z);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
for (j = 0; j < 4; ++j) {
|
||||||
|
glVertex3f(q.pt[j].x, q.pt[j].y, q.pt[j].z);
|
||||||
|
}
|
||||||
|
glVertex3f(q.pt[0].x, q.pt[0].y, q.pt[0].z);
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
glColor3f(0.0f, 0.0f, 0.0f);
|
||||||
|
{
|
||||||
|
int triIndex;
|
||||||
|
int j;
|
||||||
|
for (triIndex = 0; triIndex < convexHullGetFaceNum(hull);
|
||||||
|
++triIndex) {
|
||||||
|
convexHullFace *face = (convexHullFace *)convexHullGetFace(hull,
|
||||||
|
triIndex);
|
||||||
|
if (3 == face->vertexNum) {
|
||||||
|
triangle tri;
|
||||||
|
tri.pt[0] = *convexHullGetVertex(hull, face->u.t.indices[0]);
|
||||||
|
tri.pt[1] = *convexHullGetVertex(hull, face->u.t.indices[1]);
|
||||||
|
tri.pt[2] = *convexHullGetVertex(hull, face->u.t.indices[2]);
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
for (j = 0; j < 3; ++j) {
|
||||||
|
glVertex3f(tri.pt[j].x, tri.pt[j].y, tri.pt[j].z);
|
||||||
|
}
|
||||||
|
glVertex3f(tri.pt[0].x, tri.pt[0].y, tri.pt[0].z);
|
||||||
|
glEnd();
|
||||||
|
} else if ()
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
glColor3f(1.0f, 1.0f, 1.0f);
|
glColor3f(1.0f, 1.0f, 1.0f);
|
||||||
|
|
171
src/convexhull.c
171
src/convexhull.c
|
@ -18,7 +18,7 @@ typedef struct {
|
||||||
vec3 pt;
|
vec3 pt;
|
||||||
int plane;
|
int plane;
|
||||||
int orderOnPlane;
|
int orderOnPlane;
|
||||||
} converHullVertex;
|
} convexHullVertex;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int p1;
|
int p1;
|
||||||
|
@ -26,12 +26,15 @@ typedef struct {
|
||||||
int hill1;
|
int hill1;
|
||||||
int hill2;
|
int hill2;
|
||||||
vec3 hill1Normal;
|
vec3 hill1Normal;
|
||||||
|
int score;
|
||||||
|
int face1;
|
||||||
|
int face2;
|
||||||
} edge;
|
} edge;
|
||||||
|
|
||||||
struct convexHull {
|
struct convexHull {
|
||||||
array *vertexArray;
|
array *vertexArray;
|
||||||
array *todoArray;
|
array *todoArray;
|
||||||
array *face3Array;
|
array *faceArray;
|
||||||
int nextTodoIndex;
|
int nextTodoIndex;
|
||||||
unsigned int *openEdgeProcessedMap;
|
unsigned int *openEdgeProcessedMap;
|
||||||
hashtable *face3Hashtable;
|
hashtable *face3Hashtable;
|
||||||
|
@ -57,7 +60,7 @@ face3 *convexHullGetFaceByHashtableParam(void *userData, const void *node) {
|
||||||
if (0 == index) {
|
if (0 == index) {
|
||||||
return &hull->findFace3;
|
return &hull->findFace3;
|
||||||
}
|
}
|
||||||
return (face3 *)arrayGetItem(hull->face3Array, index - 1);
|
return (face3 *)arrayGetItem(hull->faceArray, index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int face3Hash(void *userData, const void *node) {
|
static int face3Hash(void *userData, const void *node) {
|
||||||
|
@ -104,7 +107,7 @@ convexHull *convexHullCreate(void) {
|
||||||
fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__);
|
fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hull->vertexArray = arrayCreate(sizeof(converHullVertex));
|
hull->vertexArray = arrayCreate(sizeof(convexHullVertex));
|
||||||
if (!hull->vertexArray) {
|
if (!hull->vertexArray) {
|
||||||
fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__);
|
fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__);
|
||||||
convexHullDestroy(hull);
|
convexHullDestroy(hull);
|
||||||
|
@ -116,8 +119,8 @@ convexHull *convexHullCreate(void) {
|
||||||
convexHullDestroy(hull);
|
convexHullDestroy(hull);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
hull->face3Array = arrayCreate(sizeof(face3));
|
hull->faceArray = arrayCreate(sizeof(convexHullFace));
|
||||||
if (!hull->face3Array) {
|
if (!hull->faceArray) {
|
||||||
fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__);
|
fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__);
|
||||||
convexHullDestroy(hull);
|
convexHullDestroy(hull);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -156,7 +159,8 @@ edge *convexHullFindEdge(convexHull *hull, int p1, int p2) {
|
||||||
return arrayGetItem(hull->edgeArray, index - 1);
|
return arrayGetItem(hull->edgeArray, index - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int convexHullAddEdge(convexHull *hull, int p1, int p2, int hill) {
|
int convexHullAddEdge(convexHull *hull, int p1, int p2, int hill,
|
||||||
|
int face) {
|
||||||
edge *e = convexHullFindEdge(hull, p1, p2);
|
edge *e = convexHullFindEdge(hull, p1, p2);
|
||||||
if (!e) {
|
if (!e) {
|
||||||
int newIndex = arrayGetLength(hull->edgeArray);
|
int newIndex = arrayGetLength(hull->edgeArray);
|
||||||
|
@ -165,10 +169,13 @@ int convexHullAddEdge(convexHull *hull, int p1, int p2, int hill) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
e = (edge *)arrayGetItem(hull->edgeArray, newIndex);
|
e = (edge *)arrayGetItem(hull->edgeArray, newIndex);
|
||||||
|
memset(e, 0, sizeof(edge));
|
||||||
e->p1 = p1;
|
e->p1 = p1;
|
||||||
e->p2 = p2;
|
e->p2 = p2;
|
||||||
e->hill1 = hill;
|
e->hill1 = hill;
|
||||||
e->hill2 = -1;
|
e->hill2 = -1;
|
||||||
|
e->face1 = face;
|
||||||
|
e->face2 = -1;
|
||||||
vec3Normal((vec3 *)arrayGetItem(hull->vertexArray, e->p1),
|
vec3Normal((vec3 *)arrayGetItem(hull->vertexArray, e->p1),
|
||||||
(vec3 *)arrayGetItem(hull->vertexArray, e->p2),
|
(vec3 *)arrayGetItem(hull->vertexArray, e->p2),
|
||||||
(vec3 *)arrayGetItem(hull->vertexArray, e->hill1), &e->hill1Normal);
|
(vec3 *)arrayGetItem(hull->vertexArray, e->hill1), &e->hill1Normal);
|
||||||
|
@ -179,7 +186,9 @@ int convexHullAddEdge(convexHull *hull, int p1, int p2, int hill) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
assert(-1 == e->hill2);
|
assert(-1 == e->hill2);
|
||||||
|
assert(-1 == e->face2);
|
||||||
e->hill2 = hill;
|
e->hill2 = hill;
|
||||||
|
e->face2 = face;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,13 +213,13 @@ int convexHullOpenEdgeProcessed(convexHull *hull, int firstVertex,
|
||||||
|
|
||||||
int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane,
|
int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane,
|
||||||
int orderOnPlane) {
|
int orderOnPlane) {
|
||||||
converHullVertex *vtx;
|
convexHullVertex *vtx;
|
||||||
int newVertex = arrayGetLength(hull->vertexArray);
|
int newVertex = arrayGetLength(hull->vertexArray);
|
||||||
if (0 != arraySetLength(hull->vertexArray, newVertex + 1)) {
|
if (0 != arraySetLength(hull->vertexArray, newVertex + 1)) {
|
||||||
fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__);
|
fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
vtx = (converHullVertex *)arrayGetItem(hull->vertexArray, newVertex);
|
vtx = (convexHullVertex *)arrayGetItem(hull->vertexArray, newVertex);
|
||||||
vtx->plane = plane;
|
vtx->plane = plane;
|
||||||
vtx->orderOnPlane = orderOnPlane;
|
vtx->orderOnPlane = orderOnPlane;
|
||||||
vtx->pt = *vertex;
|
vtx->pt = *vertex;
|
||||||
|
@ -252,13 +261,13 @@ static int sortface(const void *first, const void *second) {
|
||||||
int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex,
|
int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex,
|
||||||
int thirdVertex) {
|
int thirdVertex) {
|
||||||
face3 *tri;
|
face3 *tri;
|
||||||
converHullVertex *vtx1;
|
convexHullVertex *vtx1;
|
||||||
converHullVertex *vtx2;
|
convexHullVertex *vtx2;
|
||||||
converHullVertex *vtx3;
|
convexHullVertex *vtx3;
|
||||||
int newTri;
|
int newTri;
|
||||||
vtx1 = (converHullVertex *)arrayGetItem(hull->vertexArray, firstVertex);
|
vtx1 = (convexHullVertex *)arrayGetItem(hull->vertexArray, firstVertex);
|
||||||
vtx2 = (converHullVertex *)arrayGetItem(hull->vertexArray, secondVertex);
|
vtx2 = (convexHullVertex *)arrayGetItem(hull->vertexArray, secondVertex);
|
||||||
vtx3 = (converHullVertex *)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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -284,18 +293,22 @@ int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex,
|
||||||
qsort(hull->findFace3.indices, 3,
|
qsort(hull->findFace3.indices, 3,
|
||||||
sizeof(hull->findFace3.indices[0]), sortface);
|
sizeof(hull->findFace3.indices[0]), sortface);
|
||||||
if (0 == hashtableGet(hull->face3Hashtable, 0)) {
|
if (0 == hashtableGet(hull->face3Hashtable, 0)) {
|
||||||
newTri = arrayGetLength(hull->face3Array);
|
newTri = arrayGetLength(hull->faceArray);
|
||||||
if (0 != arraySetLength(hull->face3Array, newTri + 1)) {
|
if (0 != arraySetLength(hull->faceArray, newTri + 1)) {
|
||||||
fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__);
|
fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tri = (face3 *)arrayGetItem(hull->face3Array, newTri);
|
tri = (face3 *)arrayGetItem(hull->faceArray, newTri);
|
||||||
|
((convexHullFace *)tri)->vertexNum = 3;
|
||||||
*tri = hull->findFace3;
|
*tri = hull->findFace3;
|
||||||
if (0 != hashtableInsert(hull->face3Hashtable,
|
if (0 != hashtableInsert(hull->face3Hashtable,
|
||||||
(char *)0 + newTri + 1)) {
|
(char *)0 + newTri + 1)) {
|
||||||
fprintf(stderr, "%s:hashtableInsert failed.\n", __FUNCTION__);
|
fprintf(stderr, "%s:hashtableInsert failed.\n", __FUNCTION__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
convexHullAddEdge(hull, firstVertex, secondVertex, thirdVertex, newTri);
|
||||||
|
convexHullAddEdge(hull, secondVertex, thirdVertex, firstVertex, newTri);
|
||||||
|
convexHullAddEdge(hull, thirdVertex, firstVertex, secondVertex, newTri);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +321,7 @@ static void convexHullReleaseForGenerate(convexHull *hull) {
|
||||||
void convexHullDestroy(convexHull *hull) {
|
void convexHullDestroy(convexHull *hull) {
|
||||||
arrayDestroy(hull->vertexArray);
|
arrayDestroy(hull->vertexArray);
|
||||||
arrayDestroy(hull->todoArray);
|
arrayDestroy(hull->todoArray);
|
||||||
arrayDestroy(hull->face3Array);
|
arrayDestroy(hull->faceArray);
|
||||||
arrayDestroy(hull->edgeArray);
|
arrayDestroy(hull->edgeArray);
|
||||||
hashtableDestroy(hull->edgeHashtable);
|
hashtableDestroy(hull->edgeHashtable);
|
||||||
hashtableDestroy(hull->face3Hashtable);
|
hashtableDestroy(hull->face3Hashtable);
|
||||||
|
@ -374,7 +387,7 @@ static int convexHullCanAddFace3(convexHull *hull, int index1, int index2,
|
||||||
int i;
|
int i;
|
||||||
int indices[] = {index1, index2, index3};
|
int indices[] = {index1, index2, index3};
|
||||||
|
|
||||||
if (showFaceIndex == arrayGetLength(hull->face3Array)) {
|
if (showFaceIndex == arrayGetLength(hull->faceArray)) {
|
||||||
drawDebugPrintf("showFaceIndex:%d can add (%d,%d,%d)", showFaceIndex,
|
drawDebugPrintf("showFaceIndex:%d can add (%d,%d,%d)", showFaceIndex,
|
||||||
index1, index2, index3);
|
index1, index2, index3);
|
||||||
}
|
}
|
||||||
|
@ -395,7 +408,7 @@ static int convexHullCanAddFace3(convexHull *hull, int index1, int index2,
|
||||||
(vec3 *)arrayGetItem(hull->vertexArray, hill), &normal);
|
(vec3 *)arrayGetItem(hull->vertexArray, hill), &normal);
|
||||||
angle = vec3Angle(&e->hill1Normal, &normal);
|
angle = vec3Angle(&e->hill1Normal, &normal);
|
||||||
|
|
||||||
if (showFaceIndex == arrayGetLength(hull->face3Array)) {
|
if (showFaceIndex == arrayGetLength(hull->faceArray)) {
|
||||||
drawDebugPrintf("showFaceIndex:%d angle:%f (%d,%d,%d)",
|
drawDebugPrintf("showFaceIndex:%d angle:%f (%d,%d,%d)",
|
||||||
showFaceIndex, angle, e->p1, e->p2, e->hill1);
|
showFaceIndex, angle, e->p1, e->p2, e->hill1);
|
||||||
drawSphere((vec3 *)arrayGetItem(hull->vertexArray, 9),
|
drawSphere((vec3 *)arrayGetItem(hull->vertexArray, 9),
|
||||||
|
@ -435,13 +448,10 @@ int convexHullGenerate(convexHull *hull) {
|
||||||
if (!convexHullCanAddFace3(hull, index1, index2, index3)) {
|
if (!convexHullCanAddFace3(hull, index1, index2, index3)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (showFaceIndex == arrayGetLength(hull->face3Array)) {
|
if (showFaceIndex == arrayGetLength(hull->faceArray)) {
|
||||||
drawDebugPrintf("showFaceIndex:%d added face3 (%d,%d,%d)",
|
drawDebugPrintf("showFaceIndex:%d added face3 (%d,%d,%d)",
|
||||||
showFaceIndex, index1, index2, index3);
|
showFaceIndex, index1, index2, index3);
|
||||||
}
|
}
|
||||||
convexHullAddEdge(hull, index1, index2, index3);
|
|
||||||
convexHullAddEdge(hull, index2, index3, index1);
|
|
||||||
convexHullAddEdge(hull, index3, index1, index2);
|
|
||||||
convexHullAddFace3(hull, index1, index2, index3);
|
convexHullAddFace3(hull, index1, index2, index3);
|
||||||
convexHullAddTodo(hull, index2, index3, index1);
|
convexHullAddTodo(hull, index2, index3, index1);
|
||||||
convexHullAddTodo(hull, index3, index1, index2);
|
convexHullAddTodo(hull, index3, index1, index2);
|
||||||
|
@ -451,14 +461,14 @@ int convexHullGenerate(convexHull *hull) {
|
||||||
|
|
||||||
int convexHullUnifyNormals(convexHull *hull, vec3 *origin) {
|
int convexHullUnifyNormals(convexHull *hull, vec3 *origin) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < arrayGetLength(hull->face3Array); ++i) {
|
for (i = 0; i < arrayGetLength(hull->faceArray); ++i) {
|
||||||
face3 *triIdx = (face3 *)arrayGetItem(
|
face3 *triIdx = (face3 *)arrayGetItem(
|
||||||
hull->face3Array, i);
|
hull->faceArray, i);
|
||||||
converHullVertex *p1 = (converHullVertex *)arrayGetItem(
|
convexHullVertex *p1 = (convexHullVertex *)arrayGetItem(
|
||||||
hull->vertexArray, triIdx->indices[0]);
|
hull->vertexArray, triIdx->indices[0]);
|
||||||
converHullVertex *p2 = (converHullVertex *)arrayGetItem(
|
convexHullVertex *p2 = (convexHullVertex *)arrayGetItem(
|
||||||
hull->vertexArray, triIdx->indices[1]);
|
hull->vertexArray, triIdx->indices[1]);
|
||||||
converHullVertex *p3 = (converHullVertex *)arrayGetItem(
|
convexHullVertex *p3 = (convexHullVertex *)arrayGetItem(
|
||||||
hull->vertexArray, triIdx->indices[2]);
|
hull->vertexArray, triIdx->indices[2]);
|
||||||
vec3 normal;
|
vec3 normal;
|
||||||
vec3 o2v;
|
vec3 o2v;
|
||||||
|
@ -473,16 +483,107 @@ int convexHullUnifyNormals(convexHull *hull, vec3 *origin) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
face3 *convexHullGetFace3(convexHull *hull, int faceIndex) {
|
static int sortEdgeByScore(const void *first, const void *second) {
|
||||||
return (face3 *)arrayGetItem(hull->face3Array, faceIndex);
|
edge *e1 = (edge *)first;
|
||||||
|
edge *e2 = (edge *)second;
|
||||||
|
return e2->score - e1->score;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int findFace3FirstEdgeVertex(face3 *face, edge *e) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 3; ++i) {
|
||||||
|
if (face->indices[i] == e->p1 || face->indices[i] == e->p2) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int convexHullMergeTriangles(convexHull *hull) {
|
||||||
|
int edgeIndex;
|
||||||
|
|
||||||
|
for (edgeIndex = 0; edgeIndex < arrayGetLength(hull->edgeArray);
|
||||||
|
++edgeIndex) {
|
||||||
|
edge *e = (edge *)arrayGetItem(hull->edgeArray, edgeIndex);
|
||||||
|
if (-1 != e->face1 && -1 != e->face2) {
|
||||||
|
face3 *f1 = (face3 *)arrayGetItem(hull->faceArray, e->face1);
|
||||||
|
face3 *f2 = (face3 *)arrayGetItem(hull->faceArray, e->face2);
|
||||||
|
float sumArea;
|
||||||
|
vec3 f1normal;
|
||||||
|
vec3 f2normal;
|
||||||
|
convexHullVertex *f1p1 = (convexHullVertex *)arrayGetItem(
|
||||||
|
hull->vertexArray, f1->indices[0]);
|
||||||
|
convexHullVertex *f1p2 = (convexHullVertex *)arrayGetItem(
|
||||||
|
hull->vertexArray, f1->indices[1]);
|
||||||
|
convexHullVertex *f1p3 = (convexHullVertex *)arrayGetItem(
|
||||||
|
hull->vertexArray, f1->indices[2]);
|
||||||
|
convexHullVertex *f2p1 = (convexHullVertex *)arrayGetItem(
|
||||||
|
hull->vertexArray, f2->indices[0]);
|
||||||
|
convexHullVertex *f2p2 = (convexHullVertex *)arrayGetItem(
|
||||||
|
hull->vertexArray, f2->indices[1]);
|
||||||
|
convexHullVertex *f2p3 = (convexHullVertex *)arrayGetItem(
|
||||||
|
hull->vertexArray, f2->indices[2]);
|
||||||
|
sumArea = vec3TriangleArea(&f1p1->pt, &f1p2->pt, &f1p3->pt) +
|
||||||
|
vec3TriangleArea(&f2p1->pt, &f2p2->pt, &f2p3->pt);
|
||||||
|
vec3Normal(&f1p1->pt, &f1p2->pt, &f1p3->pt, &f1normal);
|
||||||
|
vec3Normal(&f2p1->pt, &f2p2->pt, &f2p3->pt, &f2normal);
|
||||||
|
e->score = sumArea * vec3DotProduct(&f1normal, &f2normal) * 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(arrayGetItem(hull->edgeArray, 0), arrayGetLength(hull->edgeArray),
|
||||||
|
sizeof(edge), sortEdgeByScore);
|
||||||
|
|
||||||
|
//
|
||||||
|
// After sort by score, the edge hashmap can not be used anymore.
|
||||||
|
//
|
||||||
|
hashtableDestroy(hull->edgeHashtable);
|
||||||
|
hull->edgeHashtable = 0;
|
||||||
|
|
||||||
|
for (edgeIndex = 0; edgeIndex < arrayGetLength(hull->edgeArray);
|
||||||
|
++edgeIndex) {
|
||||||
|
edge *e = (edge *)arrayGetItem(hull->edgeArray, edgeIndex);
|
||||||
|
if (-1 != e->face1 && -1 != e->face2) {
|
||||||
|
convexHullFace *f1 = (convexHullFace *)arrayGetItem(hull->faceArray,
|
||||||
|
e->face1);
|
||||||
|
convexHullFace *f2 = (convexHullFace *)arrayGetItem(hull->faceArray,
|
||||||
|
e->face2);
|
||||||
|
if (3 == f1->vertexNum && 3 == f2->vertexNum) {
|
||||||
|
if (e->score > 0) {
|
||||||
|
int firstEdgeVertex = findFace3FirstEdgeVertex((face3 *)f1, e);
|
||||||
|
int insertPos = firstEdgeVertex + 1;
|
||||||
|
|
||||||
|
drawDebugPrintf("score:%d", e->score);
|
||||||
|
|
||||||
|
memmove(&f1->u.q.indices[insertPos + 1],
|
||||||
|
&f1->u.q.indices[insertPos], (3 - insertPos) * sizeof(int));
|
||||||
|
f1->u.q.indices[insertPos] = e->hill2;
|
||||||
|
f1->vertexNum = 4;
|
||||||
|
f2->vertexNum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// After merge, face3 hashtable can not be used anymore.
|
||||||
|
hashtableDestroy(hull->face3Hashtable);
|
||||||
|
hull->face3Hashtable = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex) {
|
||||||
|
convexHullFace *face = (convexHullFace *)arrayGetItem(hull->faceArray,
|
||||||
|
faceIndex);
|
||||||
|
return face;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex) {
|
vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex) {
|
||||||
converHullVertex *vertex = (converHullVertex *)arrayGetItem(
|
convexHullVertex *vertex = (convexHullVertex *)arrayGetItem(
|
||||||
hull->vertexArray, vertexIndex);
|
hull->vertexArray, vertexIndex);
|
||||||
return &vertex->pt;
|
return &vertex->pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int convexHullGetFace3Num(convexHull *hull) {
|
int convexHullGetFaceNum(convexHull *hull) {
|
||||||
return arrayGetLength(hull->face3Array);
|
return arrayGetLength(hull->faceArray);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,23 @@
|
||||||
#include "3dstruct.h"
|
#include "3dstruct.h"
|
||||||
|
|
||||||
typedef struct convexHull convexHull;
|
typedef struct convexHull convexHull;
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
face4 q;
|
||||||
|
face3 t;
|
||||||
|
} u;
|
||||||
|
int vertexNum;
|
||||||
|
} convexHullFace;
|
||||||
|
|
||||||
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);
|
||||||
void convexHullDestroy(convexHull *hull);
|
void convexHullDestroy(convexHull *hull);
|
||||||
int convexHullGenerate(convexHull *hull);
|
int convexHullGenerate(convexHull *hull);
|
||||||
int convexHullUnifyNormals(convexHull *hull, vec3 *origin);
|
int convexHullUnifyNormals(convexHull *hull, vec3 *origin);
|
||||||
int convexHullGetFace3Num(convexHull *hull);
|
int convexHullMergeTriangles(convexHull *hull);
|
||||||
face3 *convexHullGetFace3(convexHull *hull, int faceIndex);
|
int convexHullGetFaceNum(convexHull *hull);
|
||||||
|
convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex);
|
||||||
vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex);
|
vec3 *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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue