mdsprite.c: prevent a couple of float divides by zero and save model file

name into m->head.nam after loading (but before preprocessing for Polymer)

git-svn-id: https://svn.eduke32.com/eduke32@2007 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-09-06 17:45:39 +00:00
parent a145cc93bc
commit 08f5290f4f

View file

@ -1616,6 +1616,8 @@ static inline void invertmatrix(float *m, float *out)
det -= m[1] * (m[3]*m[8] - m[5] * m[6]); det -= m[1] * (m[3]*m[8] - m[5] * m[6]);
det += m[2] * (m[3]*m[7] - m[4] * m[6]); det += m[2] * (m[3]*m[7] - m[4] * m[6]);
if (det != 0.0f)
{
det = 1.0f / det; det = 1.0f / det;
out[0] = det * (m[4] * m[8] - m[5] * m[7]); out[0] = det * (m[4] * m[8] - m[5] * m[7]);
@ -1630,6 +1632,13 @@ static inline void invertmatrix(float *m, float *out)
out[5] = det * (m[2] * m[3] - m[0] * m[5]); out[5] = det * (m[2] * m[3] - m[0] * m[5]);
out[8] = det * (m[0] * m[4] - m[1] * m[3]); out[8] = det * (m[0] * m[4] - m[1] * m[3]);
} }
else
{
out[0] = 1.0; out[1] = 0.0; out[2] = 0.0;
out[3] = 0.0; out[4] = 1.0; out[5] = 0.0;
out[6] = 0.0; out[7] = 0.0; out[8] = 1.0;
}
}
static inline void normalize(float *vec) static inline void normalize(float *vec)
{ {
@ -1637,12 +1646,15 @@ static inline void normalize(float *vec)
norm = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]; norm = vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2];
if (norm != 0.0)
{
norm = sqrt(norm); norm = sqrt(norm);
norm = 1.0 / norm; norm = 1.0 / norm;
vec[0] *= norm; vec[0] *= norm;
vec[1] *= norm; vec[1] *= norm;
vec[2] *= norm; vec[2] *= norm;
} }
}
static void md3postload_common(md3model_t *m) static void md3postload_common(md3model_t *m)
{ {
@ -1765,7 +1777,7 @@ static int md3postload_polymer_check(md3model_t *m)
s->tris[trii].i[2] >= s->numverts || s->tris[trii].i[2] < 0) s->tris[trii].i[2] >= s->numverts || s->tris[trii].i[2] < 0)
{ {
// corrupt model // corrupt model
OSD_Printf("Triangle index out of bounds!\n"); OSD_Printf("%s: Triangle index out of bounds!\n", m->head.nam);
return 0; return 0;
} }
@ -1800,9 +1812,7 @@ int md3postload_polymer(md3model_t *m)
i = (m->head.numframes * s->numverts * sizeof(float) * 15); i = (m->head.numframes * s->numverts * sizeof(float) * 15);
if (i > 1<<20) if (i > 1<<20)
initprintf("size %d (%d fr, %d v): md %s surf %d/%d\n", i, m->head.numframes, s->numverts, initprintf("size %d (%d fr, %d v): md %s surf %d/%d\n", i, m->head.numframes, s->numverts,
m->indices?(char *)m->indices:"null", surfi, m->head.numsurfs); m->head.nam, surfi, m->head.numsurfs);
if (m->indices)
Bfree(m->indices), m->indices=NULL;
#endif #endif
s->geometry = Bcalloc(m->head.numframes * s->numverts * sizeof(float), 15); s->geometry = Bcalloc(m->head.numframes * s->numverts * sizeof(float), 15);
@ -1840,7 +1850,7 @@ int md3postload_polymer(md3model_t *m)
{ {
// corrupt model // corrupt model
Bfree(numtris); Bfree(numtris);
OSD_Printf("Triangle index out of bounds!\n"); // OSD_Printf("Triangle index out of bounds!\n");
return 0; return 0;
} }
numtris[s->tris[trii].i[0]]++; numtris[s->tris[trii].i[0]]++;
@ -1868,7 +1878,10 @@ int md3postload_polymer(md3model_t *m)
vec2[3] = s->uv[s->tris[trii].i[2]].u - s->uv[s->tris[trii].i[1]].u; vec2[3] = s->uv[s->tris[trii].i[2]].u - s->uv[s->tris[trii].i[1]].u;
vec2[4] = s->uv[s->tris[trii].i[2]].v - s->uv[s->tris[trii].i[1]].v; vec2[4] = s->uv[s->tris[trii].i[2]].v - s->uv[s->tris[trii].i[1]].v;
r = 1.0 / (vec1[3] * vec2[4] - vec2[3] * vec1[4]); r = (vec1[3] * vec2[4] - vec2[3] * vec1[4]);
if (r != 0.0f)
{
r = 1.0 / r;
// tangent // tangent
mat[0] = (vec2[4] * vec1[0] - vec1[4] * vec2[0]) * r; mat[0] = (vec2[4] * vec1[0] - vec1[4] * vec2[0]) * r;
@ -1883,6 +1896,12 @@ int md3postload_polymer(md3model_t *m)
mat[5] = (vec1[3] * vec2[2] - vec2[3] * vec1[2]) * r; mat[5] = (vec1[3] * vec2[2] - vec2[3] * vec1[2]) * r;
normalize(&mat[3]); normalize(&mat[3]);
}
else
{
mat[0] = mat[1] = mat[2] = 0.0f;
mat[3] = mat[4] = mat[5] = 0.0f;
}
// T and B are shared for the three vertices in that triangle // T and B are shared for the three vertices in that triangle
i = 0; i = 0;
@ -1903,13 +1922,24 @@ int md3postload_polymer(md3model_t *m)
// now that we accumulated the TBNs, average and invert them for each vertex // now that we accumulated the TBNs, average and invert them for each vertex
verti = 0; verti = 0;
while (verti < (m->head.numframes * s->numverts)) while (verti < (m->head.numframes * s->numverts))
{
int32_t curnumtris = numtris[verti % s->numverts];
if (curnumtris > 0)
{ {
i = 6; i = 6;
while (i < 12) while (i < 12)
{ {
s->geometry[(verti * 15) + i] /= numtris[verti % s->numverts]; s->geometry[(verti * 15) + i] /= curnumtris;
i++; i++;
} }
}
#ifdef DEBUG_MODEL_MEM
else if (verti == verti%s->numverts)
{
OSD_Printf("%s: vert %d is unused\n", m->head.nam, verti);
}
#endif
// copy N over // copy N over
s->geometry[(verti * 15) + 12] = s->geometry[(verti * 15) + 3]; s->geometry[(verti * 15) + 12] = s->geometry[(verti * 15) + 3];
s->geometry[(verti * 15) + 13] = s->geometry[(verti * 15) + 4]; s->geometry[(verti * 15) + 13] = s->geometry[(verti * 15) + 4];
@ -3363,14 +3393,18 @@ mdmodel_t *mdload(const char *filnam)
if (vm) if (vm)
{ {
#ifdef DEBUG_MODEL_MEM md3model_t *vm3 = (md3model_t *)vm;
((md3model_t *)vm)->indices = (void *)Bstrdup(filnam);
#endif // smuggle the file name into the model struct.
md3postload_common((md3model_t *)vm); // head.nam is unused as far as I can tell
Bstrncpy(vm3->head.nam, filnam, sizeof(vm3->head.nam));
vm3->head.nam[sizeof(vm3->head.nam)-1] = 0;
md3postload_common(vm3);
#ifdef POLYMER #ifdef POLYMER
if (glrendmode!=4) if (glrendmode!=4)
if (!md3postload_polymer_check((md3model_t *)vm)) if (!md3postload_polymer_check(vm3))
{ {
mdfree(vm); mdfree(vm);
vm = (mdmodel_t *)0; vm = (mdmodel_t *)0;