2011-04-17 01:00:10 +02:00
# include "common/scummsys.h"
2008-01-26 11:47:23 +00:00
2009-05-08 07:32:33 +00:00
# include "graphics/tinygl/zmath.h"
2005-01-12 15:20:02 +00:00
2009-05-25 13:19:29 +00:00
namespace TinyGL {
2014-06-10 17:14:54 +02:00
// Inversion of a 4x4 matrix.
// It's not just unrolling, this is a different implementation that directly uses the formula whereas the other one is using another method (which is generic and thus, slower)
int MatrixInverse ( float * m ) {
2014-06-07 00:55:08 +02:00
double inv [ 16 ] , det ;
int i ;
inv [ 0 ] = m [ 5 ] * m [ 10 ] * m [ 15 ] -
m [ 5 ] * m [ 11 ] * m [ 14 ] -
m [ 9 ] * m [ 6 ] * m [ 15 ] +
m [ 9 ] * m [ 7 ] * m [ 14 ] +
m [ 13 ] * m [ 6 ] * m [ 11 ] -
m [ 13 ] * m [ 7 ] * m [ 10 ] ;
inv [ 4 ] = - m [ 4 ] * m [ 10 ] * m [ 15 ] +
m [ 4 ] * m [ 11 ] * m [ 14 ] +
m [ 8 ] * m [ 6 ] * m [ 15 ] -
m [ 8 ] * m [ 7 ] * m [ 14 ] -
m [ 12 ] * m [ 6 ] * m [ 11 ] +
m [ 12 ] * m [ 7 ] * m [ 10 ] ;
inv [ 8 ] = m [ 4 ] * m [ 9 ] * m [ 15 ] -
m [ 4 ] * m [ 11 ] * m [ 13 ] -
m [ 8 ] * m [ 5 ] * m [ 15 ] +
m [ 8 ] * m [ 7 ] * m [ 13 ] +
m [ 12 ] * m [ 5 ] * m [ 11 ] -
m [ 12 ] * m [ 7 ] * m [ 9 ] ;
inv [ 12 ] = - m [ 4 ] * m [ 9 ] * m [ 14 ] +
m [ 4 ] * m [ 10 ] * m [ 13 ] +
m [ 8 ] * m [ 5 ] * m [ 14 ] -
m [ 8 ] * m [ 6 ] * m [ 13 ] -
m [ 12 ] * m [ 5 ] * m [ 10 ] +
m [ 12 ] * m [ 6 ] * m [ 9 ] ;
inv [ 1 ] = - m [ 1 ] * m [ 10 ] * m [ 15 ] +
m [ 1 ] * m [ 11 ] * m [ 14 ] +
m [ 9 ] * m [ 2 ] * m [ 15 ] -
m [ 9 ] * m [ 3 ] * m [ 14 ] -
m [ 13 ] * m [ 2 ] * m [ 11 ] +
m [ 13 ] * m [ 3 ] * m [ 10 ] ;
inv [ 5 ] = m [ 0 ] * m [ 10 ] * m [ 15 ] -
m [ 0 ] * m [ 11 ] * m [ 14 ] -
m [ 8 ] * m [ 2 ] * m [ 15 ] +
m [ 8 ] * m [ 3 ] * m [ 14 ] +
m [ 12 ] * m [ 2 ] * m [ 11 ] -
m [ 12 ] * m [ 3 ] * m [ 10 ] ;
inv [ 9 ] = - m [ 0 ] * m [ 9 ] * m [ 15 ] +
m [ 0 ] * m [ 11 ] * m [ 13 ] +
m [ 8 ] * m [ 1 ] * m [ 15 ] -
m [ 8 ] * m [ 3 ] * m [ 13 ] -
m [ 12 ] * m [ 1 ] * m [ 11 ] +
m [ 12 ] * m [ 3 ] * m [ 9 ] ;
inv [ 13 ] = m [ 0 ] * m [ 9 ] * m [ 14 ] -
m [ 0 ] * m [ 10 ] * m [ 13 ] -
m [ 8 ] * m [ 1 ] * m [ 14 ] +
m [ 8 ] * m [ 2 ] * m [ 13 ] +
m [ 12 ] * m [ 1 ] * m [ 10 ] -
m [ 12 ] * m [ 2 ] * m [ 9 ] ;
inv [ 2 ] = m [ 1 ] * m [ 6 ] * m [ 15 ] -
m [ 1 ] * m [ 7 ] * m [ 14 ] -
m [ 5 ] * m [ 2 ] * m [ 15 ] +
m [ 5 ] * m [ 3 ] * m [ 14 ] +
m [ 13 ] * m [ 2 ] * m [ 7 ] -
m [ 13 ] * m [ 3 ] * m [ 6 ] ;
inv [ 6 ] = - m [ 0 ] * m [ 6 ] * m [ 15 ] +
m [ 0 ] * m [ 7 ] * m [ 14 ] +
m [ 4 ] * m [ 2 ] * m [ 15 ] -
m [ 4 ] * m [ 3 ] * m [ 14 ] -
m [ 12 ] * m [ 2 ] * m [ 7 ] +
m [ 12 ] * m [ 3 ] * m [ 6 ] ;
inv [ 10 ] = m [ 0 ] * m [ 5 ] * m [ 15 ] -
m [ 0 ] * m [ 7 ] * m [ 13 ] -
m [ 4 ] * m [ 1 ] * m [ 15 ] +
m [ 4 ] * m [ 3 ] * m [ 13 ] +
m [ 12 ] * m [ 1 ] * m [ 7 ] -
m [ 12 ] * m [ 3 ] * m [ 5 ] ;
inv [ 14 ] = - m [ 0 ] * m [ 5 ] * m [ 14 ] +
m [ 0 ] * m [ 6 ] * m [ 13 ] +
m [ 4 ] * m [ 1 ] * m [ 14 ] -
m [ 4 ] * m [ 2 ] * m [ 13 ] -
m [ 12 ] * m [ 1 ] * m [ 6 ] +
m [ 12 ] * m [ 2 ] * m [ 5 ] ;
inv [ 3 ] = - m [ 1 ] * m [ 6 ] * m [ 11 ] +
m [ 1 ] * m [ 7 ] * m [ 10 ] +
m [ 5 ] * m [ 2 ] * m [ 11 ] -
m [ 5 ] * m [ 3 ] * m [ 10 ] -
m [ 9 ] * m [ 2 ] * m [ 7 ] +
m [ 9 ] * m [ 3 ] * m [ 6 ] ;
inv [ 7 ] = m [ 0 ] * m [ 6 ] * m [ 11 ] -
m [ 0 ] * m [ 7 ] * m [ 10 ] -
m [ 4 ] * m [ 2 ] * m [ 11 ] +
m [ 4 ] * m [ 3 ] * m [ 10 ] +
m [ 8 ] * m [ 2 ] * m [ 7 ] -
m [ 8 ] * m [ 3 ] * m [ 6 ] ;
inv [ 11 ] = - m [ 0 ] * m [ 5 ] * m [ 11 ] +
m [ 0 ] * m [ 7 ] * m [ 9 ] +
m [ 4 ] * m [ 1 ] * m [ 11 ] -
m [ 4 ] * m [ 3 ] * m [ 9 ] -
m [ 8 ] * m [ 1 ] * m [ 7 ] +
m [ 8 ] * m [ 3 ] * m [ 5 ] ;
inv [ 15 ] = m [ 0 ] * m [ 5 ] * m [ 10 ] -
m [ 0 ] * m [ 6 ] * m [ 9 ] -
m [ 4 ] * m [ 1 ] * m [ 10 ] +
m [ 4 ] * m [ 2 ] * m [ 9 ] +
m [ 8 ] * m [ 1 ] * m [ 6 ] -
m [ 8 ] * m [ 2 ] * m [ 5 ] ;
det = m [ 0 ] * inv [ 0 ] + m [ 1 ] * inv [ 4 ] + m [ 2 ] * inv [ 8 ] + m [ 3 ] * inv [ 12 ] ;
if ( det = = 0 )
return false ;
det = 1.0 / det ;
2014-06-10 17:14:54 +02:00
for ( i = 0 ; i < 16 ; i + + ) {
m [ i ] = inv [ i ] * det ;
}
2014-06-07 00:55:08 +02:00
return true ;
2014-05-28 17:46:33 +01:00
}
void Vector3 : : normalize ( ) {
float n ;
2014-06-09 19:53:40 +02:00
n = sqrt ( X * X + Y * Y + Z * Z ) ;
2014-05-28 17:46:33 +01:00
if ( n ! = 0 ) {
2014-06-09 19:53:40 +02:00
X / = n ;
Y / = n ;
Z / = n ;
2014-05-28 17:46:33 +01:00
}
}
2014-05-28 19:27:00 +01:00
Vector4 : : Vector4 ( const Vector3 & vec , float w ) {
2014-06-09 19:53:40 +02:00
X = vec . X ;
Y = vec . Y ;
Z = vec . Z ;
W = w ;
2014-05-28 19:27:00 +01:00
}
2014-06-10 17:14:54 +02:00
void Matrix4 : : identity ( ) {
memset ( _m , 0 , sizeof ( _m ) ) ;
2014-06-08 15:20:27 +02:00
_m [ 0 ] [ 0 ] = 1.0f ;
_m [ 1 ] [ 1 ] = 1.0f ;
_m [ 2 ] [ 2 ] = 1.0f ;
_m [ 3 ] [ 3 ] = 1.0f ;
2014-05-28 17:46:33 +01:00
}
2014-06-08 15:20:27 +02:00
Matrix4 Matrix4 : : transpose ( ) const {
2014-05-28 17:46:33 +01:00
Matrix4 a ;
2014-06-07 21:32:42 +02:00
a . _m [ 0 ] [ 0 ] = this - > _m [ 0 ] [ 0 ] ;
a . _m [ 0 ] [ 1 ] = this - > _m [ 1 ] [ 0 ] ;
a . _m [ 0 ] [ 2 ] = this - > _m [ 2 ] [ 0 ] ;
a . _m [ 0 ] [ 3 ] = this - > _m [ 3 ] [ 0 ] ;
a . _m [ 1 ] , 0 , this - > _m [ 0 ] [ 1 ] ;
a . _m [ 1 ] , 1 , this - > _m [ 1 ] [ 1 ] ;
a . _m [ 1 ] , 2 , this - > _m [ 2 ] [ 1 ] ;
a . _m [ 1 ] , 3 , this - > _m [ 3 ] [ 1 ] ;
a . _m [ 2 ] [ 0 ] = this - > _m [ 0 ] [ 2 ] ;
a . _m [ 2 ] [ 1 ] = this - > _m [ 1 ] [ 2 ] ;
a . _m [ 2 ] [ 2 ] = this - > _m [ 2 ] [ 2 ] ;
a . _m [ 2 ] [ 3 ] = this - > _m [ 3 ] [ 2 ] ;
a . _m [ 3 ] [ 0 ] = this - > _m [ 0 ] [ 3 ] ;
a . _m [ 3 ] [ 1 ] = this - > _m [ 1 ] [ 3 ] ;
a . _m [ 3 ] [ 2 ] = this - > _m [ 2 ] [ 3 ] ;
a . _m [ 3 ] [ 3 ] = this - > _m [ 3 ] [ 3 ] ;
2014-05-28 17:46:33 +01:00
return a ;
}
2014-06-07 21:32:42 +02:00
void Matrix4 : : transpose ( ) {
2014-06-07 00:55:08 +02:00
Matrix4 tmp = * this ;
2014-06-07 21:32:42 +02:00
this - > _m [ 0 ] [ 0 ] = tmp . _m [ 0 ] [ 0 ] ;
this - > _m [ 0 ] [ 1 ] = tmp . _m [ 1 ] [ 0 ] ;
this - > _m [ 0 ] [ 2 ] = tmp . _m [ 2 ] [ 0 ] ;
this - > _m [ 0 ] [ 3 ] = tmp . _m [ 3 ] [ 0 ] ;
2014-06-10 17:14:54 +02:00
this - > _m [ 1 ] [ 0 ] = tmp . _m [ 0 ] [ 1 ] ;
this - > _m [ 1 ] [ 1 ] = tmp . _m [ 1 ] [ 1 ] ;
this - > _m [ 1 ] [ 2 ] = tmp . _m [ 2 ] [ 1 ] ;
this - > _m [ 1 ] [ 3 ] = tmp . _m [ 3 ] [ 1 ] ;
2014-06-07 21:32:42 +02:00
this - > _m [ 2 ] [ 0 ] = tmp . _m [ 0 ] [ 2 ] ;
this - > _m [ 2 ] [ 1 ] = tmp . _m [ 1 ] [ 2 ] ;
this - > _m [ 2 ] [ 2 ] = tmp . _m [ 2 ] [ 2 ] ;
this - > _m [ 2 ] [ 3 ] = tmp . _m [ 3 ] [ 2 ] ;
this - > _m [ 3 ] [ 0 ] = tmp . _m [ 0 ] [ 3 ] ;
this - > _m [ 3 ] [ 1 ] = tmp . _m [ 1 ] [ 3 ] ;
this - > _m [ 3 ] [ 2 ] = tmp . _m [ 2 ] [ 3 ] ;
this - > _m [ 3 ] [ 3 ] = tmp . _m [ 3 ] [ 3 ] ;
2014-06-07 00:55:08 +02:00
}
2014-05-28 19:27:00 +01:00
Matrix4 Matrix4 : : inverseOrtho ( ) const {
2014-05-28 17:46:33 +01:00
Matrix4 a ;
int i , j ;
float s ;
for ( i = 0 ; i < 3 ; i + + ) {
2014-06-10 17:14:54 +02:00
for ( j = 0 ; j < 3 ; j + + ) {
2014-06-08 15:20:27 +02:00
a . _m [ i ] [ j ] = this - > _m [ j ] [ i ] ;
2014-06-10 17:14:54 +02:00
}
2014-06-07 21:32:42 +02:00
a . _m [ 3 ] [ 0 ] = 0.0f ;
a . _m [ 3 ] [ 1 ] = 0.0f ;
a . _m [ 3 ] [ 2 ] = 0.0f ;
a . _m [ 3 ] [ 3 ] = 1.0f ;
2014-05-28 17:46:33 +01:00
for ( i = 0 ; i < 3 ; i + + ) {
s = 0 ;
2014-06-10 17:14:54 +02:00
for ( j = 0 ; j < 3 ; j + + ) {
2014-06-07 21:32:42 +02:00
s - = this - > _m [ j ] [ i ] * this - > _m [ j ] [ 3 ] ;
2014-06-10 17:14:54 +02:00
}
2014-06-07 21:32:42 +02:00
a . _m [ i ] [ 3 ] = s ;
2014-05-28 17:46:33 +01:00
}
}
return a ;
}
2014-05-28 19:27:00 +01:00
Matrix4 Matrix4 : : inverse ( ) const {
2014-06-10 17:14:54 +02:00
Matrix4 result = * this ;
MatrixInverse ( ( float * ) result . _m ) ;
2014-05-28 17:46:33 +01:00
return result ;
}
2014-06-08 15:20:27 +02:00
void Matrix4 : : rotation ( float t , int u ) {
identity ( ) ;
2014-05-28 17:46:33 +01:00
float s , c ;
int v , w ;
if ( ( v = u + 1 ) > 2 )
v = 0 ;
if ( ( w = v + 1 ) > 2 )
w = 0 ;
s = sin ( t ) ;
c = cos ( t ) ;
2014-06-08 15:20:27 +02:00
_m [ v ] [ v ] = c ;
_m [ v ] [ w ] = - s ;
_m [ w ] [ v ] = s ;
_m [ w ] [ w ] = c ;
2014-05-28 17:46:33 +01:00
}
2014-06-10 17:14:54 +02:00
bool Matrix4 : : isIdentity ( ) const {
2014-05-30 00:01:54 +01:00
//NOTE: This might need to be implemented in a fault-tolerant way.
2014-05-28 17:46:33 +01:00
for ( int i = 0 ; i < 4 ; i + + ) {
for ( int j = 0 ; j < 4 ; j + + ) {
if ( i = = j ) {
2014-06-08 19:54:58 +02:00
if ( _m [ i ] [ j ] ! = 1.0 ) {
2014-05-28 17:46:33 +01:00
return false ;
2014-06-08 19:54:58 +02:00
}
} else if ( _m [ i ] [ j ] ! = 0.0 ) {
2014-05-28 17:46:33 +01:00
return false ;
2014-06-08 19:54:58 +02:00
}
2014-05-28 17:46:33 +01:00
}
}
return true ;
}
2014-06-07 21:32:42 +02:00
void Matrix4 : : invert ( ) {
2014-06-10 17:14:54 +02:00
MatrixInverse ( ( float * ) this - > _m ) ;
2014-06-07 00:55:08 +02:00
}
2014-06-07 21:32:42 +02:00
Matrix4 Matrix4 : : frustrum ( float left , float right , float bottom , float top , float nearp , float farp ) {
float x , y , A , B , C , D ;
x = ( float ) ( ( 2.0 * nearp ) / ( right - left ) ) ;
y = ( float ) ( ( 2.0 * nearp ) / ( top - bottom ) ) ;
A = ( right + left ) / ( right - left ) ;
B = ( top + bottom ) / ( top - bottom ) ;
C = - ( farp + nearp ) / ( farp - nearp ) ;
D = ( float ) ( - ( 2.0 * farp * nearp ) / ( farp - nearp ) ) ;
Matrix4 m ;
m . _m [ 0 ] [ 0 ] = x ; m . _m [ 0 ] [ 1 ] = 0 ; m . _m [ 0 ] [ 2 ] = A ; m . _m [ 0 ] [ 3 ] = 0 ;
m . _m [ 1 ] [ 0 ] = 0 ; m . _m [ 1 ] [ 1 ] = y ; m . _m [ 1 ] [ 2 ] = B ; m . _m [ 1 ] [ 3 ] = 0 ;
m . _m [ 2 ] [ 0 ] = 0 ; m . _m [ 2 ] [ 1 ] = 0 ; m . _m [ 2 ] [ 2 ] = C ; m . _m [ 2 ] [ 3 ] = D ;
m . _m [ 3 ] [ 0 ] = 0 ; m . _m [ 3 ] [ 1 ] = 0 ; m . _m [ 3 ] [ 2 ] = - 1 ; m . _m [ 3 ] [ 3 ] = 0 ;
return m ;
}
void Matrix4 : : translate ( float x , float y , float z ) {
_m [ 0 ] [ 3 ] + = _m [ 0 ] [ 0 ] * x + _m [ 0 ] [ 1 ] * y + _m [ 0 ] [ 2 ] * z ;
_m [ 1 ] [ 3 ] + = _m [ 1 ] [ 0 ] * x + _m [ 1 ] [ 1 ] * y + _m [ 1 ] [ 2 ] * z ;
_m [ 2 ] [ 3 ] + = _m [ 2 ] [ 0 ] * x + _m [ 2 ] [ 1 ] * y + _m [ 2 ] [ 2 ] * z ;
_m [ 3 ] [ 3 ] + = _m [ 3 ] [ 0 ] * x + _m [ 3 ] [ 1 ] * y + _m [ 3 ] [ 2 ] * z ;
}
void Matrix4 : : scale ( float x , float y , float z ) {
_m [ 0 ] [ 0 ] * = x ; _m [ 0 ] [ 1 ] * = y ; _m [ 0 ] [ 2 ] * = z ;
_m [ 1 ] [ 0 ] * = x ; _m [ 1 ] [ 1 ] * = y ; _m [ 1 ] [ 2 ] * = z ;
_m [ 2 ] [ 0 ] * = x ; _m [ 2 ] [ 1 ] * = y ; _m [ 2 ] [ 2 ] * = z ;
_m [ 3 ] [ 0 ] * = x ; _m [ 3 ] [ 1 ] * = y ; _m [ 3 ] [ 2 ] * = z ;
}
2009-05-25 13:19:29 +00:00
} // end of namespace TinyGL