r_matrix.c

Go to the documentation of this file.
00001 /*
00002  * Copyright(c) 2010 DarkPlaces.
00003  * Copyright(c) 2010 Quake2World.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or(at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00013  *
00014  * See the GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019  */
00020 
00021 #include "r_local.h"
00022 #include "r_matrix.h"
00023 
00024 const matrix4x4_t identitymatrix = { { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 1 } } };
00025 
00026 void Matrix4x4_Copy (matrix4x4_t *out, const matrix4x4_t *in)
00027 {
00028     *out = *in;
00029 }
00030 
00031 void Matrix4x4_CopyRotateOnly (matrix4x4_t *out, const matrix4x4_t *in)
00032 {
00033     out->m[0][0] = in->m[0][0];
00034     out->m[0][1] = in->m[0][1];
00035     out->m[0][2] = in->m[0][2];
00036     out->m[0][3] = 0.0f;
00037     out->m[1][0] = in->m[1][0];
00038     out->m[1][1] = in->m[1][1];
00039     out->m[1][2] = in->m[1][2];
00040     out->m[1][3] = 0.0f;
00041     out->m[2][0] = in->m[2][0];
00042     out->m[2][1] = in->m[2][1];
00043     out->m[2][2] = in->m[2][2];
00044     out->m[2][3] = 0.0f;
00045     out->m[3][0] = 0.0f;
00046     out->m[3][1] = 0.0f;
00047     out->m[3][2] = 0.0f;
00048     out->m[3][3] = 1.0f;
00049 }
00050 
00051 void Matrix4x4_CopyTranslateOnly (matrix4x4_t *out, const matrix4x4_t *in)
00052 {
00053 #ifdef MATRIX4x4_OPENGLORIENTATION
00054     out->m[0][0] = 1.0f;
00055     out->m[1][0] = 0.0f;
00056     out->m[2][0] = 0.0f;
00057     out->m[3][0] = in->m[0][3];
00058     out->m[0][1] = 0.0f;
00059     out->m[1][1] = 1.0f;
00060     out->m[2][1] = 0.0f;
00061     out->m[3][1] = in->m[1][3];
00062     out->m[0][2] = 0.0f;
00063     out->m[1][2] = 0.0f;
00064     out->m[2][2] = 1.0f;
00065     out->m[3][2] = in->m[2][3];
00066     out->m[0][3] = 0.0f;
00067     out->m[1][3] = 0.0f;
00068     out->m[2][3] = 0.0f;
00069     out->m[3][3] = 1.0f;
00070 #else
00071     out->m[0][0] = 1.0f;
00072     out->m[0][1] = 0.0f;
00073     out->m[0][2] = 0.0f;
00074     out->m[0][3] = in->m[0][3];
00075     out->m[1][0] = 0.0f;
00076     out->m[1][1] = 1.0f;
00077     out->m[1][2] = 0.0f;
00078     out->m[1][3] = in->m[1][3];
00079     out->m[2][0] = 0.0f;
00080     out->m[2][1] = 0.0f;
00081     out->m[2][2] = 1.0f;
00082     out->m[2][3] = in->m[2][3];
00083     out->m[3][0] = 0.0f;
00084     out->m[3][1] = 0.0f;
00085     out->m[3][2] = 0.0f;
00086     out->m[3][3] = 1.0f;
00087 #endif
00088 }
00089 
00090 void Matrix4x4_Concat (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2)
00091 {
00092 #ifdef MATRIX4x4_OPENGLORIENTATION
00093     out->m[0][0] = in1->m[0][0] * in2->m[0][0] + in1->m[1][0] * in2->m[0][1] + in1->m[2][0] * in2->m[0][2] + in1->m[3][0] * in2->m[0][3];
00094     out->m[1][0] = in1->m[0][0] * in2->m[1][0] + in1->m[1][0] * in2->m[1][1] + in1->m[2][0] * in2->m[1][2] + in1->m[3][0] * in2->m[1][3];
00095     out->m[2][0] = in1->m[0][0] * in2->m[2][0] + in1->m[1][0] * in2->m[2][1] + in1->m[2][0] * in2->m[2][2] + in1->m[3][0] * in2->m[2][3];
00096     out->m[3][0] = in1->m[0][0] * in2->m[3][0] + in1->m[1][0] * in2->m[3][1] + in1->m[2][0] * in2->m[3][2] + in1->m[3][0] * in2->m[3][3];
00097     out->m[0][1] = in1->m[0][1] * in2->m[0][0] + in1->m[1][1] * in2->m[0][1] + in1->m[2][1] * in2->m[0][2] + in1->m[3][1] * in2->m[0][3];
00098     out->m[1][1] = in1->m[0][1] * in2->m[1][0] + in1->m[1][1] * in2->m[1][1] + in1->m[2][1] * in2->m[1][2] + in1->m[3][1] * in2->m[1][3];
00099     out->m[2][1] = in1->m[0][1] * in2->m[2][0] + in1->m[1][1] * in2->m[2][1] + in1->m[2][1] * in2->m[2][2] + in1->m[3][1] * in2->m[2][3];
00100     out->m[3][1] = in1->m[0][1] * in2->m[3][0] + in1->m[1][1] * in2->m[3][1] + in1->m[2][1] * in2->m[3][2] + in1->m[3][1] * in2->m[3][3];
00101     out->m[0][2] = in1->m[0][2] * in2->m[0][0] + in1->m[1][2] * in2->m[0][1] + in1->m[2][2] * in2->m[0][2] + in1->m[3][2] * in2->m[0][3];
00102     out->m[1][2] = in1->m[0][2] * in2->m[1][0] + in1->m[1][2] * in2->m[1][1] + in1->m[2][2] * in2->m[1][2] + in1->m[3][2] * in2->m[1][3];
00103     out->m[2][2] = in1->m[0][2] * in2->m[2][0] + in1->m[1][2] * in2->m[2][1] + in1->m[2][2] * in2->m[2][2] + in1->m[3][2] * in2->m[2][3];
00104     out->m[3][2] = in1->m[0][2] * in2->m[3][0] + in1->m[1][2] * in2->m[3][1] + in1->m[2][2] * in2->m[3][2] + in1->m[3][2] * in2->m[3][3];
00105     out->m[0][3] = in1->m[0][3] * in2->m[0][0] + in1->m[1][3] * in2->m[0][1] + in1->m[2][3] * in2->m[0][2] + in1->m[3][3] * in2->m[0][3];
00106     out->m[1][3] = in1->m[0][3] * in2->m[1][0] + in1->m[1][3] * in2->m[1][1] + in1->m[2][3] * in2->m[1][2] + in1->m[3][3] * in2->m[1][3];
00107     out->m[2][3] = in1->m[0][3] * in2->m[2][0] + in1->m[1][3] * in2->m[2][1] + in1->m[2][3] * in2->m[2][2] + in1->m[3][3] * in2->m[2][3];
00108     out->m[3][3] = in1->m[0][3] * in2->m[3][0] + in1->m[1][3] * in2->m[3][1] + in1->m[2][3] * in2->m[3][2] + in1->m[3][3] * in2->m[3][3];
00109 #else
00110     out->m[0][0] = in1->m[0][0] * in2->m[0][0] + in1->m[0][1] * in2->m[1][0] + in1->m[0][2] * in2->m[2][0]
00111             + in1->m[0][3] * in2->m[3][0];
00112     out->m[0][1] = in1->m[0][0] * in2->m[0][1] + in1->m[0][1] * in2->m[1][1] + in1->m[0][2] * in2->m[2][1]
00113             + in1->m[0][3] * in2->m[3][1];
00114     out->m[0][2] = in1->m[0][0] * in2->m[0][2] + in1->m[0][1] * in2->m[1][2] + in1->m[0][2] * in2->m[2][2]
00115             + in1->m[0][3] * in2->m[3][2];
00116     out->m[0][3] = in1->m[0][0] * in2->m[0][3] + in1->m[0][1] * in2->m[1][3] + in1->m[0][2] * in2->m[2][3]
00117             + in1->m[0][3] * in2->m[3][3];
00118     out->m[1][0] = in1->m[1][0] * in2->m[0][0] + in1->m[1][1] * in2->m[1][0] + in1->m[1][2] * in2->m[2][0]
00119             + in1->m[1][3] * in2->m[3][0];
00120     out->m[1][1] = in1->m[1][0] * in2->m[0][1] + in1->m[1][1] * in2->m[1][1] + in1->m[1][2] * in2->m[2][1]
00121             + in1->m[1][3] * in2->m[3][1];
00122     out->m[1][2] = in1->m[1][0] * in2->m[0][2] + in1->m[1][1] * in2->m[1][2] + in1->m[1][2] * in2->m[2][2]
00123             + in1->m[1][3] * in2->m[3][2];
00124     out->m[1][3] = in1->m[1][0] * in2->m[0][3] + in1->m[1][1] * in2->m[1][3] + in1->m[1][2] * in2->m[2][3]
00125             + in1->m[1][3] * in2->m[3][3];
00126     out->m[2][0] = in1->m[2][0] * in2->m[0][0] + in1->m[2][1] * in2->m[1][0] + in1->m[2][2] * in2->m[2][0]
00127             + in1->m[2][3] * in2->m[3][0];
00128     out->m[2][1] = in1->m[2][0] * in2->m[0][1] + in1->m[2][1] * in2->m[1][1] + in1->m[2][2] * in2->m[2][1]
00129             + in1->m[2][3] * in2->m[3][1];
00130     out->m[2][2] = in1->m[2][0] * in2->m[0][2] + in1->m[2][1] * in2->m[1][2] + in1->m[2][2] * in2->m[2][2]
00131             + in1->m[2][3] * in2->m[3][2];
00132     out->m[2][3] = in1->m[2][0] * in2->m[0][3] + in1->m[2][1] * in2->m[1][3] + in1->m[2][2] * in2->m[2][3]
00133             + in1->m[2][3] * in2->m[3][3];
00134     out->m[3][0] = in1->m[3][0] * in2->m[0][0] + in1->m[3][1] * in2->m[1][0] + in1->m[3][2] * in2->m[2][0]
00135             + in1->m[3][3] * in2->m[3][0];
00136     out->m[3][1] = in1->m[3][0] * in2->m[0][1] + in1->m[3][1] * in2->m[1][1] + in1->m[3][2] * in2->m[2][1]
00137             + in1->m[3][3] * in2->m[3][1];
00138     out->m[3][2] = in1->m[3][0] * in2->m[0][2] + in1->m[3][1] * in2->m[1][2] + in1->m[3][2] * in2->m[2][2]
00139             + in1->m[3][3] * in2->m[3][2];
00140     out->m[3][3] = in1->m[3][0] * in2->m[0][3] + in1->m[3][1] * in2->m[1][3] + in1->m[3][2] * in2->m[2][3]
00141             + in1->m[3][3] * in2->m[3][3];
00142 #endif
00143 }
00144 
00145 void Matrix4x4_Transpose (matrix4x4_t *out, const matrix4x4_t *in1)
00146 {
00147     out->m[0][0] = in1->m[0][0];
00148     out->m[0][1] = in1->m[1][0];
00149     out->m[0][2] = in1->m[2][0];
00150     out->m[0][3] = in1->m[3][0];
00151     out->m[1][0] = in1->m[0][1];
00152     out->m[1][1] = in1->m[1][1];
00153     out->m[1][2] = in1->m[2][1];
00154     out->m[1][3] = in1->m[3][1];
00155     out->m[2][0] = in1->m[0][2];
00156     out->m[2][1] = in1->m[1][2];
00157     out->m[2][2] = in1->m[2][2];
00158     out->m[2][3] = in1->m[3][2];
00159     out->m[3][0] = in1->m[0][3];
00160     out->m[3][1] = in1->m[1][3];
00161     out->m[3][2] = in1->m[2][3];
00162     out->m[3][3] = in1->m[3][3];
00163 }
00164 
00165 #if 1
00166 
00170 int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
00171 {
00172     float det;
00173 
00174     /* note: orientation does not matter, as transpose(invert(transpose(m))) == invert(m), proof:
00175      *   transpose(invert(transpose(m))) * m
00176      * = transpose(invert(transpose(m))) * transpose(transpose(m))
00177      * = transpose(transpose(m) * invert(transpose(m)))
00178      * = transpose(identity)
00179      * = identity
00180      */
00181 
00182     /* this seems to help gcc's common subexpression elimination, and also makes the code look nicer */
00183     float m00 = in1->m[0][0], m01 = in1->m[0][1], m02 = in1->m[0][2], m03 = in1->m[0][3], m10 = in1->m[1][0], m11 =
00184             in1->m[1][1], m12 = in1->m[1][2], m13 = in1->m[1][3], m20 = in1->m[2][0], m21 = in1->m[2][1], m22 =
00185             in1->m[2][2], m23 = in1->m[2][3], m30 = in1->m[3][0], m31 = in1->m[3][1], m32 = in1->m[3][2], m33 =
00186             in1->m[3][3];
00187 
00188     /* calculate the adjoint */
00189     out->m[0][0] = (m11 * (m22 * m33 - m23 * m32) - m21 * (m12 * m33 - m13 * m32) + m31 * (m12 * m23 - m13 * m22));
00190     out->m[0][1] = -(m01 * (m22 * m33 - m23 * m32) - m21 * (m02 * m33 - m03 * m32) + m31 * (m02 * m23 - m03 * m22));
00191     out->m[0][2] = (m01 * (m12 * m33 - m13 * m32) - m11 * (m02 * m33 - m03 * m32) + m31 * (m02 * m13 - m03 * m12));
00192     out->m[0][3] = -(m01 * (m12 * m23 - m13 * m22) - m11 * (m02 * m23 - m03 * m22) + m21 * (m02 * m13 - m03 * m12));
00193     out->m[1][0] = -(m10 * (m22 * m33 - m23 * m32) - m20 * (m12 * m33 - m13 * m32) + m30 * (m12 * m23 - m13 * m22));
00194     out->m[1][1] = (m00 * (m22 * m33 - m23 * m32) - m20 * (m02 * m33 - m03 * m32) + m30 * (m02 * m23 - m03 * m22));
00195     out->m[1][2] = -(m00 * (m12 * m33 - m13 * m32) - m10 * (m02 * m33 - m03 * m32) + m30 * (m02 * m13 - m03 * m12));
00196     out->m[1][3] = (m00 * (m12 * m23 - m13 * m22) - m10 * (m02 * m23 - m03 * m22) + m20 * (m02 * m13 - m03 * m12));
00197     out->m[2][0] = (m10 * (m21 * m33 - m23 * m31) - m20 * (m11 * m33 - m13 * m31) + m30 * (m11 * m23 - m13 * m21));
00198     out->m[2][1] = -(m00 * (m21 * m33 - m23 * m31) - m20 * (m01 * m33 - m03 * m31) + m30 * (m01 * m23 - m03 * m21));
00199     out->m[2][2] = (m00 * (m11 * m33 - m13 * m31) - m10 * (m01 * m33 - m03 * m31) + m30 * (m01 * m13 - m03 * m11));
00200     out->m[2][3] = -(m00 * (m11 * m23 - m13 * m21) - m10 * (m01 * m23 - m03 * m21) + m20 * (m01 * m13 - m03 * m11));
00201     out->m[3][0] = -(m10 * (m21 * m32 - m22 * m31) - m20 * (m11 * m32 - m12 * m31) + m30 * (m11 * m22 - m12 * m21));
00202     out->m[3][1] = (m00 * (m21 * m32 - m22 * m31) - m20 * (m01 * m32 - m02 * m31) + m30 * (m01 * m22 - m02 * m21));
00203     out->m[3][2] = -(m00 * (m11 * m32 - m12 * m31) - m10 * (m01 * m32 - m02 * m31) + m30 * (m01 * m12 - m02 * m11));
00204     out->m[3][3] = (m00 * (m11 * m22 - m12 * m21) - m10 * (m01 * m22 - m02 * m21) + m20 * (m01 * m12 - m02 * m11));
00205 
00206     /* calculate the determinant (as inverse == 1/det * adjoint, adjoint * m == identity * det, so this calculates the det) */
00207     det = m00 * out->m[0][0] + m10 * out->m[0][1] + m20 * out->m[0][2] + m30 * out->m[0][3];
00208     if (det == 0.0f)
00209         return 0;
00210 
00211     /* multiplications are faster than divisions, usually */
00212     det = 1.0f / det;
00213 
00214     /* manually unrolled loop to multiply all matrix elements by 1/det */
00215     out->m[0][0] *= det;
00216     out->m[0][1] *= det;
00217     out->m[0][2] *= det;
00218     out->m[0][3] *= det;
00219     out->m[1][0] *= det;
00220     out->m[1][1] *= det;
00221     out->m[1][2] *= det;
00222     out->m[1][3] *= det;
00223     out->m[2][0] *= det;
00224     out->m[2][1] *= det;
00225     out->m[2][2] *= det;
00226     out->m[2][3] *= det;
00227     out->m[3][0] *= det;
00228     out->m[3][1] *= det;
00229     out->m[3][2] *= det;
00230     out->m[3][3] *= det;
00231 
00232     return 1;
00233 }
00234 #elif 1
00235 
00238 int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
00239 {
00240     matrix4x4_t temp;
00241     double det;
00242     int i, j;
00243 
00244 #ifdef MATRIX4x4_OPENGLORIENTATION
00245     temp.m[0][0] = in1->m[1][1]*in1->m[2][2]*in1->m[3][3] - in1->m[1][1]*in1->m[2][3]*in1->m[3][2] - in1->m[2][1]*in1->m[1][2]*in1->m[3][3] + in1->m[2][1]*in1->m[1][3]*in1->m[3][2] + in1->m[3][1]*in1->m[1][2]*in1->m[2][3] - in1->m[3][1]*in1->m[1][3]*in1->m[2][2];
00246     temp.m[1][0] = -in1->m[1][0]*in1->m[2][2]*in1->m[3][3] + in1->m[1][0]*in1->m[2][3]*in1->m[3][2] + in1->m[2][0]*in1->m[1][2]*in1->m[3][3] - in1->m[2][0]*in1->m[1][3]*in1->m[3][2] - in1->m[3][0]*in1->m[1][2]*in1->m[2][3] + in1->m[3][0]*in1->m[1][3]*in1->m[2][2];
00247     temp.m[2][0] = in1->m[1][0]*in1->m[2][1]*in1->m[3][3] - in1->m[1][0]*in1->m[2][3]*in1->m[3][1] - in1->m[2][0]*in1->m[1][1]*in1->m[3][3] + in1->m[2][0]*in1->m[1][3]*in1->m[3][1] + in1->m[3][0]*in1->m[1][1]*in1->m[2][3] - in1->m[3][0]*in1->m[1][3]*in1->m[2][1];
00248     temp.m[3][0] = -in1->m[1][0]*in1->m[2][1]*in1->m[3][2] + in1->m[1][0]*in1->m[2][2]*in1->m[3][1] + in1->m[2][0]*in1->m[1][1]*in1->m[3][2] - in1->m[2][0]*in1->m[1][2]*in1->m[3][1] - in1->m[3][0]*in1->m[1][1]*in1->m[2][2] + in1->m[3][0]*in1->m[1][2]*in1->m[2][1];
00249     temp.m[0][1] = -in1->m[0][1]*in1->m[2][2]*in1->m[3][3] + in1->m[0][1]*in1->m[2][3]*in1->m[3][2] + in1->m[2][1]*in1->m[0][2]*in1->m[3][3] - in1->m[2][1]*in1->m[0][3]*in1->m[3][2] - in1->m[3][1]*in1->m[0][2]*in1->m[2][3] + in1->m[3][1]*in1->m[0][3]*in1->m[2][2];
00250     temp.m[1][1] = in1->m[0][0]*in1->m[2][2]*in1->m[3][3] - in1->m[0][0]*in1->m[2][3]*in1->m[3][2] - in1->m[2][0]*in1->m[0][2]*in1->m[3][3] + in1->m[2][0]*in1->m[0][3]*in1->m[3][2] + in1->m[3][0]*in1->m[0][2]*in1->m[2][3] - in1->m[3][0]*in1->m[0][3]*in1->m[2][2];
00251     temp.m[2][1] = -in1->m[0][0]*in1->m[2][1]*in1->m[3][3] + in1->m[0][0]*in1->m[2][3]*in1->m[3][1] + in1->m[2][0]*in1->m[0][1]*in1->m[3][3] - in1->m[2][0]*in1->m[0][3]*in1->m[3][1] - in1->m[3][0]*in1->m[0][1]*in1->m[2][3] + in1->m[3][0]*in1->m[0][3]*in1->m[2][1];
00252     temp.m[3][1] = in1->m[0][0]*in1->m[2][1]*in1->m[3][2] - in1->m[0][0]*in1->m[2][2]*in1->m[3][1] - in1->m[2][0]*in1->m[0][1]*in1->m[3][2] + in1->m[2][0]*in1->m[0][2]*in1->m[3][1] + in1->m[3][0]*in1->m[0][1]*in1->m[2][2] - in1->m[3][0]*in1->m[0][2]*in1->m[2][1];
00253     temp.m[0][2] = in1->m[0][1]*in1->m[1][2]*in1->m[3][3] - in1->m[0][1]*in1->m[1][3]*in1->m[3][2] - in1->m[1][1]*in1->m[0][2]*in1->m[3][3] + in1->m[1][1]*in1->m[0][3]*in1->m[3][2] + in1->m[3][1]*in1->m[0][2]*in1->m[1][3] - in1->m[3][1]*in1->m[0][3]*in1->m[1][2];
00254     temp.m[1][2] = -in1->m[0][0]*in1->m[1][2]*in1->m[3][3] + in1->m[0][0]*in1->m[1][3]*in1->m[3][2] + in1->m[1][0]*in1->m[0][2]*in1->m[3][3] - in1->m[1][0]*in1->m[0][3]*in1->m[3][2] - in1->m[3][0]*in1->m[0][2]*in1->m[1][3] + in1->m[3][0]*in1->m[0][3]*in1->m[1][2];
00255     temp.m[2][2] = in1->m[0][0]*in1->m[1][1]*in1->m[3][3] - in1->m[0][0]*in1->m[1][3]*in1->m[3][1] - in1->m[1][0]*in1->m[0][1]*in1->m[3][3] + in1->m[1][0]*in1->m[0][3]*in1->m[3][1] + in1->m[3][0]*in1->m[0][1]*in1->m[1][3] - in1->m[3][0]*in1->m[0][3]*in1->m[1][1];
00256     temp.m[3][2] = -in1->m[0][0]*in1->m[1][1]*in1->m[3][2] + in1->m[0][0]*in1->m[1][2]*in1->m[3][1] + in1->m[1][0]*in1->m[0][1]*in1->m[3][2] - in1->m[1][0]*in1->m[0][2]*in1->m[3][1] - in1->m[3][0]*in1->m[0][1]*in1->m[1][2] + in1->m[3][0]*in1->m[0][2]*in1->m[1][1];
00257     temp.m[0][3] = -in1->m[0][1]*in1->m[1][2]*in1->m[2][3] + in1->m[0][1]*in1->m[1][3]*in1->m[2][2] + in1->m[1][1]*in1->m[0][2]*in1->m[2][3] - in1->m[1][1]*in1->m[0][3]*in1->m[2][2] - in1->m[2][1]*in1->m[0][2]*in1->m[1][3] + in1->m[2][1]*in1->m[0][3]*in1->m[1][2];
00258     temp.m[1][3] = in1->m[0][0]*in1->m[1][2]*in1->m[2][3] - in1->m[0][0]*in1->m[1][3]*in1->m[2][2] - in1->m[1][0]*in1->m[0][2]*in1->m[2][3] + in1->m[1][0]*in1->m[0][3]*in1->m[2][2] + in1->m[2][0]*in1->m[0][2]*in1->m[1][3] - in1->m[2][0]*in1->m[0][3]*in1->m[1][2];
00259     temp.m[2][3] = -in1->m[0][0]*in1->m[1][1]*in1->m[2][3] + in1->m[0][0]*in1->m[1][3]*in1->m[2][1] + in1->m[1][0]*in1->m[0][1]*in1->m[2][3] - in1->m[1][0]*in1->m[0][3]*in1->m[2][1] - in1->m[2][0]*in1->m[0][1]*in1->m[1][3] + in1->m[2][0]*in1->m[0][3]*in1->m[1][1];
00260     temp.m[3][3] = in1->m[0][0]*in1->m[1][1]*in1->m[2][2] - in1->m[0][0]*in1->m[1][2]*in1->m[2][1] - in1->m[1][0]*in1->m[0][1]*in1->m[2][2] + in1->m[1][0]*in1->m[0][2]*in1->m[2][1] + in1->m[2][0]*in1->m[0][1]*in1->m[1][2] - in1->m[2][0]*in1->m[0][2]*in1->m[1][1];
00261 #else
00262     temp.m[0][0] = in1->m[1][1]*in1->m[2][2]*in1->m[3][3] - in1->m[1][1]*in1->m[3][2]*in1->m[2][3] - in1->m[1][2]*in1->m[2][1]*in1->m[3][3] + in1->m[1][2]*in1->m[3][1]*in1->m[2][3] + in1->m[1][3]*in1->m[2][1]*in1->m[3][2] - in1->m[1][3]*in1->m[3][1]*in1->m[2][2];
00263     temp.m[0][1] = -in1->m[0][1]*in1->m[2][2]*in1->m[3][3] + in1->m[0][1]*in1->m[3][2]*in1->m[2][3] + in1->m[0][2]*in1->m[2][1]*in1->m[3][3] - in1->m[0][2]*in1->m[3][1]*in1->m[2][3] - in1->m[0][3]*in1->m[2][1]*in1->m[3][2] + in1->m[0][3]*in1->m[3][1]*in1->m[2][2];
00264     temp.m[0][2] = in1->m[0][1]*in1->m[1][2]*in1->m[3][3] - in1->m[0][1]*in1->m[3][2]*in1->m[1][3] - in1->m[0][2]*in1->m[1][1]*in1->m[3][3] + in1->m[0][2]*in1->m[3][1]*in1->m[1][3] + in1->m[0][3]*in1->m[1][1]*in1->m[3][2] - in1->m[0][3]*in1->m[3][1]*in1->m[1][2];
00265     temp.m[0][3] = -in1->m[0][1]*in1->m[1][2]*in1->m[2][3] + in1->m[0][1]*in1->m[2][2]*in1->m[1][3] + in1->m[0][2]*in1->m[1][1]*in1->m[2][3] - in1->m[0][2]*in1->m[2][1]*in1->m[1][3] - in1->m[0][3]*in1->m[1][1]*in1->m[2][2] + in1->m[0][3]*in1->m[2][1]*in1->m[1][2];
00266     temp.m[1][0] = -in1->m[1][0]*in1->m[2][2]*in1->m[3][3] + in1->m[1][0]*in1->m[3][2]*in1->m[2][3] + in1->m[1][2]*in1->m[2][0]*in1->m[3][3] - in1->m[1][2]*in1->m[3][0]*in1->m[2][3] - in1->m[1][3]*in1->m[2][0]*in1->m[3][2] + in1->m[1][3]*in1->m[3][0]*in1->m[2][2];
00267     temp.m[1][1] = in1->m[0][0]*in1->m[2][2]*in1->m[3][3] - in1->m[0][0]*in1->m[3][2]*in1->m[2][3] - in1->m[0][2]*in1->m[2][0]*in1->m[3][3] + in1->m[0][2]*in1->m[3][0]*in1->m[2][3] + in1->m[0][3]*in1->m[2][0]*in1->m[3][2] - in1->m[0][3]*in1->m[3][0]*in1->m[2][2];
00268     temp.m[1][2] = -in1->m[0][0]*in1->m[1][2]*in1->m[3][3] + in1->m[0][0]*in1->m[3][2]*in1->m[1][3] + in1->m[0][2]*in1->m[1][0]*in1->m[3][3] - in1->m[0][2]*in1->m[3][0]*in1->m[1][3] - in1->m[0][3]*in1->m[1][0]*in1->m[3][2] + in1->m[0][3]*in1->m[3][0]*in1->m[1][2];
00269     temp.m[1][3] = in1->m[0][0]*in1->m[1][2]*in1->m[2][3] - in1->m[0][0]*in1->m[2][2]*in1->m[1][3] - in1->m[0][2]*in1->m[1][0]*in1->m[2][3] + in1->m[0][2]*in1->m[2][0]*in1->m[1][3] + in1->m[0][3]*in1->m[1][0]*in1->m[2][2] - in1->m[0][3]*in1->m[2][0]*in1->m[1][2];
00270     temp.m[2][0] = in1->m[1][0]*in1->m[2][1]*in1->m[3][3] - in1->m[1][0]*in1->m[3][1]*in1->m[2][3] - in1->m[1][1]*in1->m[2][0]*in1->m[3][3] + in1->m[1][1]*in1->m[3][0]*in1->m[2][3] + in1->m[1][3]*in1->m[2][0]*in1->m[3][1] - in1->m[1][3]*in1->m[3][0]*in1->m[2][1];
00271     temp.m[2][1] = -in1->m[0][0]*in1->m[2][1]*in1->m[3][3] + in1->m[0][0]*in1->m[3][1]*in1->m[2][3] + in1->m[0][1]*in1->m[2][0]*in1->m[3][3] - in1->m[0][1]*in1->m[3][0]*in1->m[2][3] - in1->m[0][3]*in1->m[2][0]*in1->m[3][1] + in1->m[0][3]*in1->m[3][0]*in1->m[2][1];
00272     temp.m[2][2] = in1->m[0][0]*in1->m[1][1]*in1->m[3][3] - in1->m[0][0]*in1->m[3][1]*in1->m[1][3] - in1->m[0][1]*in1->m[1][0]*in1->m[3][3] + in1->m[0][1]*in1->m[3][0]*in1->m[1][3] + in1->m[0][3]*in1->m[1][0]*in1->m[3][1] - in1->m[0][3]*in1->m[3][0]*in1->m[1][1];
00273     temp.m[2][3] = -in1->m[0][0]*in1->m[1][1]*in1->m[2][3] + in1->m[0][0]*in1->m[2][1]*in1->m[1][3] + in1->m[0][1]*in1->m[1][0]*in1->m[2][3] - in1->m[0][1]*in1->m[2][0]*in1->m[1][3] - in1->m[0][3]*in1->m[1][0]*in1->m[2][1] + in1->m[0][3]*in1->m[2][0]*in1->m[1][1];
00274     temp.m[3][0] = -in1->m[1][0]*in1->m[2][1]*in1->m[3][2] + in1->m[1][0]*in1->m[3][1]*in1->m[2][2] + in1->m[1][1]*in1->m[2][0]*in1->m[3][2] - in1->m[1][1]*in1->m[3][0]*in1->m[2][2] - in1->m[1][2]*in1->m[2][0]*in1->m[3][1] + in1->m[1][2]*in1->m[3][0]*in1->m[2][1];
00275     temp.m[3][1] = in1->m[0][0]*in1->m[2][1]*in1->m[3][2] - in1->m[0][0]*in1->m[3][1]*in1->m[2][2] - in1->m[0][1]*in1->m[2][0]*in1->m[3][2] + in1->m[0][1]*in1->m[3][0]*in1->m[2][2] + in1->m[0][2]*in1->m[2][0]*in1->m[3][1] - in1->m[0][2]*in1->m[3][0]*in1->m[2][1];
00276     temp.m[3][2] = -in1->m[0][0]*in1->m[1][1]*in1->m[3][2] + in1->m[0][0]*in1->m[3][1]*in1->m[1][2] + in1->m[0][1]*in1->m[1][0]*in1->m[3][2] - in1->m[0][1]*in1->m[3][0]*in1->m[1][2] - in1->m[0][2]*in1->m[1][0]*in1->m[3][1] + in1->m[0][2]*in1->m[3][0]*in1->m[1][1];
00277     temp.m[3][3] = in1->m[0][0]*in1->m[1][1]*in1->m[2][2] - in1->m[0][0]*in1->m[2][1]*in1->m[1][2] - in1->m[0][1]*in1->m[1][0]*in1->m[2][2] + in1->m[0][1]*in1->m[2][0]*in1->m[1][2] + in1->m[0][2]*in1->m[1][0]*in1->m[2][1] - in1->m[0][2]*in1->m[2][0]*in1->m[1][1];
00278 #endif
00279 
00280     det = in1->m[0][0]*temp.m[0][0] + in1->m[1][0]*temp.m[0][1] + in1->m[2][0]*temp.m[0][2] + in1->m[3][0]*temp.m[0][3];
00281     if (det == 0.0f)
00282     return 0;
00283 
00284     det = 1.0f / det;
00285 
00286     for (i = 0;i < 4;i++)
00287     for (j = 0;j < 4;j++)
00288     out->m[i][j] = temp.m[i][j] * det;
00289 
00290     return 1;
00291 }
00292 #else
00293 int Matrix4x4_Invert_Full (matrix4x4_t *out, const matrix4x4_t *in1)
00294 {
00295     double *temp;
00296     double *r[4];
00297     double rtemp[4][8];
00298     double m[4];
00299     double s;
00300 
00301     r[0] = rtemp[0];
00302     r[1] = rtemp[1];
00303     r[2] = rtemp[2];
00304     r[3] = rtemp[3];
00305 
00306 #ifdef MATRIX4x4_OPENGLORIENTATION
00307     r[0][0] = in1->m[0][0]; r[0][1] = in1->m[1][0]; r[0][2] = in1->m[2][0]; r[0][3] = in1->m[3][0];
00308     r[0][4] = 1.0; r[0][5] = r[0][6] = r[0][7] = 0.0;
00309 
00310     r[1][0] = in1->m[0][1]; r[1][1] = in1->m[1][1]; r[1][2] = in1->m[2][1]; r[1][3] = in1->m[3][1];
00311     r[1][5] = 1.0; r[1][4] = r[1][6] = r[1][7] = 0.0;
00312 
00313     r[2][0] = in1->m[0][2]; r[2][1] = in1->m[1][2]; r[2][2] = in1->m[2][2]; r[2][3] = in1->m[3][2];
00314     r[2][6] = 1.0; r[2][4] = r[2][5] = r[2][7] = 0.0;
00315 
00316     r[3][0] = in1->m[0][3]; r[3][1] = in1->m[1][3]; r[3][2] = in1->m[2][3]; r[3][3] = in1->m[3][3];
00317     r[3][7] = 1.0; r[3][4] = r[3][5] = r[3][6] = 0.0;
00318 #else
00319     r[0][0] = in1->m[0][0]; r[0][1] = in1->m[0][1]; r[0][2] = in1->m[0][2]; r[0][3] = in1->m[0][3];
00320     r[0][4] = 1.0; r[0][5] = r[0][6] = r[0][7] = 0.0;
00321 
00322     r[1][0] = in1->m[1][0]; r[1][1] = in1->m[1][1]; r[1][2] = in1->m[1][2]; r[1][3] = in1->m[1][3];
00323     r[1][5] = 1.0; r[1][4] = r[1][6] = r[1][7] = 0.0;
00324 
00325     r[2][0] = in1->m[2][0]; r[2][1] = in1->m[2][1]; r[2][2] = in1->m[2][2]; r[2][3] = in1->m[2][3];
00326     r[2][6] = 1.0; r[2][4] = r[2][5] = r[2][7] = 0.0;
00327 
00328     r[3][0] = in1->m[3][0]; r[3][1] = in1->m[3][1]; r[3][2] = in1->m[3][2]; r[3][3] = in1->m[3][3];
00329     r[3][7] = 1.0; r[3][4] = r[3][5] = r[3][6] = 0.0;
00330 #endif
00331 
00332     if (fabs (r[3][0]) > fabs (r[2][0])) {temp = r[3]; r[3] = r[2]; r[2] = temp;}
00333     if (fabs (r[2][0]) > fabs (r[1][0])) {temp = r[2]; r[2] = r[1]; r[1] = temp;}
00334     if (fabs (r[1][0]) > fabs (r[0][0])) {temp = r[1]; r[1] = r[0]; r[0] = temp;}
00335 
00336     if (r[0][0])
00337     {
00338         m[1] = r[1][0] / r[0][0];
00339         m[2] = r[2][0] / r[0][0];
00340         m[3] = r[3][0] / r[0][0];
00341 
00342         s = r[0][1]; r[1][1] -= m[1] * s; r[2][1] -= m[2] * s; r[3][1] -= m[3] * s;
00343         s = r[0][2]; r[1][2] -= m[1] * s; r[2][2] -= m[2] * s; r[3][2] -= m[3] * s;
00344         s = r[0][3]; r[1][3] -= m[1] * s; r[2][3] -= m[2] * s; r[3][3] -= m[3] * s;
00345 
00346         s = r[0][4]; if (s) {r[1][4] -= m[1] * s; r[2][4] -= m[2] * s; r[3][4] -= m[3] * s;}
00347         s = r[0][5]; if (s) {r[1][5] -= m[1] * s; r[2][5] -= m[2] * s; r[3][5] -= m[3] * s;}
00348         s = r[0][6]; if (s) {r[1][6] -= m[1] * s; r[2][6] -= m[2] * s; r[3][6] -= m[3] * s;}
00349         s = r[0][7]; if (s) {r[1][7] -= m[1] * s; r[2][7] -= m[2] * s; r[3][7] -= m[3] * s;}
00350 
00351         if (fabs (r[3][1]) > fabs (r[2][1])) {temp = r[3]; r[3] = r[2]; r[2] = temp;}
00352         if (fabs (r[2][1]) > fabs (r[1][1])) {temp = r[2]; r[2] = r[1]; r[1] = temp;}
00353 
00354         if (r[1][1])
00355         {
00356             m[2] = r[2][1] / r[1][1];
00357             m[3] = r[3][1] / r[1][1];
00358             r[2][2] -= m[2] * r[1][2];
00359             r[3][2] -= m[3] * r[1][2];
00360             r[2][3] -= m[2] * r[1][3];
00361             r[3][3] -= m[3] * r[1][3];
00362 
00363             s = r[1][4]; if (s) {r[2][4] -= m[2] * s; r[3][4] -= m[3] * s;}
00364             s = r[1][5]; if (s) {r[2][5] -= m[2] * s; r[3][5] -= m[3] * s;}
00365             s = r[1][6]; if (s) {r[2][6] -= m[2] * s; r[3][6] -= m[3] * s;}
00366             s = r[1][7]; if (s) {r[2][7] -= m[2] * s; r[3][7] -= m[3] * s;}
00367 
00368             if (fabs (r[3][2]) > fabs (r[2][2])) {temp = r[3]; r[3] = r[2]; r[2] = temp;}
00369 
00370             if (r[2][2])
00371             {
00372                 m[3] = r[3][2] / r[2][2];
00373                 r[3][3] -= m[3] * r[2][3];
00374                 r[3][4] -= m[3] * r[2][4];
00375                 r[3][5] -= m[3] * r[2][5];
00376                 r[3][6] -= m[3] * r[2][6];
00377                 r[3][7] -= m[3] * r[2][7];
00378 
00379                 if (r[3][3])
00380                 {
00381                     s = 1.0 / r[3][3];
00382                     r[3][4] *= s;
00383                     r[3][5] *= s;
00384                     r[3][6] *= s;
00385                     r[3][7] *= s;
00386 
00387                     m[2] = r[2][3];
00388                     s = 1.0 / r[2][2];
00389                     r[2][4] = s * (r[2][4] - r[3][4] * m[2]);
00390                     r[2][5] = s * (r[2][5] - r[3][5] * m[2]);
00391                     r[2][6] = s * (r[2][6] - r[3][6] * m[2]);
00392                     r[2][7] = s * (r[2][7] - r[3][7] * m[2]);
00393 
00394                     m[1] = r[1][3];
00395                     r[1][4] -= r[3][4] * m[1], r[1][5] -= r[3][5] * m[1];
00396                     r[1][6] -= r[3][6] * m[1], r[1][7] -= r[3][7] * m[1];
00397 
00398                     m[0] = r[0][3];
00399                     r[0][4] -= r[3][4] * m[0], r[0][5] -= r[3][5] * m[0];
00400                     r[0][6] -= r[3][6] * m[0], r[0][7] -= r[3][7] * m[0];
00401 
00402                     m[1] = r[1][2];
00403                     s = 1.0 / r[1][1];
00404                     r[1][4] = s * (r[1][4] - r[2][4] * m[1]), r[1][5] = s * (r[1][5] - r[2][5] * m[1]);
00405                     r[1][6] = s * (r[1][6] - r[2][6] * m[1]), r[1][7] = s * (r[1][7] - r[2][7] * m[1]);
00406 
00407                     m[0] = r[0][2];
00408                     r[0][4] -= r[2][4] * m[0], r[0][5] -= r[2][5] * m[0];
00409                     r[0][6] -= r[2][6] * m[0], r[0][7] -= r[2][7] * m[0];
00410 
00411                     m[0] = r[0][1];
00412                     s = 1.0 / r[0][0];
00413                     r[0][4] = s * (r[0][4] - r[1][4] * m[0]), r[0][5] = s * (r[0][5] - r[1][5] * m[0]);
00414                     r[0][6] = s * (r[0][6] - r[1][6] * m[0]), r[0][7] = s * (r[0][7] - r[1][7] * m[0]);
00415 
00416 #ifdef MATRIX4x4_OPENGLORIENTATION
00417                     out->m[0][0] = r[0][4];
00418                     out->m[0][1] = r[1][4];
00419                     out->m[0][2] = r[2][4];
00420                     out->m[0][3] = r[3][4];
00421                     out->m[1][0] = r[0][5];
00422                     out->m[1][1] = r[1][5];
00423                     out->m[1][2] = r[2][5];
00424                     out->m[1][3] = r[3][5];
00425                     out->m[2][0] = r[0][6];
00426                     out->m[2][1] = r[1][6];
00427                     out->m[2][2] = r[2][6];
00428                     out->m[2][3] = r[3][6];
00429                     out->m[3][0] = r[0][7];
00430                     out->m[3][1] = r[1][7];
00431                     out->m[3][2] = r[2][7];
00432                     out->m[3][3] = r[3][7];
00433 #else
00434                     out->m[0][0] = r[0][4];
00435                     out->m[0][1] = r[0][5];
00436                     out->m[0][2] = r[0][6];
00437                     out->m[0][3] = r[0][7];
00438                     out->m[1][0] = r[1][4];
00439                     out->m[1][1] = r[1][5];
00440                     out->m[1][2] = r[1][6];
00441                     out->m[1][3] = r[1][7];
00442                     out->m[2][0] = r[2][4];
00443                     out->m[2][1] = r[2][5];
00444                     out->m[2][2] = r[2][6];
00445                     out->m[2][3] = r[2][7];
00446                     out->m[3][0] = r[3][4];
00447                     out->m[3][1] = r[3][5];
00448                     out->m[3][2] = r[3][6];
00449                     out->m[3][3] = r[3][7];
00450 #endif
00451 
00452                     return 1;
00453                 }
00454             }
00455         }
00456     }
00457 
00458     return 0;
00459 }
00460 #endif
00461 
00462 void Matrix4x4_Invert_Simple (matrix4x4_t *out, const matrix4x4_t *in1)
00463 {
00464     /* we only support uniform scaling, so assume the first row is enough
00465      * (note the lack of sqrt here, because we're trying to undo the scaling,
00466      * this means multiplying by the inverse scale twice - squaring it, which
00467      * makes the sqrt a waste of time) */
00468 #if 1
00469     double scale = 1.0 / (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
00470 #else
00471     double scale = 3.0 / sqrt
00472     (in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]
00473             + in1->m[1][0] * in1->m[1][0] + in1->m[1][1] * in1->m[1][1] + in1->m[1][2] * in1->m[1][2]
00474             + in1->m[2][0] * in1->m[2][0] + in1->m[2][1] * in1->m[2][1] + in1->m[2][2] * in1->m[2][2]);
00475     scale *= scale;
00476 #endif
00477 
00478     /* invert the rotation by transposing and multiplying by the squared
00479      * recipricol of the input matrix scale as described above */
00480     out->m[0][0] = in1->m[0][0] * scale;
00481     out->m[0][1] = in1->m[1][0] * scale;
00482     out->m[0][2] = in1->m[2][0] * scale;
00483     out->m[1][0] = in1->m[0][1] * scale;
00484     out->m[1][1] = in1->m[1][1] * scale;
00485     out->m[1][2] = in1->m[2][1] * scale;
00486     out->m[2][0] = in1->m[0][2] * scale;
00487     out->m[2][1] = in1->m[1][2] * scale;
00488     out->m[2][2] = in1->m[2][2] * scale;
00489 
00490 #ifdef MATRIX4x4_OPENGLORIENTATION
00491     /* invert the translate */
00492     out->m[3][0] = -(in1->m[3][0] * out->m[0][0] + in1->m[3][1] * out->m[1][0] + in1->m[3][2] * out->m[2][0]);
00493     out->m[3][1] = -(in1->m[3][0] * out->m[0][1] + in1->m[3][1] * out->m[1][1] + in1->m[3][2] * out->m[2][1]);
00494     out->m[3][2] = -(in1->m[3][0] * out->m[0][2] + in1->m[3][1] * out->m[1][2] + in1->m[3][2] * out->m[2][2]);
00495 
00496     /* don't know if there's anything worth doing here */
00497     out->m[0][3] = 0;
00498     out->m[1][3] = 0;
00499     out->m[2][3] = 0;
00500     out->m[3][3] = 1;
00501 #else
00502     /* invert the translate */
00503     out->m[0][3] = -(in1->m[0][3] * out->m[0][0] + in1->m[1][3] * out->m[0][1] + in1->m[2][3] * out->m[0][2]);
00504     out->m[1][3] = -(in1->m[0][3] * out->m[1][0] + in1->m[1][3] * out->m[1][1] + in1->m[2][3] * out->m[1][2]);
00505     out->m[2][3] = -(in1->m[0][3] * out->m[2][0] + in1->m[1][3] * out->m[2][1] + in1->m[2][3] * out->m[2][2]);
00506 
00507     /* don't know if there's anything worth doing here */
00508     out->m[3][0] = 0;
00509     out->m[3][1] = 0;
00510     out->m[3][2] = 0;
00511     out->m[3][3] = 1;
00512 #endif
00513 }
00514 
00515 void Matrix4x4_Interpolate (matrix4x4_t *out, matrix4x4_t *in1, matrix4x4_t *in2, double frac)
00516 {
00517     int i, j;
00518     for (i = 0; i < 4; i++)
00519         for (j = 0; j < 4; j++)
00520             out->m[i][j] = in1->m[i][j] + frac * (in2->m[i][j] - in1->m[i][j]);
00521 }
00522 
00523 void Matrix4x4_Clear (matrix4x4_t *out)
00524 {
00525     int i, j;
00526     for (i = 0; i < 4; i++)
00527         for (j = 0; j < 4; j++)
00528             out->m[i][j] = 0;
00529 }
00530 
00531 void Matrix4x4_Accumulate (matrix4x4_t *out, matrix4x4_t *in, double weight)
00532 {
00533     int i, j;
00534     for (i = 0; i < 4; i++)
00535         for (j = 0; j < 4; j++)
00536             out->m[i][j] += in->m[i][j] * weight;
00537 }
00538 
00539 void Matrix4x4_Normalize (matrix4x4_t *out, matrix4x4_t *in1)
00540 {
00541     /* scale rotation matrix vectors to a length of 1
00542      * note: this is only designed to undo uniform scaling */
00543     double scale = 1.0 / sqrt(in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]);
00544     *out = *in1;
00545     Matrix4x4_Scale(out, scale, 1);
00546 }
00547 
00548 void Matrix4x4_Normalize3 (matrix4x4_t *out, matrix4x4_t *in1)
00549 {
00550     int i;
00551     double scale;
00552     /* scale each rotation matrix vector to a length of 1
00553      * intended for use after Matrix4x4_Interpolate or Matrix4x4_Accumulate */
00554     *out = *in1;
00555     for (i = 0; i < 3; i++) {
00556 #ifdef MATRIX4x4_OPENGLORIENTATION
00557         scale = sqrt(in1->m[i][0] * in1->m[i][0] + in1->m[i][1] * in1->m[i][1] + in1->m[i][2] * in1->m[i][2]);
00558         if (scale)
00559         scale = 1.0 / scale;
00560         out->m[i][0] *= scale;
00561         out->m[i][1] *= scale;
00562         out->m[i][2] *= scale;
00563 #else
00564         scale = sqrt(in1->m[0][i] * in1->m[0][i] + in1->m[1][i] * in1->m[1][i] + in1->m[2][i] * in1->m[2][i]);
00565         if (scale)
00566             scale = 1.0 / scale;
00567         out->m[0][i] *= scale;
00568         out->m[1][i] *= scale;
00569         out->m[2][i] *= scale;
00570 #endif
00571     }
00572 }
00573 
00574 void Matrix4x4_Reflect (matrix4x4_t *out, double normalx, double normaly, double normalz, double dist, double axisscale)
00575 {
00576     int i;
00577     double d;
00578     double p[4], p2[4];
00579     p[0] = normalx;
00580     p[1] = normaly;
00581     p[2] = normalz;
00582     p[3] = -dist;
00583     p2[0] = p[0] * axisscale;
00584     p2[1] = p[1] * axisscale;
00585     p2[2] = p[2] * axisscale;
00586     p2[3] = 0;
00587     for (i = 0; i < 4; i++) {
00588 #ifdef MATRIX4x4_OPENGLORIENTATION
00589         d = out->m[i][0] * p[0] + out->m[i][1] * p[1] + out->m[i][2] * p[2] + out->m[i][3] * p[3];
00590         out->m[i][0] += p2[0] * d;
00591         out->m[i][1] += p2[1] * d;
00592         out->m[i][2] += p2[2] * d;
00593 #else
00594         d = out->m[0][i] * p[0] + out->m[1][i] * p[1] + out->m[2][i] * p[2] + out->m[3][i] * p[3];
00595         out->m[0][i] += p2[0] * d;
00596         out->m[1][i] += p2[1] * d;
00597         out->m[2][i] += p2[2] * d;
00598 #endif
00599     }
00600 }
00601 
00602 void Matrix4x4_CreateIdentity (matrix4x4_t *out)
00603 {
00604     out->m[0][0] = 1.0f;
00605     out->m[0][1] = 0.0f;
00606     out->m[0][2] = 0.0f;
00607     out->m[0][3] = 0.0f;
00608     out->m[1][0] = 0.0f;
00609     out->m[1][1] = 1.0f;
00610     out->m[1][2] = 0.0f;
00611     out->m[1][3] = 0.0f;
00612     out->m[2][0] = 0.0f;
00613     out->m[2][1] = 0.0f;
00614     out->m[2][2] = 1.0f;
00615     out->m[2][3] = 0.0f;
00616     out->m[3][0] = 0.0f;
00617     out->m[3][1] = 0.0f;
00618     out->m[3][2] = 0.0f;
00619     out->m[3][3] = 1.0f;
00620 }
00621 
00622 void Matrix4x4_CreateTranslate (matrix4x4_t *out, double x, double y, double z)
00623 {
00624 #ifdef MATRIX4x4_OPENGLORIENTATION
00625     out->m[0][0]=1.0f;
00626     out->m[1][0]=0.0f;
00627     out->m[2][0]=0.0f;
00628     out->m[3][0]=x;
00629     out->m[0][1]=0.0f;
00630     out->m[1][1]=1.0f;
00631     out->m[2][1]=0.0f;
00632     out->m[3][1]=y;
00633     out->m[0][2]=0.0f;
00634     out->m[1][2]=0.0f;
00635     out->m[2][2]=1.0f;
00636     out->m[3][2]=z;
00637     out->m[0][3]=0.0f;
00638     out->m[1][3]=0.0f;
00639     out->m[2][3]=0.0f;
00640     out->m[3][3]=1.0f;
00641 #else
00642     out->m[0][0] = 1.0f;
00643     out->m[0][1] = 0.0f;
00644     out->m[0][2] = 0.0f;
00645     out->m[0][3] = x;
00646     out->m[1][0] = 0.0f;
00647     out->m[1][1] = 1.0f;
00648     out->m[1][2] = 0.0f;
00649     out->m[1][3] = y;
00650     out->m[2][0] = 0.0f;
00651     out->m[2][1] = 0.0f;
00652     out->m[2][2] = 1.0f;
00653     out->m[2][3] = z;
00654     out->m[3][0] = 0.0f;
00655     out->m[3][1] = 0.0f;
00656     out->m[3][2] = 0.0f;
00657     out->m[3][3] = 1.0f;
00658 #endif
00659 }
00660 
00661 void Matrix4x4_CreateRotate (matrix4x4_t *out, double angle, double x, double y, double z)
00662 {
00663     double len, c, s;
00664 
00665     len = x * x + y * y + z * z;
00666     if (len != 0.0f)
00667         len = 1.0f / sqrt(len);
00668     x *= len;
00669     y *= len;
00670     z *= len;
00671 
00672     angle *= -torad;
00673     c = cos(angle);
00674     s = sin(angle);
00675 
00676 #ifdef MATRIX4x4_OPENGLORIENTATION
00677     out->m[0][0]=x * x + c * (1 - x * x);
00678     out->m[1][0]=x * y * (1 - c) + z * s;
00679     out->m[2][0]=z * x * (1 - c) - y * s;
00680     out->m[3][0]=0.0f;
00681     out->m[0][1]=x * y * (1 - c) - z * s;
00682     out->m[1][1]=y * y + c * (1 - y * y);
00683     out->m[2][1]=y * z * (1 - c) + x * s;
00684     out->m[3][1]=0.0f;
00685     out->m[0][2]=z * x * (1 - c) + y * s;
00686     out->m[1][2]=y * z * (1 - c) - x * s;
00687     out->m[2][2]=z * z + c * (1 - z * z);
00688     out->m[3][2]=0.0f;
00689     out->m[0][3]=0.0f;
00690     out->m[1][3]=0.0f;
00691     out->m[2][3]=0.0f;
00692     out->m[3][3]=1.0f;
00693 #else
00694     out->m[0][0] = x * x + c * (1 - x * x);
00695     out->m[0][1] = x * y * (1 - c) + z * s;
00696     out->m[0][2] = z * x * (1 - c) - y * s;
00697     out->m[0][3] = 0.0f;
00698     out->m[1][0] = x * y * (1 - c) - z * s;
00699     out->m[1][1] = y * y + c * (1 - y * y);
00700     out->m[1][2] = y * z * (1 - c) + x * s;
00701     out->m[1][3] = 0.0f;
00702     out->m[2][0] = z * x * (1 - c) + y * s;
00703     out->m[2][1] = y * z * (1 - c) - x * s;
00704     out->m[2][2] = z * z + c * (1 - z * z);
00705     out->m[2][3] = 0.0f;
00706     out->m[3][0] = 0.0f;
00707     out->m[3][1] = 0.0f;
00708     out->m[3][2] = 0.0f;
00709     out->m[3][3] = 1.0f;
00710 #endif
00711 }
00712 
00713 void Matrix4x4_CreateScale (matrix4x4_t *out, double x)
00714 {
00715     out->m[0][0] = x;
00716     out->m[0][1] = 0.0f;
00717     out->m[0][2] = 0.0f;
00718     out->m[0][3] = 0.0f;
00719     out->m[1][0] = 0.0f;
00720     out->m[1][1] = x;
00721     out->m[1][2] = 0.0f;
00722     out->m[1][3] = 0.0f;
00723     out->m[2][0] = 0.0f;
00724     out->m[2][1] = 0.0f;
00725     out->m[2][2] = x;
00726     out->m[2][3] = 0.0f;
00727     out->m[3][0] = 0.0f;
00728     out->m[3][1] = 0.0f;
00729     out->m[3][2] = 0.0f;
00730     out->m[3][3] = 1.0f;
00731 }
00732 
00733 void Matrix4x4_CreateScale3 (matrix4x4_t *out, double x, double y, double z)
00734 {
00735     out->m[0][0] = x;
00736     out->m[0][1] = 0.0f;
00737     out->m[0][2] = 0.0f;
00738     out->m[0][3] = 0.0f;
00739     out->m[1][0] = 0.0f;
00740     out->m[1][1] = y;
00741     out->m[1][2] = 0.0f;
00742     out->m[1][3] = 0.0f;
00743     out->m[2][0] = 0.0f;
00744     out->m[2][1] = 0.0f;
00745     out->m[2][2] = z;
00746     out->m[2][3] = 0.0f;
00747     out->m[3][0] = 0.0f;
00748     out->m[3][1] = 0.0f;
00749     out->m[3][2] = 0.0f;
00750     out->m[3][3] = 1.0f;
00751 }
00752 
00753 void Matrix4x4_CreateFromQuakeEntity (matrix4x4_t *out, double x, double y, double z, double pitch, double yaw,
00754         double roll, double scale)
00755 {
00756 
00757     if (roll) {
00758         double sr, cr, sp, cp;
00759         double angle = yaw * torad;
00760         double sy = sin(angle);
00761         double cy = cos(angle);
00762         angle = pitch * torad;
00763         sp = sin(angle);
00764         cp = cos(angle);
00765         angle = roll * torad;
00766         sr = sin(angle);
00767         cr = cos(angle);
00768 #ifdef MATRIX4x4_OPENGLORIENTATION
00769         out->m[0][0] = (cp*cy) * scale;
00770         out->m[1][0] = (sr*sp*cy+cr*-sy) * scale;
00771         out->m[2][0] = (cr*sp*cy+-sr*-sy) * scale;
00772         out->m[3][0] = x;
00773         out->m[0][1] = (cp*sy) * scale;
00774         out->m[1][1] = (sr*sp*sy+cr*cy) * scale;
00775         out->m[2][1] = (cr*sp*sy+-sr*cy) * scale;
00776         out->m[3][1] = y;
00777         out->m[0][2] = (-sp) * scale;
00778         out->m[1][2] = (sr*cp) * scale;
00779         out->m[2][2] = (cr*cp) * scale;
00780         out->m[3][2] = z;
00781         out->m[0][3] = 0;
00782         out->m[1][3] = 0;
00783         out->m[2][3] = 0;
00784         out->m[3][3] = 1;
00785 #else
00786         out->m[0][0] = (cp * cy) * scale;
00787         out->m[0][1] = (sr * sp * cy + cr * -sy) * scale;
00788         out->m[0][2] = (cr * sp * cy + -sr * -sy) * scale;
00789         out->m[0][3] = x;
00790         out->m[1][0] = (cp * sy) * scale;
00791         out->m[1][1] = (sr * sp * sy + cr * cy) * scale;
00792         out->m[1][2] = (cr * sp * sy + -sr * cy) * scale;
00793         out->m[1][3] = y;
00794         out->m[2][0] = (-sp) * scale;
00795         out->m[2][1] = (sr * cp) * scale;
00796         out->m[2][2] = (cr * cp) * scale;
00797         out->m[2][3] = z;
00798         out->m[3][0] = 0;
00799         out->m[3][1] = 0;
00800         out->m[3][2] = 0;
00801         out->m[3][3] = 1;
00802 #endif
00803     } else if (pitch) {
00804         double sp, cp;
00805         double angle = yaw * torad;
00806         double sy = sin(angle);
00807         double cy = cos(angle);
00808         angle = pitch * torad;
00809         sp = sin(angle);
00810         cp = cos(angle);
00811 #ifdef MATRIX4x4_OPENGLORIENTATION
00812         out->m[0][0] = (cp*cy) * scale;
00813         out->m[1][0] = (-sy) * scale;
00814         out->m[2][0] = (sp*cy) * scale;
00815         out->m[3][0] = x;
00816         out->m[0][1] = (cp*sy) * scale;
00817         out->m[1][1] = (cy) * scale;
00818         out->m[2][1] = (sp*sy) * scale;
00819         out->m[3][1] = y;
00820         out->m[0][2] = (-sp) * scale;
00821         out->m[1][2] = 0;
00822         out->m[2][2] = (cp) * scale;
00823         out->m[3][2] = z;
00824         out->m[0][3] = 0;
00825         out->m[1][3] = 0;
00826         out->m[2][3] = 0;
00827         out->m[3][3] = 1;
00828 #else
00829         out->m[0][0] = (cp * cy) * scale;
00830         out->m[0][1] = (-sy) * scale;
00831         out->m[0][2] = (sp * cy) * scale;
00832         out->m[0][3] = x;
00833         out->m[1][0] = (cp * sy) * scale;
00834         out->m[1][1] = (cy) * scale;
00835         out->m[1][2] = (sp * sy) * scale;
00836         out->m[1][3] = y;
00837         out->m[2][0] = (-sp) * scale;
00838         out->m[2][1] = 0;
00839         out->m[2][2] = (cp) * scale;
00840         out->m[2][3] = z;
00841         out->m[3][0] = 0;
00842         out->m[3][1] = 0;
00843         out->m[3][2] = 0;
00844         out->m[3][3] = 1;
00845 #endif
00846     } else if (yaw) {
00847         const double angle = yaw * torad;
00848         const double sy = sin(angle);
00849         const double cy = cos(angle);
00850 #ifdef MATRIX4x4_OPENGLORIENTATION
00851         out->m[0][0] = (cy) * scale;
00852         out->m[1][0] = (-sy) * scale;
00853         out->m[2][0] = 0;
00854         out->m[3][0] = x;
00855         out->m[0][1] = (sy) * scale;
00856         out->m[1][1] = (cy) * scale;
00857         out->m[2][1] = 0;
00858         out->m[3][1] = y;
00859         out->m[0][2] = 0;
00860         out->m[1][2] = 0;
00861         out->m[2][2] = scale;
00862         out->m[3][2] = z;
00863         out->m[0][3] = 0;
00864         out->m[1][3] = 0;
00865         out->m[2][3] = 0;
00866         out->m[3][3] = 1;
00867 #else
00868         out->m[0][0] = (cy) * scale;
00869         out->m[0][1] = (-sy) * scale;
00870         out->m[0][2] = 0;
00871         out->m[0][3] = x;
00872         out->m[1][0] = (sy) * scale;
00873         out->m[1][1] = (cy) * scale;
00874         out->m[1][2] = 0;
00875         out->m[1][3] = y;
00876         out->m[2][0] = 0;
00877         out->m[2][1] = 0;
00878         out->m[2][2] = scale;
00879         out->m[2][3] = z;
00880         out->m[3][0] = 0;
00881         out->m[3][1] = 0;
00882         out->m[3][2] = 0;
00883         out->m[3][3] = 1;
00884 #endif
00885     } else {
00886 #ifdef MATRIX4x4_OPENGLORIENTATION
00887         out->m[0][0] = scale;
00888         out->m[1][0] = 0;
00889         out->m[2][0] = 0;
00890         out->m[3][0] = x;
00891         out->m[0][1] = 0;
00892         out->m[1][1] = scale;
00893         out->m[2][1] = 0;
00894         out->m[3][1] = y;
00895         out->m[0][2] = 0;
00896         out->m[1][2] = 0;
00897         out->m[2][2] = scale;
00898         out->m[3][2] = z;
00899         out->m[0][3] = 0;
00900         out->m[1][3] = 0;
00901         out->m[2][3] = 0;
00902         out->m[3][3] = 1;
00903 #else
00904         out->m[0][0] = scale;
00905         out->m[0][1] = 0;
00906         out->m[0][2] = 0;
00907         out->m[0][3] = x;
00908         out->m[1][0] = 0;
00909         out->m[1][1] = scale;
00910         out->m[1][2] = 0;
00911         out->m[1][3] = y;
00912         out->m[2][0] = 0;
00913         out->m[2][1] = 0;
00914         out->m[2][2] = scale;
00915         out->m[2][3] = z;
00916         out->m[3][0] = 0;
00917         out->m[3][1] = 0;
00918         out->m[3][2] = 0;
00919         out->m[3][3] = 1;
00920 #endif
00921     }
00922 }
00923 
00924 void Matrix4x4_ToVectors (const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3])
00925 {
00926 #ifdef MATRIX4x4_OPENGLORIENTATION
00927     vx[0] = in->m[0][0];
00928     vx[1] = in->m[0][1];
00929     vx[2] = in->m[0][2];
00930     vy[0] = in->m[1][0];
00931     vy[1] = in->m[1][1];
00932     vy[2] = in->m[1][2];
00933     vz[0] = in->m[2][0];
00934     vz[1] = in->m[2][1];
00935     vz[2] = in->m[2][2];
00936     t [0] = in->m[3][0];
00937     t [1] = in->m[3][1];
00938     t [2] = in->m[3][2];
00939 #else
00940     vx[0] = in->m[0][0];
00941     vx[1] = in->m[1][0];
00942     vx[2] = in->m[2][0];
00943     vy[0] = in->m[0][1];
00944     vy[1] = in->m[1][1];
00945     vy[2] = in->m[2][1];
00946     vz[0] = in->m[0][2];
00947     vz[1] = in->m[1][2];
00948     vz[2] = in->m[2][2];
00949     t[0] = in->m[0][3];
00950     t[1] = in->m[1][3];
00951     t[2] = in->m[2][3];
00952 #endif
00953 }
00954 
00955 void Matrix4x4_FromVectors (matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3])
00956 {
00957 #ifdef MATRIX4x4_OPENGLORIENTATION
00958     out->m[0][0] = vx[0];
00959     out->m[1][0] = vy[0];
00960     out->m[2][0] = vz[0];
00961     out->m[3][0] = t[0];
00962     out->m[0][1] = vx[1];
00963     out->m[1][1] = vy[1];
00964     out->m[2][1] = vz[1];
00965     out->m[3][1] = t[1];
00966     out->m[0][2] = vx[2];
00967     out->m[1][2] = vy[2];
00968     out->m[2][2] = vz[2];
00969     out->m[3][2] = t[2];
00970     out->m[0][3] = 0.0f;
00971     out->m[1][3] = 0.0f;
00972     out->m[2][3] = 0.0f;
00973     out->m[3][3] = 1.0f;
00974 #else
00975     out->m[0][0] = vx[0];
00976     out->m[0][1] = vy[0];
00977     out->m[0][2] = vz[0];
00978     out->m[0][3] = t[0];
00979     out->m[1][0] = vx[1];
00980     out->m[1][1] = vy[1];
00981     out->m[1][2] = vz[1];
00982     out->m[1][3] = t[1];
00983     out->m[2][0] = vx[2];
00984     out->m[2][1] = vy[2];
00985     out->m[2][2] = vz[2];
00986     out->m[2][3] = t[2];
00987     out->m[3][0] = 0.0f;
00988     out->m[3][1] = 0.0f;
00989     out->m[3][2] = 0.0f;
00990     out->m[3][3] = 1.0f;
00991 #endif
00992 }
00993 
00994 void Matrix4x4_ToArrayDoubleGL (const matrix4x4_t *in, double out[16])
00995 {
00996 #ifdef MATRIX4x4_OPENGLORIENTATION
00997     out[ 0] = in->m[0][0];
00998     out[ 1] = in->m[0][1];
00999     out[ 2] = in->m[0][2];
01000     out[ 3] = in->m[0][3];
01001     out[ 4] = in->m[1][0];
01002     out[ 5] = in->m[1][1];
01003     out[ 6] = in->m[1][2];
01004     out[ 7] = in->m[1][3];
01005     out[ 8] = in->m[2][0];
01006     out[ 9] = in->m[2][1];
01007     out[10] = in->m[2][2];
01008     out[11] = in->m[2][3];
01009     out[12] = in->m[3][0];
01010     out[13] = in->m[3][1];
01011     out[14] = in->m[3][2];
01012     out[15] = in->m[3][3];
01013 #else
01014     out[0] = in->m[0][0];
01015     out[1] = in->m[1][0];
01016     out[2] = in->m[2][0];
01017     out[3] = in->m[3][0];
01018     out[4] = in->m[0][1];
01019     out[5] = in->m[1][1];
01020     out[6] = in->m[2][1];
01021     out[7] = in->m[3][1];
01022     out[8] = in->m[0][2];
01023     out[9] = in->m[1][2];
01024     out[10] = in->m[2][2];
01025     out[11] = in->m[3][2];
01026     out[12] = in->m[0][3];
01027     out[13] = in->m[1][3];
01028     out[14] = in->m[2][3];
01029     out[15] = in->m[3][3];
01030 #endif
01031 }
01032 
01033 void Matrix4x4_FromArrayDoubleGL (matrix4x4_t *out, const double in[16])
01034 {
01035 #ifdef MATRIX4x4_OPENGLORIENTATION
01036     out->m[0][0] = in[0];
01037     out->m[0][1] = in[1];
01038     out->m[0][2] = in[2];
01039     out->m[0][3] = in[3];
01040     out->m[1][0] = in[4];
01041     out->m[1][1] = in[5];
01042     out->m[1][2] = in[6];
01043     out->m[1][3] = in[7];
01044     out->m[2][0] = in[8];
01045     out->m[2][1] = in[9];
01046     out->m[2][2] = in[10];
01047     out->m[2][3] = in[11];
01048     out->m[3][0] = in[12];
01049     out->m[3][1] = in[13];
01050     out->m[3][2] = in[14];
01051     out->m[3][3] = in[15];
01052 #else
01053     out->m[0][0] = in[0];
01054     out->m[1][0] = in[1];
01055     out->m[2][0] = in[2];
01056     out->m[3][0] = in[3];
01057     out->m[0][1] = in[4];
01058     out->m[1][1] = in[5];
01059     out->m[2][1] = in[6];
01060     out->m[3][1] = in[7];
01061     out->m[0][2] = in[8];
01062     out->m[1][2] = in[9];
01063     out->m[2][2] = in[10];
01064     out->m[3][2] = in[11];
01065     out->m[0][3] = in[12];
01066     out->m[1][3] = in[13];
01067     out->m[2][3] = in[14];
01068     out->m[3][3] = in[15];
01069 #endif
01070 }
01071 
01072 void Matrix4x4_ToArrayDoubleD3D (const matrix4x4_t *in, double out[16])
01073 {
01074 #ifdef MATRIX4x4_OPENGLORIENTATION
01075     out[ 0] = in->m[0][0];
01076     out[ 1] = in->m[1][0];
01077     out[ 2] = in->m[2][0];
01078     out[ 3] = in->m[3][0];
01079     out[ 4] = in->m[0][1];
01080     out[ 5] = in->m[1][1];
01081     out[ 6] = in->m[2][1];
01082     out[ 7] = in->m[3][1];
01083     out[ 8] = in->m[0][2];
01084     out[ 9] = in->m[1][2];
01085     out[10] = in->m[2][2];
01086     out[11] = in->m[3][2];
01087     out[12] = in->m[0][3];
01088     out[13] = in->m[1][3];
01089     out[14] = in->m[2][3];
01090     out[15] = in->m[3][3];
01091 #else
01092     out[0] = in->m[0][0];
01093     out[1] = in->m[0][1];
01094     out[2] = in->m[0][2];
01095     out[3] = in->m[0][3];
01096     out[4] = in->m[1][0];
01097     out[5] = in->m[1][1];
01098     out[6] = in->m[1][2];
01099     out[7] = in->m[1][3];
01100     out[8] = in->m[2][0];
01101     out[9] = in->m[2][1];
01102     out[10] = in->m[2][2];
01103     out[11] = in->m[2][3];
01104     out[12] = in->m[3][0];
01105     out[13] = in->m[3][1];
01106     out[14] = in->m[3][2];
01107     out[15] = in->m[3][3];
01108 #endif
01109 }
01110 
01111 void Matrix4x4_FromArrayDoubleD3D (matrix4x4_t *out, const double in[16])
01112 {
01113 #ifdef MATRIX4x4_OPENGLORIENTATION
01114     out->m[0][0] = in[0];
01115     out->m[1][0] = in[1];
01116     out->m[2][0] = in[2];
01117     out->m[3][0] = in[3];
01118     out->m[0][1] = in[4];
01119     out->m[1][1] = in[5];
01120     out->m[2][1] = in[6];
01121     out->m[3][1] = in[7];
01122     out->m[0][2] = in[8];
01123     out->m[1][2] = in[9];
01124     out->m[2][2] = in[10];
01125     out->m[3][2] = in[11];
01126     out->m[0][3] = in[12];
01127     out->m[1][3] = in[13];
01128     out->m[2][3] = in[14];
01129     out->m[3][3] = in[15];
01130 #else
01131     out->m[0][0] = in[0];
01132     out->m[0][1] = in[1];
01133     out->m[0][2] = in[2];
01134     out->m[0][3] = in[3];
01135     out->m[1][0] = in[4];
01136     out->m[1][1] = in[5];
01137     out->m[1][2] = in[6];
01138     out->m[1][3] = in[7];
01139     out->m[2][0] = in[8];
01140     out->m[2][1] = in[9];
01141     out->m[2][2] = in[10];
01142     out->m[2][3] = in[11];
01143     out->m[3][0] = in[12];
01144     out->m[3][1] = in[13];
01145     out->m[3][2] = in[14];
01146     out->m[3][3] = in[15];
01147 #endif
01148 }
01149 
01150 void Matrix4x4_ToArrayFloatGL (const matrix4x4_t *in, float out[16])
01151 {
01152 #ifdef MATRIX4x4_OPENGLORIENTATION
01153     out[ 0] = in->m[0][0];
01154     out[ 1] = in->m[0][1];
01155     out[ 2] = in->m[0][2];
01156     out[ 3] = in->m[0][3];
01157     out[ 4] = in->m[1][0];
01158     out[ 5] = in->m[1][1];
01159     out[ 6] = in->m[1][2];
01160     out[ 7] = in->m[1][3];
01161     out[ 8] = in->m[2][0];
01162     out[ 9] = in->m[2][1];
01163     out[10] = in->m[2][2];
01164     out[11] = in->m[2][3];
01165     out[12] = in->m[3][0];
01166     out[13] = in->m[3][1];
01167     out[14] = in->m[3][2];
01168     out[15] = in->m[3][3];
01169 #else
01170     out[0] = in->m[0][0];
01171     out[1] = in->m[1][0];
01172     out[2] = in->m[2][0];
01173     out[3] = in->m[3][0];
01174     out[4] = in->m[0][1];
01175     out[5] = in->m[1][1];
01176     out[6] = in->m[2][1];
01177     out[7] = in->m[3][1];
01178     out[8] = in->m[0][2];
01179     out[9] = in->m[1][2];
01180     out[10] = in->m[2][2];
01181     out[11] = in->m[3][2];
01182     out[12] = in->m[0][3];
01183     out[13] = in->m[1][3];
01184     out[14] = in->m[2][3];
01185     out[15] = in->m[3][3];
01186 #endif
01187 }
01188 
01189 void Matrix4x4_FromArrayFloatGL (matrix4x4_t *out, const float in[16])
01190 {
01191 #ifdef MATRIX4x4_OPENGLORIENTATION
01192     out->m[0][0] = in[0];
01193     out->m[0][1] = in[1];
01194     out->m[0][2] = in[2];
01195     out->m[0][3] = in[3];
01196     out->m[1][0] = in[4];
01197     out->m[1][1] = in[5];
01198     out->m[1][2] = in[6];
01199     out->m[1][3] = in[7];
01200     out->m[2][0] = in[8];
01201     out->m[2][1] = in[9];
01202     out->m[2][2] = in[10];
01203     out->m[2][3] = in[11];
01204     out->m[3][0] = in[12];
01205     out->m[3][1] = in[13];
01206     out->m[3][2] = in[14];
01207     out->m[3][3] = in[15];
01208 #else
01209     out->m[0][0] = in[0];
01210     out->m[1][0] = in[1];
01211     out->m[2][0] = in[2];
01212     out->m[3][0] = in[3];
01213     out->m[0][1] = in[4];
01214     out->m[1][1] = in[5];
01215     out->m[2][1] = in[6];
01216     out->m[3][1] = in[7];
01217     out->m[0][2] = in[8];
01218     out->m[1][2] = in[9];
01219     out->m[2][2] = in[10];
01220     out->m[3][2] = in[11];
01221     out->m[0][3] = in[12];
01222     out->m[1][3] = in[13];
01223     out->m[2][3] = in[14];
01224     out->m[3][3] = in[15];
01225 #endif
01226 }
01227 
01228 void Matrix4x4_ToArrayFloatD3D (const matrix4x4_t *in, float out[16])
01229 {
01230 #ifdef MATRIX4x4_OPENGLORIENTATION
01231     out[ 0] = in->m[0][0];
01232     out[ 1] = in->m[1][0];
01233     out[ 2] = in->m[2][0];
01234     out[ 3] = in->m[3][0];
01235     out[ 4] = in->m[0][1];
01236     out[ 5] = in->m[1][1];
01237     out[ 6] = in->m[2][1];
01238     out[ 7] = in->m[3][1];
01239     out[ 8] = in->m[0][2];
01240     out[ 9] = in->m[1][2];
01241     out[10] = in->m[2][2];
01242     out[11] = in->m[3][2];
01243     out[12] = in->m[0][3];
01244     out[13] = in->m[1][3];
01245     out[14] = in->m[2][3];
01246     out[15] = in->m[3][3];
01247 #else
01248     out[0] = in->m[0][0];
01249     out[1] = in->m[0][1];
01250     out[2] = in->m[0][2];
01251     out[3] = in->m[0][3];
01252     out[4] = in->m[1][0];
01253     out[5] = in->m[1][1];
01254     out[6] = in->m[1][2];
01255     out[7] = in->m[1][3];
01256     out[8] = in->m[2][0];
01257     out[9] = in->m[2][1];
01258     out[10] = in->m[2][2];
01259     out[11] = in->m[2][3];
01260     out[12] = in->m[3][0];
01261     out[13] = in->m[3][1];
01262     out[14] = in->m[3][2];
01263     out[15] = in->m[3][3];
01264 #endif
01265 }
01266 
01267 void Matrix4x4_FromArrayFloatD3D (matrix4x4_t *out, const float in[16])
01268 {
01269 #ifdef MATRIX4x4_OPENGLORIENTATION
01270     out->m[0][0] = in[0];
01271     out->m[1][0] = in[1];
01272     out->m[2][0] = in[2];
01273     out->m[3][0] = in[3];
01274     out->m[0][1] = in[4];
01275     out->m[1][1] = in[5];
01276     out->m[2][1] = in[6];
01277     out->m[3][1] = in[7];
01278     out->m[0][2] = in[8];
01279     out->m[1][2] = in[9];
01280     out->m[2][2] = in[10];
01281     out->m[3][2] = in[11];
01282     out->m[0][3] = in[12];
01283     out->m[1][3] = in[13];
01284     out->m[2][3] = in[14];
01285     out->m[3][3] = in[15];
01286 #else
01287     out->m[0][0] = in[0];
01288     out->m[0][1] = in[1];
01289     out->m[0][2] = in[2];
01290     out->m[0][3] = in[3];
01291     out->m[1][0] = in[4];
01292     out->m[1][1] = in[5];
01293     out->m[1][2] = in[6];
01294     out->m[1][3] = in[7];
01295     out->m[2][0] = in[8];
01296     out->m[2][1] = in[9];
01297     out->m[2][2] = in[10];
01298     out->m[2][3] = in[11];
01299     out->m[3][0] = in[12];
01300     out->m[3][1] = in[13];
01301     out->m[3][2] = in[14];
01302     out->m[3][3] = in[15];
01303 #endif
01304 }
01305 
01306 void Matrix4x4_ToArray12FloatGL (const matrix4x4_t *in, float out[12])
01307 {
01308 #ifdef MATRIX4x4_OPENGLORIENTATION
01309     out[ 0] = in->m[0][0];
01310     out[ 1] = in->m[0][1];
01311     out[ 2] = in->m[0][2];
01312     out[ 3] = in->m[1][0];
01313     out[ 4] = in->m[1][1];
01314     out[ 5] = in->m[1][2];
01315     out[ 6] = in->m[2][0];
01316     out[ 7] = in->m[2][1];
01317     out[ 8] = in->m[2][2];
01318     out[ 9] = in->m[3][0];
01319     out[10] = in->m[3][1];
01320     out[11] = in->m[3][2];
01321 #else
01322     out[0] = in->m[0][0];
01323     out[1] = in->m[1][0];
01324     out[2] = in->m[2][0];
01325     out[3] = in->m[0][1];
01326     out[4] = in->m[1][1];
01327     out[5] = in->m[2][1];
01328     out[6] = in->m[0][2];
01329     out[7] = in->m[1][2];
01330     out[8] = in->m[2][2];
01331     out[9] = in->m[0][3];
01332     out[10] = in->m[1][3];
01333     out[11] = in->m[2][3];
01334 #endif
01335 }
01336 
01337 void Matrix4x4_FromArray12FloatGL (matrix4x4_t *out, const float in[12])
01338 {
01339 #ifdef MATRIX4x4_OPENGLORIENTATION
01340     out->m[0][0] = in[0];
01341     out->m[0][1] = in[1];
01342     out->m[0][2] = in[2];
01343     out->m[0][3] = 0;
01344     out->m[1][0] = in[3];
01345     out->m[1][1] = in[4];
01346     out->m[1][2] = in[5];
01347     out->m[1][3] = 0;
01348     out->m[2][0] = in[6];
01349     out->m[2][1] = in[7];
01350     out->m[2][2] = in[8];
01351     out->m[2][3] = 0;
01352     out->m[3][0] = in[9];
01353     out->m[3][1] = in[10];
01354     out->m[3][2] = in[11];
01355     out->m[3][3] = 1;
01356 #else
01357     out->m[0][0] = in[0];
01358     out->m[1][0] = in[1];
01359     out->m[2][0] = in[2];
01360     out->m[3][0] = 0;
01361     out->m[0][1] = in[3];
01362     out->m[1][1] = in[4];
01363     out->m[2][1] = in[5];
01364     out->m[3][1] = 0;
01365     out->m[0][2] = in[6];
01366     out->m[1][2] = in[7];
01367     out->m[2][2] = in[8];
01368     out->m[3][2] = 0;
01369     out->m[0][3] = in[9];
01370     out->m[1][3] = in[10];
01371     out->m[2][3] = in[11];
01372     out->m[3][3] = 1;
01373 #endif
01374 }
01375 
01376 void Matrix4x4_ToArray12FloatD3D (const matrix4x4_t *in, float out[12])
01377 {
01378 #ifdef MATRIX4x4_OPENGLORIENTATION
01379     out[ 0] = in->m[0][0];
01380     out[ 1] = in->m[1][0];
01381     out[ 2] = in->m[2][0];
01382     out[ 3] = in->m[3][0];
01383     out[ 4] = in->m[0][1];
01384     out[ 5] = in->m[1][1];
01385     out[ 6] = in->m[2][1];
01386     out[ 7] = in->m[3][1];
01387     out[ 8] = in->m[0][2];
01388     out[ 9] = in->m[1][2];
01389     out[10] = in->m[2][2];
01390     out[11] = in->m[3][2];
01391 #else
01392     out[0] = in->m[0][0];
01393     out[1] = in->m[0][1];
01394     out[2] = in->m[0][2];
01395     out[3] = in->m[0][3];
01396     out[4] = in->m[1][0];
01397     out[5] = in->m[1][1];
01398     out[6] = in->m[1][2];
01399     out[7] = in->m[1][3];
01400     out[8] = in->m[2][0];
01401     out[9] = in->m[2][1];
01402     out[10] = in->m[2][2];
01403     out[11] = in->m[2][3];
01404 #endif
01405 }
01406 
01407 void Matrix4x4_FromArray12FloatD3D (matrix4x4_t *out, const float in[12])
01408 {
01409 #ifdef MATRIX4x4_OPENGLORIENTATION
01410     out->m[0][0] = in[0];
01411     out->m[1][0] = in[1];
01412     out->m[2][0] = in[2];
01413     out->m[3][0] = in[3];
01414     out->m[0][1] = in[4];
01415     out->m[1][1] = in[5];
01416     out->m[2][1] = in[6];
01417     out->m[3][1] = in[7];
01418     out->m[0][2] = in[8];
01419     out->m[1][2] = in[9];
01420     out->m[2][2] = in[10];
01421     out->m[3][2] = in[11];
01422     out->m[0][3] = 0;
01423     out->m[1][3] = 0;
01424     out->m[2][3] = 0;
01425     out->m[3][3] = 1;
01426 #else
01427     out->m[0][0] = in[0];
01428     out->m[0][1] = in[1];
01429     out->m[0][2] = in[2];
01430     out->m[0][3] = in[3];
01431     out->m[1][0] = in[4];
01432     out->m[1][1] = in[5];
01433     out->m[1][2] = in[6];
01434     out->m[1][3] = in[7];
01435     out->m[2][0] = in[8];
01436     out->m[2][1] = in[9];
01437     out->m[2][2] = in[10];
01438     out->m[2][3] = in[11];
01439     out->m[3][0] = 0;
01440     out->m[3][1] = 0;
01441     out->m[3][2] = 0;
01442     out->m[3][3] = 1;
01443 #endif
01444 }
01445 
01446 void Matrix4x4_FromOriginQuat (matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z, double w)
01447 {
01448 #ifdef MATRIX4x4_OPENGLORIENTATION
01449     m->m[0][0]=1-2*(y*y+z*z);m->m[1][0]= 2*(x*y-z*w);m->m[2][0]= 2*(x*z+y*w);m->m[3][0]=ox;
01450     m->m[0][1]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[2][1]= 2*(y*z-x*w);m->m[3][1]=oy;
01451     m->m[0][2]= 2*(x*z-y*w);m->m[1][2]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[3][2]=oz;
01452     m->m[0][3]= 0;m->m[1][3]= 0;m->m[2][3]= 0;m->m[3][3]=1;
01453 #else
01454     m->m[0][0] = 1 - 2 * (y * y + z * z);
01455     m->m[0][1] = 2 * (x * y - z * w);
01456     m->m[0][2] = 2 * (x * z + y * w);
01457     m->m[0][3] = ox;
01458     m->m[1][0] = 2 * (x * y + z * w);
01459     m->m[1][1] = 1 - 2 * (x * x + z * z);
01460     m->m[1][2] = 2 * (y * z - x * w);
01461     m->m[1][3] = oy;
01462     m->m[2][0] = 2 * (x * z - y * w);
01463     m->m[2][1] = 2 * (y * z + x * w);
01464     m->m[2][2] = 1 - 2 * (x * x + y * y);
01465     m->m[2][3] = oz;
01466     m->m[3][0] = 0;
01467     m->m[3][1] = 0;
01468     m->m[3][2] = 0;
01469     m->m[3][3] = 1;
01470 #endif
01471 }
01472 
01476 void Matrix4x4_ToOrigin3Quat4Float (const matrix4x4_t *m, float *origin, float *quat)
01477 {
01478     float s;
01479     quat[3] = sqrt(1.0f + m->m[0][0] + m->m[1][1] + m->m[2][2]) * 0.5f;
01480     s = 0.25f / quat[3];
01481 #ifdef MATRIX4x4_OPENGLORIENTATION
01482     origin[0] = m->m[3][0];
01483     origin[1] = m->m[3][1];
01484     origin[2] = m->m[3][2];
01485     quat[0] = (m->m[1][2] - m->m[2][1]) * s;
01486     quat[1] = (m->m[2][0] - m->m[0][2]) * s;
01487     quat[2] = (m->m[0][1] - m->m[1][0]) * s;
01488 #else
01489     origin[0] = m->m[0][3];
01490     origin[1] = m->m[1][3];
01491     origin[2] = m->m[2][3];
01492     quat[0] = (m->m[2][1] - m->m[1][2]) * s;
01493     quat[1] = (m->m[0][2] - m->m[2][0]) * s;
01494     quat[2] = (m->m[1][0] - m->m[0][1]) * s;
01495 #endif
01496 }
01497 
01502 void Matrix4x4_FromDoom3Joint (matrix4x4_t *m, double ox, double oy, double oz, double x, double y, double z)
01503 {
01504     double w = 1.0f - (x * x + y * y + z * z);
01505     w = w > 0.0f ? -sqrt(w) : 0.0f;
01506 #ifdef MATRIX4x4_OPENGLORIENTATION
01507     m->m[0][0]=1-2*(y*y+z*z);m->m[1][0]= 2*(x*y-z*w);m->m[2][0]= 2*(x*z+y*w);m->m[3][0]=ox;
01508     m->m[0][1]= 2*(x*y+z*w);m->m[1][1]=1-2*(x*x+z*z);m->m[2][1]= 2*(y*z-x*w);m->m[3][1]=oy;
01509     m->m[0][2]= 2*(x*z-y*w);m->m[1][2]= 2*(y*z+x*w);m->m[2][2]=1-2*(x*x+y*y);m->m[3][2]=oz;
01510     m->m[0][3]= 0;m->m[1][3]= 0;m->m[2][3]= 0;m->m[3][3]=1;
01511 #else
01512     m->m[0][0] = 1 - 2 * (y * y + z * z);
01513     m->m[0][1] = 2 * (x * y - z * w);
01514     m->m[0][2] = 2 * (x * z + y * w);
01515     m->m[0][3] = ox;
01516     m->m[1][0] = 2 * (x * y + z * w);
01517     m->m[1][1] = 1 - 2 * (x * x + z * z);
01518     m->m[1][2] = 2 * (y * z - x * w);
01519     m->m[1][3] = oy;
01520     m->m[2][0] = 2 * (x * z - y * w);
01521     m->m[2][1] = 2 * (y * z + x * w);
01522     m->m[2][2] = 1 - 2 * (x * x + y * y);
01523     m->m[2][3] = oz;
01524     m->m[3][0] = 0;
01525     m->m[3][1] = 0;
01526     m->m[3][2] = 0;
01527     m->m[3][3] = 1;
01528 #endif
01529 }
01530 
01531 void Matrix4x4_FromBonePose6s (matrix4x4_t *m, float originscale, const short *pose6s)
01532 {
01533     float origin[3];
01534     float quat[4];
01535     origin[0] = pose6s[0] * originscale;
01536     origin[1] = pose6s[1] * originscale;
01537     origin[2] = pose6s[2] * originscale;
01538     quat[0] = pose6s[3] * (1.0f / 32767.0f);
01539     quat[1] = pose6s[4] * (1.0f / 32767.0f);
01540     quat[2] = pose6s[5] * (1.0f / 32767.0f);
01541     quat[3] = 1.0f - (quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2]);
01542     quat[3] = quat[3] > 0.0f ? -sqrt(quat[3]) : 0.0f;
01543     Matrix4x4_FromOriginQuat(m, origin[0], origin[1], origin[2], quat[0], quat[1], quat[2], quat[3]);
01544 }
01545 
01546 void Matrix4x4_ToBonePose6s (const matrix4x4_t *m, float origininvscale, short *pose6s)
01547 {
01548     float origin[3];
01549     float quat[4];
01550     float s;
01551     Matrix4x4_ToOrigin3Quat4Float(m, origin, quat);
01552     /* normalize quaternion so that it is unit length */
01553     s = quat[0] * quat[0] + quat[1] * quat[1] + quat[2] * quat[2] + quat[3] * quat[3];
01554     if (s) {
01555         s = 1.0f / sqrt(s);
01556         quat[0] *= s;
01557         quat[1] *= s;
01558         quat[2] *= s;
01559         quat[3] *= s;
01560     }
01561     /* use a negative scale on the quat because the above function produces a
01562      * positive quat[3] and canonical quaternions have negative quat[3] */
01563     pose6s[0] = origin[0] * origininvscale;
01564     pose6s[1] = origin[1] * origininvscale;
01565     pose6s[2] = origin[2] * origininvscale;
01566     pose6s[3] = quat[0] * -32767.0f;
01567     pose6s[4] = quat[1] * -32767.0f;
01568     pose6s[5] = quat[2] * -32767.0f;
01569 }
01570 
01571 void Matrix4x4_Blend (matrix4x4_t *out, const matrix4x4_t *in1, const matrix4x4_t *in2, double blend)
01572 {
01573     double iblend = 1 - blend;
01574     out->m[0][0] = in1->m[0][0] * iblend + in2->m[0][0] * blend;
01575     out->m[0][1] = in1->m[0][1] * iblend + in2->m[0][1] * blend;
01576     out->m[0][2] = in1->m[0][2] * iblend + in2->m[0][2] * blend;
01577     out->m[0][3] = in1->m[0][3] * iblend + in2->m[0][3] * blend;
01578     out->m[1][0] = in1->m[1][0] * iblend + in2->m[1][0] * blend;
01579     out->m[1][1] = in1->m[1][1] * iblend + in2->m[1][1] * blend;
01580     out->m[1][2] = in1->m[1][2] * iblend + in2->m[1][2] * blend;
01581     out->m[1][3] = in1->m[1][3] * iblend + in2->m[1][3] * blend;
01582     out->m[2][0] = in1->m[2][0] * iblend + in2->m[2][0] * blend;
01583     out->m[2][1] = in1->m[2][1] * iblend + in2->m[2][1] * blend;
01584     out->m[2][2] = in1->m[2][2] * iblend + in2->m[2][2] * blend;
01585     out->m[2][3] = in1->m[2][3] * iblend + in2->m[2][3] * blend;
01586     out->m[3][0] = in1->m[3][0] * iblend + in2->m[3][0] * blend;
01587     out->m[3][1] = in1->m[3][1] * iblend + in2->m[3][1] * blend;
01588     out->m[3][2] = in1->m[3][2] * iblend + in2->m[3][2] * blend;
01589     out->m[3][3] = in1->m[3][3] * iblend + in2->m[3][3] * blend;
01590 }
01591 
01592 void Matrix4x4_Transform (const matrix4x4_t *in, const float v[3], float out[3])
01593 {
01594 #ifdef MATRIX4x4_OPENGLORIENTATION
01595     out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0] + in->m[3][0];
01596     out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1] + in->m[3][1];
01597     out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2] + in->m[3][2];
01598 #else
01599     out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2] + in->m[0][3];
01600     out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2] + in->m[1][3];
01601     out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2] + in->m[2][3];
01602 #endif
01603 }
01604 
01605 void Matrix4x4_Transform4 (const matrix4x4_t *in, const float v[4], float out[4])
01606 {
01607 #ifdef MATRIX4x4_OPENGLORIENTATION
01608     out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0] + v[3] * in->m[3][0];
01609     out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1] + v[3] * in->m[3][1];
01610     out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2] + v[3] * in->m[3][2];
01611     out[3] = v[0] * in->m[0][3] + v[1] * in->m[1][3] + v[2] * in->m[2][3] + v[3] * in->m[3][3];
01612 #else
01613     out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2] + v[3] * in->m[0][3];
01614     out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2] + v[3] * in->m[1][3];
01615     out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2] + v[3] * in->m[2][3];
01616     out[3] = v[0] * in->m[3][0] + v[1] * in->m[3][1] + v[2] * in->m[3][2] + v[3] * in->m[3][3];
01617 #endif
01618 }
01619 
01620 void Matrix4x4_Transform3x3 (const matrix4x4_t *in, const float v[3], float out[3])
01621 {
01622 #ifdef MATRIX4x4_OPENGLORIENTATION
01623     out[0] = v[0] * in->m[0][0] + v[1] * in->m[1][0] + v[2] * in->m[2][0];
01624     out[1] = v[0] * in->m[0][1] + v[1] * in->m[1][1] + v[2] * in->m[2][1];
01625     out[2] = v[0] * in->m[0][2] + v[1] * in->m[1][2] + v[2] * in->m[2][2];
01626 #else
01627     out[0] = v[0] * in->m[0][0] + v[1] * in->m[0][1] + v[2] * in->m[0][2];
01628     out[1] = v[0] * in->m[1][0] + v[1] * in->m[1][1] + v[2] * in->m[1][2];
01629     out[2] = v[0] * in->m[2][0] + v[1] * in->m[2][1] + v[2] * in->m[2][2];
01630 #endif
01631 }
01632 
01633 void Matrix4x4_TransformPositivePlane (const matrix4x4_t *in, float x, float y, float z, float d, float *o)
01634 {
01635     float scale = sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
01636     float iscale = 1.0f / scale;
01637 #ifdef MATRIX4x4_OPENGLORIENTATION
01638     o[0] = (x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0]) * iscale;
01639     o[1] = (x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1]) * iscale;
01640     o[2] = (x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2]) * iscale;
01641     o[3] = d * scale + (o[0] * in->m[3][0] + o[1] * in->m[3][1] + o[2] * in->m[3][2]);
01642 #else
01643     o[0] = (x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2]) * iscale;
01644     o[1] = (x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2]) * iscale;
01645     o[2] = (x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2]) * iscale;
01646     o[3] = d * scale + (o[0] * in->m[0][3] + o[1] * in->m[1][3] + o[2] * in->m[2][3]);
01647 #endif
01648 }
01649 
01650 void Matrix4x4_TransformStandardPlane (const matrix4x4_t *in, float x, float y, float z, float d, float *o)
01651 {
01652     float scale = sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
01653     float iscale = 1.0f / scale;
01654 #ifdef MATRIX4x4_OPENGLORIENTATION
01655     o[0] = (x * in->m[0][0] + y * in->m[1][0] + z * in->m[2][0]) * iscale;
01656     o[1] = (x * in->m[0][1] + y * in->m[1][1] + z * in->m[2][1]) * iscale;
01657     o[2] = (x * in->m[0][2] + y * in->m[1][2] + z * in->m[2][2]) * iscale;
01658     o[3] = d * scale - (o[0] * in->m[3][0] + o[1] * in->m[3][1] + o[2] * in->m[3][2]);
01659 #else
01660     o[0] = (x * in->m[0][0] + y * in->m[0][1] + z * in->m[0][2]) * iscale;
01661     o[1] = (x * in->m[1][0] + y * in->m[1][1] + z * in->m[1][2]) * iscale;
01662     o[2] = (x * in->m[2][0] + y * in->m[2][1] + z * in->m[2][2]) * iscale;
01663     o[3] = d * scale - (o[0] * in->m[0][3] + o[1] * in->m[1][3] + o[2] * in->m[2][3]);
01664 #endif
01665 }
01666 
01667 /*
01668  void Matrix4x4_SimpleUntransform (const matrix4x4_t *in, const float v[3], float out[3])
01669  {
01670  double t[3];
01671  #ifdef MATRIX4x4_OPENGLORIENTATION
01672  t[0] = v[0] - in->m[3][0];
01673  t[1] = v[1] - in->m[3][1];
01674  t[2] = v[2] - in->m[3][2];
01675  out[0] = t[0] * in->m[0][0] + t[1] * in->m[0][1] + t[2] * in->m[0][2];
01676  out[1] = t[0] * in->m[1][0] + t[1] * in->m[1][1] + t[2] * in->m[1][2];
01677  out[2] = t[0] * in->m[2][0] + t[1] * in->m[2][1] + t[2] * in->m[2][2];
01678  #else
01679  t[0] = v[0] - in->m[0][3];
01680  t[1] = v[1] - in->m[1][3];
01681  t[2] = v[2] - in->m[2][3];
01682  out[0] = t[0] * in->m[0][0] + t[1] * in->m[1][0] + t[2] * in->m[2][0];
01683  out[1] = t[0] * in->m[0][1] + t[1] * in->m[1][1] + t[2] * in->m[2][1];
01684  out[2] = t[0] * in->m[0][2] + t[1] * in->m[1][2] + t[2] * in->m[2][2];
01685  #endif
01686  }
01687  */
01688 
01689 /* FIXME: optimize */
01690 void Matrix4x4_ConcatTranslate (matrix4x4_t *out, double x, double y, double z)
01691 {
01692     matrix4x4_t base, temp;
01693     base = *out;
01694     Matrix4x4_CreateTranslate(&temp, x, y, z);
01695     Matrix4x4_Concat(out, &base, &temp);
01696 }
01697 
01698 /* FIXME: optimize */
01699 void Matrix4x4_ConcatRotate (matrix4x4_t *out, double angle, double x, double y, double z)
01700 {
01701     matrix4x4_t base, temp;
01702     base = *out;
01703     Matrix4x4_CreateRotate(&temp, angle, x, y, z);
01704     Matrix4x4_Concat(out, &base, &temp);
01705 }
01706 
01707 /* FIXME: optimize */
01708 void Matrix4x4_ConcatScale (matrix4x4_t *out, double x)
01709 {
01710     matrix4x4_t base, temp;
01711     base = *out;
01712     Matrix4x4_CreateScale(&temp, x);
01713     Matrix4x4_Concat(out, &base, &temp);
01714 }
01715 
01716 /* FIXME: optimize */
01717 void Matrix4x4_ConcatScale3 (matrix4x4_t *out, double x, double y, double z)
01718 {
01719     matrix4x4_t base, temp;
01720     base = *out;
01721     Matrix4x4_CreateScale3(&temp, x, y, z);
01722     Matrix4x4_Concat(out, &base, &temp);
01723 }
01724 
01725 void Matrix4x4_OriginFromMatrix (const matrix4x4_t *in, float *out)
01726 {
01727 #ifdef MATRIX4x4_OPENGLORIENTATION
01728     out[0] = in->m[3][0];
01729     out[1] = in->m[3][1];
01730     out[2] = in->m[3][2];
01731 #else
01732     out[0] = in->m[0][3];
01733     out[1] = in->m[1][3];
01734     out[2] = in->m[2][3];
01735 #endif
01736 }
01737 
01738 double Matrix4x4_ScaleFromMatrix (const matrix4x4_t *in)
01739 {
01740     /* we only support uniform scaling, so assume the first row is enough */
01741     return sqrt(in->m[0][0] * in->m[0][0] + in->m[0][1] * in->m[0][1] + in->m[0][2] * in->m[0][2]);
01742 }
01743 
01744 void Matrix4x4_SetOrigin (matrix4x4_t *out, double x, double y, double z)
01745 {
01746 #ifdef MATRIX4x4_OPENGLORIENTATION
01747     out->m[3][0] = x;
01748     out->m[3][1] = y;
01749     out->m[3][2] = z;
01750 #else
01751     out->m[0][3] = x;
01752     out->m[1][3] = y;
01753     out->m[2][3] = z;
01754 #endif
01755 }
01756 
01757 void Matrix4x4_AdjustOrigin (matrix4x4_t *out, double x, double y, double z)
01758 {
01759 #ifdef MATRIX4x4_OPENGLORIENTATION
01760     out->m[3][0] += x;
01761     out->m[3][1] += y;
01762     out->m[3][2] += z;
01763 #else
01764     out->m[0][3] += x;
01765     out->m[1][3] += y;
01766     out->m[2][3] += z;
01767 #endif
01768 }
01769 
01770 void Matrix4x4_Scale (matrix4x4_t *out, double rotatescale, double originscale)
01771 {
01772     out->m[0][0] *= rotatescale;
01773     out->m[0][1] *= rotatescale;
01774     out->m[0][2] *= rotatescale;
01775     out->m[1][0] *= rotatescale;
01776     out->m[1][1] *= rotatescale;
01777     out->m[1][2] *= rotatescale;
01778     out->m[2][0] *= rotatescale;
01779     out->m[2][1] *= rotatescale;
01780     out->m[2][2] *= rotatescale;
01781 #ifdef MATRIX4x4_OPENGLORIENTATION
01782     out->m[3][0] *= originscale;
01783     out->m[3][1] *= originscale;
01784     out->m[3][2] *= originscale;
01785 #else
01786     out->m[0][3] *= originscale;
01787     out->m[1][3] *= originscale;
01788     out->m[2][3] *= originscale;
01789 #endif
01790 }
01791 
01792 void Matrix4x4_Abs (matrix4x4_t *out)
01793 {
01794     out->m[0][0] = fabs(out->m[0][0]);
01795     out->m[0][1] = fabs(out->m[0][1]);
01796     out->m[0][2] = fabs(out->m[0][2]);
01797     out->m[1][0] = fabs(out->m[1][0]);
01798     out->m[1][1] = fabs(out->m[1][1]);
01799     out->m[1][2] = fabs(out->m[1][2]);
01800     out->m[2][0] = fabs(out->m[2][0]);
01801     out->m[2][1] = fabs(out->m[2][1]);
01802     out->m[2][2] = fabs(out->m[2][2]);
01803 }

Generated by  doxygen 1.6.2