PageRenderTime 53ms CodeModel.GetById 15ms app.highlight 33ms RepoModel.GetById 1ms app.codeStats 0ms

/opengles/src/linalg.h

http://ftk.googlecode.com/
C++ Header | 855 lines | 428 code | 150 blank | 277 comment | 9 complexity | f3cb75fe7ecce2b010b48c1dbf96bb71 MD5 | raw file
  1#ifndef EGL_LINALG_H
  2#define EGL_LINALG_H 1
  3
  4// ==========================================================================
  5//
  6// linalg.h	Implementation of Linear Algebra using Fixed Point Arithmetic
  7//
  8// --------------------------------------------------------------------------
  9//
 10// 10-02-2003	Hans-Martin Will	initial version
 11//
 12// --------------------------------------------------------------------------
 13//
 14// Copyright (c) 2004, Hans-Martin Will. All rights reserved.
 15// 
 16// Redistribution and use in source and binary forms, with or without 
 17// modification, are permitted provided that the following conditions are 
 18// met:
 19// 
 20//	 *  Redistributions of source code must retain the above copyright
 21// 		notice, this list of conditions and the following disclaimer. 
 22//   *	Redistributions in binary form must reproduce the above copyright
 23// 		notice, this list of conditions and the following disclaimer in the 
 24// 		documentation and/or other materials provided with the distribution. 
 25// 
 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 27// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 29// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 30// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
 31// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 32// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 33// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 34// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 35// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
 36// THE POSSIBILITY OF SUCH DAMAGE.
 37//
 38// ==========================================================================
 39
 40
 41#include "OGLES.h"
 42#include "fixed.h"
 43
 44namespace EGL {
 45
 46	// --------------------------------------------------------------------------
 47	// 3-D Vector class
 48	// --------------------------------------------------------------------------
 49
 50
 51	class Vec3D {
 52
 53		// element names compatible to GPP_VEC3D
 54		EGL_Fixed 	m_x, m_y, m_z;
 55
 56	public:
 57		// ----------------------------------------------------------------------
 58		// Constructor
 59		// ----------------------------------------------------------------------
 60		inline Vec3D() {
 61			m_x = m_y = m_z = 0;
 62		}
 63
 64		// ----------------------------------------------------------------------
 65		// Constructor
 66		//
 67		// Parameters:
 68		//	x, y, z			-	individual coordinates of 3-D vector
 69		// ----------------------------------------------------------------------
 70		inline Vec3D(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z) {
 71			m_x = x;
 72			m_y = y;
 73			m_z = z;
 74		}
 75
 76		// ----------------------------------------------------------------------
 77		// Constructor
 78		//
 79		// Parameters:
 80		//	coords			-	individual coordinates of 3-D vector
 81		// ----------------------------------------------------------------------
 82		inline Vec3D(const EGL_Fixed * coords) {
 83			m_x = coords[0];
 84			m_y = coords[1];
 85			m_z = coords[2];
 86		}
 87
 88		// ----------------------------------------------------------------------
 89		// Copy constructor
 90		// ----------------------------------------------------------------------
 91		inline Vec3D(const Vec3D& other) {
 92			m_x = other.m_x;
 93			m_y = other.m_y;
 94			m_z = other.m_z;
 95		}
 96
 97		// ----------------------------------------------------------------------
 98		// Assignment operator
 99		// ----------------------------------------------------------------------
100		inline Vec3D& operator=(const Vec3D& other) {
101			m_x = other.m_x;
102			m_y = other.m_y;
103			m_z = other.m_z;
104			return *this;
105		}
106
107		// ----------------------------------------------------------------------
108		// Vector addition
109		// ----------------------------------------------------------------------
110		inline Vec3D operator+(const Vec3D& other) const {
111			return Vec3D(m_x + other.m_x, m_y + other.m_y, m_z + other.m_z);
112		}
113
114		inline Vec3D& operator +=(const Vec3D& other) {
115			m_x += other.m_x;
116			m_y += other.m_y;
117			m_z += other.m_z;
118			return *this;
119		}
120
121		inline Vec3D operator-(const Vec3D& other) const {
122			return Vec3D(m_x - other.m_x, m_y - other.m_y, m_z - other.m_z);
123		}
124
125		inline Vec3D& operator -=(const Vec3D& other) {
126			m_x -= other.m_x;
127			m_y -= other.m_y;
128			m_z -= other.m_z;
129			return *this;
130		}
131
132		// ----------------------------------------------------------------------
133		// Scaling of vector
134		//
135		// Parameters:
136		//	factor		-	scale factor
137		// ----------------------------------------------------------------------
138		inline Vec3D operator*(EGL_Fixed factor) const {
139			return Vec3D(EGL_Mul(m_x, factor), 
140							EGL_Mul(m_y, factor),
141							EGL_Mul(m_z, factor));
142		}
143
144		inline Vec3D& operator *=(EGL_Fixed factor) {
145			m_x = EGL_Mul(m_x, factor);
146			m_y = EGL_Mul(m_y, factor);
147			m_z = EGL_Mul(m_z, factor);
148			return *this;
149		}
150
151		// ----------------------------------------------------------------------
152		// Dot product between two vectors
153		//
154		// Parameters:
155		//	other		-	second operand
156		// ----------------------------------------------------------------------
157		inline EGL_Fixed operator*(const Vec3D& other) const {
158			return EGL_Mul(m_x, other.m_x) +
159				EGL_Mul(m_y, other.m_y) +
160				EGL_Mul(m_z, other.m_z);
161		}
162
163		// ----------------------------------------------------------------------
164		// Cross product for two vectors
165		//
166		// Parameters:
167		//	other		-	second operand
168		// ----------------------------------------------------------------------
169		inline Vec3D Cross(const Vec3D& other) const {
170			return Vec3D(EGL_Mul(m_y, other.m_z) - EGL_Mul(m_z, other.m_y),
171				-EGL_Mul(m_x, other.m_z) + EGL_Mul(m_z, other.m_x),
172				EGL_Mul(m_x, other.m_y) - EGL_Mul(m_y, other.m_x));
173		}
174
175		// ----------------------------------------------------------------------
176		// Euclidean length of vector
177		// ----------------------------------------------------------------------
178		inline EGL_Fixed Length() const {
179			return EGL_Sqrt(LengthSq());
180		}
181
182		// ----------------------------------------------------------------------
183		// Square of Euclidean length of vector
184		// ----------------------------------------------------------------------
185		inline EGL_Fixed LengthSq() const {
186			return (*this) * (*this);
187		}
188
189		// ----------------------------------------------------------------------
190		// Normalize the vector to unit length
191		// ----------------------------------------------------------------------
192		inline void Normalize() {
193			*this *= EGL_InvSqrt(LengthSq());
194		}
195
196		// ----------------------------------------------------------------------
197		// Element accessors
198		// ----------------------------------------------------------------------
199
200		inline EGL_Fixed x() const {
201			return m_x;
202		}
203
204		inline EGL_Fixed y() const {
205			return m_y;
206		}
207
208		inline EGL_Fixed z() const {
209			return m_z;
210		}
211
212		inline void setX(EGL_Fixed value) {
213			m_x = value;
214		}
215
216		inline void setY(EGL_Fixed value) {
217			m_y = value;
218		}
219
220		inline void setZ(EGL_Fixed value) {
221			m_z = value;
222		}
223	};
224
225
226	inline OGLES_API Vec3D operator*(EGL_Fixed factor, const Vec3D& vector) {
227		return vector * factor;
228	}
229
230
231
232	// --------------------------------------------------------------------------
233	// 4-D Vector class
234	// --------------------------------------------------------------------------
235
236
237	class Vec4D {
238
239		// element names compatible to GPP_VEC4D
240		EGL_Fixed 	m_x, m_y, m_z, m_w;
241
242	public:
243		// ----------------------------------------------------------------------
244		// Constructor
245		// ----------------------------------------------------------------------
246		inline Vec4D() {
247			m_x = m_y = m_z = 0;
248			m_w = 1;
249		}
250
251		// ----------------------------------------------------------------------
252		// Constructor, canonical embedding of R^3 in SO^2
253		//
254		// Parameters:
255		//	x, y, z			-	individual coordinates of 3-D vector
256		// ----------------------------------------------------------------------
257		inline Vec4D(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z) {
258			m_x = x;
259			m_y = y;
260			m_z = z;
261			m_w = EGL_ONE;
262		}
263
264		// ----------------------------------------------------------------------
265		// Constructor
266		//
267		// Parameters:
268		//	coords			-	individual coordinates of 3-D vector
269		// ----------------------------------------------------------------------
270		inline Vec4D(const EGL_Fixed * coords) {
271			m_x = coords[0];
272			m_y = coords[1];
273			m_z = coords[2];
274			m_w = coords[3];
275		}
276
277		// ----------------------------------------------------------------------
278		// Constructor
279		//
280		// Parameters:
281		//	x, y, z, w			-	individual coordinates of 4-D vector
282		// ----------------------------------------------------------------------
283		inline Vec4D(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z, EGL_Fixed w) {
284			m_x = x;
285			m_y = y;
286			m_z = z;
287			m_w = w;
288		}
289
290		// ----------------------------------------------------------------------
291		// Copy constructor
292		// ----------------------------------------------------------------------
293		inline Vec4D(const Vec4D& other) {
294			m_x = other.m_x;
295			m_y = other.m_y;
296			m_z = other.m_z;
297			m_w = other.m_w;
298		}
299
300
301		// ----------------------------------------------------------------------
302		// Assignment operator
303		// ----------------------------------------------------------------------
304		inline Vec4D& operator=(const Vec4D& other) {
305			m_x = other.m_x;
306			m_y = other.m_y;
307			m_z = other.m_z;
308			m_w = other.m_w;
309			return *this;
310		}
311
312		// ----------------------------------------------------------------------
313		// Projection operator
314		// ----------------------------------------------------------------------
315		inline operator Vec3D() const {
316			EGL_Fixed factor = EGL_Inverse(m_w);
317
318			return Vec3D(EGL_Mul(m_x, factor), EGL_Mul(m_y, factor), EGL_Mul(m_z, factor));
319		}
320
321		// ----------------------------------------------------------------------
322		// Projection operator
323		// ----------------------------------------------------------------------
324		inline Vec3D Project() const {
325			return Vec3D(m_x, m_y, m_z);
326		}
327
328		// ----------------------------------------------------------------------
329		// Vector addition
330		// ----------------------------------------------------------------------
331		inline Vec4D operator+(const Vec4D& other) const {
332			return Vec4D(m_x + other.m_x, m_y + other.m_y, m_z + other.m_z, m_w + other.m_w);
333		}
334
335		inline Vec4D& operator +=(const Vec4D& other) {
336			m_x += other.m_x;
337			m_y += other.m_y;
338			m_z += other.m_z;
339			m_w += other.m_w;
340			return *this;
341		}
342
343		inline Vec4D operator-(const Vec4D& other) const {
344			return Vec4D(m_x - other.m_x, m_y - other.m_y, m_z - other.m_z, m_w - other.m_w);
345		}
346
347		inline Vec4D& operator -=(const Vec4D& other) {
348			m_x -= other.m_x;
349			m_y -= other.m_y;
350			m_z -= other.m_z;
351			m_w -= other.m_w;
352			return *this;
353		}
354
355		inline Vec4D operator-() const {
356			return Vec4D(-m_x, -m_y, -m_z, -m_w);
357		}
358
359		// ----------------------------------------------------------------------
360		// Scaling of vector
361		//
362		// Parameters:
363		//	factor		-	scale factor
364		// ----------------------------------------------------------------------
365		inline Vec4D operator*(EGL_Fixed factor) const {
366			return Vec4D(EGL_Mul(m_x, factor), 
367							EGL_Mul(m_y, factor),
368							EGL_Mul(m_z, factor),
369							EGL_Mul(m_w, factor));
370		}
371
372		inline Vec4D& operator *=(EGL_Fixed factor) {
373			m_x = EGL_Mul(m_x, factor);
374			m_y = EGL_Mul(m_y, factor);
375			m_z = EGL_Mul(m_z, factor);
376			m_w = EGL_Mul(m_w, factor);
377
378			return *this;
379		}
380
381		// ----------------------------------------------------------------------
382		// Dot product between two vectors
383		//
384		// Parameters:
385		//	other		-	second operand
386		// ----------------------------------------------------------------------
387		inline EGL_Fixed operator*(const Vec4D& other) const {
388			return EGL_Mul(m_x, other.m_x) +
389				EGL_Mul(m_y, other.m_y) +
390				EGL_Mul(m_z, other.m_z) +
391				EGL_Mul(m_w, other.m_w);
392		}
393
394		inline I64 longProduct(const Vec4D& other) const {
395			return 
396				(static_cast<I64>(m_x) * static_cast<I64>(other.m_x) +
397				 static_cast<I64>(m_y) * static_cast<I64>(other.m_y) +
398				 static_cast<I64>(m_z) * static_cast<I64>(other.m_z) +
399				 static_cast<I64>(m_w) * static_cast<I64>(other.m_w)) >> EGL_PRECISION;
400		}
401
402		// ----------------------------------------------------------------------
403		// Euclidean length of vector
404		// ----------------------------------------------------------------------
405		inline EGL_Fixed Length() const {
406			return EGL_Sqrt(LengthSq());
407		}
408
409		// ----------------------------------------------------------------------
410		// Square of Euclidean length of vector
411		// ----------------------------------------------------------------------
412		inline EGL_Fixed LengthSq() const {
413			return (*this) * (*this);
414		}
415
416		// ----------------------------------------------------------------------
417		// Normalize the vector to unit length
418		// ----------------------------------------------------------------------
419		inline void Normalize() {
420			*this *= EGL_InvSqrt(LengthSq());
421		}
422
423		// ----------------------------------------------------------------------
424		// Element accessors
425		// ----------------------------------------------------------------------
426
427		inline EGL_Fixed x() const {
428			return m_x;
429		}
430
431		inline EGL_Fixed y() const {
432			return m_y;
433		}
434
435		inline EGL_Fixed z() const {
436			return m_z;
437		}
438
439		inline EGL_Fixed w() const {
440			return m_w;
441		}
442
443		inline void setX(EGL_Fixed value) {
444			m_x = value;
445		}
446
447		inline void setY(EGL_Fixed value) {
448			m_y = value;
449		}
450
451		inline void setZ(EGL_Fixed value) {
452			m_z = value;
453		}
454
455		inline void setW(EGL_Fixed value) {
456			m_w = value;
457		}
458	};
459
460
461	inline OGLES_API Vec3D EGL_Direction(const Vec4D& from, const Vec4D& to) {
462		Vec3D result (EGL_Mul(to.x(), from.w()) - EGL_Mul(from.x(), to.w()),
463			EGL_Mul(to.y(), from.w()) - EGL_Mul(from.y(), to.w()),
464			EGL_Mul(to.z(), from.w()) - EGL_Mul(from.z(), to.w()));
465
466		return result;
467	}
468
469	inline OGLES_API Vec4D operator*(EGL_Fixed factor, const Vec4D& vector) {
470		return vector * factor;
471	}
472
473
474	// --------------------------------------------------------------------------
475	// 4x4 Matrix class
476	// --------------------------------------------------------------------------
477
478
479	class Matrix4x4 {
480
481		enum {
482			ROWS = 4,			// number of rows per matrix
483			COLUMNS = 4,		// number of columns per matrix
484			ELEMENTS = 16,		// total number of elements
485		};
486
487		EGL_Fixed m_elements[16];
488		bool m_identity;		// flag to mark identity matrix
489
490	public:
491		// ----------------------------------------------------------------------
492		// This function effectively defines the order in which individual
493		// matrix elements are stored in the underlying 1-D vector.
494		//
495		// Parameters:
496		//	row			- row index into the matrix
497		//	column		- column index into the matrix
498		//
499		// Returns:
500		//	Reference to the indexed matrix element
501		// ----------------------------------------------------------------------
502		inline EGL_Fixed& Element(int row, int column) {
503			return m_elements[row + column * ROWS]; 
504		}
505
506		inline const EGL_Fixed& Element(int row, int column) const {
507			return m_elements[row + column * ROWS]; 
508		}
509
510		inline EGL_Fixed& Element(int index) {
511			return m_elements[index]; 
512		}
513
514		inline const EGL_Fixed& Element(int index) const {
515			return m_elements[index]; 
516		}
517
518		inline bool IsIdentity() const {
519			return m_identity;
520		}
521
522		// ----------------------------------------------------------------------
523		// Default constructor: Initialize the matrix as identity matrix
524		// ----------------------------------------------------------------------
525		inline Matrix4x4() {
526			MakeIdentity();
527		}
528
529
530		// ----------------------------------------------------------------------
531		// Construct matrix from vector of elements
532		//
533		// Parameters:
534		//	elements		-	Pointer to array of elements, which are stored
535		//						column by column
536		// ----------------------------------------------------------------------
537		inline Matrix4x4(const EGL_Fixed * elements) {
538			for (int index = 0; index < ELEMENTS; ++index) {
539				m_elements[index] = elements[index];
540			}
541
542			m_identity = false;
543		}
544
545
546		// ----------------------------------------------------------------------
547		// Construct matrix from individual elements
548		//
549		// Parameters:
550		//	m00,...,m33		-	mij specifies the value of Element(i, j)
551		// ----------------------------------------------------------------------
552		inline Matrix4x4(EGL_Fixed m00, EGL_Fixed m01, EGL_Fixed m02, EGL_Fixed m03,
553							EGL_Fixed m10, EGL_Fixed m11, EGL_Fixed m12, EGL_Fixed m13,
554							EGL_Fixed m20, EGL_Fixed m21, EGL_Fixed m22, EGL_Fixed m23,
555							EGL_Fixed m30, EGL_Fixed m31, EGL_Fixed m32, EGL_Fixed m33) {
556
557			Element(0, 0) = m00;
558			Element(1, 0) = m10;
559			Element(2, 0) = m20;
560			Element(3, 0) = m30;
561
562			Element(0, 1) = m01;
563			Element(1, 1) = m11;
564			Element(2, 1) = m21;
565			Element(3, 1) = m31;
566
567			Element(0, 2) = m02;
568			Element(1, 2) = m12;
569			Element(2, 2) = m22;
570			Element(3, 2) = m32;
571
572			Element(0, 3) = m03;
573			Element(1, 3) = m13;
574			Element(2, 3) = m23;
575			Element(3, 3) = m33;
576
577			m_identity = false;
578		}
579
580
581		// ----------------------------------------------------------------------
582		// Copy constructor
583		// ----------------------------------------------------------------------
584		inline Matrix4x4(const Matrix4x4& other) {
585			for (int index = 0; index < ELEMENTS; ++index) {
586				m_elements[index] = other.m_elements[index];
587			}
588
589			m_identity = other.m_identity;
590		}
591
592
593		// ----------------------------------------------------------------------
594		// Assignment operator
595		// ----------------------------------------------------------------------
596		inline Matrix4x4& operator=(const Matrix4x4& other) {
597			for (int index = 0; index < ELEMENTS; ++index) {
598				m_elements[index] = other.m_elements[index];
599			}
600
601			m_identity = other.m_identity;
602
603			return *this;
604		}
605
606
607		// ----------------------------------------------------------------------
608		// Reset matrix to be an identity matrix
609		// ----------------------------------------------------------------------
610		inline void MakeIdentity() {
611			Element(0, 0) = Element(1, 1) = Element(2, 2) = Element(3, 3) = EGL_ONE;
612			Element(0, 1) = Element(0, 2) = Element(0, 3) = 0;
613			Element(1, 0) = Element(1, 2) = Element(1, 3) = 0;
614			Element(2, 0) = Element(2, 1) = Element(2, 3) = 0;
615			Element(3, 0) = Element(3, 1) = Element(3, 2) = 0;
616			m_identity = true;
617		}
618
619
620		// ----------------------------------------------------------------------
621		// Matrix multiplication as (*this) * other
622		//
623		// Parameters:
624		//	other		-	RHS in matrix multiplication
625		// ----------------------------------------------------------------------
626		inline Matrix4x4 operator*(const Matrix4x4& other) const {
627			Matrix4x4 result;
628
629			for (int i = 0; i < ROWS; ++i) {
630				for (int j = 0; j < COLUMNS; ++j) {
631					EGL_Fixed sum = 0;
632
633					for (int k = 0; k < COLUMNS; ++k) {
634						sum += EGL_Mul(Element(i, k), other.Element(k, j));
635					}
636
637					result.Element(i, j) = sum;
638				}
639			}
640
641			result.m_identity = m_identity && other.m_identity;
642			return result;
643		}
644
645
646		// ----------------------------------------------------------------------
647		// Transform a 3-D vector using this matrix. The vector is extended
648		// with a homogenuous coordinate of 1 before being multiplied.
649		//
650		// Parameters:
651		//	vector		-	The vector to be transformed
652		// ----------------------------------------------------------------------
653		inline Vec4D operator*(const Vec3D& vector) const {
654			return Vec4D(
655				EGL_Mul(vector.x(), Element(0, 0)) +
656				EGL_Mul(vector.y(), Element(0, 1)) +
657				EGL_Mul(vector.z(), Element(0, 2)) +
658				Element(0, 3),
659
660				EGL_Mul(vector.x(), Element(1, 0)) +
661				EGL_Mul(vector.y(), Element(1, 1)) +
662				EGL_Mul(vector.z(), Element(1, 2)) +
663				Element(1, 3),
664
665				EGL_Mul(vector.x(), Element(2, 0)) +
666				EGL_Mul(vector.y(), Element(2, 1)) +
667				EGL_Mul(vector.z(), Element(2, 2)) +
668				Element(2, 3),
669
670				EGL_Mul(vector.x(), Element(3, 0)) +
671				EGL_Mul(vector.y(), Element(3, 1)) +
672				EGL_Mul(vector.z(), Element(3, 2)) +
673				Element(3, 3));
674		}
675
676
677		// ----------------------------------------------------------------------
678		// Transform a 3-D vector using this matrix using only the upper right
679		// 3x3 sub-matrix. The vector is extended
680		// with a homogenuous coordinate of 1 before being multiplied.
681		//
682		// Parameters:
683		//	vector		-	The vector to be transformed
684		// ----------------------------------------------------------------------
685		inline Vec3D Multiply3x3(const Vec3D& vector) const {
686			return Vec3D(
687				EGL_Mul(vector.x(), Element(0, 0)) +
688				EGL_Mul(vector.y(), Element(0, 1)) +
689				EGL_Mul(vector.z(), Element(0, 2)),
690
691				EGL_Mul(vector.x(), Element(1, 0)) +
692				EGL_Mul(vector.y(), Element(1, 1)) +
693				EGL_Mul(vector.z(), Element(1, 2)),
694
695				EGL_Mul(vector.x(), Element(2, 0)) +
696				EGL_Mul(vector.y(), Element(2, 1)) +
697				EGL_Mul(vector.z(), Element(2, 2)));
698		}
699
700
701
702		// ----------------------------------------------------------------------
703		// Return the Z coordinate after transformation using this matrix
704		// Used for fog calculation, which requires eye distance
705		// ----------------------------------------------------------------------
706		inline EGL_Fixed GetTransformedZ(const Vec3D& vector) const {
707			return
708				EGL_Mul(vector.x(), Element(2, 0)) +
709				EGL_Mul(vector.y(), Element(2, 1)) +
710				EGL_Mul(vector.z(), Element(2, 2)) +
711				Element(2, 3);
712		}
713
714
715		// ----------------------------------------------------------------------
716		// Transform a 4-D vector using this matrix. 
717		//
718		// Parameters:
719		//	vector		-	The vector to be transformed
720		// ----------------------------------------------------------------------
721		inline Vec4D operator*(const Vec4D& vector) const {
722			return Vec4D(
723				EGL_Mul(vector.x(), Element(0, 0)) +
724				EGL_Mul(vector.y(), Element(0, 1)) +
725				EGL_Mul(vector.z(), Element(0, 2)) +
726				EGL_Mul(vector.w(), Element(0, 3)),
727
728				EGL_Mul(vector.x(), Element(1, 0)) +
729				EGL_Mul(vector.y(), Element(1, 1)) +
730				EGL_Mul(vector.z(), Element(1, 2)) +
731				EGL_Mul(vector.w(), Element(1, 3)),
732
733				EGL_Mul(vector.x(), Element(2, 0)) +
734				EGL_Mul(vector.y(), Element(2, 1)) +
735				EGL_Mul(vector.z(), Element(2, 2)) +
736				EGL_Mul(vector.w(), Element(2, 3)),
737
738				EGL_Mul(vector.x(), Element(3, 0)) +
739				EGL_Mul(vector.y(), Element(3, 1)) +
740				EGL_Mul(vector.z(), Element(3, 2)) +
741				EGL_Mul(vector.w(), Element(3, 3)));
742		}
743
744
745		inline void Multiply(const Vec4D& vector, Vec4D& result) const {
746			result = Vec4D(
747				EGL_Mul(vector.x(), Element(0, 0)) +
748				EGL_Mul(vector.y(), Element(0, 1)) +
749				EGL_Mul(vector.z(), Element(0, 2)) +
750				EGL_Mul(vector.w(), Element(0, 3)),
751
752				EGL_Mul(vector.x(), Element(1, 0)) +
753				EGL_Mul(vector.y(), Element(1, 1)) +
754				EGL_Mul(vector.z(), Element(1, 2)) +
755				EGL_Mul(vector.w(), Element(1, 3)),
756
757				EGL_Mul(vector.x(), Element(2, 0)) +
758				EGL_Mul(vector.y(), Element(2, 1)) +
759				EGL_Mul(vector.z(), Element(2, 2)) +
760				EGL_Mul(vector.w(), Element(2, 3)),
761
762				EGL_Mul(vector.x(), Element(3, 0)) +
763				EGL_Mul(vector.y(), Element(3, 1)) +
764				EGL_Mul(vector.z(), Element(3, 2)) +
765				EGL_Mul(vector.w(), Element(3, 3)));
766		}
767
768
769		// ----------------------------------------------------------------------
770		// Calculate the matrix for which the upper left 3x3 matrix is the 
771		// inverse of the upper left 3x3 matrix of the receiver canconically
772		// embedded into 4-dimensional space
773		// ----------------------------------------------------------------------
774		Matrix4x4 InverseUpper3(bool rescale) const;
775
776		// ----------------------------------------------------------------------
777		// Compute general inverse of a 4 by 4 matrix
778		// ----------------------------------------------------------------------
779		Matrix4x4 Inverse() const;
780
781		Matrix4x4 Transpose() const {
782			Matrix4x4 result;
783
784			for (int i = 0; i < ROWS; ++i) {
785				for (int j = 0; j < COLUMNS; ++j) {
786					result.Element(i, j) = Element(j, i);
787				}
788			}
789
790			result.m_identity = m_identity;
791			return result;
792		}
793
794		// ----------------------------------------------------------------------
795		// Create a transformation matrix that scales in x, y and z direction
796		// according to the given scale factors.
797		//
798		// Parameters:
799		//	x			-	scale factor in x direction
800		//	y			-	scale factor in y direction
801		//	z			-	scale factor in z direction
802		// ----------------------------------------------------------------------
803		static Matrix4x4 CreateScale(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z);
804
805
806		// ----------------------------------------------------------------------
807		// Create a transformation matrix that rotates around the axis specified
808		// by x, and and z by a the given angle.
809		//
810		// Parameters:
811		//	angle		-	the angle in degrees
812		//  x, y, z		-	the direction of the axis as vector from the origin
813		// ----------------------------------------------------------------------
814		static Matrix4x4 CreateRotate(EGL_Fixed angle, EGL_Fixed x, 
815			EGL_Fixed y, EGL_Fixed z);
816
817
818		// ----------------------------------------------------------------------
819		// Create a transformation matrix that translates in x, y and z direction
820		// according to the given translation values.
821		//
822		// Parameters:
823		//	x			-	translation in x direction
824		//	y			-	translation in y direction
825		//	z			-	translation in z direction
826		// ----------------------------------------------------------------------
827		static Matrix4x4 CreateTranslate(EGL_Fixed x, EGL_Fixed y, EGL_Fixed z);
828
829
830		// ----------------------------------------------------------------------
831		// Create a transformation matrix for a perspective projection of the
832		// cube described by its corners into the unit volume.
833		//
834		// Parameters:
835		//	l, b, -n	- lower left point to be mapped into lower left front
836		//  r, t, -f	- upper right point and maximum depth coordinate
837		// ----------------------------------------------------------------------
838		static Matrix4x4 CreateFrustrum(EGL_Fixed left, EGL_Fixed right, 
839			EGL_Fixed bottom, EGL_Fixed top, EGL_Fixed zNear, EGL_Fixed zFar);
840
841
842		// ----------------------------------------------------------------------
843		// Create a transformation matrix for an orthographic projection of the
844		// cube described by its corners into the unit volume.
845		//
846		// Parameters:
847		//	l, b, -n	- lower left point to be mapped into lower left front
848		//  r, t, -f	- upper right point and maximum depth coordinate
849		// ----------------------------------------------------------------------
850		static Matrix4x4 CreateOrtho(EGL_Fixed left, EGL_Fixed right, 
851			EGL_Fixed bottom, EGL_Fixed top, EGL_Fixed zNear, EGL_Fixed zFar);
852	};
853}
854
855#endif // ndef EGL_LINALG_H