- 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_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;
|
||||||
|
|||||||
@@ -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,10 +328,14 @@ 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
|
||||||
|
if ( e % 32 == 0 )
|
||||||
|
{
|
||||||
u32 realNbStrips = 0;
|
u32 realNbStrips = 0;
|
||||||
for ( u32 i = 0 ; i < nbStrips ; i++ )
|
for ( u32 i = 0 ; i < nbStrips ; i++ )
|
||||||
if ( !strips[i].Empty() )
|
if ( !strips[i].Empty() )
|
||||||
@@ -338,6 +345,7 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
|||||||
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] )
|
||||||
|
{
|
||||||
|
//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];
|
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++ )
|
||||||
@@ -588,11 +628,21 @@ void MultiPathStripper(const std::vector<u32>& indices, std::vector<u32>& stripL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( stripID == -1 )
|
if ( stripID == -1 )
|
||||||
|
{
|
||||||
|
// create a new strip
|
||||||
|
if ( !freeStrips.Empty() )
|
||||||
|
{
|
||||||
|
stripID = freeStrips.Head()->freeStrip;
|
||||||
|
freeStrips.Head()->freeStrip = -1;
|
||||||
|
freeStrips.Head()->freeLink.Unlink();
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
assert(nbStrips < MAX_STRIPS);
|
assert(nbStrips < MAX_STRIPS);
|
||||||
stripID = nbStrips;
|
stripID = nbStrips;
|
||||||
LIST_DECLARE(Face, stripLink)* strip = &strips[stripID];
|
|
||||||
nbStrips++;
|
nbStrips++;
|
||||||
|
}
|
||||||
|
LIST_DECLARE(Face, stripLink)* strip = &strips[stripID];
|
||||||
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();
|
||||||
|
|
||||||
|
u32 stripID = -1;
|
||||||
|
if ( !freeStrips.Empty() )
|
||||||
|
{
|
||||||
|
stripID = freeStrips.Head()->freeStrip;
|
||||||
|
freeStrips.Head()->freeStrip = -1;
|
||||||
|
freeStrips.Head()->freeLink.Unlink();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
assert(nbStrips < MAX_STRIPS);
|
assert(nbStrips < MAX_STRIPS);
|
||||||
LIST_DECLARE(Face, stripLink)& strip = strips[nbStrips];
|
stripID = nbStrips;
|
||||||
nbStrips++;
|
nbStrips++;
|
||||||
|
}
|
||||||
|
LIST_DECLARE(Face, stripLink)& strip = strips[stripID];
|
||||||
strip.InsertHead(f);
|
strip.InsertHead(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user