| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | 
							- /*
 -  * matrix.c
 -  *
 -  * Some useful matrix functions.
 -  *
 -  * Brian Paul
 -  * 10 Feb 2004
 -  */
 - 
 - 
 - 
 - #include <stdio.h>
 - #include <stdlib.h>
 - #include <math.h>
 - 
 - 
 - /**
 -  * Pretty-print the given matrix.
 -  */
 - void
 - PrintMatrix(const float p[16])
 - {
 -    printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[0], p[4], p[8], p[12]);
 -    printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[1], p[5], p[9], p[13]);
 -    printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[2], p[6], p[10], p[14]);
 -    printf("[ %6.3f %6.3f %6.3f %6.3f ]\n", p[3], p[7], p[11], p[15]);
 - }
 - 
 - 
 - /**
 -  * Build a glFrustum matrix.
 -  */
 - void
 - Frustum(float left, float right, float bottom, float top, float nearZ, float farZ, float *m)
 - {
 -    float x = (2.0F*nearZ) / (right-left);
 -    float y = (2.0F*nearZ) / (top-bottom);
 -    float a = (right+left) / (right-left);
 -    float b = (top+bottom) / (top-bottom);
 -    float c = -(farZ+nearZ) / ( farZ-nearZ);
 -    float d = -(2.0F*farZ*nearZ) / (farZ-nearZ);
 - 
 - #define M(row,col)  m[col*4+row]
 -    M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
 -    M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
 -    M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
 -    M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
 - #undef M
 - }
 - 
 - 
 - /**
 -  * Build a glOrtho marix.
 -  */
 - void
 - Ortho(float left, float right, float bottom, float top, float nearZ, float farZ, float *m)
 - {
 - #define M(row,col)  m[col*4+row]
 -    M(0,0) = 2.0F / (right-left);
 -    M(0,1) = 0.0F;
 -    M(0,2) = 0.0F;
 -    M(0,3) = -(right+left) / (right-left);
 - 
 -    M(1,0) = 0.0F;
 -    M(1,1) = 2.0F / (top-bottom);
 -    M(1,2) = 0.0F;
 -    M(1,3) = -(top+bottom) / (top-bottom);
 - 
 -    M(2,0) = 0.0F;
 -    M(2,1) = 0.0F;
 -    M(2,2) = -2.0F / (farZ-nearZ);
 -    M(2,3) = -(farZ+nearZ) / (farZ-nearZ);
 - 
 -    M(3,0) = 0.0F;
 -    M(3,1) = 0.0F;
 -    M(3,2) = 0.0F;
 -    M(3,3) = 1.0F;
 - #undef M
 - }
 - 
 - 
 - /**
 -  * Decompose a projection matrix to determine original glFrustum or
 -  * glOrtho parameters.
 -  */
 - void
 - DecomposeProjection( const float *m,
 -                      int *isPerspective,
 -                      float *leftOut, float *rightOut,
 -                      float *botOut, float *topOut,
 -                      float *nearOut, float *farOut)
 - {
 -    if (m[15] == 0.0) {
 -       /* perspective */
 -       float p[16];
 -       const float x = m[0];  /* 2N / (R-L) */
 -       const float y = m[5];  /* 2N / (T-B) */
 -       const float a = m[8];  /* (R+L) / (R-L) */
 -       const float b = m[9];  /* (T+B) / (T-B) */
 -       const float c = m[10]; /* -(F+N) / (F-N) */
 -       const float d = m[14]; /* -2FN / (F-N) */
 - 
 -       /* These equations found with simple algebra, knowing the arithmetic
 -        * use to set up a typical perspective projection matrix in OpenGL.
 -        */
 -       const float nearZ = -d / (1.0 - c);
 -       const float farZ = (c - 1.0) * nearZ / (c + 1.0);
 -       const float left = nearZ * (a - 1.0) / x;
 -       const float right = 2.0 * nearZ / x + left;
 -       const float bottom = nearZ * (b - 1.0) / y;
 -       const float top = 2.0 * nearZ / y + bottom;
 - 
 -       *isPerspective = 1;
 -       *leftOut = left;
 -       *rightOut = right;
 -       *botOut = bottom;
 -       *topOut = top;
 -       *nearOut = nearZ;
 -       *farOut = farZ;
 -    }
 -    else {
 -       /* orthographic */
 -       const float x = m[0];  /*  2 / (R-L) */
 -       const float y = m[5];  /*  2 / (T-B) */
 -       const float z = m[10]; /* -2 / (F-N) */
 -       const float a = m[12]; /* -(R+L) / (R-L) */
 -       const float b = m[13]; /* -(T+B) / (T-B) */
 -       const float c = m[14]; /* -(F+N) / (F-N) */
 -       /* again, simple algebra */
 -       const float right  = -(a - 1.0) / x;
 -       const float left   = right - 2.0 / x;
 -       const float top    = -(b - 1.0) / y;
 -       const float bottom = top - 2.0 / y;
 -       const float farZ   = (c - 1.0) / z;
 -       const float nearZ  = farZ + 2.0 / z;
 - 
 -       *isPerspective = 0;
 -       *leftOut = left;
 -       *rightOut = right;
 -       *botOut = bottom;
 -       *topOut = top;
 -       *nearOut = nearZ;
 -       *farOut = farZ;
 -    }
 - }
 - 
 - 
 - #if 0
 - /* test harness */
 - int
 - main(int argc, char *argv[])
 - {
 -    float m[16], p[16];
 -    float l, r, b, t, n, f;
 -    int persp;
 -    int i;
 - 
 - #if 0
 -    l = -.9;
 -    r = 1.2;
 -    b = -0.5;
 -    t = 1.4;
 -    n = 30;
 -    f = 84;
 -    printf("  Frustum(%f, %f, %f, %f, %f, %f\n",l+1, r+1.2, b+.5, t+.3, n, f);
 -    Frustum(l+1, r+1.2, b+.5, t+.3, n, f, p);
 -    DecomposeProjection(p, &persp, &l, &r, &b, &t, &n, &f);
 -    printf("glFrustum(%f, %f, %f, %f, %f, %f)\n",
 -           l, r, b, t, n, f);
 -    PrintMatrix(p);
 - #else
 -    printf("Ortho(-1, 1, -1, 1, 10, 84)\n");
 -    Ortho(-1, 1, -1, 1, 10, 84, m);
 -    PrintMatrix(m);
 -    DecomposeProjection(m, &persp, &l, &r, &b, &t, &n, &f);
 -    printf("Ortho(%f, %f, %f, %f, %f, %f) %d\n", l, r, b, t, n, f, persp);
 - #endif
 - 
 -    return 0;
 - }
 - #endif
 
 
  |