- added free list of strips

- tried a few weightings for the selection of adjacent faces
This commit is contained in:
daniel borges
2012-09-17 23:18:03 +02:00
parent 194673b5dd
commit 591239b339
3 changed files with 110 additions and 31 deletions

View File

@@ -113,6 +113,8 @@ int Convert(const char* input, const char* output)
| aiComponent_CAMERAS | aiComponent_CAMERAS
| aiComponent_MATERIALS); | aiComponent_MATERIALS);
printf("Loading %s...", input);
// Import file // Import file
const aiScene* scene = importer.ReadFile(input, const aiScene* scene = importer.ReadFile(input,
aiProcess_FixInfacingNormals aiProcess_FixInfacingNormals
@@ -128,6 +130,8 @@ int Convert(const char* input, const char* output)
| aiProcess_ImproveCacheLocality | aiProcess_ImproveCacheLocality
| aiProcess_RemoveComponent); | aiProcess_RemoveComponent);
puts(" done");
if ( scene == 0 ) if ( scene == 0 )
{ {
fprintf(stderr, "Could not import %s\n", input); fprintf(stderr, "Could not import %s\n", input);
@@ -149,8 +153,11 @@ int Convert(const char* input, const char* output)
return 3; return 3;
} }
printf("Initializing OpenGL\n");
InitOpenGL(); InitOpenGL();
printf("Stripping...\n");
//std::vector<u32> indices; //std::vector<u32> indices;
//for ( u32 i = 0 ; i < mesh->mNumFaces ; i++ ) //for ( u32 i = 0 ; i < mesh->mNumFaces ; i++ )
//{ //{
@@ -265,6 +272,8 @@ int Convert(const char* input, const char* output)
#endif #endif
printf("%d strips generated for %d triangles\n", nbStrips, mesh->mNumFaces); printf("%d strips generated for %d triangles\n", nbStrips, mesh->mNumFaces);
puts("Scaling...");
// TODO: AABB => OBB, for higher precision // TODO: AABB => OBB, for higher precision
Box box = ComputeBoundingBox(mesh->mVertices, mesh->mNumVertices); Box box = ComputeBoundingBox(mesh->mVertices, mesh->mNumVertices);
aiVector3D minDS(-7.99f); aiVector3D minDS(-7.99f);
@@ -277,6 +286,8 @@ int Convert(const char* input, const char* output)
translate = translate / scale; translate = translate / scale;
scale = (maxDS - minDS) / scale; scale = (maxDS - minDS) / scale;
puts("Generating display list...");
// Generate display list // Generate display list
std::vector<u32> list; std::vector<u32> list;
@@ -390,11 +401,15 @@ int Convert(const char* input, const char* output)
} }
} }
printf("Exporting to %s...", output);
// Output file // Output file
FILE* f = fopen(output, "wb"); FILE* f = fopen(output, "wb");
fwrite(&list[0], sizeof(list[0]), list.size(), f); fwrite(&list[0], sizeof(list[0]), list.size(), f);
fclose(f); fclose(f);
puts(" done");
#ifdef NVTRISTRIP #ifdef NVTRISTRIP
delete[] strips; delete[] strips;
delete[] indices; delete[] indices;

View File

