uiacceltk/hitchcock/coretoolkit/inc/Matrix.h
changeset 0 15bf7259bb7c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 #ifndef MATRIX_H
       
    19 #define MATRIX_H
       
    20 
       
    21 #include "Util.h"
       
    22 #include <string.h>
       
    23 #define _USE_MATH_DEFINES
       
    24 #include <math.h>
       
    25 
       
    26 namespace shadergen
       
    27 {
       
    28 
       
    29 static const float s_identityMatrix[16] =
       
    30 {
       
    31 	1.f, 0.f, 0.f, 0.f,
       
    32 	0.f, 1.f, 0.f, 0.f,
       
    33 	0.f, 0.f, 1.f, 0.f,
       
    34 	0.f, 0.f, 0.f, 1.f
       
    35 };
       
    36 
       
    37 #define EPSILON (.01f)
       
    38 
       
    39 /*!
       
    40  * \brief
       
    41  * Simple class for simulating OpenGL's matrix operations.
       
    42  */
       
    43 class Matrix
       
    44 {
       
    45 
       
    46 public:
       
    47 
       
    48 	/*!
       
    49 	 * \brief
       
    50 	 * Default constructor.
       
    51 	 *
       
    52 	 * \remarks
       
    53 	 * Does nothing. Could initialize the matrix to identity, but then
       
    54 	 * again, why would it? It only hides errors.
       
    55 	 */
       
    56 	Matrix (void)
       
    57 	{
       
    58 	}
       
    59 
       
    60 	Matrix (const Matrix& mat)
       
    61 	{
       
    62 		(*this) = mat;
       
    63 	}
       
    64 
       
    65 	const Matrix& operator= (const Matrix& mat)
       
    66 	{
       
    67 		memcpy(m, mat.m, 16 * sizeof(float));
       
    68 		return *this;
       
    69 	}
       
    70 
       
    71 	/*!
       
    72 	 * \brief
       
    73 	 * glLoadMatrix() implementation.
       
    74 	 * 
       
    75 	 * \param nm
       
    76 	 * Array of 16 floats.
       
    77 	 */
       
    78 	void loadMatrix (const float* nm)
       
    79 	{
       
    80 		memcpy(m, nm, 16 * sizeof(float));
       
    81 	}
       
    82 
       
    83 	/*!
       
    84 	 * \brief
       
    85 	 * glLoadIdentity() implementation
       
    86 	 */
       
    87 	void loadIdentity (void)
       
    88 	{
       
    89 		memcpy(m, s_identityMatrix, 16 * sizeof(float));
       
    90 	}
       
    91 
       
    92 	/*!
       
    93 	 * \brief
       
    94 	 * Check if the matrix is identity or not.
       
    95 	 * 
       
    96 	 * \returns
       
    97 	 * Returns true if the matrix is the identity matrix, false otherwise.
       
    98 	 */
       
    99 	bool isIdentity (void) const
       
   100 	{
       
   101 		return !memcmp(m, s_identityMatrix, 16 * sizeof(float));
       
   102 	}
       
   103 
       
   104 	/*!
       
   105 	 * \brief
       
   106 	 * glMultMatrix() implementation.
       
   107 	 * 
       
   108 	 * \param b
       
   109 	 * The other matrix, as floats.
       
   110 	 */
       
   111 	void multiply (const float* b)
       
   112 	{
       
   113 		float dst[16];
       
   114 		for (int i = 0; i < 4; i++)
       
   115 		{
       
   116 			for (int j = 0; j < 4; j++)
       
   117 			{
       
   118 				float sum = 0.f;
       
   119 				for (int k = 0; k < 4; k++)
       
   120 					sum += m[i + 4 * k] * b[k + 4 * j];
       
   121 
       
   122 				dst[i + 4 * j] = sum;
       
   123 			}
       
   124 		}
       
   125 
       
   126 		memcpy(m, dst, 16 * sizeof(float));
       
   127 	}
       
   128 
       
   129 	/*!
       
   130 	 * \brief
       
   131 	 * Sums given matrix (4x4) to this matrix (4x4).
       
   132 	 * 
       
   133 	 * \param b
       
   134 	 * The other matrix, as floats.
       
   135 	 */
       
   136 	void plus (const float* b)
       
   137 	{
       
   138 	    for (int i = 0; i < 4; i++)
       
   139 	    {
       
   140 	        for (int j = 0; j < 4; j++)
       
   141 	        {
       
   142 	            m[i + 4 * j] += b[i + 4 * j];
       
   143 	        }
       
   144 	    }
       
   145 	}
       
   146 
       
   147 	/*!
       
   148 	 * \brief
       
   149 	 * glScalef() implementation.
       
   150 	 * 
       
   151 	 * \param sx
       
   152 	 * X scale
       
   153 	 * 
       
   154 	 * \param sy
       
   155 	 * Y scale
       
   156 	 * 
       
   157 	 * \param sz
       
   158 	 * Z scale
       
   159 	 */
       
   160 	void scale (const float sx, const float sy, const float sz)
       
   161 	{
       
   162 		const float sm[16] =
       
   163 		{
       
   164 			sx, 0.f, 0.f, 0.f,
       
   165 			0.f,  sy, 0.f, 0.f,
       
   166 			0.f, 0.f,  sz, 0.f,
       
   167 			0.f, 0.f, 0.f, 1.f
       
   168 		};
       
   169 
       
   170 		multiply(sm);
       
   171 	}
       
   172 
       
   173 	/*!
       
   174 	 * \brief
       
   175 	 * glTranslatef() implementation.
       
   176 	 * 
       
   177 	 * \param tx
       
   178 	 * X component of the translation vector
       
   179 	 * 
       
   180 	 * \param ty
       
   181 	 * Y component of the translation vector
       
   182 	 * 
       
   183 	 * \param tz
       
   184 	 * Z component of the translation vector
       
   185 	 */
       
   186 	void translate (const float tx, const float ty, const float tz)
       
   187 	{
       
   188 		const float tm[16] =
       
   189 		{
       
   190 			1.f, 0.f, 0.f, 0.f,
       
   191 			0.f, 1.f, 0.f, 0.f,
       
   192 			0.f, 0.f, 1.f, 0.f,
       
   193 			tx,  ty,  tz,  1.f
       
   194 		};
       
   195 
       
   196 		multiply(tm);
       
   197 	}
       
   198 
       
   199 	/*!
       
   200 	 * \brief
       
   201 	 * glRotatef() implementation
       
   202 	 * 
       
   203 	 * \param angle
       
   204 	 * The amount of rotation
       
   205 	 * 
       
   206 	 * \param x
       
   207 	 * X component of the axis about which to rotate
       
   208 	 * 
       
   209 	 * \param y
       
   210 	 * Y component of the axis about which to rotate
       
   211 	 * 
       
   212 	 * \param z
       
   213 	 * Z component of the axis about which to rotate
       
   214 	 */
       
   215 	void rotate (const float angle, const float x, const float y, const float z)
       
   216 	{
       
   217 		static const float deg_to_rad = 2.f * (float)M_PI / 360.f;
       
   218 		// normalised vector components
       
   219 		float x_n;
       
   220 		float y_n;
       
   221 		float z_n;
       
   222 		float angle_rad = angle * deg_to_rad;
       
   223 
       
   224 		// normalise if needed
       
   225 		const float length = (float)sqrt(double(x * x) + 
       
   226 					  double(y * y) + 
       
   227 					  double(z * z));
       
   228 		if(fabs(length - 1.0f) > EPSILON) {
       
   229 			// in fp calculations, division by zero -> (+/-)inf
       
   230 			// can't really help if it's the case.
       
   231 			const float inv_length = 1.f / length;
       
   232 			x_n = x * inv_length;
       
   233 			y_n = y * inv_length;
       
   234 			z_n = z * inv_length;
       
   235 		} else {
       
   236 			x_n = x;
       
   237 			y_n = y;
       
   238 			z_n = z;
       
   239 		}
       
   240 
       
   241 		const float c = cos(angle_rad);
       
   242 		const float s = sin(angle_rad);
       
   243 		const float c_1 = 1.f - c;
       
   244 
       
   245 		const float rm[16] =
       
   246 		{
       
   247 	x_n * x_n * c_1 + c,	   y_n * x_n * c_1 + z_n * s, x_n * z_n * c_1 - y_n * s, 0.f,
       
   248 	x_n * y_n * c_1 - z_n * s, y_n * y_n * c_1 + c,	      y_n * z_n * c_1 + x_n * s, 0.f,
       
   249 	x_n * z_n * c_1 + y_n * s, y_n * z_n * c_1 - x_n * s, z_n * z_n * c_1 + c,	 0.f,
       
   250 	0.f, 			   0.f,			      0.f,		   	 1.f
       
   251 
       
   252 		};
       
   253 
       
   254 		multiply(rm);
       
   255 	}
       
   256 
       
   257 	/*!
       
   258 	 * \brief
       
   259 	 * glFrustumf() implementation
       
   260 	 * 
       
   261 	 * \param l
       
   262 	 * Left
       
   263 	 * 
       
   264 	 * \param r
       
   265 	 * Right
       
   266 	 * 
       
   267 	 * \param b
       
   268 	 * Bottom
       
   269 	 * 
       
   270 	 * \param t
       
   271 	 * Top
       
   272 	 * 
       
   273 	 * \param n
       
   274 	 * Near
       
   275 	 * 
       
   276 	 * \param f
       
   277 	 * Far
       
   278 	 */
       
   279 	void frustum (const float l, const float r, const float b, const float t, const float n, const float f)
       
   280 	{
       
   281 		SG_ASSERT(r != l);
       
   282 		SG_ASSERT(t != b);
       
   283 		SG_ASSERT(n != f);
       
   284 
       
   285 		const float rl = 1.f / (r - l);
       
   286 		const float tb = 1.f / (t - b);
       
   287 		const float fn = 1.f / (f - n);
       
   288 
       
   289 		const float A = (r + l) * rl;
       
   290 		const float B = (t + b) * tb;
       
   291 		const float C = -(f + n) * fn; 
       
   292 		const float D = -2.f * f * n * fn;
       
   293 
       
   294 		const float fm[16] =
       
   295 		{
       
   296 			2.f * n * rl,	0.f, 		0.f,	0.f,
       
   297 			0.f,		2.f * n * tb,	0.f,	0.f,
       
   298 			A,		B,		C,	-1.f,
       
   299 			0.f,		0.f,		D,	0.f
       
   300 		};
       
   301 		
       
   302 		multiply(fm);
       
   303 	}
       
   304 
       
   305 	/*!
       
   306 	 * \brief
       
   307 	 * glOrthof() implementation
       
   308 	 * 
       
   309 	 * \param l
       
   310 	 * Left
       
   311 	 * 
       
   312 	 * \param r
       
   313 	 * Right
       
   314 	 * 
       
   315 	 * \param b
       
   316 	 * Bottom
       
   317 	 * 
       
   318 	 * \param t
       
   319 	 * Top
       
   320 	 * 
       
   321 	 * \param n
       
   322 	 * Near
       
   323 	 * 
       
   324 	 * \param f
       
   325 	 * Far
       
   326 	 */
       
   327 	void ortho (const float l, const float r, const float b, const float t, const float n, const float f)
       
   328 	{
       
   329 		SG_ASSERT(r != l);
       
   330 		SG_ASSERT(t != b);
       
   331 		SG_ASSERT(n != f);
       
   332 
       
   333 		const float rl = 1.f / (r - l);
       
   334 		const float tb = 1.f / (t - b);
       
   335 		const float fn = 1.f / (f - n);
       
   336 
       
   337 		const float tx = -(r + l) * rl;
       
   338 		const float ty = -(t + b) * tb;
       
   339 		const float tz = -(f + n) * fn;
       
   340 
       
   341 		const float om[16] = 
       
   342 		{
       
   343 			2.f * rl,	0.f,		0.f,		0.f,
       
   344 			0.f,		2.f * tb,	0.f,		0.f,
       
   345 			0.f,		0.f,		-2.f * fn,	0.f,
       
   346 			tx,		ty,		tz,		1.f
       
   347 		};
       
   348 
       
   349 		multiply(om);
       
   350 	}
       
   351 
       
   352 
       
   353 	/*!
       
   354 	 * \brief
       
   355 	 * Returns pointer to floats making up the matrix. Suitable for 
       
   356 	 * glLoadMatrix().
       
   357 	 */
       
   358 	const float *getMatrix(void) const {
       
   359 		return m;
       
   360 	}
       
   361 
       
   362 
       
   363 private:
       
   364 	
       
   365 	float m[16];
       
   366 };
       
   367 
       
   368 
       
   369 } /* namespace shadergen */
       
   370 
       
   371 #endif /* MATRIX_H */