23 #include "worldsimconfig.h"
30 #include <gsl/gsl_blas.h>
72 operator QString()
const;
91 wVector getEuleroAngles()
const;
117 void transformTriplex(
real* dst,
int dstStrideInBytes,
real* src,
int srcStrideInBytes,
int count)
const;
155 #include "wquaternion.h"
159 inline wMatrix::wMatrix() : x_ax(&data[0]), y_ax(&data[4]), z_ax(&data[8]), w_pos(&data[12]) {
194 x2 = 2.0 * rotation.q1 * rotation.q1;
195 y2 = 2.0 * rotation.q2 * rotation.q2;
196 z2 = 2.0 * rotation.q3 * rotation.q3;
199 xy = 2.0 * rotation.q1 * rotation.q2;
200 xz = 2.0 * rotation.q1 * rotation.q3;
201 xw = 2.0 * rotation.q1 * rotation.q0;
202 yz = 2.0 * rotation.q2 * rotation.q3;
203 yw = 2.0 * rotation.q2 * rotation.q0;
204 zw = 2.0 * rotation.q3 * rotation.q0;
206 x_ax =
wVector( 1.0-y2-z2, xy+zw, xz-yw, 0.0 );
207 y_ax =
wVector( xy-zw, 1.0-x2-z2, yz+xw, 0.0 );
208 z_ax =
wVector( xz+yw, yz-xw, 1.0-x2-y2, 0.0 );
210 w_pos.x = position.x;
211 w_pos.y = position.y;
212 w_pos.z = position.z;
221 x_ax[0]=rot[0]; x_ax[1]=rot[1]; x_ax[2]=rot[2]; x_ax[3]=0.0 ;
222 y_ax[0]=rot[4]; y_ax[1]=rot[5]; y_ax[2]=rot[6]; y_ax[3]=0.0 ;
223 z_ax[0]=rot[8]; z_ax[1]=rot[9]; z_ax[2]=rot[10]; z_ax[3]=0.0 ;
224 w_pos[0]=pos[0]; w_pos[1]=pos[1]; w_pos[2]=pos[2]; w_pos[3]=1.0 ;
227 inline wMatrix::operator QString()
const {
228 return QString(
"[%1, %2, %3, %4]").arg(x_ax).arg(y_ax).arg(z_ax).arg(w_pos);
236 memcpy(data, other.data, 16 *
sizeof(
real));
241 if (&other ==
this) {
245 memcpy(data, other.data, 16 *
sizeof(
real));
260 wVector(x_ax.y, y_ax.y, z_ax.y, 0.0f),
261 wVector(x_ax.z, y_ax.z, z_ax.z, 0.0f),
262 wVector(- (w_pos % x_ax), - (w_pos % y_ax), - (w_pos % z_ax), 1.0f));
267 wVector(x_ax.y, y_ax.y, z_ax.y, 0.0f),
268 wVector(x_ax.z, y_ax.z, z_ax.z, 0.0f),
269 wVector(0.0f, 0.0f, 0.0f, 1.0f));
274 wVector(x_ax.y, y_ax.y, z_ax.y, w_pos.y),
275 wVector(x_ax.z, y_ax.z, z_ax.z, w_pos.z),
276 wVector(x_ax.w, y_ax.w, z_ax.w, w_pos.w));
283 const real minSin = 0.99995f;
286 yaw = asin( -
min(
max( matrix[0][2], -0.999999 ), 0.999999) );
287 if( matrix[0][2] < minSin ) {
288 if( matrix[0][2] > -minSin ) {
289 roll = atan2( matrix[0][1], matrix[0][0] );
290 pitch = atan2( matrix[1][2], matrix[2][2] );
292 pitch = atan2( matrix[1][0], matrix[1][1] );
295 pitch = -atan2( matrix[1][0], matrix[1][1] );
298 return wVector(pitch, yaw, roll, 0.0);
328 wVector diffCentre = ret.w_pos - centre;
330 ret.w_pos = diffCentre + centre;
336 return wMatrix (
wVector (A[0][0] * B[0][0] + A[0][1] * B[1][0] + A[0][2] * B[2][0] + A[0][3] * B[3][0],
337 A[0][0] * B[0][1] + A[0][1] * B[1][1] + A[0][2] * B[2][1] + A[0][3] * B[3][1],
338 A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2] * B[2][2] + A[0][3] * B[3][2],
339 A[0][0] * B[0][3] + A[0][1] * B[1][3] + A[0][2] * B[2][3] + A[0][3] * B[3][3]),
340 wVector (A[1][0] * B[0][0] + A[1][1] * B[1][0] + A[1][2] * B[2][0] + A[1][3] * B[3][0],
341 A[1][0] * B[0][1] + A[1][1] * B[1][1] + A[1][2] * B[2][1] + A[1][3] * B[3][1],
342 A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2] * B[2][2] + A[1][3] * B[3][2],
343 A[1][0] * B[0][3] + A[1][1] * B[1][3] + A[1][2] * B[2][3] + A[1][3] * B[3][3]),
344 wVector (A[2][0] * B[0][0] + A[2][1] * B[1][0] + A[2][2] * B[2][0] + A[2][3] * B[3][0],
345 A[2][0] * B[0][1] + A[2][1] * B[1][1] + A[2][2] * B[2][1] + A[2][3] * B[3][1],
346 A[2][0] * B[0][2] + A[2][1] * B[1][2] + A[2][2] * B[2][2] + A[2][3] * B[3][2],
347 A[2][0] * B[0][3] + A[2][1] * B[1][3] + A[2][2] * B[2][3] + A[2][3] * B[3][3]),
355 return wVector( v.x * x_ax.x + v.y * y_ax.x + v.z * z_ax.x,
356 v.x * x_ax.y + v.y * y_ax.y + v.z * z_ax.y,
357 v.x * x_ax.z + v.y * y_ax.z + v.z * z_ax.z);
361 return wVector( v%x_ax, v%y_ax, v%z_ax );
377 dstStrideInBytes /=
sizeof(
real);
378 srcStrideInBytes /=
sizeof(
real);
380 for(
int i=0; i<count; i++ ) {
384 dst[0] = x*x_ax.x + y*y_ax.x + z*z_ax.x + w_pos.x;
385 dst[1] = x*x_ax.y + y*y_ax.y + z*z_ax.y + w_pos.y;
386 dst[2] = x*x_ax.z + y*y_ax.z + z*z_ax.z + w_pos.z;
387 dst += dstStrideInBytes;
388 src += srcStrideInBytes;
396 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 4, 4, 4, 1.0, A.data, 4, B.data, 4, 0.0, res.data, 4);
400 return wMatrix (
wVector (A[0][0] * B[0][0] + A[0][1] * B[1][0] + A[0][2] * B[2][0] + A[0][3] * B[3][0],
401 A[0][0] * B[0][1] + A[0][1] * B[1][1] + A[0][2] * B[2][1] + A[0][3] * B[3][1],
402 A[0][0] * B[0][2] + A[0][1] * B[1][2] + A[0][2] * B[2][2] + A[0][3] * B[3][2],
403 A[0][0] * B[0][3] + A[0][1] * B[1][3] + A[0][2] * B[2][3] + A[0][3] * B[3][3]),
404 wVector (A[1][0] * B[0][0] + A[1][1] * B[1][0] + A[1][2] * B[2][0] + A[1][3] * B[3][0],
405 A[1][0] * B[0][1] + A[1][1] * B[1][1] + A[1][2] * B[2][1] + A[1][3] * B[3][1],
406 A[1][0] * B[0][2] + A[1][1] * B[1][2] + A[1][2] * B[2][2] + A[1][3] * B[3][2],
407 A[1][0] * B[0][3] + A[1][1] * B[1][3] + A[1][2] * B[2][3] + A[1][3] * B[3][3]),
408 wVector (A[2][0] * B[0][0] + A[2][1] * B[1][0] + A[2][2] * B[2][0] + A[2][3] * B[3][0],
409 A[2][0] * B[0][1] + A[2][1] * B[1][1] + A[2][2] * B[2][1] + A[2][3] * B[3][1],
410 A[2][0] * B[0][2] + A[2][1] * B[1][2] + A[2][2] * B[2][2] + A[2][3] * B[3][2],
411 A[2][0] * B[0][3] + A[2][1] * B[1][3] + A[2][2] * B[2][3] + A[2][3] * B[3][3]),
412 wVector (A[3][0] * B[0][0] + A[3][1] * B[1][0] + A[3][2] * B[2][0] + A[3][3] * B[3][0],
413 A[3][0] * B[0][1] + A[3][1] * B[1][1] + A[3][2] * B[2][1] + A[3][3] * B[3][1],
414 A[3][0] * B[0][2] + A[3][1] * B[1][2] + A[3][2] * B[2][2] + A[3][3] * B[3][2],
415 A[3][0] * B[0][3] + A[3][1] * B[1][3] + A[3][2] * B[2][3] + A[3][3] * B[3][3]));
427 tmp.w = globalPlane % w_pos + globalPlane.w;
433 real zz = (x_ax.y*y_ax.z - x_ax.z*y_ax.y)*z_ax.x
434 + (x_ax.z*y_ax.x - x_ax.x*y_ax.z)*z_ax.y
435 + (x_ax.x*y_ax.y - x_ax.y*y_ax.x)*z_ax.z;
439 if( fabs( zz ) < 0.99f) {
462 wVector (0.0f, 1.0f, 0.0f, 0.0f),
463 wVector (0.0f, 0.0f, 1.0f, 0.0f),
464 wVector (0.0f, 0.0f, 0.0f, 1.0f) );
469 wVector (0.0f, 0.0f, 0.0f, 0.0f),
470 wVector (0.0f, 0.0f, 0.0f, 0.0f),
471 wVector (0.0f, 0.0f, 0.0f, 0.0f) );
480 if( fabs(Z.z) > 0.577f ) {
481 X = Z *
wVector( -Z.y, Z.z, 0.0f );
483 X = Z *
wVector( -Z.y, Z.x, 0.0f );
495 real cosAng = cos(ang);
496 real sinAng = sin(ang);
498 wVector(0.0f, cosAng, sinAng, 0.0f),
499 wVector(0.0f, -sinAng, cosAng, 0.0f),
500 wVector(0.0f, 0.0f, 0.0f, 1.0f) );
504 real cosAng = cos(ang);
505 real sinAng = sin(ang);
507 wVector (0.0f, 1.0f, 0.0f, 0.0f),
508 wVector (sinAng, 0.0f, cosAng, 0.0f),
509 wVector (0.0f, 0.0f, 0.0f, 1.0f) );
513 real cosAng = cos(ang);
514 real sinAng = sin(ang);
516 wVector (-sinAng, cosAng, 0.0f, 0.0f),
517 wVector ( 0.0f, 0.0f, 1.0f, 0.0f),
518 wVector ( 0.0f, 0.0f, 0.0f, 1.0f) );
static wMatrix identity()
create an identity matrix
wMatrix operator*(const wMatrix &B) const
matrix multiplication
wMatrix()
Construct an unintialized matrix.
static wMatrix grammSchmidt(const wVector &dir)
calculate an orthonormal matrix with the Z vector pointing on the dir direction, and the Y and Z are ...
wVector transformPlane(const wVector &localPlane) const
...
wVector getEuleroAngles() const
return the Eulero angle of rotation
wVector untransformPlane(const wVector &globalPlane) const
...
wMatrix inverse() const
calculate the inverse of transformation matrix
FARSA_UTIL_TEMPLATE const T max(const T &t1, const U &t2)
wVectorT< true > & operator[](int i)
indexing operator
wVectorT & normalize()
Normalize the vector.
static wMatrix roll(real ang)
create a rotation around Z axis of ang radians
static wMatrix pitch(real ang)
create a rotation around X axis of ang radians
bool sanityCheck()
return true if the transformation matrix is valid
wMatrix transpose4X4() const
full transposition of the transformation matrix
wVectorT & rotateAround(wVectorT< false > axis, real theta)
rotate the position indicated by this wVectorT around the axis by the angle theta ...
wMatrix & operator=(const wMatrix &other)
Copy operator.
wMatrix transpose() const
transpose the rotation sub-matrix
void sanitifize()
change the matrix in order to get a valid one that represent the same rotation/translation ...
wVector rotateVector(const wVector &v) const
rotate the vector v, it doesn't apply position transformation
wMatrix rotateAround(const wVector &axis, const wVector ¢re, real angle) const
Rotate this matrix around the axis, and position passed of radians specified.
wVector untransformVector(const wVector &v) const
invert the rotation and translation on the vector v
wMatrix rotateMatrix(const wMatrix &tm) const
rotate the matrix passed by rotation specified by this and return a copy
static wMatrix yaw(real ang)
create a rotation around Y axis of ang radians
FARSA_UTIL_TEMPLATE const T min(const T &t1, const U &t2)
void transformTriplex(real *dst, int dstStrideInBytes, real *src, int srcStrideInBytes, int count) const
apply transformation to a chunck of vectors
wVector unrotateVector(const wVector &v) const
inverte the rotation of this matrix on the vector v
wVector transformVector(const wVector &v) const
apply both rotation and translation to the vector v
static wMatrix zero()
create a zero matrix