@@ -5,7 +5,7 @@
#include "List.h" #include "List.h"
#include "opengl.h" #include "opengl.h"
#define MAX_STRIPS 1024 #define MAX_STRIPS 16384
float* vertices; float* vertices;
@@ -31,8 +31,11 @@ struct Face
LIST_LINK(Face) dualLink; LIST_LINK(Face) dualLink;
LIST_LINK(Face) stripLink; LIST_LINK(Face) stripLink;
LIST_LINK(Face) freeLink;
Face() : connectivity(0), dualConnectivity(0), set(UNCONNECTED), strip(-1) { adj[0] = adj[1] = adj[2] = 0; dual[0] = dual[1] = dual[2] = false; } s32 freeStrip;
Face() : connectivity(0), dualConnectivity(0), set(UNCONNECTED), strip(-1), freeStrip(-1) { adj[0] = adj[1] = adj[2] = 0; dual[0] = dual[1] = dual[2] = false; }
void RemoveFromDual(Face* f) void RemoveFromDual(Face* f)
{ {
@@ -325,19 +328,24 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
u32 nbStrips = 0; u32 nbStrips = 0;
LIST_DECLARE(Face, stripLink) strips[MAX_STRIPS]; LIST_DECLARE(Face, stripLink) strips[MAX_STRIPS];
LIST_DECLARE(Face, freeLink) freeStrips;
// stripify // stripify
for ( u32 e = 0 ; e < nbEdges ; e++ ) for ( u32 e = 0 ; e < nbEdges ; e++ )
{ {
#ifdef _DEBUG #ifdef _DEBUG
u32 realNbStrips = 0; if ( e % 32 == 0 )
for ( u32 i = 0 ; i < nbStrips ; i++ ) {
if ( !strips[i].Empty() ) u32 realNbStrips = 0;
realNbStrips++; for ( u32 i = 0 ; i < nbStrips ; i++ )
if ( !strips[i].Empty() )
realNbStrips++;
printf("[%d] strips:%d(%d) U0:%d U1:%d C1:%d U2:%d C2:%d U3:%d\n", printf("[%d] strips:%d(%d) U0:%d U1:%d C1:%d U2:%d C2:%d U3:%d\n",
e, realNbStrips, nbStrips, e, realNbStrips, nbStrips,
Length(unconnected[0]), Length(unconnected[1]), Length(connected[0]), Length(unconnected[0]), Length(unconnected[1]), Length(connected[0]),
Length(unconnected[2]), Length(connected[1]), Length(unconnected[3])); Length(unconnected[2]), Length(connected[1]), Length(unconnected[3]));
}
#endif #endif
Face* face[2] = { 0, 0 }; Face* face[2] = { 0, 0 };
if ( !unconnected[1].Empty() ) if ( !unconnected[1].Empty() )
@@ -373,15 +381,27 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
assert(face[0]->dualConnectivity > 0); assert(face[0]->dualConnectivity > 0);
face[0]->dualLink.Unlink(); face[0]->dualLink.Unlink();
for ( u32 i = 0 ; face[1] == 0 && i < face[0]->connectivity ; i++ ) u32 power = 0;
for ( u32 i = 0 ; i < face[0]->connectivity ; i++ )
{ {
if ( face[0]->dual[i] ) if ( face[0]->dual[i] )
face[1] = face[0]->adj[i]; {
//u32 p = 1;
//u32 p = (3 - face[0]->adj[i]->dualConnectivity) + 1 + face[0]->adj[i]->set * 10;
u32 p = face[0]->adj[i]->dualConnectivity + 1 + face[0]->adj[i]->set * 10;
//u32 p = face[0]->adj[i]->dualConnectivity + 1 + (2 - face[0]->adj[i]->set) * 10;
//u32 p = face[0]->adj[i]->strip + 10;
if ( p > power )
{
face[1] = face[0]->adj[i];
power = p;
}
}
} }
assert(face[1]); assert(face[1]);
face[1]->dualLink.Unlink(); face[1]->dualLink.Unlink();
ShowDebug(faces, nbTris, face[0], face[1], strips, nbStrips); //ShowDebug(faces, nbTris, face[0], face[1], strips, nbStrips);
assert(face[0]->set != Face::FULLY_CONNECTED); assert(face[0]->set != Face::FULLY_CONNECTED);
assert(face[1]->set != Face::FULLY_CONNECTED); assert(face[1]->set != Face::FULLY_CONNECTED);
@@ -392,6 +412,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
{ {
if ( face[0]->strip != face[1]->strip ) if ( face[0]->strip != face[1]->strip )
{ {
// merge one strip into the other
LIST_DECLARE(Face, stripLink)& strip0 = strips[face[0]->strip]; LIST_DECLARE(Face, stripLink)& strip0 = strips[face[0]->strip];
LIST_DECLARE(Face, stripLink)& strip1 = strips[face[1]->strip]; LIST_DECLARE(Face, stripLink)& strip1 = strips[face[1]->strip];
Face* strip0head = strip0.Head(); Face* strip0head = strip0.Head();
@@ -400,6 +421,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
Face* strip1tail = strip1.Tail(); Face* strip1tail = strip1.Tail();
if ( strip0.Head()->IsAdjacent(strip1.Tail()) ) if ( strip0.Head()->IsAdjacent(strip1.Tail()) )
{ {
freeStrips.InsertHead(face[1]);
assert(face[1]->freeStrip == -1);
face[1]->freeStrip = face[1]->strip;
Face* f = strip1.Tail(); Face* f = strip1.Tail();
while ( f ) while ( f )
{ {
@@ -414,6 +439,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
else if ( strip1.Head()->IsAdjacent(strip0.Tail()) ) else if ( strip1.Head()->IsAdjacent(strip0.Tail()) )
{ {
freeStrips.InsertHead(face[0]);
assert(face[0]->freeStrip == -1);
face[0]->freeStrip = face[0]->strip;
Face* f = strip0.Tail(); Face* f = strip0.Tail();
while ( f ) while ( f )
{ {
@@ -428,6 +457,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
else if ( strip1.Tail()->IsAdjacent(strip0.Tail()) ) else if ( strip1.Tail()->IsAdjacent(strip0.Tail()) )
{ {
freeStrips.InsertHead(face[1]);
assert(face[1]->freeStrip == -1);
face[1]->freeStrip = face[1]->strip;
Face* f = strip1.Tail(); Face* f = strip1.Tail();
while ( f ) while ( f )
{ {
@@ -442,6 +475,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
else if ( strip1.Head()->IsAdjacent(strip0.Head()) ) else if ( strip1.Head()->IsAdjacent(strip0.Head()) )
{ {
freeStrips.InsertHead(face[1]);
assert(face[1]->freeStrip == -1);
face[1]->freeStrip = face[1]->strip;
Face* f = strip1.Head(); Face* f = strip1.Head();
while ( f ) while ( f )
{ {
@@ -464,6 +501,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
{ {
if ( face[1]->set != Face::CONNECTED ) if ( face[1]->set != Face::CONNECTED )
{ {
// attach face to strip
LIST_DECLARE(Face, stripLink)& strip = strips[face[0]->strip]; LIST_DECLARE(Face, stripLink)& strip = strips[face[0]->strip];
if ( face[0]->stripLink.Next() == 0 ) if ( face[0]->stripLink.Next() == 0 )
{ {
@@ -484,6 +522,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
{ {
if ( face[0]->set != Face::CONNECTED ) if ( face[0]->set != Face::CONNECTED )
{ {
// attach face to strip
LIST_DECLARE(Face, stripLink)& strip = strips[face[1]->strip]; LIST_DECLARE(Face, stripLink)& strip = strips[face[1]->strip];
if ( face[1]->stripLink.Next() == 0 ) if ( face[1]->stripLink.Next() == 0 )
{ {
@@ -501,6 +540,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
else else
{ {
// try to find a strip where both faces can be attached to
assert(face[0]->set != Face::FULLY_CONNECTED); assert(face[0]->set != Face::FULLY_CONNECTED);
assert(face[1]->set != Face::FULLY_CONNECTED); assert(face[1]->set != Face::FULLY_CONNECTED);
for ( u32 s = 0 ; stripID == -1 && s < nbStrips ; s++ ) for ( u32 s = 0 ; stripID == -1 && s < nbStrips ; s++ )
@@ -589,10 +629,20 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
if ( stripID == -1 ) if ( stripID == -1 )
{ {
assert(nbStrips < MAX_STRIPS); // create a new strip
stripID = nbStrips; if ( !freeStrips.Empty() )
{
stripID = freeStrips.Head()->freeStrip;
freeStrips.Head()->freeStrip = -1;
freeStrips.Head()->freeLink.Unlink();
}
else
{
assert(nbStrips < MAX_STRIPS);
stripID = nbStrips;
nbStrips++;
}
LIST_DECLARE(Face, stripLink)* strip = &strips[stripID]; LIST_DECLARE(Face, stripLink)* strip = &strips[stripID];
nbStrips++;
assert(face[0] && face[1]); assert(face[0] && face[1]);
assert(!face[0]->stripLink.IsLinked()); assert(!face[0]->stripLink.IsLinked());
assert(!face[1]->stripLink.IsLinked()); assert(!face[1]->stripLink.IsLinked());
@@ -604,6 +654,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
} }
// tag faces
if ( stripID != -1 ) if ( stripID != -1 )
{ {
for ( u32 i = 0 ; i < 2 ; i++ ) for ( u32 i = 0 ; i < 2 ; i++ )
@@ -620,6 +671,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
} }
} }
// update dual graph
for ( u32 f = 0 ; f < 2 ; f++ ) for ( u32 f = 0 ; f < 2 ; f++ )
{ {
if ( face[f]->strip != -1 ) if ( face[f]->strip != -1 )
@@ -663,9 +715,20 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
Face* f = unconnected[0].Tail(); Face* f = unconnected[0].Tail();
f->dualLink.Unlink(); f->dualLink.Unlink();
assert(nbStrips < MAX_STRIPS); u32 stripID = -1;
LIST_DECLARE(Face, stripLink)& strip = strips[nbStrips]; if ( !freeStrips.Empty() )
nbStrips++; {
stripID = freeStrips.Head()->freeStrip;
freeStrips.Head()->freeStrip = -1;
freeStrips.Head()->freeLink.Unlink();
}
else
{
assert(nbStrips < MAX_STRIPS);
stripID = nbStrips;
nbStrips++;
}
LIST_DECLARE(Face, stripLink)& strip = strips[stripID];
strip.InsertHead(f); strip.InsertHead(f);
} }

View File

@@ -26,6 +26,7 @@ float rotatePhi = 0.f;
float rotateTheta = 0.f; float rotateTheta = 0.f;
float dist = 4.f; float dist = 4.f;
float h = .5f; float h = .5f;
float scale = 1.f;
static LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
@@ -141,6 +142,7 @@ void BeginSceneOpenGL()
glVertex3f(0.f, 0.f, 0.f); glVertex3f(0.f, 0.f, 0.f);
glVertex3f(0.f, 0.f, 1000.f); glVertex3f(0.f, 0.f, 1000.f);
glEnd(); glEnd();
glScalef(scale, scale, scale);
} }
bool EndSceneOpenGL() bool EndSceneOpenGL()
@@ -162,18 +164,17 @@ bool EndSceneOpenGL()
break; break;
case WM_KEYDOWN: case WM_KEYDOWN:
if ( msg.wParam == 'S' ) switch ( msg.wParam )
return false; {
if ( msg.wParam == VK_ESCAPE ) case 'S' : return false;
exit(0); case VK_ESCAPE: exit(0);
if ( msg.wParam == VK_DOWN ) case VK_DOWN: dist = maxf(dist + .02f, 1.f); break;
dist = maxf(dist + 0.2f, 1.f); case VK_UP: dist = minf(dist - 0.02f, 10.f); break;
if ( msg.wParam == VK_UP ) case 'Y': h = maxf(h + .02f, -5.f); break;
dist = minf(dist - 0.2f, 10.f); case 'H': h = minf(h - .02f, 5.f); break;
if ( msg.wParam == 'Y' ) case 'Z': scale *= 2.f; break;
h = maxf(h + 0.02f, -5.f); case 'A': scale /= 2.f; break;
if ( msg.wParam == 'H' ) }
h = minf(h - 0.02f, 5.f);
break; break;
case WM_MOUSEMOVE: case WM_MOUSEMOVE: