Try to make sense of obj's mtl files.
Added --ignoresurfname arg to optimise obj files (where the source object's name is not going to be used for skin files). git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5811 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
9d2573f708
commit
d855cc6e84
1 changed files with 114 additions and 5 deletions
119
iqm/iqm.cpp
119
iqm/iqm.cpp
|
@ -133,6 +133,7 @@ struct filespec
|
||||||
int endframe;
|
int endframe;
|
||||||
meshprop meshprops;
|
meshprop meshprops;
|
||||||
const char *materialprefix;
|
const char *materialprefix;
|
||||||
|
bool ignoresurfname;
|
||||||
Quat rotate;
|
Quat rotate;
|
||||||
float scale;
|
float scale;
|
||||||
Vec3 translate;
|
Vec3 translate;
|
||||||
|
@ -152,6 +153,7 @@ struct filespec
|
||||||
endframe = -1;
|
endframe = -1;
|
||||||
meshprops = meshprop();
|
meshprops = meshprop();
|
||||||
materialprefix = NULL;
|
materialprefix = NULL;
|
||||||
|
ignoresurfname = false;
|
||||||
rotate = Quat(0, 0, 0, 1);
|
rotate = Quat(0, 0, 0, 1);
|
||||||
scale = 1;
|
scale = 1;
|
||||||
translate = Vec3(0,0,0);
|
translate = Vec3(0,0,0);
|
||||||
|
@ -1170,6 +1172,14 @@ void makemeshes(const filespec &spec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (spec.ignoresurfname)
|
||||||
|
{
|
||||||
|
loopv(emeshes)
|
||||||
|
{
|
||||||
|
emeshes[i].name = getnamekey("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loopv(emeshes)
|
loopv(emeshes)
|
||||||
{
|
{
|
||||||
emesh &em1 = emeshes[i];
|
emesh &em1 = emeshes[i];
|
||||||
|
@ -1195,7 +1205,6 @@ void makemeshes(const filespec &spec)
|
||||||
if(tinfo.empty()) continue;
|
if(tinfo.empty()) continue;
|
||||||
|
|
||||||
mesh &m = meshes.add();
|
mesh &m = meshes.add();
|
||||||
m.name = sharestring(em1.name);
|
|
||||||
if (spec.materialprefix)
|
if (spec.materialprefix)
|
||||||
{
|
{
|
||||||
char material[512];
|
char material[512];
|
||||||
|
@ -1204,6 +1213,10 @@ void makemeshes(const filespec &spec)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m.material = sharestring(em1.material);
|
m.material = sharestring(em1.material);
|
||||||
|
if (!em1.name)
|
||||||
|
m.name = sharestring(em1.material);
|
||||||
|
else
|
||||||
|
m.name = sharestring(em1.name);
|
||||||
m.firsttri = triangles.length();
|
m.firsttri = triangles.length();
|
||||||
m.firstvert = numfverts+vmap.length();
|
m.firstvert = numfverts+vmap.length();
|
||||||
maketriangles(tinfo, mmap);
|
maketriangles(tinfo, mmap);
|
||||||
|
@ -2557,13 +2570,78 @@ void parseobjvert(char *s, vector<Vec3> &out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mtlinfo{
|
||||||
|
const char *name;
|
||||||
|
const char *tex; //often null
|
||||||
|
Vec4 rgba; //often 1,1,1,1
|
||||||
|
mtlinfo(const char *matname) : name(getnamekey(matname)), tex(NULL),rgba(Vec4(1,1,1,1)) {}
|
||||||
|
};
|
||||||
|
static vector<mtlinfo> parsemtl(stream *f)
|
||||||
|
{
|
||||||
|
vector<mtlinfo> ret;
|
||||||
|
char buf[512];
|
||||||
|
mtlinfo dummy(""), *curmat = &dummy;
|
||||||
|
|
||||||
|
if (f)
|
||||||
|
while(f->getline(buf, sizeof(buf)))
|
||||||
|
{
|
||||||
|
char *c = buf;
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
if (*c == '#')
|
||||||
|
continue;
|
||||||
|
else if(!strncmp(c, "newmtl", 6) && isspace(c[6]))
|
||||||
|
{
|
||||||
|
while(isalpha(*c)) c++;
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
char *name = c;
|
||||||
|
size_t namelen = strlen(c);
|
||||||
|
while(namelen > 0 && isspace(name[namelen-1])) namelen--;
|
||||||
|
name[namelen] = 0;
|
||||||
|
|
||||||
|
curmat = &ret.add(mtlinfo(name));
|
||||||
|
}
|
||||||
|
else if(!strncmp(c, "Kd", 2) && isspace(c[2]))
|
||||||
|
{ //diffuse colours...
|
||||||
|
while(isalpha(*c)) c++;
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
loopi(3)
|
||||||
|
{
|
||||||
|
curmat->rgba[i] = strtod(c, &c);
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
if(!*c) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!strncmp(c, "D", 1) && isspace(c[1]))
|
||||||
|
{ //'disolve', so basically alpha
|
||||||
|
while(isalpha(*c)) c++;
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
curmat->rgba[3] = strtod(c, &c);
|
||||||
|
}
|
||||||
|
else if(!strncmp(c, "map_Kd", 6) && isspace(c[6]))
|
||||||
|
{
|
||||||
|
while(isalpha(*c)) c++;
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
char *name = c;
|
||||||
|
size_t namelen = strlen(c);
|
||||||
|
while(namelen > 0 && isspace(name[namelen-1])) namelen--;
|
||||||
|
name[namelen] = 0;
|
||||||
|
curmat->tex = getnamekey(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool parseobj(stream *f)
|
bool parseobj(stream *f)
|
||||||
{
|
{
|
||||||
vector<Vec3> attrib[3];
|
vector<Vec3> attrib[3]; //coord, tangemt, normal.
|
||||||
char buf[512];
|
char buf[512];
|
||||||
hashtable<objvert, int> verthash;
|
hashtable<objvert, int> verthash;
|
||||||
string meshname = "", matname = "";
|
string meshname = "", matname = "", tmpname="";
|
||||||
int curmesh = -1, smooth = 0;
|
int curmesh = -1, smooth = 0;
|
||||||
|
Vec4 col = {1,1,1,1};
|
||||||
|
|
||||||
|
vector<mtlinfo> mtl;
|
||||||
|
|
||||||
while(f->getline(buf, sizeof(buf)))
|
while(f->getline(buf, sizeof(buf)))
|
||||||
{
|
{
|
||||||
|
@ -2588,15 +2666,42 @@ bool parseobj(stream *f)
|
||||||
curmesh = -1;
|
curmesh = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'm':
|
||||||
|
{
|
||||||
|
if(strncmp(c, "mtllib", 6)) continue;
|
||||||
|
while(isalpha(*c)) c++;
|
||||||
|
while(isspace(*c)) c++;
|
||||||
|
const char *name = c;
|
||||||
|
size_t namelen = strlen(name);
|
||||||
|
while(namelen > 0 && isspace(name[namelen-1])) namelen--;
|
||||||
|
copystring(tmpname, name, min(namelen+1, sizeof(tmpname)));
|
||||||
|
mtl = parsemtl(openfile(tmpname, "r"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'u':
|
case 'u':
|
||||||
{
|
{
|
||||||
if(strncmp(c, "usemtl", 6)) continue;
|
if(strncmp(c, "usemtl", 6)) continue;
|
||||||
while(isalpha(*c)) c++;
|
while(isalpha(*c)) c++;
|
||||||
while(isspace(*c)) c++;
|
while(isspace(*c)) c++;
|
||||||
char *name = c;
|
const char *name = c;
|
||||||
size_t namelen = strlen(name);
|
size_t namelen = strlen(name);
|
||||||
while(namelen > 0 && isspace(name[namelen-1])) namelen--;
|
while(namelen > 0 && isspace(name[namelen-1])) namelen--;
|
||||||
copystring(matname, name, min(namelen+1, sizeof(matname)));
|
copystring(matname, name, min(namelen+1, sizeof(matname)));
|
||||||
|
col = Vec4(1,1,1,1);
|
||||||
|
|
||||||
|
loopv(mtl)
|
||||||
|
{ //if its an obj material, swap out the vertex colour+mat name for whatever the mtl file specifies.
|
||||||
|
if (!strcmp(matname, mtl[i].name))
|
||||||
|
{
|
||||||
|
col = mtl[i].rgba;
|
||||||
|
const char *tex = mtl[i].tex;
|
||||||
|
if (!tex)
|
||||||
|
tex = (col[3] < 1)?"whiteskin#VC#BLEND":"whiteskin#VC"; //not me being racist or anything...
|
||||||
|
copystring(matname, tex, sizeof(matname));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
curmesh = -1;
|
curmesh = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2651,6 +2756,7 @@ bool parseobj(stream *f)
|
||||||
epositions.add(Vec4(vkey.attrib[0] < 0 ? Vec3(0, 0, 0) : attrib[0][vkey.attrib[0]].zxy(), 1));
|
epositions.add(Vec4(vkey.attrib[0] < 0 ? Vec3(0, 0, 0) : attrib[0][vkey.attrib[0]].zxy(), 1));
|
||||||
if(vkey.attrib[2] >= 0) enormals.add(attrib[2][vkey.attrib[2]].zxy());
|
if(vkey.attrib[2] >= 0) enormals.add(attrib[2][vkey.attrib[2]].zxy());
|
||||||
etexcoords.add(vkey.attrib[1] < 0 ? Vec4(0, 0, 0, 0) : Vec4(attrib[1][vkey.attrib[1]].x, 1-attrib[1][vkey.attrib[1]].y, 0, 0));
|
etexcoords.add(vkey.attrib[1] < 0 ? Vec4(0, 0, 0, 0) : Vec4(attrib[1][vkey.attrib[1]].x, 1-attrib[1][vkey.attrib[1]].y, 0, 0));
|
||||||
|
ecolors.add(col);
|
||||||
}
|
}
|
||||||
if(v0 < 0) v0 = *index;
|
if(v0 < 0) v0 = *index;
|
||||||
else if(v1 < 0) v1 = *index;
|
else if(v1 < 0) v1 = *index;
|
||||||
|
@ -5444,6 +5550,8 @@ bool parseanimfield(const char *tok, char **line, filespec &spec, bool defaults)
|
||||||
spec.noanim = !!strtoul(mystrtok(line), NULL, 0);
|
spec.noanim = !!strtoul(mystrtok(line), NULL, 0);
|
||||||
else if (!strcasecmp(tok, "materialprefix"))
|
else if (!strcasecmp(tok, "materialprefix"))
|
||||||
spec.materialprefix = newstring(mystrtok(line));
|
spec.materialprefix = newstring(mystrtok(line));
|
||||||
|
else if (!strcasecmp(tok, "ignoresurfname"))
|
||||||
|
spec.ignoresurfname = atoi(mystrtok(line));
|
||||||
else if(!strcasecmp(tok, "start"))
|
else if(!strcasecmp(tok, "start"))
|
||||||
spec.startframe = max(atoi(mystrtok(line)), 0);
|
spec.startframe = max(atoi(mystrtok(line)), 0);
|
||||||
else if(!strcasecmp(tok, "end"))
|
else if(!strcasecmp(tok, "end"))
|
||||||
|
@ -5687,6 +5795,7 @@ int main(int argc, char **argv)
|
||||||
else if(!strcasecmp(&argv[i][2], "start")) { if(i + 1 < argc) inspec.startframe = max(atoi(argv[++i]), 0); }
|
else if(!strcasecmp(&argv[i][2], "start")) { if(i + 1 < argc) inspec.startframe = max(atoi(argv[++i]), 0); }
|
||||||
else if(!strcasecmp(&argv[i][2], "end")) { if(i + 1 < argc) inspec.endframe = atoi(argv[++i]); }
|
else if(!strcasecmp(&argv[i][2], "end")) { if(i + 1 < argc) inspec.endframe = atoi(argv[++i]); }
|
||||||
else if(!strcasecmp(&argv[i][2], "scale")) { if(i + 1 < argc) inspec.scale = clamp(atof(argv[++i]), 1e-8, 1e8); }
|
else if(!strcasecmp(&argv[i][2], "scale")) { if(i + 1 < argc) inspec.scale = clamp(atof(argv[++i]), 1e-8, 1e8); }
|
||||||
|
else if(!strcasecmp(&argv[i][2], "ignoresurfname")) inspec.ignoresurfname = true;
|
||||||
else if(!strcasecmp(&argv[i][2], "help")) help();
|
else if(!strcasecmp(&argv[i][2], "help")) help();
|
||||||
else if(!strcasecmp(&argv[i][2], "forcejoints")) forcejoints = true;
|
else if(!strcasecmp(&argv[i][2], "forcejoints")) forcejoints = true;
|
||||||
else if(!strcasecmp(&argv[i][2], "meshtrans"))
|
else if(!strcasecmp(&argv[i][2], "meshtrans"))
|
||||||
|
@ -5753,8 +5862,8 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (outfiles[0])
|
if (outfiles[0])
|
||||||
{
|
{
|
||||||
inspec.reset();
|
|
||||||
infiles.add(inspec).file = outfiles[0];
|
infiles.add(inspec).file = outfiles[0];
|
||||||
|
inspec.reset();
|
||||||
outfiles[0] = NULL;
|
outfiles[0] = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue