glmatrix cleanup

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@2761 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
Lee Salzman
2008-09-25 12:14:20 +00:00
parent a589a738dc
commit a17d0e5ca8
6 changed files with 118 additions and 72 deletions
+22 -12
View File
@@ -137,10 +137,12 @@ static inline uint hthash(const ivec &k)
return k.x^k.y^k.z;
}
#ifndef STANDALONE
struct glmatrixf
{
GLfloat v[16];
float v[16];
float operator[](int i) const { return v[i]; }
float &operator[](int i) { return v[i]; }
#define ROTVEC(A, B) \
{ \
@@ -196,7 +198,7 @@ struct glmatrixf
void identity()
{
static const GLfloat m[16] =
static const float m[16] =
{
1, 0, 0, 0,
0, 1, 0, 0,
@@ -225,6 +227,11 @@ struct glmatrixf
v[8] *= z; v[9] *= z; v[10] *= z; v[11] *= z;
}
void projective()
{
loopi(2) loopj(4) v[i + j*4] = 0.5f*(v[i + j*4] + v[3 + j*4]);
}
void invertnormal(vec &dir) const
{
vec n(dir);
@@ -244,14 +251,6 @@ struct glmatrixf
pos.z = p.x*v[8] + p.y*v[9] + p.z*v[10];
}
void transform(const vec &in, vec4 &out) const
{
out.x = in.x*v[0] + in.y*v[4] + in.z*v[8] + v[12];
out.y = in.x*v[1] + in.y*v[5] + in.z*v[9] + v[13];
out.z = in.x*v[2] + in.y*v[6] + in.z*v[10] + v[14];
out.w = in.x*v[3] + in.y*v[7] + in.z*v[11] + v[15];
}
float transformx(const vec &p) const
{
return p.x*v[0] + p.y*v[4] + p.z*v[8] + v[12];
@@ -272,10 +271,21 @@ struct glmatrixf
return p.x*v[3] + p.y*v[7] + p.z*v[11] + v[15];
}
void transform(const vec &in, vec4 &out) const
{
out.x = transformx(in);
out.y = transformy(in);
out.z = transformz(in);
out.w = transformw(in);
}
vec gettranslation() const
{
return vec(v[12], v[13], v[14]);
}
float determinant() const;
void adjoint(const glmatrixf &m);
bool invert(const glmatrixf &m, float mindet = 1.0e-10f);
};
#endif
+1 -1
View File
@@ -203,7 +203,7 @@ extern serverinfo *getconnectedserverinfo();
extern void pingservers();
// rendergl
extern GLdouble mvmatrix[16], projmatrix[16], mvpmatrix[16], invmvmatrix[16];
extern glmatrixf mvmatrix, projmatrix, mvpmatrix, invmvmatrix, invmvpmatrix;
extern void gl_checkextensions();
extern void gl_init(int w, int h, int bpp, int depth, int fsaa);
+24 -44
View File
@@ -144,12 +144,11 @@ void enablepolygonoffset(GLenum type)
return;
}
GLdouble offsetmatrix[16];
memcpy(offsetmatrix, projmatrix, 16*sizeof(GLdouble));
glmatrixf offsetmatrix = projmatrix;
offsetmatrix[14] += depthoffset * projmatrix[10];
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(offsetmatrix);
glLoadMatrixf(offsetmatrix.v);
glMatrixMode(GL_MODELVIEW);
}
@@ -164,7 +163,7 @@ void disablepolygonoffset(GLenum type, bool restore)
if(restore)
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projmatrix);
glLoadMatrixf(projmatrix.v);
glMatrixMode(GL_MODELVIEW);
}
}
@@ -510,18 +509,17 @@ void transplayer()
glTranslatef(-camera1->o.x, -camera1->o.y, -camera1->o.z);
}
void genclipmatrix(double a, double b, double c, double d, GLdouble matrix[16])
void genclipmatrix(float a, float b, float c, float d, glmatrixf &matrix)
{
// transform the clip plane into camera space
double clip[4];
float clip[4];
loopi(4) clip[i] = a*invmvmatrix[i*4 + 0] + b*invmvmatrix[i*4 + 1] + c*invmvmatrix[i*4 + 2] + d*invmvmatrix[i*4 + 3];
memcpy(matrix, projmatrix, 16*sizeof(GLdouble));
float x = ((clip[0]<0 ? -1 : (clip[0]>0 ? 1 : 0)) + matrix[8]) / matrix[0],
y = ((clip[1]<0 ? -1 : (clip[1]>0 ? 1 : 0)) + matrix[9]) / matrix[5],
w = (1 + matrix[10]) / matrix[14],
float x = ((clip[0]<0 ? -1 : (clip[0]>0 ? 1 : 0)) + projmatrix[8]) / projmatrix[0],
y = ((clip[1]<0 ? -1 : (clip[1]>0 ? 1 : 0)) + projmatrix[9]) / projmatrix[5],
w = (1 + projmatrix[10]) / projmatrix[14],
scale = 2 / (x*clip[0] + y*clip[1] - clip[2] + w*clip[3]);
matrix = projmatrix;
matrix[2] = clip[0]*scale;
matrix[6] = clip[1]*scale;
matrix[10] = clip[2]*scale + 1.0f;
@@ -599,11 +597,11 @@ void drawreflection(float hf, int w, int h, float changelod, bool refract)
glScalef(1, 1, -1);
}
GLdouble clipmat[16];
glmatrixf clipmat;
genclipmatrix(0, 0, -1, 0.1f*reflectclip+hf, clipmat);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixd(clipmat);
glLoadMatrixf(clipmat.v);
glMatrixMode(GL_MODELVIEW);
renderstripssky();
@@ -811,37 +809,20 @@ bool outsidemap(physent *pl)
}
float cursordepth = 0.9f;
GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16], mvpmatrix[16], invmvmatrix[16];
glmatrixf mvmatrix, projmatrix, mvpmatrix, invmvmatrix, invmvpmatrix;
vec worldpos, camdir, camup, camright;
void readmatrices()
{
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
camright = vec(float(mvmatrix[0]), float(mvmatrix[4]), float(mvmatrix[8]));
camup = vec(float(mvmatrix[1]), float(mvmatrix[5]), float(mvmatrix[9]));
camdir = vec(float(-mvmatrix[2]), float(-mvmatrix[6]), float(-mvmatrix[10]));
glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix.v);
glGetFloatv(GL_PROJECTION_MATRIX, projmatrix.v);
camright = vec(mvmatrix[0], mvmatrix[4], mvmatrix[8]);
camup = vec(mvmatrix[1], mvmatrix[5], mvmatrix[9]);
camdir = vec(-mvmatrix[2], -mvmatrix[6], -mvmatrix[10]);
loopi(4) loopj(4)
{
double c = 0;
loopk(4) c += projmatrix[k*4 + j] * mvmatrix[i*4 + k];
mvpmatrix[i*4 + j] = c;
}
loopi(3)
{
loopj(3) invmvmatrix[i*4 + j] = mvmatrix[i + j*4];
invmvmatrix[i*4 + 3] = 0;
}
loopi(3)
{
double c = 0;
loopj(3) c -= mvmatrix[i*4 + j] * mvmatrix[12 + j];
invmvmatrix[12 + i] = c;
}
invmvmatrix[15] = 1;
mvpmatrix.mul(projmatrix, mvmatrix);
invmvmatrix.invert(mvmatrix);
invmvpmatrix.invert(mvpmatrix);
}
// stupid function to cater for stupid ATI linux drivers that return incorrect depth values
@@ -860,11 +841,10 @@ float depthcorrect(float d)
void readdepth(int w, int h, vec &pos)
{
glReadPixels(w/2, h/2, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &cursordepth);
double worldx = 0, worldy = 0, worldz = 0;
gluUnProject(w/2, h/2, depthcorrect(cursordepth), mvmatrix, projmatrix, viewport, &worldx, &worldy, &worldz);
pos.x = (float)worldx;
pos.y = (float)worldy;
pos.z = (float)worldz;
vec screen(0, 0, depthcorrect(cursordepth)*2 - 1);
vec4 world;
invmvpmatrix.transform(screen, world);
pos = vec(world.x, world.y, world.z).div(world.w);
}
void gl_drawframe(int w, int h, float changelod, float curfps)
+63
View File
@@ -296,3 +296,66 @@ bool isbigendian()
return !(*((char *)(&one)));
}
//////////////// geometry utils ////////////////
static inline float det2x2(float a, float b, float c, float d) { return a*d - b*c; }
static inline float det3x3(float a1, float a2, float a3,
float b1, float b2, float b3,
float c1, float c2, float c3)
{
return a1 * det2x2(b2, b3, c2, c3)
- b1 * det2x2(a2, a3, c2, c3)
+ c1 * det2x2(a2, a3, b2, b3);
}
float glmatrixf::determinant() const
{
float a1 = v[0], a2 = v[1], a3 = v[2], a4 = v[3],
b1 = v[4], b2 = v[5], b3 = v[6], b4 = v[7],
c1 = v[8], c2 = v[9], c3 = v[10], c4 = v[11],
d1 = v[12], d2 = v[13], d3 = v[14], d4 = v[15];
return a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)
- b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)
+ c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)
- d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
}
void glmatrixf::adjoint(const glmatrixf &m)
{
float a1 = m.v[0], a2 = m.v[1], a3 = m.v[2], a4 = m.v[3],
b1 = m.v[4], b2 = m.v[5], b3 = m.v[6], b4 = m.v[7],
c1 = m.v[8], c2 = m.v[9], c3 = m.v[10], c4 = m.v[11],
d1 = m.v[12], d2 = m.v[13], d3 = m.v[14], d4 = m.v[15];
v[0] = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
v[1] = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
v[2] = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
v[3] = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
v[4] = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
v[5] = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
v[6] = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
v[7] = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
v[8] = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
v[9] = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
v[10] = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
v[11] = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
v[12] = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
v[13] = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
v[14] = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
v[15] = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
}
bool glmatrixf::invert(const glmatrixf &m, float mindet)
{
float det = m.determinant();
if(fabs(det) < mindet) return false;
adjoint(m);
float invdet = 1/det;
loopi(16) v[i] *= invdet;
return true;
}
+1 -1
View File
@@ -446,7 +446,7 @@ struct vertmodel : model
bb curbb;
getcurbb(curbb, as, cur, prev, ai_t);
glmatrixf mat;
mat.mul(mvpmatrix, matrixstack[matrixpos].v);
mat.mul(mvpmatrix, matrixstack[matrixpos]);
if(!addshadowbox(curbb.low, curbb.high, shadowpos, mat)) return;
}
+7 -14
View File
@@ -75,13 +75,11 @@ extern int nquads;
void setprojtexmatrix()
{
GLdouble matrix[16];
memcpy(matrix, mvpmatrix, 16*sizeof(GLdouble));
loopi(2) loopj(4) matrix[i + j*4] = 0.5f*(matrix[i + j*4] + matrix[3 + j*4]);
glmatrixf projtex = mvpmatrix;
projtex.projective();
glMatrixMode(GL_TEXTURE);
glLoadMatrixd(matrix);
glLoadMatrixf(projtex.v);
}
void setupmultitexrefract(GLuint reflecttex, GLuint refracttex)
@@ -238,16 +236,11 @@ void calcwaterscissor()
float sx1 = 1, sy1 = 1, sx2 = -1, sy2 = -1;
loopi(4)
{
vec p(i&1 ? wx2 : wx1, i&2 ? wy2 : wy1, hdr.waterlevel-0.3f);
float w = p.x*mvpmatrix[3] + p.y*mvpmatrix[7] + p.z*mvpmatrix[11] + mvpmatrix[15],
x = p.x*mvpmatrix[0] + p.y*mvpmatrix[4] + p.z*mvpmatrix[8] + mvpmatrix[12],
y = p.x*mvpmatrix[1] + p.y*mvpmatrix[5] + p.z*mvpmatrix[9] + mvpmatrix[13],
z = p.x*mvpmatrix[2] + p.y*mvpmatrix[6] + p.z*mvpmatrix[10] + mvpmatrix[14];
v[i] = vec4(x, y, z, w);
if(z >= 0)
vec4 &p = v[i];
mvpmatrix.transform(vec(i&1 ? wx2 : wx1, i&2 ? wy2 : wy1, hdr.waterlevel-0.3f), p);
if(p.z >= 0)
{
x /= w;
y /= w;
float x = p.x / p.w, y = p.y / p.w;
sx1 = min(sx1, x);
sy1 = min(sy1, y);
sx2 = max(sx2, x);