Skip to content
Snippets Groups Projects
Commit 2ca8c0a9 authored by Gundalf's avatar Gundalf
Browse files

Remap indices for better vertex cache locality.

parent 5804f0cb
No related branches found
No related tags found
No related merge requests found
......@@ -77,7 +77,9 @@ bool Exporter::makeCollisionHierarchy(NiNodeRef &parent, INode *node, TimeValue
for (int i=0; i<mesh->getNumFaces(); i++)
addFace(tris, verts, vnorms, i, vi, mesh);
NiTriStripsDataRef data = makeTriStripsData(tris);
TriStrips strips;
strippify(strips, verts, vnorms, tris);
NiTriStripsDataRef data = makeTriStripsData(strips);
data->SetVertices(verts);
data->SetNormals(vnorms);
......
......@@ -32,6 +32,7 @@ void Exporter::writeConfig()
// regSet(hKey, "npx_wthresh", mWeldThresh);
regSet(hKey, "npx_tprefix", mTexPrefix);
regSet(hKey, "npx_coll", mExportCollision);
regSet(hKey, "npx_remap", mRemapIndices);
}
void Exporter::readConfig(INode *node)
......@@ -55,6 +56,7 @@ void Exporter::readConfig()
// regGet(hKey, "npx_wthresh", mWeldThresh);
regGet(hKey, "npx_tprefix", mTexPrefix);
regGet(hKey, "npx_coll", mExportCollision);
regGet(hKey, "npx_remap", mRemapIndices);
}
......
......@@ -10,6 +10,7 @@ bool Exporter::mVertexColors=true;
float Exporter::mWeldThresh=0.1f;
string Exporter::mTexPrefix="textures";
bool Exporter::mExportCollision=true;
bool Exporter::mRemapIndices=true;
Exporter::Exporter(Interface *i)
: mI(i)
......
......@@ -30,6 +30,7 @@ public:
static bool mVertexColors;
static float mWeldThresh;
static bool mExportCollision;
static bool mRemapIndices;
Exporter(Interface *i);
......@@ -83,9 +84,9 @@ private:
bool equal(const Vector3 &a, const Point3 &b, float thresh);
/* tristrips */
void strippify(TriStrips &strips, const Triangles &tris);
void strippify(TriStrips &strips, vector<Vector3> &verts, vector<Vector3> &norms, const Triangles &tris);
void strippify(TriStrips &strips, FaceGroup &grp);
NiTriStripsDataRef makeTriStripsData(const TriStrips &strips);
NiTriStripsDataRef makeTriStripsData(const Triangles &tris);
/* mesh export */
// adds a vertex to a face group if it doesn't exist yet. returns new or previous index into the
......
......@@ -79,7 +79,9 @@ bool Exporter::makeMesh(NiNodeRef &parent, Mtl *mtl, FaceGroup &grp)
NiTriStripsRef stripsShape = DynamicCast<NiTriStrips>(CreateBlock("NiTriStrips"));
shape = DynamicCast<NiTriBasedGeom>(stripsShape);
NiTriStripsDataRef stripData = makeTriStripsData(grp.faces);
TriStrips strips;
strippify(strips, grp);
NiTriStripsDataRef stripData = makeTriStripsData(strips);
data = DynamicCast<NiTriBasedGeomData>(stripData);
} else
......
......@@ -70,6 +70,7 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
CheckDlgButton(hWnd, IDC_CHK_VCOLORS, Exporter::mVertexColors);
SetDlgItemText(hWnd, IDC_ED_TEXPREFIX, Exporter::mTexPrefix.c_str());
CheckDlgButton(hWnd, IDC_CHK_COLL, Exporter::mExportCollision);
CheckDlgButton(hWnd, IDC_CHK_REMAP, Exporter::mRemapIndices);
TSTR tmp;
tmp.printf("%.4f", Exporter::mWeldThresh);
......@@ -97,6 +98,7 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA
Exporter::mExportLights = IsDlgButtonChecked(hWnd, IDC_CHK_LIGHTS);
Exporter::mVertexColors = IsDlgButtonChecked(hWnd, IDC_CHK_VCOLORS);
Exporter::mExportCollision = IsDlgButtonChecked(hWnd, IDC_CHK_COLL);
Exporter::mRemapIndices = IsDlgButtonChecked(hWnd, IDC_CHK_REMAP);
GetDlgItemText(hWnd, IDC_ED_TEXPREFIX, tmp, MAX_PATH);
Exporter::mTexPrefix = tmp;
......
......@@ -80,9 +80,9 @@ EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Export Nif"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
CONTROL "",IDC_EDIT,"CustEdit",NOT WS_VISIBLE | WS_TABSTOP,122,
48,35,10
CONTROL "",IDC_SPIN,"SpinnerControl",NOT WS_VISIBLE,160,47,7,10
CONTROL "",IDC_EDIT,"CustEdit",NOT WS_VISIBLE | WS_TABSTOP,148,8,
35,10
CONTROL "",IDC_SPIN,"SpinnerControl",NOT WS_VISIBLE,186,7,7,10
PUSHBUTTON "&Export",IDOK,7,87,34,14
PUSHBUTTON "&Cancel",IDCANCEL,44,87,33,14
CONTROL "Include &Hidden",IDC_CHK_HIDDEN,"Button",
......@@ -95,16 +95,18 @@ BEGIN
LTEXT "Texture &Prefix",IDC_STATIC,7,60,44,8
CONTROL "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX |
WS_DISABLED | WS_TABSTOP,7,31,35,10
EDITTEXT IDC_ED_WELDTHRESH,44,44,35,12,ES_AUTOHSCROLL | NOT
WS_VISIBLE | WS_DISABLED
LTEXT "Auto-&Weld",IDC_LBL_WELDTHRESH,44,34,34,8,NOT
EDITTEXT IDC_ED_WELDTHRESH,16,44,35,12,ES_AUTOHSCROLL | NOT
WS_VISIBLE | WS_DISABLED
LTEXT "Auto-&Weld",IDC_LBL_WELDTHRESH,7,45,34,8,NOT WS_VISIBLE |
WS_DISABLED
CONTROL "Export Co&llision",IDC_CHK_COLL,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,85,18,68,10
CONTROL "&Vertex Colors",IDC_CHK_VCOLORS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,85,31,68,10
LTEXT "http://niftools.sourceforge.net",IDC_LBL_LINK,98,87,95,
14,SS_NOTIFY | SS_CENTERIMAGE
CONTROL "&Remap Indices",IDC_CHK_REMAP,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,85,46,68,10
END
......
#include "pch.h"
void Exporter::strippify(TriStrips &strips, const Triangles &tris)
void Exporter::strippify(TriStrips &strips, vector<Vector3> &verts, vector<Vector3> &norms, const Triangles &tris)
{
unsigned short *data = (unsigned short *)malloc(tris.size() * 3 * 2);
for (int i=0; i<tris.size(); i++)
int i;
for (i=0; i<tris.size(); i++)
{
data[i * 3 + 0] = tris[i][0];
data[i * 3 + 1] = tris[i][1];
......@@ -14,7 +15,7 @@ void Exporter::strippify(TriStrips &strips, const Triangles &tris)
PrimitiveGroup * groups = 0;
unsigned short numGroups = 0;
// GF 3, what about others?
// GF 3+
SetCacheSize(CACHESIZE_GEFORCE3);
// don't generate hundreds of strips
SetStitchStrips(true);
......@@ -24,19 +25,125 @@ void Exporter::strippify(TriStrips &strips, const Triangles &tris)
if (!groups)
return;
for (int g=0; g<numGroups; g++)
if (!mRemapIndices)
{
if (groups[g].type == PT_STRIP)
for (int g=0; g<numGroups; g++)
{
strips.push_back(TriStrip(groups[g].numIndices));
TriStrip &strip = strips.back();
if (groups[g].type == PT_STRIP)
{
strips.push_back(TriStrip(groups[g].numIndices));
TriStrip &strip = strips.back();
for (int s=0; s<groups[g].numIndices; s++)
strip[s] = groups[g].indices[s];
for (int s=0; s<groups[g].numIndices; s++)
strip[s] = groups[g].indices[s];
}
}
} else
{
// remap indices
PrimitiveGroup *rmGroups;
RemapIndices(groups, numGroups, verts.size(), &rmGroups);
vector<Vector3> tverts = verts;
vector<Vector3> tnorms = norms;
for (int g=0; g<numGroups; g++)
{
if (rmGroups[g].type == PT_STRIP)
{
strips.push_back(TriStrip(rmGroups[g].numIndices));
TriStrip &strip = strips.back();
for (int s=0; s<rmGroups[g].numIndices; s++)
{
strip[s] = rmGroups[g].indices[s];
unsigned short a = strip[s], b = groups[g].indices[s];
verts[a] = tverts[b];
norms[a] = tnorms[b];
}
}
}
delete [] rmGroups;
}
delete [] groups;
}
void Exporter::strippify(TriStrips &strips, FaceGroup &grp)
{
unsigned short *data = (unsigned short *)malloc(grp.faces.size() * 3 * 2);
int i;
for (i=0; i<grp.faces.size(); i++)
{
data[i * 3 + 0] = grp.faces[i][0];
data[i * 3 + 1] = grp.faces[i][1];
data[i * 3 + 2] = grp.faces[i][2];
}
PrimitiveGroup * groups = 0;
unsigned short numGroups = 0;
// GF 3+
SetCacheSize(CACHESIZE_GEFORCE3);
// don't generate hundreds of strips
SetStitchStrips(true);
GenerateStrips(data, grp.faces.size()*3, &groups, &numGroups);
free( data );
if (!groups)
return;
if (!mRemapIndices)
{
for (int g=0; g<numGroups; g++)
{
if (groups[g].type == PT_STRIP)
{
strips.push_back(TriStrip(groups[g].numIndices));
TriStrip &strip = strips.back();
for (int s=0; s<groups[g].numIndices; s++)
strip[s] = groups[g].indices[s];
}
}
} else
{
// remap indices
PrimitiveGroup *rmGroups;
RemapIndices(groups, numGroups, grp.verts.size(), &rmGroups);
FaceGroup tmp = grp;
for (int g=0; g<numGroups; g++)
{
if (rmGroups[g].type == PT_STRIP)
{
strips.push_back(TriStrip(rmGroups[g].numIndices));
TriStrip &strip = strips.back();
for (int s=0; s<rmGroups[g].numIndices; s++)
{
strip[s] = rmGroups[g].indices[s];
unsigned short a = strip[s], b = groups[g].indices[s];
grp.verts[a] = tmp.verts[b];
grp.vnorms[a] = tmp.vnorms[b];
grp.uvs[a] = tmp.uvs[b];
if (grp.vcolors.size() > 0)
grp.vcolors[a] = tmp.vcolors[b];
}
}
}
delete [] rmGroups;
}
delete [] groups;
}
......@@ -56,11 +163,3 @@ NiTriStripsDataRef Exporter::makeTriStripsData(const TriStrips &strips)
return stripData;
}
NiTriStripsDataRef Exporter::makeTriStripsData(const Triangles &tris)
{
TriStrips strips;
strippify(strips, tris);
return makeTriStripsData(strips);
}
......@@ -20,6 +20,8 @@
#define IDC_CHK_COLL 1010
#define IDC_LBL_LINK 1011
#define IDC_CHK_VCOLORS 1012
#define IDC_CHK_VCOLORS2 1013
#define IDC_CHK_REMAP 1013
#define IDC_COLOR 1456
#define IDC_EDIT 1490
#define IDC_SPIN 1496
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment