ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

zmath.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 /*
00024  * This file is based on, or a modified version of code from TinyGL (C) 1997-1998 Fabrice Bellard,
00025  * which is licensed under the zlib-license (see LICENSE).
00026  * It also has modifications by the ResidualVM-team, which are covered under the GPLv2 (or later).
00027  */
00028 
00029 #include "common/scummsys.h"
00030 
00031 #include "graphics/tinygl/zmath.h"
00032 
00033 namespace TinyGL {
00034 
00035 // Inversion of a 4x4 matrix.
00036 // It's not just unrolling, this is a different implementation that directly
00037 // uses the formula whereas the previous one is using another method (which is generic and thus, slower) 
00038 int MatrixInverse(float *m) {
00039     double inv[16];
00040 
00041     inv[0] = m[5]  * m[10] * m[15] - 
00042         m[5]  * m[11] * m[14] - 
00043         m[9]  * m[6]  * m[15] + 
00044         m[9]  * m[7]  * m[14] +
00045         m[13] * m[6]  * m[11] - 
00046         m[13] * m[7]  * m[10];
00047 
00048     inv[4] = -m[4]  * m[10] * m[15] + 
00049         m[4]  * m[11] * m[14] + 
00050         m[8]  * m[6]  * m[15] - 
00051         m[8]  * m[7]  * m[14] - 
00052         m[12] * m[6]  * m[11] + 
00053         m[12] * m[7]  * m[10];
00054 
00055     inv[8] = m[4]  * m[9] * m[15] - 
00056         m[4]  * m[11] * m[13] - 
00057         m[8]  * m[5] * m[15] + 
00058         m[8]  * m[7] * m[13] + 
00059         m[12] * m[5] * m[11] - 
00060         m[12] * m[7] * m[9];
00061 
00062     inv[12] = -m[4]  * m[9] * m[14] + 
00063         m[4]  * m[10] * m[13] +
00064         m[8]  * m[5] * m[14] - 
00065         m[8]  * m[6] * m[13] - 
00066         m[12] * m[5] * m[10] + 
00067         m[12] * m[6] * m[9];
00068 
00069     inv[1] = -m[1]  * m[10] * m[15] + 
00070         m[1]  * m[11] * m[14] + 
00071         m[9]  * m[2] * m[15] - 
00072         m[9]  * m[3] * m[14] - 
00073         m[13] * m[2] * m[11] + 
00074         m[13] * m[3] * m[10];
00075 
00076     inv[5] = m[0]  * m[10] * m[15] - 
00077         m[0]  * m[11] * m[14] - 
00078         m[8]  * m[2] * m[15] + 
00079         m[8]  * m[3] * m[14] + 
00080         m[12] * m[2] * m[11] - 
00081         m[12] * m[3] * m[10];
00082 
00083     inv[9] = -m[0]  * m[9] * m[15] + 
00084         m[0]  * m[11] * m[13] + 
00085         m[8]  * m[1] * m[15] - 
00086         m[8]  * m[3] * m[13] - 
00087         m[12] * m[1] * m[11] + 
00088         m[12] * m[3] * m[9];
00089 
00090     inv[13] = m[0]  * m[9] * m[14] - 
00091         m[0]  * m[10] * m[13] - 
00092         m[8]  * m[1] * m[14] + 
00093         m[8]  * m[2] * m[13] + 
00094         m[12] * m[1] * m[10] - 
00095         m[12] * m[2] * m[9];
00096 
00097     inv[2] = m[1]  * m[6] * m[15] - 
00098         m[1]  * m[7] * m[14] - 
00099         m[5]  * m[2] * m[15] + 
00100         m[5]  * m[3] * m[14] + 
00101         m[13] * m[2] * m[7] - 
00102         m[13] * m[3] * m[6];
00103 
00104     inv[6] = -m[0]  * m[6] * m[15] + 
00105         m[0]  * m[7] * m[14] + 
00106         m[4]  * m[2] * m[15] - 
00107         m[4]  * m[3] * m[14] - 
00108         m[12] * m[2] * m[7] + 
00109         m[12] * m[3] * m[6];
00110 
00111     inv[10] = m[0]  * m[5] * m[15] - 
00112         m[0]  * m[7] * m[13] - 
00113         m[4]  * m[1] * m[15] + 
00114         m[4]  * m[3] * m[13] + 
00115         m[12] * m[1] * m[7] - 
00116         m[12] * m[3] * m[5];
00117 
00118     inv[14] = -m[0]  * m[5] * m[14] + 
00119         m[0]  * m[6] * m[13] + 
00120         m[4]  * m[1] * m[14] - 
00121         m[4]  * m[2] * m[13] - 
00122         m[12] * m[1] * m[6] + 
00123         m[12] * m[2] * m[5];
00124 
00125     inv[3] = -m[1] * m[6] * m[11] + 
00126         m[1] * m[7] * m[10] + 
00127         m[5] * m[2] * m[11] - 
00128         m[5] * m[3] * m[10] - 
00129         m[9] * m[2] * m[7] + 
00130         m[9] * m[3] * m[6];
00131 
00132     inv[7] = m[0] * m[6] * m[11] - 
00133         m[0] * m[7] * m[10] - 
00134         m[4] * m[2] * m[11] + 
00135         m[4] * m[3] * m[10] + 
00136         m[8] * m[2] * m[7] - 
00137         m[8] * m[3] * m[6];
00138 
00139     inv[11] = -m[0] * m[5] * m[11] + 
00140         m[0] * m[7] * m[9] + 
00141         m[4] * m[1] * m[11] - 
00142         m[4] * m[3] * m[9] - 
00143         m[8] * m[1] * m[7] + 
00144         m[8] * m[3] * m[5];
00145 
00146     inv[15] = m[0] * m[5] * m[10] - 
00147         m[0] * m[6] * m[9] - 
00148         m[4] * m[1] * m[10] + 
00149         m[4] * m[2] * m[9] + 
00150         m[8] * m[1] * m[6] - 
00151         m[8] * m[2] * m[5];
00152 
00153     double det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
00154 
00155     if (det == 0)
00156         return false;
00157 
00158     det = 1.0 / det;
00159 
00160     for (int i = 0; i < 16; i++) {
00161         m[i] = inv[i] * det;
00162     }
00163     return true;
00164 }
00165 
00166 void Vector3::normalize() {
00167     float n = sqrt(X * X + Y * Y + Z * Z);
00168     if (n != 0) {
00169         X /= n;
00170         Y /= n;
00171         Z /= n;
00172     }
00173 }
00174 
00175 Vector4::Vector4(const Vector3 &vec, float w) {
00176     X = vec.X;
00177     Y = vec.Y;
00178     Z = vec.Z;
00179     W = w;
00180 }
00181 
00182 void Matrix4::identity() {
00183     memset(_m, 0, sizeof(_m));
00184     _m[0][0] = 1.0f;
00185     _m[1][1] = 1.0f;
00186     _m[2][2] = 1.0f;
00187     _m[3][3] = 1.0f;
00188 }
00189 
00190 Matrix4 Matrix4::transpose() const {
00191     Matrix4 a;
00192 
00193     a._m[0][0] = this->_m[0][0];
00194     a._m[0][1] = this->_m[1][0];
00195     a._m[0][2] = this->_m[2][0];
00196     a._m[0][3] = this->_m[3][0];
00197 
00198     a._m[1][0] = this->_m[0][1];
00199     a._m[1][1] = this->_m[1][1];
00200     a._m[1][2] = this->_m[2][1];
00201     a._m[1][3] = this->_m[3][1];
00202 
00203     a._m[2][0] = this->_m[0][2];
00204     a._m[2][1] = this->_m[1][2];
00205     a._m[2][2] = this->_m[2][2];
00206     a._m[2][3] = this->_m[3][2];
00207 
00208     a._m[3][0] = this->_m[0][3];
00209     a._m[3][1] = this->_m[1][3];
00210     a._m[3][2] = this->_m[2][3];
00211     a._m[3][3] = this->_m[3][3];
00212 
00213     return a;
00214 }
00215 
00216 void Matrix4::transpose() {
00217     Matrix4 tmp = *this;
00218     this->_m[0][0] = tmp._m[0][0];
00219     this->_m[0][1] = tmp._m[1][0];
00220     this->_m[0][2] = tmp._m[2][0];
00221     this->_m[0][3] = tmp._m[3][0];
00222 
00223     this->_m[1][0] = tmp._m[0][1];
00224     this->_m[1][1] = tmp._m[1][1];
00225     this->_m[1][2] = tmp._m[2][1];
00226     this->_m[1][3] = tmp._m[3][1];
00227 
00228     this->_m[2][0] = tmp._m[0][2];
00229     this->_m[2][1] = tmp._m[1][2];
00230     this->_m[2][2] = tmp._m[2][2];
00231     this->_m[2][3] = tmp._m[3][2];
00232 
00233     this->_m[3][0] = tmp._m[0][3];
00234     this->_m[3][1] = tmp._m[1][3];
00235     this->_m[3][2] = tmp._m[2][3];
00236     this->_m[3][3] = tmp._m[3][3];
00237 }
00238 
00239 Matrix4 Matrix4::inverseOrtho() const {
00240     Matrix4 a;
00241 
00242     for (int i = 0; i < 3; i++) {
00243         for (int j = 0; j < 3; j++) {
00244             a._m[i][j] = this->_m[j][i];
00245         }
00246     }
00247     a._m[3][0] = 0.0f;
00248     a._m[3][1] = 0.0f;
00249     a._m[3][2] = 0.0f;
00250     a._m[3][3] = 1.0f;
00251 
00252     for (int i = 0; i < 3; i++) {
00253         float s = 0;
00254         for (int j = 0; j < 3; j++) {
00255             s -= this->_m[j][i] * this->_m[j][3];
00256         }
00257         a._m[i][3] = s;
00258     }
00259 
00260     return a;
00261 }
00262 
00263 Matrix4 Matrix4::inverse() const {
00264     Matrix4 result = *this;
00265     MatrixInverse((float *)result._m);
00266 
00267     return result;
00268 }
00269 
00270 void Matrix4::rotation(float t, int u) {
00271     float s, c;
00272     int v, w;
00273 
00274     identity();
00275 
00276     if ((v = u + 1) > 2)
00277         v = 0;
00278     if ((w = v + 1) > 2)
00279         w = 0;
00280     s = sin(t);
00281     c = cos(t);
00282     _m[v][v] = c;
00283     _m[v][w] = -s;
00284     _m[w][v] = s;
00285     _m[w][w] = c;
00286 }
00287 
00288 bool Matrix4::isIdentity() const {
00289     //NOTE: This might need to be implemented in a fault-tolerant way.
00290     for (int i = 0; i < 4; i++) {
00291         for (int j = 0; j < 4; j++) {
00292             if (i == j) {
00293                 if (_m[i][j] != 1.0) {
00294                     return false;
00295                 }
00296             } else if (_m[i][j] != 0.0) {
00297                 return false;
00298             }
00299         }
00300     }
00301     return true;
00302 }
00303 
00304 void Matrix4::invert() {
00305     MatrixInverse((float *)this->_m);
00306 }
00307 
00308 Matrix4 Matrix4::frustum(float left, float right, float bottom, float top, float nearp, float farp) {
00309     float x, y, A, B, C, D;
00310 
00311     x = (float)((2.0 * nearp) / (right - left));
00312     y = (float)((2.0 * nearp) / (top - bottom));
00313     A = (right + left) / (right - left);
00314     B = (top + bottom) / (top - bottom);
00315     C = -(farp + nearp) / (farp - nearp);
00316     D = (float)(-(2.0 * farp * nearp) / (farp - nearp));
00317 
00318     Matrix4 m;
00319 
00320     m._m[0][0] = x; m._m[0][1] = 0; m._m[0][2] = A; m._m[0][3] = 0;
00321     m._m[1][0] = 0; m._m[1][1] = y; m._m[1][2] = B; m._m[1][3] = 0;
00322     m._m[2][0] = 0; m._m[2][1] = 0; m._m[2][2] = C; m._m[2][3] = D;
00323     m._m[3][0] = 0; m._m[3][1] = 0; m._m[3][2] = -1; m._m[3][3] = 0;
00324 
00325     return m;
00326 }
00327 
00328 void Matrix4::translate(float x, float y, float z) {
00329     _m[0][3] += _m[0][0] * x + _m[0][1] * y + _m[0][2] * z;
00330     _m[1][3] += _m[1][0] * x + _m[1][1] * y + _m[1][2] * z;
00331     _m[2][3] += _m[2][0] * x + _m[2][1] * y + _m[2][2] * z;
00332     _m[3][3] += _m[3][0] * x + _m[3][1] * y + _m[3][2] * z;
00333 }
00334 
00335 void Matrix4::scale(float x, float y, float z) {
00336     _m[0][0] *= x; _m[0][1] *= y; _m[0][2] *= z;
00337     _m[1][0] *= x; _m[1][1] *= y; _m[1][2] *= z;
00338     _m[2][0] *= x; _m[2][1] *= y; _m[2][2] *= z;
00339     _m[3][0] *= x; _m[3][1] *= y; _m[3][2] *= z;
00340 }
00341 
00342 } // end of namespace TinyGL


Generated on Sat Nov 30 2019 05:00:32 for ResidualVM by doxygen 1.7.1
curved edge   curved edge