Calculate inverse TBN matrix for planes.

git-svn-id: https://svn.eduke32.com/eduke32@1241 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
plagman 2009-03-11 13:23:05 +00:00
parent e158a9e71c
commit 09ef2dae34
2 changed files with 136 additions and 29 deletions

View file

@ -126,7 +126,10 @@ typedef struct s_prplane {
int32_t vertcount;
GLuint vbo;
// attributes
GLdouble plane[4];
GLfloat t[3];
GLfloat b[3];
GLfloat n[3];
GLfloat plane[4];
_prmaterial material;
// elements
GLushort* indices;
@ -212,7 +215,7 @@ void polymer_addlight(_prlight light);
// CORE
static void polymer_displayrooms(int16_t sectnum);
static void polymer_drawplane(int16_t sectnum, int16_t wallnum, _prplane* plane, int32_t indicecount);
static void polymer_inb4mirror(GLfloat* buffer, GLdouble* plane);
static void polymer_inb4mirror(GLfloat* buffer, GLfloat* plane);
static void polymer_animatesprites(void);
// SECTORS
static int32_t polymer_initsector(int16_t sectnum);
@ -227,8 +230,8 @@ static int32_t polymer_initwall(int16_t wallnum);
static void polymer_updatewall(int16_t wallnum);
static void polymer_drawwall(int16_t sectnum, int16_t wallnum);
// HSR
static void polymer_buffertoplane(GLfloat* buffer, GLushort* indices, int32_t indicecount, GLdouble* plane);
static void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLdouble* out);
static void polymer_buffertoplane(GLfloat* buffer, GLushort* indices, int32_t indicecount, GLfloat* plane, GLfloat* t, GLfloat* b, GLfloat* n);
static void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out);
static void polymer_transformpoint(float* inpos, float* pos, float* matrix);
static void polymer_pokesector(int16_t sectnum);
static void polymer_extractfrustum(GLfloat* modelview, GLfloat* projection, float* frustum);

View file

@ -755,7 +755,7 @@ void polymer_drawsprite(int32_t snum)
i++;
}
polymer_buffertoplane(spriteplane.buffer, NULL, 4, spriteplane.plane);
polymer_buffertoplane(spriteplane.buffer, NULL, 4, spriteplane.plane, spriteplane.t, spriteplane.b, spriteplane.n);
spriteplane.lightcount = 0;
i = 0;
@ -1192,7 +1192,47 @@ static void polymer_drawplane(int16_t sectnum, int16_t wallnum, _prplane
// bglBindTexture(GL_TEXTURE_2D, plane->material.diffusemap);
bglNormal3f((float)(-plane->plane[0]), (float)(-plane->plane[1]), (float)(-plane->plane[2]));
bglNormal3f((float)(plane->plane[0]), (float)(plane->plane[1]), (float)(plane->plane[2]));
// debug code for drawing plane inverse TBN
// bglDisable(GL_TEXTURE_2D);
// bglBegin(GL_LINES);
// bglColor4f(1.0, 0.0, 0.0, 1.0);
// bglVertex3f(plane->buffer[0],
// plane->buffer[1],
// plane->buffer[2]);
// bglVertex3f(plane->buffer[0] + plane->t[0] * 50,
// plane->buffer[1] + plane->t[1] * 50,
// plane->buffer[2] + plane->t[2] * 50);
// bglColor4f(0.0, 1.0, 0.0, 1.0);
// bglVertex3f(plane->buffer[0],
// plane->buffer[1],
// plane->buffer[2]);
// bglVertex3f(plane->buffer[0] + plane->b[0] * 50,
// plane->buffer[1] + plane->b[1] * 50,
// plane->buffer[2] + plane->b[2] * 50);
// bglColor4f(0.0, 0.0, 1.0, 1.0);
// bglVertex3f(plane->buffer[0],
// plane->buffer[1],
// plane->buffer[2]);
// bglVertex3f(plane->buffer[0] + plane->n[0] * 50,
// plane->buffer[1] + plane->n[1] * 50,
// plane->buffer[2] + plane->n[2] * 50);
// bglEnd();
// bglEnable(GL_TEXTURE_2D);
// debug code for drawing plane normals
// bglDisable(GL_TEXTURE_2D);
// bglBegin(GL_LINES);
// bglColor4f(1.0, 1.0, 1.0, 1.0);
// bglVertex3f(plane->buffer[0],
// plane->buffer[1],
// plane->buffer[2]);
// bglVertex3f(plane->buffer[0] + plane->plane[0] * 50,
// plane->buffer[1] + plane->plane[1] * 50,
// plane->buffer[2] + plane->plane[2] * 50);
// bglEnd();
// bglEnable(GL_TEXTURE_2D);
materialbits = polymer_bindmaterial(plane->material, plane->lights, plane->lightcount);
@ -1215,7 +1255,7 @@ static void polymer_drawplane(int16_t sectnum, int16_t wallnum, _prplane
// }
}
static void polymer_inb4mirror(GLfloat* buffer, GLdouble* plane)
static void polymer_inb4mirror(GLfloat* buffer, GLfloat* plane)
{
float pv;
float reflectionmatrix[16];
@ -1525,8 +1565,10 @@ finish:
if (wallinvalidate)
{
s->invalidid++;
polymer_buffertoplane(s->floor.buffer, s->floor.indices, s->indicescount, s->floor.plane);
polymer_buffertoplane(s->ceil.buffer, s->ceil.indices, s->indicescount, s->ceil.plane);
polymer_buffertoplane(s->floor.buffer, s->floor.indices, s->indicescount, s->floor.plane,
s->floor.t, s->floor.b, s->floor.n);
polymer_buffertoplane(s->ceil.buffer, s->ceil.indices, s->indicescount, s->ceil.plane,
s->ceil.t, s->ceil.b, s->ceil.n);
}
s->controlstate = 1;
@ -2065,7 +2107,7 @@ static void polymer_updatewall(int16_t wallnum)
w->cap[7] += 1048576; // this number is the result of 1048574 + 2
w->cap[10] += 1048576; // this one is arbitrary
polymer_buffertoplane(w->bigportal, NULL, 4, w->wall.plane);
polymer_buffertoplane(w->bigportal, NULL, 4, w->wall.plane, w->wall.t, w->wall.b, w->wall.n);
memcpy(w->over.plane, w->wall.plane, sizeof(w->wall.plane));
memcpy(w->mask.plane, w->wall.plane, sizeof(w->wall.plane));
@ -2134,39 +2176,101 @@ static void polymer_drawwall(int16_t sectnum, int16_t wallnum)
#define INDICE(n) ((indices) ? (indices[i+n]*5) : ((i+n)*5))
// HSR
static void polymer_buffertoplane(GLfloat* buffer, GLushort* indices, int32_t indicecount, GLdouble* plane)
static void polymer_buffertoplane(GLfloat* buffer, GLushort* indices, int32_t indicecount, GLfloat* plane, GLfloat* t, GLfloat* b, GLfloat* n)
{
GLfloat vec1[3], vec2[3];
GLfloat vec1[5], vec2[5], norm, r, BxN[3], NxT[3], TxB[3];
int32_t i;
i = 0;
do
{
vec1[0] = buffer[(INDICE(1)) + 0] - buffer[(INDICE(0)) + 0];
vec1[1] = buffer[(INDICE(1)) + 1] - buffer[(INDICE(0)) + 1];
vec1[2] = buffer[(INDICE(1)) + 2] - buffer[(INDICE(0)) + 2];
vec1[0] = buffer[(INDICE(1)) + 0] - buffer[(INDICE(0)) + 0]; //x1
vec1[1] = buffer[(INDICE(1)) + 1] - buffer[(INDICE(0)) + 1]; //y1
vec1[2] = buffer[(INDICE(1)) + 2] - buffer[(INDICE(0)) + 2]; //z1
vec1[3] = buffer[(INDICE(1)) + 3] - buffer[(INDICE(0)) + 3]; //s1
vec1[4] = buffer[(INDICE(1)) + 4] - buffer[(INDICE(0)) + 4]; //t1
vec2[0] = buffer[(INDICE(2)) + 0] - buffer[(INDICE(1)) + 0];
vec2[1] = buffer[(INDICE(2)) + 1] - buffer[(INDICE(1)) + 1];
vec2[2] = buffer[(INDICE(2)) + 2] - buffer[(INDICE(1)) + 2];
vec2[0] = buffer[(INDICE(2)) + 0] - buffer[(INDICE(1)) + 0]; //x2
vec2[1] = buffer[(INDICE(2)) + 1] - buffer[(INDICE(1)) + 1]; //y2
vec2[2] = buffer[(INDICE(2)) + 2] - buffer[(INDICE(1)) + 2]; //z2
vec2[3] = buffer[(INDICE(2)) + 3] - buffer[(INDICE(1)) + 3]; //s2
vec2[4] = buffer[(INDICE(2)) + 4] - buffer[(INDICE(1)) + 4]; //t2
polymer_crossproduct(vec2, vec1, plane);
// normalize
vec1[0] = plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2];
norm = plane[0] * plane[0] + plane[1] * plane[1] + plane[2] * plane[2];
if (norm >= 5000) // hack to work around a precision issue with slopes
{
// normalize the normal/plane equation and calculate its plane norm
norm = -sqrt(norm);
plane[0] /= norm;
plane[1] /= norm;
plane[2] /= norm;
plane[3] = (plane[0] * buffer[0] + plane[1] * buffer[1] + plane[2] * buffer[2]);
// calculate T and B
r = 1.0 / (vec1[3] * vec2[4] - vec2[3] * vec1[4]);
// tangent
t[0] = (vec2[4] * vec1[0] - vec1[4] * vec2[0]) * r;
t[1] = (vec2[4] * vec1[1] - vec1[4] * vec2[1]) * r;
t[2] = (vec2[4] * vec1[2] - vec1[4] * vec2[2]) * r;
// bitangent
b[0] = (vec1[3] * vec2[0] - vec2[3] * vec1[0]) * r;
b[1] = (vec1[3] * vec2[1] - vec2[3] * vec1[1]) * r;
b[2] = (vec1[3] * vec2[2] - vec2[3] * vec1[2]) * r;
// invert T, B and N
r = 1.0f / ((t[0] * b[1] * plane[2] - t[2] * b[1] * plane[0]) +
(b[0] * plane[1] * t[2] - b[2] * plane[1] * t[0]) +
(plane[0] * t[1] * b[2] - plane[2] * t[1] * b[0]));
polymer_crossproduct(b, plane, BxN);
polymer_crossproduct(plane, t, NxT);
polymer_crossproduct(t, b, TxB);
// GLSL matrix constructors are in column-major order
t[0] = BxN[0] * r;
t[1] = -NxT[0] * r;
t[2] = TxB[0] * r;
b[0] = -BxN[1] * r;
b[1] = NxT[1] * r;
b[2] = -TxB[1] * r;
n[0] = BxN[2] * r;
n[1] = -NxT[2] * r;
n[2] = TxB[2] * r;
// normalize T, B and N
norm = t[0] * t[0] + t[1] * t[1] + t[2] * t[2];
norm = sqrt(norm);
t[0] /= norm;
t[1] /= norm;
t[2] /= norm;
norm = b[0] * b[0] + b[1] * b[1] + b[2] * b[2];
norm = sqrt(norm);
b[0] /= norm;
b[1] /= norm;
b[2] /= norm;
norm = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
norm = sqrt(norm);
n[0] /= norm;
n[1] /= norm;
n[2] /= norm;
break;
}
i+= 3;
}
while ((i < indicecount) && (vec1[0] < 5000)); // hack to work around a precision issue with slopes
vec1[0] = sqrt(vec1[0]);
plane[0] /= vec1[0];
plane[1] /= vec1[0];
plane[2] /= vec1[0];
plane[3] = -(plane[0] * buffer[0] + plane[1] * buffer[1] + plane[2] * buffer[2]);
while (i < indicecount);
}
static void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLdouble* out)
static void polymer_crossproduct(GLfloat* in_a, GLfloat* in_b, GLfloat* out)
{
out[0] = in_a[1] * in_b[2] - in_a[2] * in_b[1];
out[1] = in_a[2] * in_b[0] - in_a[0] * in_b[2];