Home | History | Annotate | Download | only in Tools
      1 /*!****************************************************************************
      2 
      3  @file         PVRTVector.h
      4  @copyright    Copyright (c) Imagination Technologies Limited.
      5  @brief        Vector and matrix mathematics library
      6 
      7 ******************************************************************************/
      8 #ifndef __PVRTVECTOR_H__
      9 #define __PVRTVECTOR_H__
     10 
     11 #include "assert.h"
     12 #include "PVRTGlobal.h"
     13 #include "PVRTFixedPoint.h"
     14 #include "PVRTMatrix.h"
     15 #include <string.h>
     16 #include <math.h>
     17 
     18 /*!***************************************************************************
     19 ** Forward Declarations for vector and matrix structs
     20 ****************************************************************************/
     21 struct PVRTVec4;
     22 struct PVRTVec3;
     23 struct PVRTMat3;
     24 struct PVRTMat4;
     25 
     26 /*!***************************************************************************
     27  @fn       			PVRTLinearEqSolve
     28  @param[in]			pSrc	2D array of floats. 4 Eq linear problem is 5x4
     29 							matrix, constants in first column
     30  @param[in]			nCnt	Number of equations to solve
     31  @param[out]		pRes	Result
     32  @brief      		Solves 'nCnt' simultaneous equations of 'nCnt' variables.
     33 					pRes should be an array large enough to contain the
     34 					results: the values of the 'nCnt' variables.
     35 					This fn recursively uses Gaussian Elimination.
     36 *****************************************************************************/
     37 void PVRTLinearEqSolve(VERTTYPE * const pRes, VERTTYPE ** const pSrc, const int nCnt);
     38 
     39 /*!***************************************************************************
     40  @struct            PVRTVec2
     41  @brief             2 component vector
     42 *****************************************************************************/
     43 struct PVRTVec2
     44 {
     45 	VERTTYPE x, y;
     46 	/*!***************************************************************************
     47 		** Constructors
     48 		****************************************************************************/
     49 	/*!***************************************************************************
     50 		@brief      		Blank constructor.
     51 		*****************************************************************************/
     52 	PVRTVec2() : x(0), y(0) {}
     53 	/*!***************************************************************************
     54 		@brief      		Simple constructor from 2 values.
     55 		@param[in]			fX	X component of vector
     56 		@param[in]			fY	Y component of vector
     57 		*****************************************************************************/
     58 	PVRTVec2(VERTTYPE fX, VERTTYPE fY) : x(fX), y(fY) {}
     59 	/*!***************************************************************************
     60 		@brief      		Constructor from a single value.
     61 		@param[in]			fValue	    A component value
     62 		*****************************************************************************/
     63 	PVRTVec2(VERTTYPE fValue) : x(fValue), y(fValue) {}
     64 	/*!***************************************************************************
     65 		@brief      		Constructor from an array
     66 		@param[in]			pVec	An array
     67 		*****************************************************************************/
     68 	PVRTVec2(const VERTTYPE* pVec) : x(pVec[0]), y(pVec[1]) {}
     69 	/*!***************************************************************************
     70 		@brief      		Constructor from a Vec3
     71 		@param[in]			v3Vec   A Vec3
     72 		*****************************************************************************/
     73 	PVRTVec2(const PVRTVec3& v3Vec);
     74 	/*!***************************************************************************
     75 		** Operators
     76 		****************************************************************************/
     77 	/*!***************************************************************************
     78 		@brief      		componentwise addition operator for two Vec2s
     79 		@param[in]			rhs     Another Vec2
     80 		@return 			result of addition
     81 		*****************************************************************************/
     82 	PVRTVec2 operator+(const PVRTVec2& rhs) const
     83 	{
     84 		PVRTVec2 out(*this);
     85 		return out += rhs;
     86 	}
     87 	/*!***************************************************************************
     88 		@brief      		componentwise subtraction operator for two Vec2s
     89 		@param[in]			rhs    Another vec2
     90 		@return 			result of subtraction
     91 		****************************************************************************/
     92 	PVRTVec2 operator-(const PVRTVec2& rhs) const
     93 	{
     94 		PVRTVec2 out(*this);
     95 		return out -= rhs;
     96 	}
     97 
     98 	/*!***************************************************************************
     99 		@brief      		Componentwise addition and assignment operator for two Vec2s
    100 		@param[in]			rhs    Another vec2
    101 		@return 			result of addition
    102 		****************************************************************************/
    103 	PVRTVec2& operator+=(const PVRTVec2& rhs)
    104 	{
    105 		x += rhs.x;
    106 		y += rhs.y;
    107 		return *this;
    108 	}
    109 
    110 	/*!***************************************************************************
    111 		@brief      		Componentwise subtraction and assignment operator for two Vec2s
    112 		@param[in]			rhs    Another vec2
    113 		@return 			Result of subtraction
    114 		****************************************************************************/
    115 	PVRTVec2& operator-=(const PVRTVec2& rhs)
    116 	{
    117 		x -= rhs.x;
    118 		y -= rhs.y;
    119 		return *this;
    120 	}
    121 
    122 	/*!***************************************************************************
    123 		@brief      		Negation operator for a Vec2
    124 		@param[in]			rhs    Another vec2
    125 		@return 			Result of negation
    126 		****************************************************************************/
    127 	friend PVRTVec2 operator- (const PVRTVec2& rhs) { return PVRTVec2(-rhs.x, -rhs.y); }
    128 
    129 	/*!***************************************************************************
    130 		@brief      		Multiplication operator for a Vec2
    131 		@param[in]			lhs     Scalar
    132 		@param[in]			rhs     A Vec2
    133 		@return 			result of multiplication
    134 		****************************************************************************/
    135 	friend PVRTVec2 operator*(const VERTTYPE lhs, const PVRTVec2&  rhs)
    136 	{
    137 		PVRTVec2 out(lhs);
    138 		return out *= rhs;
    139 	}
    140 
    141 	/*!***************************************************************************
    142 		@brief      		Division operator for scalar and Vec2
    143 		@param[in]			lhs scalar
    144 		@param[in]			rhs a Vec2
    145 		@return 			Result of division
    146 		****************************************************************************/
    147 	friend PVRTVec2 operator/(const VERTTYPE lhs, const PVRTVec2&  rhs)
    148 	{
    149 		PVRTVec2 out(lhs);
    150 		return out /= rhs;
    151 	}
    152 
    153 	/*!**************************************************************************
    154 		@brief      		Componentwise multiplication by scalar for Vec2*
    155 		@param[in]			rhs     A scalar
    156 		@return 			Result of multiplication
    157 		****************************************************************************/
    158 	PVRTVec2 operator*(const VERTTYPE& rhs) const
    159 	{
    160 		PVRTVec2 out(*this);
    161 		return out *= rhs;
    162 	}
    163 
    164 	/*!***************************************************************************
    165 		@brief      		Componentwise multiplication and assignment by scalar for Vec2
    166 		@param[in]			rhs     A scalar
    167 		@return 			Result of multiplication and assignment
    168 		****************************************************************************/
    169 	PVRTVec2& operator*=(const VERTTYPE& rhs)
    170 	{
    171 		x = VERTTYPEMUL(x, rhs);
    172 		y = VERTTYPEMUL(y, rhs);
    173 		return *this;
    174 	}
    175 
    176 	/*!***************************************************************************
    177 		@brief      		Componentwise multiplication and assignment by Vec2 for Vec2
    178 		@param[in]			rhs     A Vec2
    179 		@return 			Result of multiplication and assignment
    180 		****************************************************************************/
    181 	PVRTVec2& operator*=(const PVRTVec2& rhs)
    182 	{
    183 		x = VERTTYPEMUL(x, rhs.x);
    184 		y = VERTTYPEMUL(y, rhs.y);
    185 		return *this;
    186 	}
    187 
    188 	/*!***************************************************************************
    189 		@brief      		componentwise division by scalar for Vec2
    190 		@param[in]			rhs a scalar
    191 		@return 			result of division
    192 		****************************************************************************/
    193 	PVRTVec2 operator/(const VERTTYPE& rhs) const
    194 	{
    195 		PVRTVec2 out(*this);
    196 		return out /= rhs;
    197 	}
    198 
    199 	/*!***************************************************************************
    200 		@brief      		componentwise division and assignment by scalar for Vec2
    201 		@param[in]			rhs a scalar
    202 		@return 			result of division and assignment
    203 		****************************************************************************/
    204 	PVRTVec2& operator/=(const VERTTYPE& rhs)
    205 	{
    206 		x = VERTTYPEDIV(x, rhs);
    207 		y = VERTTYPEDIV(y, rhs);
    208 		return *this;
    209 	}
    210 
    211 	/*!***************************************************************************
    212 		@brief      		componentwise division and assignment by Vec2 for Vec2
    213 		@param[in]			rhs a Vec2
    214 		@return 			result of division and assignment
    215 		****************************************************************************/
    216 	PVRTVec2& operator/=(const PVRTVec2& rhs)
    217 	{
    218 		x = VERTTYPEDIV(x, rhs.x);
    219 		y = VERTTYPEDIV(y, rhs.y);
    220 		return *this;
    221 	}
    222 
    223 	/*!***************************************************************************
    224         @brief      		PVRTVec2 equality operator
    225         @param[in]			rhs     A single value
    226         @return 			true if the two vectors are equal
    227 	****************************************************************************/
    228 	bool operator==(const PVRTVec2& rhs) const
    229 	{
    230 		return ((x == rhs.x) && (y == rhs.y));
    231 	}
    232 
    233 	/*!***************************************************************************
    234         @brief      		PVRTVec2 inequality operator
    235         @param[in]			rhs     A single value
    236         @return 			true if the two vectors are not equal
    237 	****************************************************************************/
    238 	bool operator!=(const PVRTVec2& rhs) const
    239 	{
    240 		return ((x != rhs.x) || (y != rhs.y));
    241 	}
    242 
    243 	// FUNCTIONS
    244 	/*!***************************************************************************
    245 		@brief      		calculates the square of the magnitude of the vector
    246 		@return 			The square of the magnitude of the vector
    247 		****************************************************************************/
    248 	VERTTYPE lenSqr() const
    249 	{
    250 		return VERTTYPEMUL(x,x)+VERTTYPEMUL(y,y);
    251 	}
    252 
    253 	/*!***************************************************************************
    254 		@fn       			length
    255 		@return 			the of the magnitude of the vector
    256 		@brief      		calculates the magnitude of the vector
    257 		****************************************************************************/
    258 	VERTTYPE length() const
    259 	{
    260 		return (VERTTYPE) f2vt(sqrt(vt2f(x)*vt2f(x) + vt2f(y)*vt2f(y)));
    261 	}
    262 
    263 	/*!***************************************************************************
    264 		@fn       			normalize
    265 		@return 			the normalized value of the vector
    266 		@brief      		normalizes the vector
    267 		****************************************************************************/
    268 	PVRTVec2 normalize()
    269 	{
    270 		return *this /= length();
    271 	}
    272 
    273 	/*!***************************************************************************
    274 		@fn       			normalized
    275 		@return 			returns the normalized value of the vector
    276 		@brief      		returns a normalized vector of the same direction as this
    277 		vector
    278 		****************************************************************************/
    279 	PVRTVec2 normalized() const
    280 	{
    281 		PVRTVec2 out(*this);
    282 		return out.normalize();
    283 	}
    284 
    285 	/*!***************************************************************************
    286 		@fn       			rotated90
    287 		@return 			returns the vector rotated 90
    288 		@brief      		returns the vector rotated 90
    289 		****************************************************************************/
    290 	PVRTVec2 rotated90() const
    291 	{
    292 		return PVRTVec2(-y, x);
    293 	}
    294 
    295 	/*!***************************************************************************
    296 		@fn       			dot
    297 		@param[in]			rhs    A single value
    298 		@return 			scalar product
    299 		@brief      		calculate the scalar product of two Vec3s
    300 		****************************************************************************/
    301 	VERTTYPE dot(const PVRTVec2& rhs) const
    302 	{
    303 		return VERTTYPEMUL(x, rhs.x) + VERTTYPEMUL(y, rhs.y);
    304 	}
    305 
    306 	/*!***************************************************************************
    307 		@fn       			ptr
    308 		@return 			pointer
    309 		@brief      		returns a pointer to memory containing the values of the
    310 		Vec3
    311 		****************************************************************************/
    312 	VERTTYPE *ptr() { return (VERTTYPE*)this; }
    313 };
    314 
    315 /*!***************************************************************************
    316  @struct            PVRTVec3
    317  @brief             3 component vector
    318 ****************************************************************************/
    319 struct PVRTVec3 : public PVRTVECTOR3
    320 {
    321 /*!***************************************************************************
    322 ** Constructors
    323 ****************************************************************************/
    324 /*!***************************************************************************
    325  @brief      		Blank constructor.
    326 *****************************************************************************/
    327 	PVRTVec3()
    328 	{
    329 		x = y = z = 0;
    330 	}
    331 /*!***************************************************************************
    332  @brief      		Simple constructor from 3 values.
    333  @param[in]			fX	X component of vector
    334  @param[in]			fY	Y component of vector
    335  @param[in]			fZ	Z component of vector
    336 *****************************************************************************/
    337 	PVRTVec3(VERTTYPE fX, VERTTYPE fY, VERTTYPE fZ)
    338 	{
    339 		x = fX;	y = fY;	z = fZ;
    340 	}
    341 /*!***************************************************************************
    342  @brief      		Constructor from a single value.
    343  @param[in]			fValue	 A component value
    344 *****************************************************************************/
    345 	PVRTVec3(const VERTTYPE fValue)
    346 	{
    347 		x = fValue; y = fValue; z = fValue;
    348 	}
    349 /*!***************************************************************************
    350  @brief      		Constructor from an array
    351  @param[in]			pVec	An array
    352 *****************************************************************************/
    353 	PVRTVec3(const VERTTYPE* pVec)
    354 	{
    355 		x = (*pVec++); y = (*pVec++); z = *pVec;
    356 	}
    357 /*!***************************************************************************
    358  @brief      		Constructor from a PVRTVec4
    359  @param[in]			v4Vec   A PVRTVec4
    360 *****************************************************************************/
    361 	PVRTVec3(const PVRTVec4& v4Vec);
    362 /*!***************************************************************************
    363 ** Operators
    364 ****************************************************************************/
    365 /*!***************************************************************************
    366  @brief      		componentwise addition operator for two PVRTVec3s
    367  @param[in]			rhs     Another PVRTVec3
    368  @return 			result of addition
    369 *****************************************************************************/
    370 	PVRTVec3 operator+(const PVRTVec3& rhs) const
    371 	{
    372 		PVRTVec3 out;
    373 		out.x = x+rhs.x;
    374 		out.y = y+rhs.y;
    375 		out.z = z+rhs.z;
    376 		return out;
    377 	}
    378 /*!***************************************************************************
    379  @brief      		Componentwise subtraction operator for two PVRTVec3s
    380  @param[in]			rhs    Another PVRTVec3
    381  @return 			result of subtraction
    382 ****************************************************************************/
    383 	PVRTVec3 operator-(const PVRTVec3& rhs) const
    384 	{
    385 		PVRTVec3 out;
    386 		out.x = x-rhs.x;
    387 		out.y = y-rhs.y;
    388 		out.z = z-rhs.z;
    389 		return out;
    390 	}
    391 
    392 /*!***************************************************************************
    393  @brief      		Componentwise addition and assignement operator for two PVRTVec3s
    394  @param[in]			rhs    Another PVRTVec3
    395  @return 			Result of addition
    396 ****************************************************************************/
    397 	PVRTVec3& operator+=(const PVRTVec3& rhs)
    398 	{
    399 		x +=rhs.x;
    400 		y +=rhs.y;
    401 		z +=rhs.z;
    402 		return *this;
    403 	}
    404 
    405 /*!***************************************************************************
    406  @brief      		Componentwise subtraction and assignement operator for two PVRTVec3s
    407  @param[in]			rhs    Another PVRTVec3
    408  @return 			Result of subtraction
    409 ****************************************************************************/
    410 	PVRTVec3& operator-=(const PVRTVec3& rhs)
    411 	{
    412 		x -=rhs.x;
    413 		y -=rhs.y;
    414 		z -=rhs.z;
    415 		return *this;
    416 	}
    417 
    418 /*!***************************************************************************
    419  @brief      		Negation operator for a PVRTVec3
    420  @param[in]			rhs    Another PVRTVec3
    421  @return 			Result of negation
    422 ****************************************************************************/
    423 	friend PVRTVec3 operator - (const PVRTVec3& rhs) { return PVRTVec3(rhs) *= f2vt(-1); }
    424 
    425 /*!***************************************************************************
    426  @brief      		multiplication operator for a PVRTVec3
    427  @param[in]			lhs     Single value
    428  @param[in]			rhs     A PVRTVec3
    429  @return 			Result of multiplication
    430 ****************************************************************************/
    431 	friend PVRTVec3 operator*(const VERTTYPE lhs, const PVRTVec3&  rhs)
    432 	{
    433 		PVRTVec3 out;
    434 		out.x = VERTTYPEMUL(lhs,rhs.x);
    435 		out.y = VERTTYPEMUL(lhs,rhs.y);
    436 		out.z = VERTTYPEMUL(lhs,rhs.z);
    437 		return out;
    438 	}
    439 
    440 /*!***************************************************************************
    441  @brief      		Negation operator for a PVRTVec3
    442  @param[in]			lhs     Single value
    443  @param[in]			rhs     A PVRTVec3
    444  @return 			result of negation
    445 ****************************************************************************/
    446 	friend PVRTVec3 operator/(const VERTTYPE lhs, const PVRTVec3&  rhs)
    447 	{
    448 		PVRTVec3 out;
    449 		out.x = VERTTYPEDIV(lhs,rhs.x);
    450 		out.y = VERTTYPEDIV(lhs,rhs.y);
    451 		out.z = VERTTYPEDIV(lhs,rhs.z);
    452 		return out;
    453 	}
    454 
    455 /*!***************************************************************************
    456  @brief      		Matrix multiplication operator PVRTVec3 and PVRTMat3
    457  @param[in]			rhs     A PVRTMat3
    458  @return 			Result of multiplication
    459 ****************************************************************************/
    460 	PVRTVec3 operator*(const PVRTMat3& rhs) const;
    461 
    462 /*!***************************************************************************
    463  @brief      		Matrix multiplication and assignment operator for PVRTVec3 and PVRTMat3
    464  @param[in]			rhs     A PVRTMat3
    465  @return 			Result of multiplication and assignment
    466 ****************************************************************************/
    467 	PVRTVec3& operator*=(const PVRTMat3& rhs);
    468 
    469 /*!***************************************************************************
    470  @brief      		Componentwise multiplication by single dimension value for PVRTVec3
    471  @param[in]			rhs     A single value
    472  @return 			Result of multiplication
    473 ****************************************************************************/
    474 	PVRTVec3 operator*(const VERTTYPE& rhs) const
    475 	{
    476 		PVRTVec3 out;
    477 		out.x = VERTTYPEMUL(x,rhs);
    478 		out.y = VERTTYPEMUL(y,rhs);
    479 		out.z = VERTTYPEMUL(z,rhs);
    480 		return out;
    481 	}
    482 
    483 /*!***************************************************************************
    484  @brief      		Componentwise multiplication and assignement by single
    485 					dimension value	for PVRTVec3
    486  @param[in]			rhs    A single value
    487  @return 			Result of multiplication and assignment
    488 ****************************************************************************/
    489 	PVRTVec3& operator*=(const VERTTYPE& rhs)
    490 	{
    491 		x = VERTTYPEMUL(x,rhs);
    492 		y = VERTTYPEMUL(y,rhs);
    493 		z = VERTTYPEMUL(z,rhs);
    494 		return *this;
    495 	}
    496 
    497 /*!***************************************************************************
    498  @brief      		Componentwise division by single dimension value for PVRTVec3
    499  @param[in]			rhs    A single value
    500  @return 			Result of division
    501 ****************************************************************************/
    502 	PVRTVec3 operator/(const VERTTYPE& rhs) const
    503 	{
    504 		PVRTVec3 out;
    505 		out.x = VERTTYPEDIV(x,rhs);
    506 		out.y = VERTTYPEDIV(y,rhs);
    507 		out.z = VERTTYPEDIV(z,rhs);
    508 		return out;
    509 	}
    510 
    511 /*!***************************************************************************
    512  @brief      		Componentwise division and assignement by single
    513 					dimension value	for PVRTVec3
    514  @param[in]			rhs    A single value
    515  @return 			Result of division and assignment
    516 ****************************************************************************/
    517 	PVRTVec3& operator/=(const VERTTYPE& rhs)
    518 	{
    519 		x = VERTTYPEDIV(x,rhs);
    520 		y = VERTTYPEDIV(y,rhs);
    521 		z = VERTTYPEDIV(z,rhs);
    522 		return *this;
    523 	}
    524 
    525 /*!***************************************************************************
    526  @brief      		PVRTVec3 equality operator
    527  @param[in]			rhs    A single value
    528  @return 			true if the two vectors are equal
    529 ****************************************************************************/
    530 	bool operator==(const PVRTVec3& rhs) const
    531 	{
    532 		return ((x == rhs.x) && (y == rhs.y) && (z == rhs.z));
    533 	}
    534 
    535 /*!***************************************************************************
    536  @brief      		PVRTVec3 inequality operator
    537  @param[in]			rhs    A single value
    538  @return 			true if the two vectors are not equal
    539 	****************************************************************************/
    540 	bool operator!=(const PVRTVec3& rhs) const
    541 	{
    542 		return ((x != rhs.x) || (y != rhs.y) || (z != rhs.z));
    543 	}
    544 	// FUNCTIONS
    545 /*!***************************************************************************
    546  @fn       			lenSqr
    547  @return 			the square of the magnitude of the vector
    548  @brief      		calculates the square of the magnitude of the vector
    549 ****************************************************************************/
    550 	VERTTYPE lenSqr() const
    551 	{
    552 		return VERTTYPEMUL(x,x)+VERTTYPEMUL(y,y)+VERTTYPEMUL(z,z);
    553 	}
    554 
    555 /*!***************************************************************************
    556  @fn       			length
    557  @return 			the of the magnitude of the vector
    558  @brief      		calculates the magnitude of the vector
    559 ****************************************************************************/
    560 	VERTTYPE length() const
    561 	{
    562 		return (VERTTYPE) f2vt(sqrt(vt2f(x)*vt2f(x) + vt2f(y)*vt2f(y) + vt2f(z)*vt2f(z)));
    563 	}
    564 
    565 /*!***************************************************************************
    566  @fn       			normalize
    567  @return 			the normalized value of the vector
    568  @brief      		normalizes the vector
    569 ****************************************************************************/
    570 	PVRTVec3 normalize()
    571 	{
    572 #if defined(PVRT_FIXED_POINT_ENABLE)
    573 		// Scale vector by uniform value
    574 		int n = PVRTABS(x) + PVRTABS(y) + PVRTABS(z);
    575 		x = VERTTYPEDIV(x, n);
    576 		y = VERTTYPEDIV(y, n);
    577 		z = VERTTYPEDIV(z, n);
    578 
    579 		// Calculate x2+y2+z2/sqrt(x2+y2+z2)
    580 		int f = dot(*this);
    581 		f = VERTTYPEDIV(PVRTF2X(1.0f), PVRTF2X(sqrt(PVRTX2F(f))));
    582 
    583 		// Multiply vector components by f
    584 		x = PVRTXMUL(x, f);
    585 		y = PVRTXMUL(y, f);
    586 		z = PVRTXMUL(z, f);
    587 #else
    588 		VERTTYPE len = length();
    589 		x =VERTTYPEDIV(x,len);
    590 		y =VERTTYPEDIV(y,len);
    591 		z =VERTTYPEDIV(z,len);
    592 #endif
    593 		return *this;
    594 	}
    595 
    596 /*!***************************************************************************
    597  @fn       			normalized
    598  @return 			returns the normalized value of the vector
    599  @brief      		returns a normalized vector of the same direction as this
    600 					vector
    601 ****************************************************************************/
    602 	PVRTVec3 normalized() const
    603 	{
    604 		PVRTVec3 out;
    605 #if defined(PVRT_FIXED_POINT_ENABLE)
    606 		// Scale vector by uniform value
    607 		int n = PVRTABS(x) + PVRTABS(y) + PVRTABS(z);
    608 		out.x = VERTTYPEDIV(x, n);
    609 		out.y = VERTTYPEDIV(y, n);
    610 		out.z = VERTTYPEDIV(z, n);
    611 
    612 		// Calculate x2+y2+z2/sqrt(x2+y2+z2)
    613 		int f = out.dot(out);
    614 		f = VERTTYPEDIV(PVRTF2X(1.0f), PVRTF2X(sqrt(PVRTX2F(f))));
    615 
    616 		// Multiply vector components by f
    617 		out.x = PVRTXMUL(out.x, f);
    618 		out.y = PVRTXMUL(out.y, f);
    619 		out.z = PVRTXMUL(out.z, f);
    620 #else
    621 		VERTTYPE len = length();
    622 		out.x =VERTTYPEDIV(x,len);
    623 		out.y =VERTTYPEDIV(y,len);
    624 		out.z =VERTTYPEDIV(z,len);
    625 #endif
    626 		return out;
    627 	}
    628 
    629 /*!***************************************************************************
    630  @fn       			dot
    631  @param[in]			rhs    A single value
    632  @return 			scalar product
    633  @brief      		calculate the scalar product of two PVRTVec3s
    634 ****************************************************************************/
    635 	VERTTYPE dot(const PVRTVec3& rhs) const
    636 	{
    637 		return VERTTYPEMUL(x,rhs.x)+VERTTYPEMUL(y,rhs.y)+VERTTYPEMUL(z,rhs.z);
    638 	}
    639 
    640 /*!***************************************************************************
    641  @fn       			cross
    642  @return 			returns three-dimensional vector
    643  @brief      		calculate the cross product of two PVRTVec3s
    644 ****************************************************************************/
    645 	PVRTVec3 cross(const PVRTVec3& rhs) const
    646 	{
    647 		PVRTVec3 out;
    648 		out.x = VERTTYPEMUL(y,rhs.z)-VERTTYPEMUL(z,rhs.y);
    649 		out.y = VERTTYPEMUL(z,rhs.x)-VERTTYPEMUL(x,rhs.z);
    650 		out.z = VERTTYPEMUL(x,rhs.y)-VERTTYPEMUL(y,rhs.x);
    651 		return out;
    652 	}
    653 
    654 /*!***************************************************************************
    655  @fn       			ptr
    656  @return 			pointer
    657  @brief      		returns a pointer to memory containing the values of the
    658 					PVRTVec3
    659 ****************************************************************************/
    660 	VERTTYPE *ptr() { return (VERTTYPE*)this; }
    661 };
    662 
    663 /*!***************************************************************************
    664  @struct            PVRTVec4
    665  @brief             4 component vector
    666 ****************************************************************************/
    667 struct PVRTVec4 : public PVRTVECTOR4
    668 {
    669 /*!***************************************************************************
    670 ** Constructors
    671 ****************************************************************************/
    672 /*!***************************************************************************
    673  @brief      	Blank constructor.
    674 *****************************************************************************/
    675 	PVRTVec4(){}
    676 
    677 /*!***************************************************************************
    678  @brief      	Blank constructor.
    679 *****************************************************************************/
    680 	PVRTVec4(const VERTTYPE vec)
    681 	{
    682 		x = vec; y = vec; z = vec; w = vec;
    683 	}
    684 
    685 /*!***************************************************************************
    686  @brief      	Constructs a PVRTVec4 from 4 separate values
    687  @param[in]		fX      Value of x component
    688  @param[in]		fY      Value of y component
    689  @param[in]		fZ      Value of z component
    690  @param[in]		fW      Value of w component
    691 ****************************************************************************/
    692 	PVRTVec4(VERTTYPE fX, VERTTYPE fY, VERTTYPE fZ, VERTTYPE fW)
    693 	{
    694 		x = fX;	y = fY;	z = fZ;	w = fW;
    695 	}
    696 
    697 /*!***************************************************************************
    698  @param[in]			vec3 a PVRTVec3
    699  @param[in]			fW     Value of w component
    700  @brief      		Constructs a PVRTVec4 from a vec3 and a w component
    701 ****************************************************************************/
    702 	PVRTVec4(const PVRTVec3& vec3, VERTTYPE fW)
    703 	{
    704 		x = vec3.x;	y = vec3.y;	z = vec3.z;	w = fW;
    705 	}
    706 
    707 /*!***************************************************************************
    708  @brief      		Constructs a vec4 from a vec3 and a w component
    709  @param[in]			fX value of x component
    710  @param[in]			vec3 a PVRTVec3
    711 ****************************************************************************/
    712 	PVRTVec4(VERTTYPE fX, const PVRTVec3& vec3)
    713 	{
    714 		x = fX;	y = vec3.x;	z = vec3.y;	w = vec3.z;
    715 	}
    716 
    717 /*!***************************************************************************
    718  @brief      		Constructs a PVRTVec4 from a pointer to an array of four values
    719  @param[in]			pVec a pointer to an array of four values
    720 ****************************************************************************/
    721 	PVRTVec4(const VERTTYPE* pVec)
    722 	{
    723 		x = (*pVec++); y = (*pVec++); z= (*pVec++); w = *pVec;
    724 	}
    725 
    726 /*!***************************************************************************
    727 ** PVRTVec4 Operators
    728 ****************************************************************************/
    729 /*!***************************************************************************
    730  @brief      		Addition operator for PVRTVec4
    731  @param[in]			rhs    Another PVRTVec4
    732  @return 			result of addition
    733 ****************************************************************************/
    734 	PVRTVec4 operator+(const PVRTVec4& rhs) const
    735 	{
    736 		PVRTVec4 out;
    737 		out.x = x+rhs.x;
    738 		out.y = y+rhs.y;
    739 		out.z = z+rhs.z;
    740 		out.w = w+rhs.w;
    741 		return out;
    742 	}
    743 
    744 /*!***************************************************************************
    745  @brief      		Subtraction operator for PVRTVec4
    746  @param[in]			rhs    Another PVRTVec4
    747  @return 			result of subtraction
    748 ****************************************************************************/
    749 	PVRTVec4 operator-(const PVRTVec4& rhs) const
    750 	{
    751 		PVRTVec4 out;
    752 		out.x = x-rhs.x;
    753 		out.y = y-rhs.y;
    754 		out.z = z-rhs.z;
    755 		out.w = w-rhs.w;
    756 		return out;
    757 	}
    758 
    759 /*!***************************************************************************
    760  @brief      		Addition and assignment operator for PVRTVec4
    761  @param[in]			rhs    Another PVRTVec4
    762  @return 			result of addition and assignment
    763 ****************************************************************************/
    764 	PVRTVec4& operator+=(const PVRTVec4& rhs)
    765 	{
    766 		x +=rhs.x;
    767 		y +=rhs.y;
    768 		z +=rhs.z;
    769 		w +=rhs.w;
    770 		return *this;
    771 	}
    772 
    773 /*!***************************************************************************
    774  @brief      		Subtraction and assignment operator for PVRTVec4
    775  @param[in]			rhs    Another PVRTVec4
    776  @return 			result of subtraction and assignment
    777 ****************************************************************************/
    778 	PVRTVec4& operator-=(const PVRTVec4& rhs)
    779 	{
    780 		x -=rhs.x;
    781 		y -=rhs.y;
    782 		z -=rhs.z;
    783 		w -=rhs.w;
    784 		return *this;
    785 	}
    786 
    787 /*!***************************************************************************
    788  @brief      		Matrix multiplication for PVRTVec4 and PVRTMat4
    789  @param[in]			rhs    A PVRTMat4
    790  @return 			result of multiplication
    791 ****************************************************************************/
    792 	PVRTVec4 operator*(const PVRTMat4& rhs) const;
    793 
    794 /*!***************************************************************************
    795  @brief      		Matrix multiplication and assignment for PVRTVec4 and PVRTMat4
    796  @param[in]			rhs    A PVRTMat4
    797  @return 			result of multiplication and assignement
    798 ****************************************************************************/
    799 	PVRTVec4& operator*=(const PVRTMat4& rhs);
    800 
    801 /*!***************************************************************************
    802  @brief      		Componentwise multiplication of a PVRTVec4 by a single value
    803  @param[in]			rhs  A single dimension value
    804  @return 			result of multiplication
    805 ****************************************************************************/
    806 	PVRTVec4 operator*(const VERTTYPE& rhs) const
    807 	{
    808 		PVRTVec4 out;
    809 		out.x = VERTTYPEMUL(x,rhs);
    810 		out.y = VERTTYPEMUL(y,rhs);
    811 		out.z = VERTTYPEMUL(z,rhs);
    812 		out.w = VERTTYPEMUL(w,rhs);
    813 		return out;
    814 	}
    815 
    816 /*!***************************************************************************
    817  @brief      		componentwise multiplication and assignment of a PVRTVec4 by
    818                     a single value
    819  @param[in]			rhs     A single dimension value
    820  @return 			result of multiplication and assignment
    821 ****************************************************************************/
    822 	PVRTVec4& operator*=(const VERTTYPE& rhs)
    823 	{
    824 		x = VERTTYPEMUL(x,rhs);
    825 		y = VERTTYPEMUL(y,rhs);
    826 		z = VERTTYPEMUL(z,rhs);
    827 		w = VERTTYPEMUL(w,rhs);
    828 		return *this;
    829 	}
    830 
    831 /*!***************************************************************************
    832  @brief      		componentwise division of a PVRTVec4 by a single value
    833  @param[in]			rhs     A single dimension value
    834  @return 			result of division
    835 ****************************************************************************/
    836 	PVRTVec4 operator/(const VERTTYPE& rhs) const
    837 	{
    838 		PVRTVec4 out;
    839 		out.x = VERTTYPEDIV(x,rhs);
    840 		out.y = VERTTYPEDIV(y,rhs);
    841 		out.z = VERTTYPEDIV(z,rhs);
    842 		out.w = VERTTYPEDIV(w,rhs);
    843 		return out;
    844 	}
    845 
    846 /*!***************************************************************************
    847  @brief      		componentwise division and assignment of a PVRTVec4 by
    848 					a single value
    849  @param[in]				rhs a single dimension value
    850  @return 			result of division and assignment
    851 ****************************************************************************/
    852 	PVRTVec4& operator/=(const VERTTYPE& rhs)
    853 	{
    854 		x = VERTTYPEDIV(x,rhs);
    855 		y = VERTTYPEDIV(y,rhs);
    856 		z = VERTTYPEDIV(z,rhs);
    857 		w = VERTTYPEDIV(w,rhs);
    858 		return *this;
    859 	}
    860 
    861 /*!***************************************************************************
    862  @brief      		componentwise multiplication of a PVRTVec4 by
    863 					a single value
    864  @param[in]				lhs a single dimension value
    865  @param[in]				rhs a PVRTVec4
    866  @return 			result of muliplication
    867 ****************************************************************************/
    868 friend PVRTVec4 operator*(const VERTTYPE lhs, const PVRTVec4&  rhs)
    869 {
    870 	PVRTVec4 out;
    871 	out.x = VERTTYPEMUL(lhs,rhs.x);
    872 	out.y = VERTTYPEMUL(lhs,rhs.y);
    873 	out.z = VERTTYPEMUL(lhs,rhs.z);
    874 	out.w = VERTTYPEMUL(lhs,rhs.w);
    875 	return out;
    876 }
    877 
    878 /*!***************************************************************************
    879  @brief      		PVRTVec4 equality operator
    880  @param[in]			rhs    A single value
    881  @return 			true if the two vectors are equal
    882 ****************************************************************************/
    883 bool operator==(const PVRTVec4& rhs) const
    884 {
    885 	return ((x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w));
    886 }
    887 
    888 /*!***************************************************************************
    889 @brief      		PVRTVec4 inequality operator
    890 @param[in]			rhs    A single value
    891 @return 			true if the two vectors are not equal
    892 	****************************************************************************/
    893 bool operator!=(const PVRTVec4& rhs) const
    894 {
    895 	return ((x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w));
    896 }
    897 /*!***************************************************************************
    898 ** Functions
    899 ****************************************************************************/
    900 /*!***************************************************************************
    901  @fn       			lenSqr
    902  @return 			square of the magnitude of the vector
    903  @brief      		calculates the square of the magnitude of the vector
    904 ****************************************************************************/
    905 	VERTTYPE lenSqr() const
    906 	{
    907 		return VERTTYPEMUL(x,x)+VERTTYPEMUL(y,y)+VERTTYPEMUL(z,z)+VERTTYPEMUL(w,w);
    908 	}
    909 
    910 /*!***************************************************************************
    911  @fn       			length
    912  @return 			the magnitude of the vector
    913  @brief      		calculates the magnitude of the vector
    914 ****************************************************************************/
    915 	VERTTYPE length() const
    916 	{
    917 		return (VERTTYPE) f2vt(sqrt(vt2f(x)*vt2f(x) + vt2f(y)*vt2f(y) + vt2f(z)*vt2f(z) + vt2f(w)*vt2f(w)));
    918 	}
    919 
    920 /*!***************************************************************************
    921  @fn       			normalize
    922  @return 			normalized vector
    923  @brief      		calculates the normalized value of a PVRTVec4
    924 ****************************************************************************/
    925 	PVRTVec4 normalize()
    926 	{
    927 		VERTTYPE len = length();
    928 		x =VERTTYPEDIV(x,len);
    929 		y =VERTTYPEDIV(y,len);
    930 		z =VERTTYPEDIV(z,len);
    931 		w =VERTTYPEDIV(w,len);
    932 		return *this;
    933 	}
    934 /*!***************************************************************************
    935  @fn       			normalized
    936  @return 			normalized vector
    937  @brief      		returns a normalized vector of the same direction as this
    938 					vector
    939 ****************************************************************************/
    940 	PVRTVec4 normalized() const
    941 	{
    942 		PVRTVec4 out;
    943 		VERTTYPE len = length();
    944 		out.x =VERTTYPEDIV(x,len);
    945 		out.y =VERTTYPEDIV(y,len);
    946 		out.z =VERTTYPEDIV(z,len);
    947 		out.w =VERTTYPEDIV(w,len);
    948 		return out;
    949 	}
    950 
    951 /*!***************************************************************************
    952  @fn       			dot
    953  @return 			scalar product
    954  @brief      		returns a normalized vector of the same direction as this
    955 					vector
    956 ****************************************************************************/
    957 	VERTTYPE dot(const PVRTVec4& rhs) const
    958 	{
    959 		return VERTTYPEMUL(x,rhs.x)+VERTTYPEMUL(y,rhs.y)+VERTTYPEMUL(z,rhs.z)+VERTTYPEMUL(w,rhs.w);
    960 	}
    961 
    962 /*!***************************************************************************
    963  @fn       			ptr
    964  @return 			pointer to vector values
    965  @brief      		returns a pointer to memory containing the values of the
    966 					PVRTVec3
    967 ****************************************************************************/
    968 	VERTTYPE *ptr() { return (VERTTYPE*)this; }
    969 };
    970 
    971 /*!***************************************************************************
    972  @struct            PVRTMat3
    973  @brief             3x3 Matrix
    974 ****************************************************************************/
    975 struct PVRTMat3 : public PVRTMATRIX3
    976 {
    977 /*!***************************************************************************
    978 ** Constructors
    979 ****************************************************************************/
    980 /*!***************************************************************************
    981  @brief      		Blank constructor.
    982 *****************************************************************************/
    983 	PVRTMat3(){}
    984 /*!***************************************************************************
    985  @brief      		Constructor from array.
    986  @param[in]			pMat    An array of values for the matrix
    987 *****************************************************************************/
    988 	PVRTMat3(const VERTTYPE* pMat)
    989 	{
    990 		VERTTYPE* ptr = f;
    991 		for(int i=0;i<9;i++)
    992 		{
    993 			(*ptr++)=(*pMat++);
    994 		}
    995 	}
    996 
    997 /*!***************************************************************************
    998  @brief      	    Constructor from distinct values.
    999  @param[in]	    	m0	m0 matrix value
   1000  @param[in]	    	m1	m1 matrix value
   1001  @param[in]	    	m2	m2 matrix value
   1002  @param[in]	    	m3	m3 matrix value
   1003  @param[in]	    	m4	m4 matrix value
   1004  @param[in]	    	m5	m5 matrix value
   1005  @param[in]	    	m6	m6 matrix value
   1006  @param[in]	    	m7	m7 matrix value
   1007  @param[in]	    	m8	m8 matrix value
   1008 *****************************************************************************/
   1009 	PVRTMat3(VERTTYPE m0,VERTTYPE m1,VERTTYPE m2,
   1010 		VERTTYPE m3,VERTTYPE m4,VERTTYPE m5,
   1011 		VERTTYPE m6,VERTTYPE m7,VERTTYPE m8)
   1012 	{
   1013 		f[0]=m0;f[1]=m1;f[2]=m2;
   1014 		f[3]=m3;f[4]=m4;f[5]=m5;
   1015 		f[6]=m6;f[7]=m7;f[8]=m8;
   1016 	}
   1017 
   1018 /*!***************************************************************************
   1019  @brief      		Constructor from 4x4 matrix - uses top left values
   1020  @param[in]			mat - a PVRTMat4
   1021 *****************************************************************************/
   1022 	PVRTMat3(const PVRTMat4& mat);
   1023 
   1024 /****************************************************************************
   1025 ** PVRTMat3 OPERATORS
   1026 ****************************************************************************/
   1027 /*!***************************************************************************
   1028  @brief      		Returns the value of the element at the specified row and column
   1029 					of the PVRTMat3
   1030  @param[in]			row			row of matrix
   1031  @param[in]			column		column of matrix
   1032  @return 			value of element
   1033 *****************************************************************************/
   1034 	VERTTYPE& operator()(const int row, const int column)
   1035 	{
   1036 		return f[column*3+row];
   1037 	}
   1038 /*!***************************************************************************
   1039  @brief      		Returns the value of the element at the specified row and column
   1040 					of the PVRTMat3
   1041  @param[in]			row			row of matrix
   1042  @param[in]			column		column of matrix
   1043  @return 			value of element
   1044 *****************************************************************************/
   1045 	const VERTTYPE& operator()(const int row, const int column) const
   1046 	{
   1047 		return f[column*3+row];
   1048 	}
   1049 
   1050 /*!***************************************************************************
   1051  @brief      		Matrix multiplication of two 3x3 matrices.
   1052  @param[in]			rhs     Another PVRTMat3
   1053  @return 			result of multiplication
   1054 *****************************************************************************/
   1055 	PVRTMat3 operator*(const PVRTMat3& rhs) const
   1056 	{
   1057 		PVRTMat3 out;
   1058 		// col 1
   1059 		out.f[0] =	VERTTYPEMUL(f[0],rhs.f[0])+VERTTYPEMUL(f[3],rhs.f[1])+VERTTYPEMUL(f[6],rhs.f[2]);
   1060 		out.f[1] =	VERTTYPEMUL(f[1],rhs.f[0])+VERTTYPEMUL(f[4],rhs.f[1])+VERTTYPEMUL(f[7],rhs.f[2]);
   1061 		out.f[2] =	VERTTYPEMUL(f[2],rhs.f[0])+VERTTYPEMUL(f[5],rhs.f[1])+VERTTYPEMUL(f[8],rhs.f[2]);
   1062 
   1063 		// col 2
   1064 		out.f[3] =	VERTTYPEMUL(f[0],rhs.f[3])+VERTTYPEMUL(f[3],rhs.f[4])+VERTTYPEMUL(f[6],rhs.f[5]);
   1065 		out.f[4] =	VERTTYPEMUL(f[1],rhs.f[3])+VERTTYPEMUL(f[4],rhs.f[4])+VERTTYPEMUL(f[7],rhs.f[5]);
   1066 		out.f[5] =	VERTTYPEMUL(f[2],rhs.f[3])+VERTTYPEMUL(f[5],rhs.f[4])+VERTTYPEMUL(f[8],rhs.f[5]);
   1067 
   1068 		// col3
   1069 		out.f[6] =	VERTTYPEMUL(f[0],rhs.f[6])+VERTTYPEMUL(f[3],rhs.f[7])+VERTTYPEMUL(f[6],rhs.f[8]);
   1070 		out.f[7] =	VERTTYPEMUL(f[1],rhs.f[6])+VERTTYPEMUL(f[4],rhs.f[7])+VERTTYPEMUL(f[7],rhs.f[8]);
   1071 		out.f[8] =	VERTTYPEMUL(f[2],rhs.f[6])+VERTTYPEMUL(f[5],rhs.f[7])+VERTTYPEMUL(f[8],rhs.f[8]);
   1072 		return out;
   1073 	}
   1074 
   1075 /*!***************************************************************************
   1076  @brief      		element by element addition operator.
   1077  @param[in]			rhs     Another PVRTMat3
   1078  @return 			result of addition
   1079 *****************************************************************************/
   1080 	PVRTMat3 operator+(const PVRTMat3& rhs) const
   1081 	{
   1082 		PVRTMat3 out;
   1083 		VERTTYPE const *lptr = f, *rptr = rhs.f;
   1084 		VERTTYPE *outptr = out.f;
   1085 		for(int i=0;i<9;i++)
   1086 		{
   1087 			(*outptr++) = (*lptr++) + (*rptr++);
   1088 		}
   1089 		return out;
   1090 	}
   1091 
   1092 /*!***************************************************************************
   1093  @brief      		element by element subtraction operator.
   1094  @param[in]			rhs     Another PVRTMat3
   1095  @return 			result of subtraction
   1096 *****************************************************************************/
   1097 	PVRTMat3 operator-(const PVRTMat3& rhs) const
   1098 	{
   1099 		PVRTMat3 out;
   1100 		VERTTYPE const *lptr = f, *rptr = rhs.f;
   1101 		VERTTYPE *outptr = out.f;
   1102 		for(int i=0;i<9;i++)
   1103 		{
   1104 			(*outptr++) = (*lptr++) - (*rptr++);
   1105 		}
   1106 		return out;
   1107 	}
   1108 
   1109 /*!***************************************************************************
   1110  @brief      		Element by element addition and assignment operator.
   1111  @param[in]			rhs     Another PVRTMat3
   1112  @return 			Result of addition and assignment
   1113 *****************************************************************************/
   1114 	PVRTMat3& operator+=(const PVRTMat3& rhs)
   1115 	{
   1116 		VERTTYPE *lptr = f;
   1117 		VERTTYPE const *rptr = rhs.f;
   1118 		for(int i=0;i<9;i++)
   1119 		{
   1120 			(*lptr++) += (*rptr++);
   1121 		}
   1122 		return *this;
   1123 	}
   1124 
   1125 /*!***************************************************************************
   1126  @brief      		element by element subtraction and assignment operator.
   1127  @param[in]			rhs     Another PVRTMat3
   1128  @return 			result of subtraction and assignment
   1129 *****************************************************************************/
   1130 	PVRTMat3& operator-=(const PVRTMat3& rhs)
   1131 	{
   1132 		VERTTYPE *lptr = f;
   1133 		VERTTYPE const *rptr = rhs.f;
   1134 		for(int i=0;i<9;i++)
   1135 		{
   1136 			(*lptr++) -= (*rptr++);
   1137 		}
   1138 		return *this;
   1139 	}
   1140 
   1141 /*!***************************************************************************
   1142  @brief      		Matrix multiplication and assignment of two 3x3 matrices.
   1143  @param[in]			rhs     Another PVRTMat3
   1144  @return 			result of multiplication and assignment
   1145 *****************************************************************************/
   1146 	PVRTMat3& operator*=(const PVRTMat3& rhs)
   1147 	{
   1148 		PVRTMat3 out;
   1149 		// col 1
   1150 		out.f[0] =	VERTTYPEMUL(f[0],rhs.f[0])+VERTTYPEMUL(f[3],rhs.f[1])+VERTTYPEMUL(f[6],rhs.f[2]);
   1151 		out.f[1] =	VERTTYPEMUL(f[1],rhs.f[0])+VERTTYPEMUL(f[4],rhs.f[1])+VERTTYPEMUL(f[7],rhs.f[2]);
   1152 		out.f[2] =	VERTTYPEMUL(f[2],rhs.f[0])+VERTTYPEMUL(f[5],rhs.f[1])+VERTTYPEMUL(f[8],rhs.f[2]);
   1153 
   1154 		// col 2
   1155 		out.f[3] =	VERTTYPEMUL(f[0],rhs.f[3])+VERTTYPEMUL(f[3],rhs.f[4])+VERTTYPEMUL(f[6],rhs.f[5]);
   1156 		out.f[4] =	VERTTYPEMUL(f[1],rhs.f[3])+VERTTYPEMUL(f[4],rhs.f[4])+VERTTYPEMUL(f[7],rhs.f[5]);
   1157 		out.f[5] =	VERTTYPEMUL(f[2],rhs.f[3])+VERTTYPEMUL(f[5],rhs.f[4])+VERTTYPEMUL(f[8],rhs.f[5]);
   1158 
   1159 		// col3
   1160 		out.f[6] =	VERTTYPEMUL(f[0],rhs.f[6])+VERTTYPEMUL(f[3],rhs.f[7])+VERTTYPEMUL(f[6],rhs.f[8]);
   1161 		out.f[7] =	VERTTYPEMUL(f[1],rhs.f[6])+VERTTYPEMUL(f[4],rhs.f[7])+VERTTYPEMUL(f[7],rhs.f[8]);
   1162 		out.f[8] =	VERTTYPEMUL(f[2],rhs.f[6])+VERTTYPEMUL(f[5],rhs.f[7])+VERTTYPEMUL(f[8],rhs.f[8]);
   1163 		*this = out;
   1164 		return *this;
   1165 	}
   1166 
   1167 /*!***************************************************************************
   1168  @brief      		Element multiplication by a single value.
   1169  @param[in]			rhs    A single value
   1170  @return 			Result of multiplication and assignment
   1171 *****************************************************************************/
   1172 	PVRTMat3& operator*(const VERTTYPE rhs)
   1173 	{
   1174 		for (int i=0; i<9; ++i)
   1175 		{
   1176 			f[i]*=rhs;
   1177 		}
   1178 		return *this;
   1179 	}
   1180 /*!***************************************************************************
   1181  @brief      		Element multiplication and assignment by a single value.
   1182  @param[in]			rhs    A single value
   1183  @return 			result of multiplication and assignment
   1184 *****************************************************************************/
   1185 	PVRTMat3& operator*=(const VERTTYPE rhs)
   1186 	{
   1187 		for (int i=0; i<9; ++i)
   1188 		{
   1189 			f[i]*=rhs;
   1190 		}
   1191 		return *this;
   1192 	}
   1193 
   1194 /*!***************************************************************************
   1195  @brief      		Matrix multiplication of 3x3 matrix and vec3
   1196  @param[in]			rhs    Another PVRTVec3
   1197  @return 			result of multiplication
   1198 *****************************************************************************/
   1199 	PVRTVec3 operator*(const PVRTVec3& rhs) const
   1200 	{
   1201 		PVRTVec3 out;
   1202 		out.x = VERTTYPEMUL(rhs.x,f[0])+VERTTYPEMUL(rhs.y,f[3])+VERTTYPEMUL(rhs.z,f[6]);
   1203 		out.y = VERTTYPEMUL(rhs.x,f[1])+VERTTYPEMUL(rhs.y,f[4])+VERTTYPEMUL(rhs.z,f[7]);
   1204 		out.z = VERTTYPEMUL(rhs.x,f[2])+VERTTYPEMUL(rhs.y,f[5])+VERTTYPEMUL(rhs.z,f[8]);
   1205 
   1206 		return out;
   1207 	}
   1208 
   1209 
   1210 	// FUNCTIONS
   1211 /*!***************************************************************************
   1212 ** Functions
   1213 *****************************************************************************/
   1214 /*!***************************************************************************
   1215  @fn       			determinant
   1216  @return 			result of multiplication
   1217  @brief      		Matrix multiplication and assignment of 3x3 matrix and vec3
   1218 *****************************************************************************/
   1219 	VERTTYPE determinant() const
   1220 	{
   1221 		return VERTTYPEMUL(f[0],(VERTTYPEMUL(f[4],f[8])-VERTTYPEMUL(f[7],f[5])))
   1222 			- VERTTYPEMUL(f[3],(VERTTYPEMUL(f[1],f[8])-VERTTYPEMUL(f[7],f[2])))
   1223 			+ VERTTYPEMUL(f[6],(VERTTYPEMUL(f[1],f[5])-VERTTYPEMUL(f[4],f[2])));
   1224 	}
   1225 
   1226 /*!***************************************************************************
   1227  @fn       			inverse
   1228  @return 			inverse mat3
   1229  @brief      		Calculates multiplicative inverse of this matrix
   1230 *****************************************************************************/
   1231 	PVRTMat3 inverse() const
   1232 	{
   1233 		PVRTMat3 out;
   1234 
   1235 
   1236 		VERTTYPE recDet = determinant();
   1237 		_ASSERT(recDet!=0);
   1238 		recDet = VERTTYPEDIV(f2vt(1.0f),recDet);
   1239 
   1240 		//TODO: deal with singular matrices with more than just an assert
   1241 
   1242 		// inverse is 1/det * adjoint of M
   1243 
   1244 		// adjoint is transpose of cofactor matrix
   1245 
   1246 		// do transpose and cofactors in one step
   1247 
   1248 		out.f[0] = VERTTYPEMUL(f[4],f[8]) - VERTTYPEMUL(f[5],f[7]);
   1249 		out.f[1] = VERTTYPEMUL(f[2],f[7]) - VERTTYPEMUL(f[1],f[8]);
   1250 		out.f[2] = VERTTYPEMUL(f[1],f[5]) - VERTTYPEMUL(f[2],f[4]);
   1251 
   1252 		out.f[3] = VERTTYPEMUL(f[5],f[6]) - VERTTYPEMUL(f[3],f[8]);
   1253 		out.f[4] = VERTTYPEMUL(f[0],f[8]) - VERTTYPEMUL(f[2],f[6]);
   1254 		out.f[5] = VERTTYPEMUL(f[2],f[3]) - VERTTYPEMUL(f[0],f[5]);
   1255 
   1256 		out.f[6] = VERTTYPEMUL(f[3],f[7]) - VERTTYPEMUL(f[4],f[6]);
   1257 		out.f[7] = VERTTYPEMUL(f[1],f[6]) - VERTTYPEMUL(f[0],f[7]);
   1258 		out.f[8] = VERTTYPEMUL(f[0],f[4]) - VERTTYPEMUL(f[1],f[3]);
   1259 
   1260 		out *= recDet;
   1261 		return out;
   1262 	}
   1263 
   1264 /*!***************************************************************************
   1265  @fn       			transpose
   1266  @return 			transpose 3x3 matrix
   1267  @brief      		Calculates the transpose of this matrix
   1268 *****************************************************************************/
   1269 	PVRTMat3 transpose() const
   1270 	{
   1271 		PVRTMat3 out;
   1272 		out.f[0] = f[0];	out.f[3] = f[1];	out.f[6] = f[2];
   1273 		out.f[1] = f[3];	out.f[4] = f[4];	out.f[7] = f[5];
   1274 		out.f[2] = f[6];	out.f[5] = f[7];	out.f[8] = f[8];
   1275 		return out;
   1276 	}
   1277 
   1278 /*!***************************************************************************
   1279  @fn       			ptr
   1280  @return 			pointer to an array of the elements of this PVRTMat3
   1281  @brief      		Calculates transpose of this matrix
   1282 *****************************************************************************/
   1283 	VERTTYPE *ptr() { return (VERTTYPE*)&f; }
   1284 
   1285 /*!***************************************************************************
   1286 ** Static factory functions
   1287 *****************************************************************************/
   1288 /*!***************************************************************************
   1289  @fn       			Identity
   1290  @return 			a PVRTMat3 representation of the 3x3 identity matrix
   1291  @brief      		Generates an identity matrix
   1292 *****************************************************************************/
   1293 	static PVRTMat3 Identity()
   1294 	{
   1295 		PVRTMat3 out;
   1296 		out.f[0] = 1;out.f[1] = 0;out.f[2] = 0;
   1297 		out.f[3] = 0;out.f[4] = 1;out.f[5] = 0;
   1298 		out.f[6] = 0;out.f[7] = 0;out.f[8] = 1;
   1299 		return out;
   1300 	}
   1301 
   1302 /*!***************************************************************************
   1303  @fn       			RotationX
   1304  @return 			a PVRTMat3 corresponding to the requested rotation
   1305  @brief      		Calculates a matrix corresponding to a rotation of angle
   1306 					degrees about the X axis
   1307 *****************************************************************************/
   1308 	static PVRTMat3 RotationX(VERTTYPE angle);
   1309 
   1310 /*!***************************************************************************
   1311  @fn       			RotationY
   1312  @return 			a PVRTMat3 corresponding to the requested rotation
   1313  @brief      		Calculates a matrix corresponding to a rotation of angle
   1314 					degrees about the Y axis
   1315 *****************************************************************************/
   1316 	static PVRTMat3 RotationY(VERTTYPE angle);
   1317 
   1318 /*!***************************************************************************
   1319  @fn       			RotationZ
   1320  @return 			a PVRTMat3 corresponding to the requested rotation
   1321  @brief      		Calculates a matrix corresponding to a rotation of angle
   1322 					degrees about the Z axis
   1323 *****************************************************************************/
   1324 	static PVRTMat3 RotationZ(VERTTYPE angle);
   1325 
   1326 /*!***************************************************************************
   1327  @fn       			Rotation2D
   1328  @return 			a PVRTMat3 corresponding to the requested rotation
   1329  @brief      		Calculates a matrix corresponding to a rotation of angle
   1330 					degrees about the Z axis
   1331 *****************************************************************************/
   1332 	static PVRTMat3 Rotation2D(VERTTYPE angle)
   1333 	{
   1334 		return RotationZ(angle);
   1335 	}
   1336 
   1337 /*!***************************************************************************
   1338  @fn       			Scale
   1339  @return 			a PVRTMat3 corresponding to the requested scaling transformation
   1340  @brief      		Calculates a matrix corresponding to scaling of fx, fy and fz
   1341 					times in each axis.
   1342 *****************************************************************************/
   1343 	static PVRTMat3 Scale(const VERTTYPE fx,const VERTTYPE fy,const VERTTYPE fz)
   1344 	{
   1345 		return PVRTMat3(fx,0,0,
   1346 						0,fy,0,
   1347 						0,0,fz);
   1348 	}
   1349 
   1350 /*!***************************************************************************
   1351  @fn       			Scale2D
   1352  @return 			a PVRTMat3 corresponding to the requested scaling transformation
   1353  @brief      		Calculates a matrix corresponding to scaling of fx, fy and fz
   1354 					times in each axis.
   1355 *****************************************************************************/
   1356 	static PVRTMat3 Scale2D(const VERTTYPE fx,const VERTTYPE fy)
   1357 	{
   1358 		return PVRTMat3(fx,0,0,
   1359 						0,fy,0,
   1360 						0,0,f2vt(1));
   1361 	}
   1362 
   1363 /*!***************************************************************************
   1364  @fn       			Translation2D
   1365  @return 			a PVRTMat3 corresponding to the requested translation
   1366  @brief      		Calculates a matrix corresponding to a transformation
   1367 					of tx and ty times in each axis.
   1368 *****************************************************************************/
   1369 	static PVRTMat3 Translation2D(const VERTTYPE tx, const VERTTYPE ty)
   1370 	{
   1371 		return PVRTMat3( f2vt(1),    0,  0,
   1372 						 0,    f2vt(1),  0,
   1373 						tx,  		ty,  f2vt(1));
   1374 	}
   1375 
   1376 };
   1377 
   1378 /*!***************************************************************************
   1379  @struct            PVRTMat4
   1380  @brief             4x4 Matrix
   1381 ****************************************************************************/
   1382 struct PVRTMat4 : public PVRTMATRIX
   1383 {
   1384 /*!***************************************************************************
   1385 ** Constructors
   1386 ****************************************************************************/
   1387 /*!***************************************************************************
   1388  @brief      		Blank constructor.
   1389 *****************************************************************************/
   1390 	PVRTMat4(){}
   1391 /*!***************************************************************************
   1392  @brief      		Constructor from array.
   1393  @param[in]			m0	m0 matrix value
   1394  @param[in]			m1	m1 matrix value
   1395  @param[in]			m2	m2 matrix value
   1396  @param[in]			m3	m3 matrix value
   1397  @param[in]			m4	m4 matrix value
   1398  @param[in]			m5	m5 matrix value
   1399  @param[in]			m6	m6 matrix value
   1400  @param[in]			m7	m7 matrix value
   1401  @param[in]			m8	m8 matrix value
   1402  @param[in]			m9	m9 matrix value
   1403  @param[in]			m10	m10 matrix value
   1404  @param[in]			m11	m11 matrix value
   1405  @param[in]			m12	m12 matrix value
   1406  @param[in]			m13	m13 matrix value
   1407  @param[in]			m14	m14 matrix value
   1408  @param[in]			m15	m15 matrix value
   1409 *****************************************************************************/
   1410 	PVRTMat4(VERTTYPE m0,VERTTYPE m1,VERTTYPE m2,VERTTYPE m3,
   1411 		VERTTYPE m4,VERTTYPE m5,VERTTYPE m6,VERTTYPE m7,
   1412 		VERTTYPE m8,VERTTYPE m9,VERTTYPE m10,VERTTYPE m11,
   1413 		VERTTYPE m12,VERTTYPE m13,VERTTYPE m14,VERTTYPE m15)
   1414 	{
   1415 		f[0]=m0;f[1]=m1;f[2]=m2;f[3]=m3;
   1416 		f[4]=m4;f[5]=m5;f[6]=m6;f[7]=m7;
   1417 		f[8]=m8;f[9]=m9;f[10]=m10;f[11]=m11;
   1418 		f[12]=m12;f[13]=m13;f[14]=m14;f[15]=m15;
   1419 	}
   1420 /*!***************************************************************************
   1421  @brief      		Constructor from distinct values.
   1422  @param[in]			mat     A pointer to an array of 16 VERTTYPEs
   1423 *****************************************************************************/
   1424 	PVRTMat4(const VERTTYPE* mat)
   1425 	{
   1426 		VERTTYPE* ptr = f;
   1427 		for(int i=0;i<16;i++)
   1428 		{
   1429 			(*ptr++)=(*mat++);
   1430 		}
   1431 	}
   1432 
   1433 /****************************************************************************
   1434 ** PVRTMat4 OPERATORS
   1435 ****************************************************************************/
   1436 /*!***************************************************************************
   1437  @brief      		Returns value of the element at row r and colun c of the
   1438 					PVRTMat4
   1439  @param[in]				r - row of matrix
   1440  @param[in]				c - column of matrix
   1441  @return 			value of element
   1442 *****************************************************************************/
   1443 	VERTTYPE& operator()(const int r, const int c)
   1444 	{
   1445 		return f[c*4+r];
   1446 	}
   1447 
   1448 /*!***************************************************************************
   1449  @brief      		Returns value of the element at row r and colun c of the
   1450 					PVRTMat4
   1451  @param[in]				r - row of matrix
   1452  @param[in]				c - column of matrix
   1453  @return 			value of element
   1454 *****************************************************************************/
   1455 	const VERTTYPE& operator()(const int r, const int c) const
   1456 	{
   1457 		return f[c*4+r];
   1458 	}
   1459 
   1460 /*!***************************************************************************
   1461  @brief      		Matrix multiplication of two 4x4 matrices.
   1462  @param[in]				rhs another PVRTMat4
   1463  @return 			result of multiplication
   1464 *****************************************************************************/
   1465 	PVRTMat4 operator*(const PVRTMat4& rhs) const;
   1466 
   1467 /*!***************************************************************************
   1468  @brief      		element by element addition operator.
   1469  @param[in]				rhs another PVRTMat4
   1470  @return 			result of addition
   1471 *****************************************************************************/
   1472 	PVRTMat4 operator+(const PVRTMat4& rhs) const
   1473 	{
   1474 		PVRTMat4 out;
   1475 		VERTTYPE const *lptr = f, *rptr = rhs.f;
   1476 		VERTTYPE *outptr = out.f;
   1477 		for(int i=0;i<16;i++)
   1478 		{
   1479 			(*outptr++) = (*lptr++) + (*rptr++);
   1480 		}
   1481 		return out;
   1482 	}
   1483 
   1484 /*!***************************************************************************
   1485  @brief      		element by element subtraction operator.
   1486  @param[in]				rhs another PVRTMat4
   1487  @return 			result of subtraction
   1488 *****************************************************************************/
   1489 	PVRTMat4 operator-(const PVRTMat4& rhs) const
   1490 	{
   1491 		PVRTMat4 out;
   1492 		for(int i=0;i<16;i++)
   1493 		{
   1494 			out.f[i] = f[i]-rhs.f[i];
   1495 		}
   1496 		return out;
   1497 	}
   1498 
   1499 /*!***************************************************************************
   1500  @brief      		element by element addition and assignment operator.
   1501  @param[in]				rhs another PVRTMat4
   1502  @return 			result of addition and assignment
   1503 *****************************************************************************/
   1504 	PVRTMat4& operator+=(const PVRTMat4& rhs)
   1505 	{
   1506 		VERTTYPE *lptr = f;
   1507 		VERTTYPE const *rptr = rhs.f;
   1508 		for(int i=0;i<16;i++)
   1509 		{
   1510 			(*lptr++) += (*rptr++);
   1511 		}
   1512 		return *this;
   1513 	}
   1514 
   1515 /*!***************************************************************************
   1516  @brief      		element by element subtraction and assignment operator.
   1517  @param[in]				rhs another PVRTMat4
   1518  @return 			result of subtraction and assignment
   1519 *****************************************************************************/
   1520 	PVRTMat4& operator-=(const PVRTMat4& rhs)
   1521 	{
   1522 		VERTTYPE *lptr = f;
   1523 		VERTTYPE const *rptr = rhs.f;
   1524 		for(int i=0;i<16;i++)
   1525 		{
   1526 			(*lptr++) -= (*rptr++);
   1527 		}
   1528 		return *this;
   1529 	}
   1530 
   1531 
   1532 /*!***************************************************************************
   1533  @brief      		Matrix multiplication and assignment of two 4x4 matrices.
   1534  @param[in]				rhs another PVRTMat4
   1535  @return 			result of multiplication and assignment
   1536 *****************************************************************************/
   1537 	PVRTMat4& operator*=(const PVRTMat4& rhs)
   1538 	{
   1539 		PVRTMat4 result;
   1540 		// col 0
   1541 		result.f[0] =	VERTTYPEMUL(f[0],rhs.f[0])+VERTTYPEMUL(f[4],rhs.f[1])+VERTTYPEMUL(f[8],rhs.f[2])+VERTTYPEMUL(f[12],rhs.f[3]);
   1542 		result.f[1] =	VERTTYPEMUL(f[1],rhs.f[0])+VERTTYPEMUL(f[5],rhs.f[1])+VERTTYPEMUL(f[9],rhs.f[2])+VERTTYPEMUL(f[13],rhs.f[3]);
   1543 		result.f[2] =	VERTTYPEMUL(f[2],rhs.f[0])+VERTTYPEMUL(f[6],rhs.f[1])+VERTTYPEMUL(f[10],rhs.f[2])+VERTTYPEMUL(f[14],rhs.f[3]);
   1544 		result.f[3] =	VERTTYPEMUL(f[3],rhs.f[0])+VERTTYPEMUL(f[7],rhs.f[1])+VERTTYPEMUL(f[11],rhs.f[2])+VERTTYPEMUL(f[15],rhs.f[3]);
   1545 
   1546 		// col 1
   1547 		result.f[4] =	VERTTYPEMUL(f[0],rhs.f[4])+VERTTYPEMUL(f[4],rhs.f[5])+VERTTYPEMUL(f[8],rhs.f[6])+VERTTYPEMUL(f[12],rhs.f[7]);
   1548 		result.f[5] =	VERTTYPEMUL(f[1],rhs.f[4])+VERTTYPEMUL(f[5],rhs.f[5])+VERTTYPEMUL(f[9],rhs.f[6])+VERTTYPEMUL(f[13],rhs.f[7]);
   1549 		result.f[6] =	VERTTYPEMUL(f[2],rhs.f[4])+VERTTYPEMUL(f[6],rhs.f[5])+VERTTYPEMUL(f[10],rhs.f[6])+VERTTYPEMUL(f[14],rhs.f[7]);
   1550 		result.f[7] =	VERTTYPEMUL(f[3],rhs.f[4])+VERTTYPEMUL(f[7],rhs.f[5])+VERTTYPEMUL(f[11],rhs.f[6])+VERTTYPEMUL(f[15],rhs.f[7]);
   1551 
   1552 		// col 2
   1553 		result.f[8] =	VERTTYPEMUL(f[0],rhs.f[8])+VERTTYPEMUL(f[4],rhs.f[9])+VERTTYPEMUL(f[8],rhs.f[10])+VERTTYPEMUL(f[12],rhs.f[11]);
   1554 		result.f[9] =	VERTTYPEMUL(f[1],rhs.f[8])+VERTTYPEMUL(f[5],rhs.f[9])+VERTTYPEMUL(f[9],rhs.f[10])+VERTTYPEMUL(f[13],rhs.f[11]);
   1555 		result.f[10] =	VERTTYPEMUL(f[2],rhs.f[8])+VERTTYPEMUL(f[6],rhs.f[9])+VERTTYPEMUL(f[10],rhs.f[10])+VERTTYPEMUL(f[14],rhs.f[11]);
   1556 		result.f[11] =	VERTTYPEMUL(f[3],rhs.f[8])+VERTTYPEMUL(f[7],rhs.f[9])+VERTTYPEMUL(f[11],rhs.f[10])+VERTTYPEMUL(f[15],rhs.f[11]);
   1557 
   1558 		// col 3
   1559 		result.f[12] =	VERTTYPEMUL(f[0],rhs.f[12])+VERTTYPEMUL(f[4],rhs.f[13])+VERTTYPEMUL(f[8],rhs.f[14])+VERTTYPEMUL(f[12],rhs.f[15]);
   1560 		result.f[13] =	VERTTYPEMUL(f[1],rhs.f[12])+VERTTYPEMUL(f[5],rhs.f[13])+VERTTYPEMUL(f[9],rhs.f[14])+VERTTYPEMUL(f[13],rhs.f[15]);
   1561 		result.f[14] =	VERTTYPEMUL(f[2],rhs.f[12])+VERTTYPEMUL(f[6],rhs.f[13])+VERTTYPEMUL(f[10],rhs.f[14])+VERTTYPEMUL(f[14],rhs.f[15]);
   1562 		result.f[15] =	VERTTYPEMUL(f[3],rhs.f[12])+VERTTYPEMUL(f[7],rhs.f[13])+VERTTYPEMUL(f[11],rhs.f[14])+VERTTYPEMUL(f[15],rhs.f[15]);
   1563 
   1564 		*this = result;
   1565 		return *this;
   1566 	}
   1567 
   1568 /*!***************************************************************************
   1569  @brief      		element multiplication by a single value.
   1570  @param[in]			rhs    A single value
   1571  @return 			result of multiplication and assignment
   1572 *****************************************************************************/
   1573 	PVRTMat4& operator*(const VERTTYPE rhs)
   1574 	{
   1575 		for (int i=0; i<16; ++i)
   1576 		{
   1577 			f[i]*=rhs;
   1578 		}
   1579 		return *this;
   1580 	}
   1581 /*!***************************************************************************
   1582  @brief      		element multiplication and assignment by a single value.
   1583  @param[in]			rhs    A single value
   1584  @return 			result of multiplication and assignment
   1585 *****************************************************************************/
   1586 	PVRTMat4& operator*=(const VERTTYPE rhs)
   1587 	{
   1588 		for (int i=0; i<16; ++i)
   1589 		{
   1590 			f[i]*=rhs;
   1591 		}
   1592 		return *this;
   1593 	}
   1594 
   1595 /*!***************************************************************************
   1596  @brief      		element assignment operator.
   1597  @param[in]				rhs another PVRTMat4
   1598  @return 			result of assignment
   1599 *****************************************************************************/
   1600 	PVRTMat4& operator=(const PVRTMat4& rhs)
   1601 	{
   1602 		for (int i=0; i<16; ++i)
   1603 		{
   1604 			f[i] =rhs.f[i];
   1605 		}
   1606 		return *this;
   1607 	}
   1608 /*!***************************************************************************
   1609  @brief      		Matrix multiplication of 4x4 matrix and vec3
   1610  @param[in]				rhs a PVRTVec4
   1611  @return 			result of multiplication
   1612 *****************************************************************************/
   1613 	PVRTVec4 operator*(const PVRTVec4& rhs) const
   1614 	{
   1615 		PVRTVec4 out;
   1616 		out.x = VERTTYPEMUL(rhs.x,f[0])+VERTTYPEMUL(rhs.y,f[4])+VERTTYPEMUL(rhs.z,f[8])+VERTTYPEMUL(rhs.w,f[12]);
   1617 		out.y = VERTTYPEMUL(rhs.x,f[1])+VERTTYPEMUL(rhs.y,f[5])+VERTTYPEMUL(rhs.z,f[9])+VERTTYPEMUL(rhs.w,f[13]);
   1618 		out.z = VERTTYPEMUL(rhs.x,f[2])+VERTTYPEMUL(rhs.y,f[6])+VERTTYPEMUL(rhs.z,f[10])+VERTTYPEMUL(rhs.w,f[14]);
   1619 		out.w = VERTTYPEMUL(rhs.x,f[3])+VERTTYPEMUL(rhs.y,f[7])+VERTTYPEMUL(rhs.z,f[11])+VERTTYPEMUL(rhs.w,f[15]);
   1620 
   1621 		return out;
   1622 	}
   1623 
   1624 /*!***************************************************************************
   1625  @brief      		Matrix multiplication and assignment of 4x4 matrix and vec3
   1626  @param[in]				rhs a PVRTVec4
   1627  @return 			result of multiplication and assignment
   1628 *****************************************************************************/
   1629 	PVRTVec4 operator*=(const PVRTVec4& rhs) const
   1630 	{
   1631 		PVRTVec4 out;
   1632 		out.x = VERTTYPEMUL(rhs.x,f[0])+VERTTYPEMUL(rhs.y,f[4])+VERTTYPEMUL(rhs.z,f[8])+VERTTYPEMUL(rhs.w,f[12]);
   1633 		out.y = VERTTYPEMUL(rhs.x,f[1])+VERTTYPEMUL(rhs.y,f[5])+VERTTYPEMUL(rhs.z,f[9])+VERTTYPEMUL(rhs.w,f[13]);
   1634 		out.z = VERTTYPEMUL(rhs.x,f[2])+VERTTYPEMUL(rhs.y,f[6])+VERTTYPEMUL(rhs.z,f[10])+VERTTYPEMUL(rhs.w,f[14]);
   1635 		out.w = VERTTYPEMUL(rhs.x,f[3])+VERTTYPEMUL(rhs.y,f[7])+VERTTYPEMUL(rhs.z,f[11])+VERTTYPEMUL(rhs.w,f[15]);
   1636 
   1637 		return out;
   1638 	}
   1639 
   1640 /*!***************************************************************************
   1641  @brief      		Calculates multiplicative inverse of this matrix
   1642 					The matrix must be of the form :
   1643 					A 0
   1644 					C 1
   1645 					Where A is a 3x3 matrix and C is a 1x3 matrix.
   1646  @return 			inverse mat4
   1647 *****************************************************************************/
   1648 	PVRTMat4 inverse() const;
   1649 
   1650 /*!***************************************************************************
   1651  @fn       			inverseEx
   1652  @return 			inverse mat4
   1653  @brief      		Calculates multiplicative inverse of this matrix
   1654 					Uses a linear equation solver and the knowledge that M.M^-1=I.
   1655 					Use this fn to calculate the inverse of matrices that
   1656 					inverse() cannot.
   1657 *****************************************************************************/
   1658 	PVRTMat4 inverseEx() const
   1659 	{
   1660 		PVRTMat4 out;
   1661 		VERTTYPE 		*ppRows[4];
   1662 		VERTTYPE 		pRes[4];
   1663 		VERTTYPE 		pIn[20];
   1664 		int				i, j;
   1665 
   1666 		for(i = 0; i < 4; ++i)
   1667 			ppRows[i] = &pIn[i * 5];
   1668 
   1669 		/* Solve 4 sets of 4 linear equations */
   1670 		for(i = 0; i < 4; ++i)
   1671 		{
   1672 			for(j = 0; j < 4; ++j)
   1673 			{
   1674 				ppRows[j][0] = PVRTMat4::Identity().f[i + 4 * j];
   1675 				memcpy(&ppRows[j][1], &f[j * 4], 4 * sizeof(VERTTYPE));
   1676 			}
   1677 
   1678 			PVRTLinearEqSolve(pRes, (VERTTYPE**)ppRows, 4);
   1679 
   1680 			for(j = 0; j < 4; ++j)
   1681 			{
   1682 				out.f[i + 4 * j] = pRes[j];
   1683 			}
   1684 		}
   1685 
   1686 		return out;
   1687 	}
   1688 
   1689 /*!***************************************************************************
   1690  @fn       			transpose
   1691  @return 			transpose mat4
   1692  @brief      		Calculates transpose of this matrix
   1693 *****************************************************************************/
   1694 	PVRTMat4 transpose() const
   1695 	{
   1696 		PVRTMat4 out;
   1697 		out.f[0] = f[0];		out.f[1] = f[4];		out.f[2] = f[8];		out.f[3] = f[12];
   1698 		out.f[4] = f[1];		out.f[5] = f[5];		out.f[6] = f[9];		out.f[7] = f[13];
   1699 		out.f[8] = f[2];		out.f[9] = f[6];		out.f[10] = f[10];		out.f[11] = f[14];
   1700 		out.f[12] = f[3];		out.f[13] = f[7];		out.f[14] = f[11];		out.f[15] = f[15];
   1701 		return out;
   1702 	}
   1703 
   1704 /*!***************************************************************************
   1705  @brief      		Alters the translation component of the transformation matrix.
   1706  @param[in]			tx      Distance of translation in x axis
   1707  @param[in]			ty      Distance of translation in y axis
   1708  @param[in]			tz      Distance of translation in z axis
   1709  @return 			Returns this
   1710 *****************************************************************************/
   1711 	PVRTMat4& postTranslate(VERTTYPE tx, VERTTYPE ty, VERTTYPE tz)
   1712 	{
   1713 		f[12] += VERTTYPEMUL(tx,f[0])+VERTTYPEMUL(ty,f[4])+VERTTYPEMUL(tz,f[8]);
   1714 		f[13] += VERTTYPEMUL(tx,f[1])+VERTTYPEMUL(ty,f[5])+VERTTYPEMUL(tz,f[9]);
   1715 		f[14] += VERTTYPEMUL(tx,f[2])+VERTTYPEMUL(ty,f[6])+VERTTYPEMUL(tz,f[10]);
   1716 		f[15] += VERTTYPEMUL(tx,f[3])+VERTTYPEMUL(ty,f[7])+VERTTYPEMUL(tz,f[11]);
   1717 
   1718 //			col(3) += tx * col(0) + ty * col(1) + tz * col(2);
   1719 		return *this;
   1720 	}
   1721 
   1722 /*!***************************************************************************
   1723  @brief      		Alters the translation component of the transformation matrix.
   1724  @param[in]			tvec    Translation vector
   1725  @return 			Returns this
   1726 *****************************************************************************/
   1727 	PVRTMat4& postTranslate(const PVRTVec3& tvec)
   1728 	{
   1729 		return postTranslate(tvec.x, tvec.y, tvec.z);
   1730 	}
   1731 
   1732 /*!***************************************************************************
   1733  @brief      		Translates the matrix from the passed parameters
   1734  @param[in]			tx      Distance of translation in x axis
   1735  @param[in]			ty      Distance of translation in y axis
   1736  @param[in]			tz      Distance of translation in z axis
   1737  @return 			Returns this
   1738 *****************************************************************************/
   1739 	PVRTMat4& preTranslate(VERTTYPE tx, VERTTYPE ty, VERTTYPE tz)
   1740 	{
   1741 		f[0]+=VERTTYPEMUL(f[3],tx);	f[4]+=VERTTYPEMUL(f[7],tx);	f[8]+=VERTTYPEMUL(f[11],tx);	f[12]+=VERTTYPEMUL(f[15],tx);
   1742 		f[1]+=VERTTYPEMUL(f[3],ty);	f[5]+=VERTTYPEMUL(f[7],ty);	f[9]+=VERTTYPEMUL(f[11],ty);	f[13]+=VERTTYPEMUL(f[15],ty);
   1743 		f[2]+=VERTTYPEMUL(f[3],tz);	f[6]+=VERTTYPEMUL(f[7],tz);	f[10]+=VERTTYPEMUL(f[11],tz);	f[14]+=VERTTYPEMUL(f[15],tz);
   1744 
   1745 //			row(0) += tx * row(3);
   1746 //			row(1) += ty * row(3);
   1747 //			row(2) += tz * row(3);
   1748 		return *this;
   1749 	}
   1750 
   1751 /*!***************************************************************************
   1752  @brief      		Translates the matrix from the passed parameters
   1753  @param[in]			tvec    Translation vector
   1754  @return 			Returns the translation defined by the passed parameters
   1755 *****************************************************************************/
   1756 	PVRTMat4& preTranslate(const PVRTVec3& tvec)
   1757 	{
   1758 		return preTranslate(tvec.x, tvec.y, tvec.z);
   1759 	}
   1760 /*!***************************************************************************
   1761  @brief      		Calculates transpose of this matrix
   1762  @return 			pointer to an array of the elements of this PVRTMat4
   1763 *****************************************************************************/
   1764 	VERTTYPE *ptr() { return (VERTTYPE*)&f; }
   1765 
   1766 /*!***************************************************************************
   1767 ** Static factory functions
   1768 *****************************************************************************/
   1769 /*!***************************************************************************
   1770  @brief      		Generates an identity matrix
   1771  @return 			a PVRTMat4 representation of the 4x4 identity matrix
   1772 *****************************************************************************/
   1773 	static PVRTMat4 Identity()
   1774 	{
   1775 		PVRTMat4 out;
   1776 		out.f[0] = f2vt(1);out.f[1] = 0;out.f[2] = 0;out.f[3] = 0;
   1777 		out.f[4] = 0;out.f[5] = f2vt(1);out.f[6] = 0;out.f[7] = 0;
   1778 		out.f[8] = 0;out.f[9] = 0;out.f[10] = f2vt(1);out.f[11] = 0;
   1779 		out.f[12] = 0;out.f[13] = 0;out.f[14] = 0;out.f[15] = f2vt(1);
   1780 		return out;
   1781 	}
   1782 
   1783 /*!***************************************************************************
   1784  @fn       			RotationX
   1785  @return 			a PVRTMat3 corresponding to the requested rotation
   1786  @brief      		Calculates a matrix corresponding to a rotation of angle
   1787 					degrees about the X axis
   1788 *****************************************************************************/
   1789 	static PVRTMat4 RotationX(VERTTYPE angle);
   1790 /*!***************************************************************************
   1791  @fn       			RotationY
   1792  @return 			a PVRTMat3 corresponding to the requested rotation
   1793  @brief      		Calculates a matrix corresponding to a rotation of angle
   1794 					degrees about the Y axis
   1795 *****************************************************************************/
   1796 	static PVRTMat4 RotationY(VERTTYPE angle);
   1797 /*!***************************************************************************
   1798  @fn       			RotationZ
   1799  @return 			a PVRTMat3 corresponding to the requested rotation
   1800  @brief      		Calculates a matrix corresponding to a rotation of angle
   1801 					degrees about the Z axis
   1802 *****************************************************************************/
   1803 	static PVRTMat4 RotationZ(VERTTYPE angle);
   1804 
   1805 /*!***************************************************************************
   1806  @brief      		Calculates a matrix corresponding to scaling of fx, fy and fz
   1807 					times in each axis.
   1808  @return 			a PVRTMat3 corresponding to the requested scaling transformation
   1809 *****************************************************************************/
   1810 	static PVRTMat4 Scale(const VERTTYPE fx,const VERTTYPE fy,const VERTTYPE fz)
   1811 	{
   1812 		return PVRTMat4(fx,0,0,0,
   1813 			0,fy,0,0,
   1814 			0,0,fz,0,
   1815 			0,0,0,f2vt(1));
   1816 	}
   1817 
   1818 /*!***************************************************************************
   1819  @brief      		Calculates a matrix corresponding to scaling of the given vector.
   1820  @return 			a PVRTMat3 corresponding to the requested scaling transformation
   1821 *****************************************************************************/
   1822 	static PVRTMat4 Scale(const PVRTVec3& vec)
   1823 	{
   1824 		return Scale(vec.x, vec.y, vec.z);
   1825 	}
   1826 
   1827 /*!***************************************************************************
   1828  @brief      		Calculates a 4x4 matrix corresponding to a transformation
   1829 					of tx, ty and tz distance in each axis.
   1830  @return 			a PVRTMat4 corresponding to the requested translation
   1831 *****************************************************************************/
   1832 	static PVRTMat4 Translation(const VERTTYPE tx, const VERTTYPE ty, const VERTTYPE tz)
   1833 	{
   1834 		return PVRTMat4(f2vt(1),0,0,0,
   1835 			0,f2vt(1),0,0,
   1836 			0,0,f2vt(1),0,
   1837 			tx,ty,tz,f2vt(1));
   1838 	}
   1839 
   1840 /*!***************************************************************************
   1841  @brief      		Calculates a 4x4 matrix corresponding to a transformation
   1842 					of tx, ty and tz distance in each axis as taken from the
   1843 					given vector.
   1844  @return 			a PVRTMat4 corresponding to the requested translation
   1845 *****************************************************************************/
   1846 
   1847 	static PVRTMat4 Translation(const PVRTVec3& vec)
   1848 	{
   1849 		return Translation(vec.x, vec.y, vec.z);
   1850 	}
   1851 
   1852 /*!***************************************************************************
   1853 ** Clipspace enum
   1854 ** Determines whether clip space Z ranges from -1 to 1 (OGL) or from 0 to 1 (D3D)
   1855 *****************************************************************************/
   1856 	enum eClipspace { OGL, D3D };
   1857 
   1858 /*!***************************************************************************
   1859  @brief      		Translates the matrix from the passed parameters
   1860  @param[in]			left        Left view plane
   1861  @param[in]			top         Top view plane
   1862  @param[in]			right       Right view plane
   1863  @param[in]			bottom      Bottom view plane
   1864  @param[in]			nearPlane   The near rendering plane
   1865  @param[in]			farPlane    The far rendering plane
   1866  @param[in]			cs          Which clipspace convention is being used
   1867  @param[in]			bRotate     Is the viewport in portrait or landscape mode
   1868  @return 			Returns the orthogonal projection matrix defined by the passed parameters
   1869 *****************************************************************************/
   1870 	static PVRTMat4 Ortho(VERTTYPE left, VERTTYPE top, VERTTYPE right,
   1871 		VERTTYPE bottom, VERTTYPE nearPlane, VERTTYPE farPlane, const eClipspace cs, bool bRotate = false)
   1872 	{
   1873 		VERTTYPE rcplmr = VERTTYPEDIV(VERTTYPE(1),(left - right));
   1874 		VERTTYPE rcpbmt = VERTTYPEDIV(VERTTYPE(1),(bottom - top));
   1875 		VERTTYPE rcpnmf = VERTTYPEDIV(VERTTYPE(1),(nearPlane - farPlane));
   1876 
   1877 		PVRTMat4 result;
   1878 
   1879 		if (bRotate)
   1880 		{
   1881 			result.f[0]=0;		result.f[4]=VERTTYPEMUL(2,rcplmr); result.f[8]=0; result.f[12]=VERTTYPEMUL(-(right+left),rcplmr);
   1882 			result.f[1]=VERTTYPEMUL(-2,rcpbmt);	result.f[5]=0;		result.f[9]=0;	result.f[13]=VERTTYPEMUL((top+bottom),rcpbmt);
   1883 		}
   1884 		else
   1885 		{
   1886 			result.f[0]=VERTTYPEMUL(-2,rcplmr);	result.f[4]=0; result.f[8]=0; result.f[12]=VERTTYPEMUL(right+left,rcplmr);
   1887 			result.f[1]=0;		result.f[5]=VERTTYPEMUL(-2,rcpbmt);	result.f[9]=0;	result.f[13]=VERTTYPEMUL((top+bottom),rcpbmt);
   1888 		}
   1889 		if (cs == D3D)
   1890 		{
   1891 			result.f[2]=0;	result.f[6]=0;	result.f[10]=-rcpnmf;	result.f[14]=VERTTYPEMUL(nearPlane,rcpnmf);
   1892 		}
   1893 		else
   1894 		{
   1895 			result.f[2]=0;	result.f[6]=0;	result.f[10]=VERTTYPEMUL(-2,rcpnmf);	result.f[14]=VERTTYPEMUL(nearPlane + farPlane,rcpnmf);
   1896 		}
   1897 		result.f[3]=0;	result.f[7]=0;	result.f[11]=0;	result.f[15]=1;
   1898 
   1899 		return result;
   1900 	}
   1901 
   1902 /*!***************************************************************************
   1903  @fn       			LookAtRH
   1904  @param[in]				vEye position of 'camera'
   1905  @param[in]				vAt target that camera points at
   1906  @param[in]				vUp up vector for camera
   1907  @return 			Returns the view matrix defined by the passed parameters
   1908  @brief      		Create a look-at view matrix for a right hand coordinate
   1909 					system
   1910 *****************************************************************************/
   1911 	static PVRTMat4 LookAtRH(const PVRTVec3& vEye, const PVRTVec3& vAt, const PVRTVec3& vUp)
   1912 		{ return LookAt(vEye, vAt, vUp, true); }
   1913 /*!***************************************************************************
   1914  @fn       			LookAtLH
   1915  @param[in]				vEye position of 'camera'
   1916  @param[in]				vAt target that camera points at
   1917  @param[in]				vUp up vector for camera
   1918  @return 			Returns the view matrix defined by the passed parameters
   1919  @brief      		Create a look-at view matrix for a left hand coordinate
   1920 					system
   1921 *****************************************************************************/
   1922 	static PVRTMat4 LookAtLH(const PVRTVec3& vEye, const PVRTVec3& vAt, const PVRTVec3& vUp)
   1923 		{ return LookAt(vEye, vAt, vUp, false);	}
   1924 
   1925 /*!***************************************************************************
   1926  @brief      	Create a perspective matrix for a right hand coordinate
   1927 				system
   1928  @param[in]			width		width of viewplane
   1929  @param[in]			height		height of viewplane
   1930  @param[in]			nearPlane	near clipping distance
   1931  @param[in]			farPlane	far clipping distance
   1932  @param[in]			cs			cs which clipspace convention is being used
   1933  @param[in]			bRotate is the viewport in portrait or landscape mode
   1934  @return 		Perspective matrix
   1935 *****************************************************************************/
   1936 	static PVRTMat4 PerspectiveRH(VERTTYPE width, VERTTYPE height, VERTTYPE nearPlane,
   1937 		VERTTYPE farPlane, const eClipspace cs, bool bRotate = false)
   1938 		{ return Perspective(width, height, nearPlane, farPlane, cs, true, bRotate); }
   1939 
   1940 /*!***************************************************************************
   1941  @brief      	Create a perspective matrix for a left hand coordinate
   1942 				system
   1943  @param[in]			width		width of viewplane
   1944  @param[in]			height		height of viewplane
   1945  @param[in]			nearPlane	near clipping distance
   1946  @param[in]			farPlane	far clipping distance
   1947  @param[in]			cs			cs which clipspace convention is being used
   1948  @param[in]			bRotate is the viewport in portrait or landscape mode
   1949  @return 		Perspective matrix
   1950 *****************************************************************************/
   1951 	static PVRTMat4 PerspectiveLH(VERTTYPE width, VERTTYPE height, VERTTYPE nearPlane, VERTTYPE farPlane, const eClipspace cs, bool bRotate = false)
   1952 		{ return Perspective(width, height, nearPlane, farPlane, cs, false, bRotate); }
   1953 
   1954 /*!***************************************************************************
   1955  @brief      	Create a perspective matrix for a right hand coordinate
   1956 				system
   1957  @param[in]			width		width of viewplane
   1958  @param[in]			height		height of viewplane
   1959  @param[in]			nearPlane	near clipping distance
   1960  @param[in]			cs			cs which clipspace convention is being used
   1961  @param[in]			bRotate is the viewport in portrait or landscape mode
   1962  @return 		Perspective matrix
   1963 *****************************************************************************/
   1964 	static PVRTMat4 PerspectiveFloatDepthRH(VERTTYPE width, VERTTYPE height, VERTTYPE nearPlane, const eClipspace cs, bool bRotate = false)
   1965 		{ return PerspectiveFloatDepth(width, height, nearPlane, cs, true, bRotate); }
   1966 
   1967 /*!***************************************************************************
   1968  @brief      	Create a perspective matrix for a left hand coordinate
   1969 				system
   1970  @param[in]			width		width of viewplane
   1971  @param[in]			height		height of viewplane
   1972  @param[in]			nearPlane	near clipping distance
   1973  @param[in]			cs			cs which clipspace convention is being used
   1974  @param[in]			bRotate is the viewport in portrait or landscape mode
   1975  @return 		Perspective matrix
   1976 *****************************************************************************/
   1977 	static PVRTMat4 PerspectiveFloatDepthLH(VERTTYPE width, VERTTYPE height, VERTTYPE nearPlane, const eClipspace cs, bool bRotate = false)
   1978 		{ return PerspectiveFloatDepth(width, height, nearPlane, cs, false, bRotate); }
   1979 
   1980 /*!***************************************************************************
   1981  @brief      	Create a perspective matrix for a right hand coordinate
   1982 				system
   1983  @param[in]			fovy		angle of view (vertical)
   1984  @param[in]			aspect		aspect ratio of view
   1985  @param[in]			nearPlane	near clipping distance
   1986  @param[in]			farPlane	far clipping distance
   1987  @param[in]			cs			cs which clipspace convention is being used
   1988  @param[in]			bRotate is the viewport in portrait or landscape mode
   1989  @return 		Perspective matrix
   1990 *****************************************************************************/
   1991 	static PVRTMat4 PerspectiveFovRH(VERTTYPE fovy, VERTTYPE aspect, VERTTYPE nearPlane, VERTTYPE farPlane, const eClipspace cs, bool bRotate = false)
   1992 		{ return PerspectiveFov(fovy, aspect, nearPlane, farPlane, cs, true, bRotate); }
   1993 /*!***************************************************************************
   1994  @brief      	Create a perspective matrix for a left hand coordinate
   1995 				system
   1996  @param[in]			fovy		angle of view (vertical)
   1997  @param[in]			aspect		aspect ratio of view
   1998  @param[in]			nearPlane	near clipping distance
   1999  @param[in]			farPlane	far clipping distance
   2000  @param[in]			cs			cs which clipspace convention is being used
   2001  @param[in]			bRotate is the viewport in portrait or landscape mode
   2002  @return 		Perspective matrix
   2003 *****************************************************************************/
   2004 	static PVRTMat4 PerspectiveFovLH(VERTTYPE fovy, VERTTYPE aspect, VERTTYPE nearPlane, VERTTYPE farPlane, const eClipspace cs, bool bRotate = false)
   2005 		{ return PerspectiveFov(fovy, aspect, nearPlane, farPlane, cs, false, bRotate); }
   2006 
   2007 /*!***************************************************************************
   2008  @brief      	Create a perspective matrix for a right hand coordinate
   2009 				system
   2010  @param[in]			fovy		angle of view (vertical)
   2011  @param[in]			aspect		aspect ratio of view
   2012  @param[in]			nearPlane	near clipping distance
   2013  @param[in]			cs			cs which clipspace convention is being used
   2014  @param[in]			bRotate is the viewport in portrait or landscape mode
   2015  @return 		Perspective matrix
   2016 *****************************************************************************/
   2017 	static PVRTMat4 PerspectiveFovFloatDepthRH(VERTTYPE fovy, VERTTYPE aspect, VERTTYPE nearPlane, const eClipspace cs, bool bRotate = false)
   2018 		{ return PerspectiveFovFloatDepth(fovy, aspect, nearPlane, cs, true, bRotate); }
   2019 /*!***************************************************************************
   2020  @brief      	Create a perspective matrix for a left hand coordinate
   2021 				system
   2022  @param[in]			fovy		angle of view (vertical)
   2023  @param[in]			aspect		aspect ratio of view
   2024  @param[in]			nearPlane	near clipping distance
   2025  @param[in]			cs			cs which clipspace convention is being used
   2026  @param[in]			bRotate is the viewport in portrait or landscape mode
   2027  @return 		Perspective matrix
   2028 *****************************************************************************/
   2029 	static PVRTMat4 PerspectiveFovFloatDepthLH(VERTTYPE fovy, VERTTYPE aspect, VERTTYPE nearPlane, const eClipspace cs, bool bRotate = false)
   2030 		{ return PerspectiveFovFloatDepth(fovy, aspect, nearPlane, cs, false, bRotate); }
   2031 
   2032 /*!***************************************************************************
   2033  @brief      		Create a look-at view matrix
   2034  @param[in]			vEye            Position of 'camera'
   2035  @param[in]			vAt             Target that camera points at
   2036  @param[in]			vUp             Up vector for camera
   2037  @param[in]			bRightHanded    Handedness of coordinate system
   2038  @return 			Returns the view matrix defined by the passed parameters
   2039 *****************************************************************************/
   2040 	static PVRTMat4 LookAt(const PVRTVec3& vEye, const PVRTVec3& vAt, const PVRTVec3& vUp, bool bRightHanded)
   2041 	{
   2042 		PVRTVec3 vForward, vUpNorm, vSide;
   2043 		PVRTMat4 result;
   2044 
   2045 		vForward = (bRightHanded) ? vEye - vAt : vAt - vEye;
   2046 
   2047 		vForward.normalize();
   2048 		vSide   = vUp.cross( vForward);
   2049 		vSide	= vSide.normalized();
   2050 		vUpNorm = vForward.cross(vSide);
   2051 		vUpNorm = vUpNorm.normalized();
   2052 
   2053 		result.f[0]=vSide.x;	result.f[4]=vSide.y;	result.f[8]=vSide.z;		result.f[12]=0;
   2054 		result.f[1]=vUpNorm.x;	result.f[5]=vUpNorm.y;	result.f[9]=vUpNorm.z;		result.f[13]=0;
   2055 		result.f[2]=vForward.x; result.f[6]=vForward.y;	result.f[10]=vForward.z;	result.f[14]=0;
   2056 		result.f[3]=0;			result.f[7]=0;			result.f[11]=0;				result.f[15]=f2vt(1);
   2057 
   2058 
   2059 		result.postTranslate(-vEye);
   2060 		return result;
   2061 	}
   2062 
   2063 /*!***************************************************************************
   2064  @brief      	Create a perspective matrix
   2065  @param[in]		width		Width of viewplane
   2066  @param[in]		height		Height of viewplane
   2067  @param[in]		nearPlane	Near clipping distance
   2068  @param[in]		farPlane	Far clipping distance
   2069  @param[in]		cs			Which clipspace convention is being used
   2070  @param[in]		bRightHanded	Handedness of coordinate system
   2071  @param[in]		bRotate		Is the viewport in portrait or landscape mode
   2072  @return 		Perspective matrix
   2073 *****************************************************************************/
   2074 	static PVRTMat4 Perspective(
   2075 		VERTTYPE width, VERTTYPE height,
   2076 		VERTTYPE nearPlane, VERTTYPE farPlane,
   2077 		const eClipspace cs,
   2078 		bool bRightHanded,
   2079 		bool bRotate = false)
   2080 	{
   2081 		VERTTYPE n2 = VERTTYPEMUL(f2vt(2),nearPlane);
   2082 		VERTTYPE rcpnmf = VERTTYPEDIV(f2vt(1),(nearPlane - farPlane));
   2083 
   2084 		PVRTMat4 result;
   2085 		if (bRotate)
   2086 		{
   2087 			result.f[0] = 0;	result.f[4]=VERTTYPEDIV(-n2,width);	result.f[8]=0;	result.f[12]=0;
   2088 			result.f[1] = VERTTYPEDIV(n2,height);	result.f[5]=0;	result.f[9]=0;	result.f[13]=0;
   2089 		}
   2090 		else
   2091 		{
   2092 			result.f[0] = VERTTYPEDIV(n2,width);	result.f[4]=0;	result.f[8]=0;	result.f[12]=0;
   2093 			result.f[1] = 0;	result.f[5]=VERTTYPEDIV(n2,height);	result.f[9]=0;	result.f[13]=0;
   2094 		}
   2095 		if (cs == D3D)
   2096 		{
   2097 			result.f[2] = 0;	result.f[6]=0;	result.f[10]=VERTTYPEMUL(farPlane,rcpnmf);	result.f[14]=VERTTYPEMUL(VERTTYPEMUL(farPlane,rcpnmf),nearPlane);
   2098 		}
   2099 		else
   2100 		{
   2101 			result.f[2] = 0;	result.f[6]=0;	result.f[10]=VERTTYPEMUL(farPlane+nearPlane,rcpnmf);	result.f[14]=VERTTYPEMUL(VERTTYPEMUL(farPlane,rcpnmf),n2);
   2102 		}
   2103 		result.f[3] = 0;	result.f[7]=0;	result.f[11]=f2vt(-1);	result.f[15]=0;
   2104 
   2105 		if (!bRightHanded)
   2106 		{
   2107 			result.f[10] = VERTTYPEMUL(result.f[10], f2vt(-1));
   2108 			result.f[11] = f2vt(1);
   2109 		}
   2110 
   2111 		return result;
   2112 	}
   2113 
   2114 /*!***************************************************************************
   2115  @brief      	Perspective calculation where far plane is assumed to be at an infinite distance and the screen
   2116 				space Z is inverted
   2117  @param[in]		width		Width of viewplane
   2118  @param[in]		height		Height of viewplane
   2119  @param[in]		nearPlane	Near clipping distance
   2120  @param[in]		cs			Which clipspace convention is being used
   2121  @param[in]		bRightHanded	Handedness of coordinate system
   2122  @param[in]		bRotate		Is the viewport in portrait or landscape mode
   2123  @return 		Perspective matrix
   2124 *****************************************************************************/
   2125 	static PVRTMat4 PerspectiveFloatDepth(
   2126 		VERTTYPE width, VERTTYPE height,
   2127 		VERTTYPE nearPlane,
   2128 		const eClipspace cs,
   2129 		bool bRightHanded,
   2130 		bool bRotate = false)
   2131 	{
   2132 		VERTTYPE n2 = VERTTYPEMUL(2,nearPlane);
   2133 
   2134 		PVRTMat4 result;
   2135 		if (bRotate)
   2136 		{
   2137 			result.f[0] = 0;	result.f[4]=VERTTYPEDIV(-n2,width);	result.f[8]=0;	result.f[12]=0;
   2138 			result.f[1] = VERTTYPEDIV(n2,height);	result.f[5]=0;	result.f[9]=0;	result.f[13]=0;
   2139 		}
   2140 		else
   2141 		{
   2142 			result.f[0] = VERTTYPEDIV(n2,width);	result.f[4]=0;	result.f[8]=0;	result.f[12]=0;
   2143 			result.f[1] = 0;	result.f[5]=VERTTYPEDIV(n2,height);	result.f[9]=0;	result.f[13]=0;
   2144 		}
   2145 		if (cs == D3D)
   2146 		{
   2147 			result.f[2] = 0;	result.f[6]=0;	result.f[10]=0;	result.f[14]=nearPlane;
   2148 		}
   2149 		else
   2150 		{
   2151 			result.f[2] = 0;	result.f[6]=0;	result.f[10]=(bRightHanded?(VERTTYPE)1:(VERTTYPE)-1);	result.f[14]=n2;
   2152 		}
   2153 		result.f[3] = (VERTTYPE)0;	result.f[7]=(VERTTYPE)0;	result.f[11]= (bRightHanded?(VERTTYPE)-1:(VERTTYPE)1);	result.f[15]=(VERTTYPE)0;
   2154 
   2155 		return result;
   2156 	}
   2157 
   2158 /*!***************************************************************************
   2159  @brief      	Perspective calculation where field of view is used instead of near plane dimensions
   2160  @param[in]		fovy		Angle of view (vertical)
   2161  @param[in]		aspect		Aspect ratio of view
   2162  @param[in]		nearPlane	Near clipping distance
   2163  @param[in]		farPlane	Far clipping distance
   2164  @param[in]		cs			Which clipspace convention is being used
   2165  @param[in]		bRightHanded	Handedness of coordinate system
   2166  @param[in]		bRotate		Is the viewport in portrait or landscape mode
   2167  @return 		Perspective matrix
   2168 *****************************************************************************/
   2169 	static PVRTMat4 PerspectiveFov(
   2170 		VERTTYPE fovy, VERTTYPE aspect,
   2171 		VERTTYPE nearPlane, VERTTYPE farPlane,
   2172 		const eClipspace cs,
   2173 		bool bRightHanded,
   2174 		bool bRotate = false)
   2175 	{
   2176 		VERTTYPE height = VERTTYPEMUL(VERTTYPEMUL(f2vt(2.0f),nearPlane),PVRTTAN(VERTTYPEMUL(fovy,f2vt(0.5f))));
   2177 		if (bRotate) return Perspective(height, VERTTYPEDIV(height,aspect), nearPlane, farPlane, cs, bRightHanded, bRotate);
   2178 		return Perspective(VERTTYPEMUL(height,aspect), height, nearPlane, farPlane, cs, bRightHanded, bRotate);
   2179 	}
   2180 
   2181 /*!***************************************************************************
   2182  @brief      	Perspective calculation where field of view is used instead of near plane dimensions
   2183 				and far plane is assumed to be at an infinite distance with inverted Z range
   2184  @param[in]		fovy		Angle of view (vertical)
   2185  @param[in]		aspect		Aspect ratio of view
   2186  @param[in]		nearPlane	Near clipping distance
   2187  @param[in]		cs			Which clipspace convention is being used
   2188  @param[in]		bRightHanded	Handedness of coordinate system
   2189  @param[in]		bRotate		Is the viewport in portrait or landscape mode
   2190  @return 		Perspective matrix
   2191 *****************************************************************************/
   2192 	static PVRTMat4 PerspectiveFovFloatDepth(
   2193 		VERTTYPE fovy, VERTTYPE aspect,
   2194 		VERTTYPE nearPlane,
   2195 		const eClipspace cs,
   2196 		bool bRightHanded,
   2197 		bool bRotate = false)
   2198 	{
   2199 		VERTTYPE height = VERTTYPEMUL(VERTTYPEMUL(2,nearPlane), PVRTTAN(VERTTYPEMUL(fovy,0.5)));
   2200 		if (bRotate) return PerspectiveFloatDepth(height, VERTTYPEDIV(height,aspect), nearPlane, cs, bRightHanded, bRotate);
   2201 		return PerspectiveFloatDepth(VERTTYPEMUL(height,aspect), height, nearPlane, cs, bRightHanded, bRotate);
   2202 	}
   2203 };
   2204 
   2205 #endif /*__PVRTVECTOR_H__*/
   2206 
   2207 /*****************************************************************************
   2208 End of file (PVRTVector.h)
   2209 *****************************************************************************/
   2210 
   2211