- added free list of strips
- tried a few weightings for the selection of adjacent faces
This commit is contained in:
@@ -113,6 +113,8 @@ int Convert(const char* input, const char* output)
|
||||
| aiComponent_CAMERAS
|
||||
| aiComponent_MATERIALS);
|
||||
|
||||
printf("Loading %s...", input);
|
||||
|
||||
// Import file
|
||||
const aiScene* scene = importer.ReadFile(input,
|
||||
aiProcess_FixInfacingNormals
|
||||
@@ -128,6 +130,8 @@ int Convert(const char* input, const char* output)
|
||||
| aiProcess_ImproveCacheLocality
|
||||
| aiProcess_RemoveComponent);
|
||||
|
||||
puts(" done");
|
||||
|
||||
if ( scene == 0 )
|
||||
{
|
||||
fprintf(stderr, "Could not import %s\n", input);
|
||||
@@ -149,8 +153,11 @@ int Convert(const char* input, const char* output)
|
||||
return 3;
|
||||
}
|
||||
|
||||
printf("Initializing OpenGL\n");
|
||||
InitOpenGL();
|
||||
|
||||
printf("Stripping...\n");
|
||||
|
||||
//std::vector<u32> indices;
|
||||
//for ( u32 i = 0 ; i < mesh->mNumFaces ; i++ )
|
||||
//{
|
||||
@@ -265,6 +272,8 @@ int Convert(const char* input, const char* output)
|
||||
#endif
|
||||
printf("%d strips generated for %d triangles\n", nbStrips, mesh->mNumFaces);
|
||||
|
||||
puts("Scaling...");
|
||||
|
||||
// TODO: AABB => OBB, for higher precision
|
||||
Box box = ComputeBoundingBox(mesh->mVertices, mesh->mNumVertices);
|
||||
aiVector3D minDS(-7.99f);
|
||||
@@ -277,6 +286,8 @@ int Convert(const char* input, const char* output)
|
||||
translate = translate / scale;
|
||||
scale = (maxDS - minDS) / scale;
|
||||
|
||||
puts("Generating display list...");
|
||||
|
||||
// Generate display list
|
||||
std::vector<u32> list;
|
||||
|
||||
@@ -390,11 +401,15 @@ int Convert(const char* input, const char* output)
|
||||
}
|
||||
}
|
||||
|
||||
printf("Exporting to %s...", output);
|
||||
|
||||
// Output file
|
||||
FILE* f = fopen(output, "wb");
|
||||
fwrite(&list[0], sizeof(list[0]), list.size(), f);
|
||||
fclose(f);
|
||||
|
||||
puts(" done");
|
||||
|
||||
#ifdef NVTRISTRIP
|
||||
delete[] strips;
|
||||
delete[] indices;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "List.h"
|
||||
#include "opengl.h"
|
||||
|
||||
#define MAX_STRIPS 1024
|
||||
#define MAX_STRIPS 16384
|
||||
|
||||
float* vertices;
|
||||
|
||||
@@ -31,8 +31,11 @@ struct Face
|
||||
|
||||
LIST_LINK(Face) dualLink;
|
||||
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)
|
||||
{
|
||||
@@ -325,19 +328,24 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
u32 nbStrips = 0;
|
||||
LIST_DECLARE(Face, stripLink) strips[MAX_STRIPS];
|
||||
|
||||
LIST_DECLARE(Face, freeLink) freeStrips;
|
||||
|
||||
// stripify
|
||||
for ( u32 e = 0 ; e < nbEdges ; e++ )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
u32 realNbStrips = 0;
|
||||
for ( u32 i = 0 ; i < nbStrips ; i++ )
|
||||
if ( !strips[i].Empty() )
|
||||
realNbStrips++;
|
||||
if ( e % 32 == 0 )
|
||||
{
|
||||
u32 realNbStrips = 0;
|
||||
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",
|
||||
e, realNbStrips, nbStrips,
|
||||
Length(unconnected[0]), Length(unconnected[1]), Length(connected[0]),
|
||||
Length(unconnected[2]), Length(connected[1]), Length(unconnected[3]));
|
||||
printf("[%d] strips:%d(%d) U0:%d U1:%d C1:%d U2:%d C2:%d U3:%d\n",
|
||||
e, realNbStrips, nbStrips,
|
||||
Length(unconnected[0]), Length(unconnected[1]), Length(connected[0]),
|
||||
Length(unconnected[2]), Length(connected[1]), Length(unconnected[3]));
|
||||
}
|
||||
#endif
|
||||
Face* face[2] = { 0, 0 };
|
||||
if ( !unconnected[1].Empty() )
|
||||
@@ -373,15 +381,27 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
assert(face[0]->dualConnectivity > 0);
|
||||
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] )
|
||||
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]);
|
||||
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[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 )
|
||||
{
|
||||
// merge one strip into the other
|
||||
LIST_DECLARE(Face, stripLink)& strip0 = strips[face[0]->strip];
|
||||
LIST_DECLARE(Face, stripLink)& strip1 = strips[face[1]->strip];
|
||||
Face* strip0head = strip0.Head();
|
||||
@@ -400,6 +421,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
Face* strip1tail = 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();
|
||||
while ( f )
|
||||
{
|
||||
@@ -414,6 +439,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
}
|
||||
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();
|
||||
while ( f )
|
||||
{
|
||||
@@ -428,6 +457,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
}
|
||||
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();
|
||||
while ( f )
|
||||
{
|
||||
@@ -442,6 +475,10 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
}
|
||||
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();
|
||||
while ( f )
|
||||
{
|
||||
@@ -464,6 +501,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
{
|
||||
if ( face[1]->set != Face::CONNECTED )
|
||||
{
|
||||
// attach face to strip
|
||||
LIST_DECLARE(Face, stripLink)& strip = strips[face[0]->strip];
|
||||
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 )
|
||||
{
|
||||
// attach face to strip
|
||||
LIST_DECLARE(Face, stripLink)& strip = strips[face[1]->strip];
|
||||
if ( face[1]->stripLink.Next() == 0 )
|
||||
{
|
||||
@@ -501,6 +540,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to find a strip where both faces can be attached to
|
||||
assert(face[0]->set != Face::FULLY_CONNECTED);
|
||||
assert(face[1]->set != Face::FULLY_CONNECTED);
|
||||
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 )
|
||||
{
|
||||
assert(nbStrips < MAX_STRIPS);
|
||||
stripID = nbStrips;
|
||||
// create a new strip
|
||||
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];
|
||||
nbStrips++;
|
||||
assert(face[0] && face[1]);
|
||||
assert(!face[0]->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 )
|
||||
{
|
||||
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++ )
|
||||
{
|
||||
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();
|
||||
f->dualLink.Unlink();
|
||||
|
||||
assert(nbStrips < MAX_STRIPS);
|
||||
LIST_DECLARE(Face, stripLink)& strip = strips[nbStrips];
|
||||
nbStrips++;
|
||||
u32 stripID = -1;
|
||||
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];
|
||||
strip.InsertHead(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ float rotatePhi = 0.f;
|
||||
float rotateTheta = 0.f;
|
||||
float dist = 4.f;
|
||||
float h = .5f;
|
||||
float scale = 1.f;
|
||||
|
||||
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, 1000.f);
|
||||
glEnd();
|
||||
glScalef(scale, scale, scale);
|
||||
}
|
||||
|
||||
bool EndSceneOpenGL()
|
||||
@@ -162,18 +164,17 @@ bool EndSceneOpenGL()
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
if ( msg.wParam == 'S' )
|
||||
return false;
|
||||
if ( msg.wParam == VK_ESCAPE )
|
||||
exit(0);
|
||||
if ( msg.wParam == VK_DOWN )
|
||||
dist = maxf(dist + 0.2f, 1.f);
|
||||
if ( msg.wParam == VK_UP )
|
||||
dist = minf(dist - 0.2f, 10.f);
|
||||
if ( msg.wParam == 'Y' )
|
||||
h = maxf(h + 0.02f, -5.f);
|
||||
if ( msg.wParam == 'H' )
|
||||
h = minf(h - 0.02f, 5.f);
|
||||
switch ( msg.wParam )
|
||||
{
|
||||
case 'S' : return false;
|
||||
case VK_ESCAPE: exit(0);
|
||||
case VK_DOWN: dist = maxf(dist + .02f, 1.f); break;
|
||||
case VK_UP: dist = minf(dist - 0.02f, 10.f); break;
|
||||
case 'Y': h = maxf(h + .02f, -5.f); break;
|
||||
case 'H': h = minf(h - .02f, 5.f); break;
|
||||
case 'Z': scale *= 2.f; break;
|
||||
case 'A': scale /= 2.f; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
|
||||
Reference in New Issue
Block a user