matrix_4.cpp

Go to the documentation of this file.
00001 /*
00002  * matrix4_t.cpp
00003  *
00004  * Copyright (C) 2009   Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * 4x4 matrix aimed at 3D transformations.  See matrix4_t.h
00032  */
00033 
00034 // includes --------------------------------------------------------------------
00035 #include "matrix_4.h"           // always include our own header first!
00036 
00037 #include <math.h>
00038 
00039 #include "perf/perf.h"
00040 
00041 
00042 ////////////////////////////////////////////////////////////////////////////////
00043 //
00044 //      static helper methods
00045 //
00046 ////////////////////////////////////////////////////////////////////////////////
00047 
00048 
00049 
00050 
00051 ////////////////////////////////////////////////////////////////////////////////
00052 //
00053 //      public API
00054 //
00055 ////////////////////////////////////////////////////////////////////////////////
00056 
00057 void
00058 matrix4_t::setZero
00059 (
00060 void
00061 )
00062 throw()
00063 {
00064         // unroll the loops...
00065         m[ 0]   = 0;
00066         m[ 1]   = 0;
00067         m[ 2]   = 0;
00068         m[ 3]   = 0;
00069         m[ 4]   = 0;
00070         m[ 5]   = 0;
00071         m[ 6]   = 0;
00072         m[ 7]   = 0;
00073         m[ 8]   = 0;
00074         m[ 9]   = 0;
00075         m[10]   = 0;
00076         m[11]   = 0;
00077         m[12]   = 0;
00078         m[13]   = 0;
00079         m[14]   = 0;
00080         m[15]   = 0;
00081 }
00082 
00083 
00084 
00085 void
00086 matrix4_t::addTranslation
00087 (
00088 IN const point3d_t& t
00089 )
00090 throw()
00091 {
00092         m[ 3] += t.x;
00093         m[ 7] += t.y;
00094         m[11] += t.z;
00095 }
00096 
00097 
00098 
00099 void
00100 matrix4_t::setZRotation
00101 (
00102 IN float radians
00103 )
00104 throw()
00105 {
00106         float C = cos(radians);
00107         float S = sin(radians);
00108 
00109         // unroll loops...
00110         m[ 0]   = C;
00111         m[ 1]   = S;
00112         m[ 2]   = 0;
00113         m[ 3]   = 0;
00114         m[ 4]   = -S;
00115         m[ 5]   = C;
00116         m[ 6]   = 0;
00117         m[ 7]   = 0;
00118         m[ 8]   = 0;
00119         m[ 9]   = 0;
00120         m[10]   = 1;
00121         m[11]   = 0;
00122         m[12]   = 0;
00123         m[13]   = 0;
00124         m[14]   = 0;
00125         m[15]   = 1;
00126 }
00127 
00128 
00129 
00130 void
00131 matrix4_t::setXRotation
00132 (
00133 IN float radians
00134 )
00135 throw()
00136 {
00137         float C = cos(radians);
00138         float S = sin(radians);
00139 
00140         // unroll the loops...
00141         m[ 0]   = 1;
00142         m[ 1]   = 0;
00143         m[ 2]   = 0;
00144         m[ 3]   = 0;
00145         m[ 4]   = 0;
00146         m[ 5]   = C;
00147         m[ 6]   = S;
00148         m[ 7]   = 0;
00149         m[ 8]   = 0;
00150         m[ 9]   = -S;
00151         m[10]   = C;
00152         m[11]   = 0;
00153         m[12]   = 0;
00154         m[13]   = 0;
00155         m[14]   = 0;
00156         m[15]   = 1;
00157 }
00158 
00159 
00160 
00161 void
00162 matrix4_t::setYRotation
00163 (
00164 IN float radians
00165 )
00166 throw()
00167 {
00168         float C = cos(radians);
00169         float S = sin(radians);
00170 
00171         // unroll loops...
00172         m[ 0]   = C;
00173         m[ 1]   = 0;
00174         m[ 2]   = -S;
00175         m[ 3]   = 0;
00176         m[ 4]   = 0;
00177         m[ 5]   = 1;
00178         m[ 6]   = 0;
00179         m[ 7]   = 0;
00180         m[ 8]   = S;
00181         m[ 9]   = 0;
00182         m[10]   = C;
00183         m[11]   = 0;
00184         m[12]   = 0;
00185         m[13]   = 0;
00186         m[14]   = 0;
00187         m[15]   = 1;
00188 }
00189 
00190 
00191 
00192 void
00193 matrix4_t::setXYZScale
00194 (
00195 IN float r
00196 )
00197 throw()
00198 {
00199         // unroll the loops...
00200         m[ 0]   = r;
00201         m[ 1]   = 0;
00202         m[ 2]   = 0;
00203         m[ 3]   = 0;
00204         m[ 4]   = 0;
00205         m[ 5]   = r;
00206         m[ 6]   = 0;
00207         m[ 7]   = 0;
00208         m[ 8]   = 0;
00209         m[ 9]   = 0;
00210         m[10]   = r;
00211         m[11]   = 0;
00212         m[12]   = 0;
00213         m[13]   = 0;
00214         m[14]   = 0;
00215         m[15]   = 1;
00216 }
00217 
00218 
00219 
00220 void
00221 matrix4_t::dump
00222 (
00223 IN const char * txt
00224 )
00225 const
00226 throw()
00227 {
00228         ASSERT(txt, "null");
00229 
00230         DPRINTF("%s 4x4 matrix:", txt);
00231         for (int row = 0; row < 4; ++row) {
00232                 const float * p = m + 4 * row;
00233                 DPRINTF("  [ %6.3f  %6.3f  %6.3f  %6.3f ]",
00234                     p[0], p[1], p[2], p[3]);
00235         }
00236 }
00237 
00238 
00239 
00240 point3d_t
00241 matrix4_t::transform
00242 (
00243 IN const point3d_t& p
00244 )
00245 const
00246 throw()
00247 {
00248         point3d_t r(0.0, 0.0, 0.0);
00249         const float * pp = &p.x;
00250         for (int i = 0; i < 3; ++i) {
00251                 r.x += m[i] * pp[i];
00252                 r.y += m[4 + i] * pp[i];
00253                 r.z += m[8 + i] * pp[i];
00254         }
00255 
00256         r.x += m[ 3];
00257         r.y += m[ 7];
00258         r.z += m[11];
00259 
00260         return r;
00261 }
00262 
00263 
00264 
00265 void
00266 matrix4_t::setToProductOf
00267 (
00268 IN const matrix4_t& A,
00269 IN const matrix4_t& B
00270 )
00271 throw()
00272 {
00273         for (int i = 0; i < 4; ++i) {
00274                 for (int j = 0; j < 4; ++j) {
00275                         float * pM = m + 4 * i + j;
00276                         *pM = 0.0;
00277                         const float * pA = A.m + 4 * i;
00278                         const float * pB = B.m + j;
00279                         for (int k = 0; k < 4; ++k, pA++, pB += 4) {
00280                                 *pM += (*pA) * (*pB);
00281                         }
00282                 }
00283         }
00284 }
00285 
00286 
00287 
00288 void
00289 matrix4_t::addMatrix
00290 (
00291 IN const matrix4_t& A
00292 )
00293 throw()
00294 {
00295         // unroll the loops...
00296         m[ 0]   += A.m[ 0];
00297         m[ 1]   += A.m[ 1];
00298         m[ 2]   += A.m[ 2];
00299         m[ 3]   += A.m[ 3];
00300         m[ 4]   += A.m[ 4];
00301         m[ 5]   += A.m[ 5];
00302         m[ 6]   += A.m[ 6];
00303         m[ 7]   += A.m[ 7];
00304         m[ 8]   += A.m[ 8];
00305         m[ 9]   += A.m[ 9];
00306         m[10]   += A.m[10];
00307         m[11]   += A.m[11];
00308         m[12]   += A.m[12];
00309         m[13]   += A.m[13];
00310         m[14]   += A.m[14];
00311         m[15]   += A.m[15];
00312 }
00313 
00314 
00315 
00316 void
00317 matrix4_t::subtractMatrix
00318 (
00319 IN const matrix4_t& A
00320 )
00321 throw()
00322 {
00323         // unroll the loops...
00324         m[ 0]   -= A.m [0];
00325         m[ 1]   -= A.m[ 1];
00326         m[ 2]   -= A.m[ 2];
00327         m[ 3]   -= A.m[ 3];
00328         m[ 4]   -= A.m[ 4];
00329         m[ 5]   -= A.m[ 5];
00330         m[ 6]   -= A.m[ 6];
00331         m[ 7]   -= A.m[ 7];
00332         m[ 8]   -= A.m[ 8];
00333         m[ 9]   -= A.m[ 9];
00334         m[10]   -= A.m[10];
00335         m[11]   -= A.m[11];
00336         m[12]   -= A.m[12];
00337         m[13]   -= A.m[13];
00338         m[14]   -= A.m[14];
00339         m[15]   -= A.m[15];
00340 }
00341 
00342 
00343 
00344 void
00345 matrix4_t::transpose
00346 (
00347 void
00348 )
00349 throw()
00350 {
00351         // i: column loop
00352         for (int i = 0; i < 4; ++i) {
00353 
00354                 // j: row loop
00355                 for (int j = i + 1; j < 4; ++j) {
00356                         int i0 = 4 * i + j;
00357                         int i1 = 4 * j + i;
00358                         float tmp = m[i0];
00359                         m[i0] = m[i1];
00360                         m[i1] = tmp;
00361                 }
00362         }
00363 }
00364 
00365 
00366 
00367 void
00368 transformPoints
00369 (
00370 IN const matrix4_t& T,
00371 IN int N,
00372 IN const point3d_t * in,
00373 OUT point3d_t * out
00374 )
00375 {
00376         ASSERT(N >= 0, "Bad point count: %d", N);
00377         ASSERT(in, "null");
00378         ASSERT(out, "null");
00379 
00380         const point3d_t * p = in;
00381         point3d_t * q = out;
00382         for (int i = 0; i < N; ++i, ++p, ++q) {
00383                 *q = T * (*p);
00384         }
00385 }
00386