Warning, /include/Geant4/tools/lina/mat4 is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_mat4
0005 #define tools_mat4
0006
0007 #include "mat"
0008
0009 namespace tools {
0010
0011 template <class T>
0012 class mat4 : public mat<T,4> {
0013 typedef mat<T,4> parent;
0014 typedef mat<T,4> pr;
0015 public:
0016 mat4():parent() {}
0017 mat4(const mat<T,4>& a_from):parent(a_from){}
0018 virtual ~mat4() {}
0019 public:
0020 mat4(const mat4& a_from):parent(a_from){}
0021 mat4& operator=(const mat4& a_from){
0022 parent::operator=(a_from);
0023 return *this;
0024 }
0025 public:
0026 mat4(const T& a_00,const T& a_01,const T& a_02,const T& a_03, //first row
0027 const T& a_10,const T& a_11,const T& a_12,const T& a_13, //second row
0028 const T& a_20,const T& a_21,const T& a_22,const T& a_23, //third row
0029 const T& a_30,const T& a_31,const T& a_32,const T& a_33) //fourth row
0030 {
0031 set_matrix(a_00,a_01,a_02,a_03,
0032 a_10,a_11,a_12,a_13,
0033 a_20,a_21,a_22,a_23,
0034 a_30,a_31,a_32,a_33);
0035 }
0036 public:
0037 void set_matrix(const mat4<T>& a_m) {parent::set_matrix(a_m);}
0038 void set_matrix(
0039 const T& a_00,const T& a_01,const T& a_02,const T& a_03, //1 row
0040 const T& a_10,const T& a_11,const T& a_12,const T& a_13, //2 row
0041 const T& a_20,const T& a_21,const T& a_22,const T& a_23, //3 row
0042 const T& a_30,const T& a_31,const T& a_32,const T& a_33) //4 row
0043 {
0044 //a_<R><C>
0045 //pr::m_vec[R + C * 4];
0046 pr::m_vec[0] = a_00;pr::m_vec[4] = a_01;pr::m_vec[ 8] = a_02;pr::m_vec[12] = a_03;
0047 pr::m_vec[1] = a_10;pr::m_vec[5] = a_11;pr::m_vec[ 9] = a_12;pr::m_vec[13] = a_13;
0048 pr::m_vec[2] = a_20;pr::m_vec[6] = a_21;pr::m_vec[10] = a_22;pr::m_vec[14] = a_23;
0049 pr::m_vec[3] = a_30;pr::m_vec[7] = a_31;pr::m_vec[11] = a_32;pr::m_vec[15] = a_33;
0050 }
0051
0052 void set_scale(const T& a_s) {_set_scale(a_s,a_s,a_s,pr::m_vec);}
0053 void set_scale(const T& a_1,const T& a_2,const T& a_3) {_set_scale(a_1,a_2,a_3,pr::m_vec);}
0054 void set_translate(const T& a_x,const T& a_y,const T& a_z) {_set_translate(a_x,a_y,a_z,pr::m_vec);}
0055 void set_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T(*a_sin)(T),T(*a_cos)(T)) {
0056 _set_rotate(a_x,a_y,a_z,a_angle,pr::m_vec,a_sin,a_cos);
0057 }
0058 void set_ortho(const T& a_l,const T& a_r, //left,right
0059 const T& a_b,const T& a_t, //bottom,top
0060 const T& a_n,const T& a_f) { //znear,zfar
0061 // from man glOrtho.
0062 T tx = -(a_r+a_l)/(a_r-a_l);
0063 T ty = -(a_t+a_b)/(a_t-a_b);
0064 T tz = -(a_f+a_n)/(a_f-a_n);
0065
0066 T a_00,a_01,a_02,a_03;
0067 T a_10,a_11,a_12,a_13;
0068 T a_20,a_21,a_22,a_23;
0069 T a_30,a_31,a_32,a_33;
0070 a_00 = 2/(a_r-a_l);a_01 = 0;a_02 = 0;a_03 = tx;
0071 a_10 = 0;a_11 = 2/(a_t-a_b);a_12 = 0;a_13 = ty;
0072 a_20 = 0;a_21 = 0;a_22 = -2/(a_f-a_n);a_23 = tz;
0073 a_30 = 0;a_31 = 0;a_32 = 0;a_33 = 1;
0074 set_matrix(a_00,a_01,a_02,a_03, //1 row
0075 a_10,a_11,a_12,a_13, //2 row
0076 a_20,a_21,a_22,a_23, //3 row
0077 a_30,a_31,a_32,a_33); //4 row
0078
0079 //NOTE : Z(x,y, z,1) = -2z/(f-n)+tz = [-2z-f-n]/(f-n)
0080 // W(x,y, z,1) = 1 -> Z/W = Z
0081 // Z(x,y,-n,1) = -1
0082 // Z(x,y,-f,1) = 1
0083
0084 // Z(x,y,-(f+n)/2,1) = 0
0085
0086 // X(x,0, z,1) = 2x/(r-l)+tx = [2x-r-l]/(r-l)
0087 // X(r,0, z,1) = 1
0088
0089 // the view direction is then (0,0,1) in the final projection.
0090 }
0091 void set_frustum(const T& a_l,const T& a_r, //left,right
0092 const T& a_b,const T& a_t, //bottom,top
0093 const T& a_n,const T& a_f) { //znear,zfar
0094 // from man glFrustum.
0095 T A = (a_r+a_l)/(a_r-a_l);
0096 T B = (a_t+a_b)/(a_t-a_b);
0097 T C = -(a_f+a_n)/(a_f-a_n);
0098 T D = -(2*a_f*a_n)/(a_f-a_n);
0099
0100 T a_00,a_01,a_02,a_03;
0101 T a_10,a_11,a_12,a_13;
0102 T a_20,a_21,a_22,a_23;
0103 T a_30,a_31,a_32,a_33;
0104 a_00 = (2*a_n)/(a_r-a_l);a_01 = 0;a_02 = A;a_03 = 0;
0105 a_10 = 0;a_11 = (2*a_n)/(a_t-a_b);a_12 = B;a_13 = 0;
0106 a_20 = 0;a_21 = 0;a_22 = C;a_23 = D;
0107 a_30 = 0;a_31 = 0;a_32 = -1;a_33 = 0;
0108 set_matrix(a_00,a_01,a_02,a_03, //1 row
0109 a_10,a_11,a_12,a_13, //2 row
0110 a_20,a_21,a_22,a_23, //3 row
0111 a_30,a_31,a_32,a_33); //4 row
0112
0113 //NOTE : Z(x,y, z,1) = C*z+D = -[(f+n)*z+2*f*n]/(f-n)
0114
0115 // Z(x,y,-n,1) = -[-fn-nn+2fn]/(f-n) = -[fn-nn]/(f-n) = -n
0116 // W(x,y,-n,1) = n
0117 // -> Z/W(x,y,-n,1) = -1
0118
0119 // Z(x,y,-2fn/(f+n),1) = 0
0120 // -> Z/W = 0
0121
0122 // Z(x,y,-f,1) = -[-ff-fn+2fn]/(f-n) = -[fn-ff]/(f-n) = f
0123 // W(x,y,-f,1) = f
0124 // -> Z/W(x,y,-f,1) = 1
0125
0126 // X(x,0, z,1) = 2nx/(r-l)+z(r+l)/(r-l) = [2nx+zr+zl]/(r-l)
0127 // X(r,0,-n,1) = [nr-nl]/(r-l) = n
0128 // W(r,0,-n,1) = n
0129 // -> X/W(r,0,-n,1) = 1
0130
0131 // X(l,0,-n,1) = (2nl-n(r+l))/(r-l) = -n
0132 // W(l,0,-n,1) = n
0133 // -> X/W(l,0,-n,1) = -1
0134
0135 // lrbt corners are in plane z=-1 at xy=+/-1.
0136
0137 // eye ?
0138 // eye before ? (0,0,z,1) -> (zA,zB,zC+D,-z) /W -> (-A,-B,-(C+D/z),1)
0139 // z=0 -> (0,0,D=-2fn(f-n),0)
0140
0141 }
0142
0143 void get_translate(T& a_x,T& a_y,T& a_z) const {
0144 a_x = pr::m_vec[12];
0145 a_y = pr::m_vec[13];
0146 a_z = pr::m_vec[14];
0147 }
0148
0149 void no_translate() {
0150 pr::m_vec[12] = 0;
0151 pr::m_vec[13] = 0;
0152 pr::m_vec[14] = 0;
0153 }
0154
0155 public:
0156 void mul_4(T& a_x,T& a_y,T& a_z,T& a_p) const {
0157 // a_[x,y,z,p] = this * a_[x,y,z,p]
0158 //pr::m_vec[R + C * 4];
0159 //pr::m_vec[0]= 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0160 //pr::m_vec[1]= 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0161 //pr::m_vec[2]= 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0162 //pr::m_vec[3]= 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0163 T x = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z+pr::m_vec[12]*a_p;
0164 T y = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z+pr::m_vec[13]*a_p;
0165 T z = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z+pr::m_vec[14]*a_p;
0166 T p = pr::m_vec[3]*a_x+pr::m_vec[7]*a_y+pr::m_vec[11]*a_z+pr::m_vec[15]*a_p;
0167 a_x = x;
0168 a_y = y;
0169 a_z = z;
0170 a_p = p;
0171 }
0172 void mul_4_opt(T& a_x,T& a_y,T& a_z,T& a_p,T a_tmp[4]) const {
0173 // a_[x,y,z,p] = this * a_[x,y,z,p]
0174 //pr::m_vec[R + C * 4];
0175 //pr::m_vec[0]= 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0176 //pr::m_vec[1]= 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0177 //pr::m_vec[2]= 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0178 //pr::m_vec[3]= 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0179 a_tmp[0] = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z+pr::m_vec[12]*a_p;
0180 a_tmp[1] = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z+pr::m_vec[13]*a_p;
0181 a_tmp[2] = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z+pr::m_vec[14]*a_p;
0182 a_tmp[3] = pr::m_vec[3]*a_x+pr::m_vec[7]*a_y+pr::m_vec[11]*a_z+pr::m_vec[15]*a_p;
0183 a_x = a_tmp[0];
0184 a_y = a_tmp[1];
0185 a_z = a_tmp[2];
0186 a_p = a_tmp[3];
0187 }
0188 void mul_3(T& a_x,T& a_y,T& a_z) const {
0189 // a_[x,y,z] = this * a_[x,y,z]
0190 //pr::m_vec[R + C * 4];
0191 //pr::m_vec[0]= 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0192 //pr::m_vec[1]= 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0193 //pr::m_vec[2]= 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0194 //pr::m_vec[3]= 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0195 T x = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z+pr::m_vec[12];
0196 T y = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z+pr::m_vec[13];
0197 T z = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z+pr::m_vec[14];
0198 a_x = x;
0199 a_y = y;
0200 a_z = z;
0201 }
0202 void mul_3_opt(T& a_x,T& a_y,T& a_z,T a_tmp[3]) const {
0203 // a_[x,y,z] = this * a_[x,y,z]
0204 //pr::m_vec[R + C * 4];
0205 //pr::m_vec[0]= 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0206 //pr::m_vec[1]= 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0207 //pr::m_vec[2]= 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0208 //pr::m_vec[3]= 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0209 a_tmp[0] = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z+pr::m_vec[12];
0210 a_tmp[1] = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z+pr::m_vec[13];
0211 a_tmp[2] = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z+pr::m_vec[14];
0212 a_x = a_tmp[0];
0213 a_y = a_tmp[1];
0214 a_z = a_tmp[2];
0215 }
0216 void mul_2(T& a_x,T& a_y) const {
0217 // a_[x,y] = this * a_[x,y]
0218 //pr::m_vec[R + C * 4];
0219 //pr::m_vec[0]= 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0220 //pr::m_vec[1]= 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0221 //pr::m_vec[2]= 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0222 //pr::m_vec[3]= 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0223 T x = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[12];
0224 T y = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[13];
0225 a_x = x;
0226 a_y = y;
0227 }
0228
0229 void mul_dir_3(T& a_x,T& a_y,T& a_z) const {
0230 // used to multiply normals.
0231 // a_[x,y,z] = rot_part(this) * a_[x,y,z]
0232
0233 T x = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z;
0234 T y = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z;
0235 T z = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z;
0236 a_x = x;
0237 a_y = y;
0238 a_z = z;
0239 }
0240 void mul_dir_3_opt(T& a_x,T& a_y,T& a_z,T a_tmp[3]) const {
0241 // used to multiply normals.
0242 // a_[x,y,z] = rot_part(this) * a_[x,y,z]
0243
0244 a_tmp[0] = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z;
0245 a_tmp[1] = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z;
0246 a_tmp[2] = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z;
0247 a_x = a_tmp[0];
0248 a_y = a_tmp[1];
0249 a_z = a_tmp[2];
0250 }
0251
0252 void mul_trans_3(T& a_x,T& a_y,T& a_z) const {
0253 // used in sg::healpix.
0254 // a_[x,y,z] = trans_part(this) * a_[x,y,z]
0255 a_x += pr::m_vec[12];
0256 a_y += pr::m_vec[13];
0257 a_z += pr::m_vec[14];
0258 }
0259
0260 template <class VEC>
0261 void mul_dir_3(VEC& a_dir) const {mul_dir_3(a_dir[0],a_dir[1],a_dir[2]);}
0262
0263 void mul_scale(const T& a_sx,const T& a_sy,const T& a_sz) {
0264 // this = this * mat4_scale(a_s[x,y,z]
0265 //pr::m_vec[R + C * 4];
0266 //pr::m_vec[0]= 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0267 //pr::m_vec[1]= 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0268 //pr::m_vec[2]= 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0269 //pr::m_vec[3]= 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0270 pr::m_vec[0] *= a_sx;
0271 pr::m_vec[1] *= a_sx;
0272 pr::m_vec[2] *= a_sx;
0273 pr::m_vec[3] *= a_sx;
0274
0275 pr::m_vec[4] *= a_sy;
0276 pr::m_vec[5] *= a_sy;
0277 pr::m_vec[6] *= a_sy;
0278 pr::m_vec[7] *= a_sy;
0279
0280 pr::m_vec[ 8] *= a_sz;
0281 pr::m_vec[ 9] *= a_sz;
0282 pr::m_vec[10] *= a_sz;
0283 pr::m_vec[11] *= a_sz;
0284 }
0285 void mul_scale(const T& a_s) {
0286 pr::m_vec[0] *= a_s;
0287 pr::m_vec[1] *= a_s;
0288 pr::m_vec[2] *= a_s;
0289 pr::m_vec[3] *= a_s;
0290
0291 pr::m_vec[4] *= a_s;
0292 pr::m_vec[5] *= a_s;
0293 pr::m_vec[6] *= a_s;
0294 pr::m_vec[7] *= a_s;
0295
0296 pr::m_vec[ 8] *= a_s;
0297 pr::m_vec[ 9] *= a_s;
0298 pr::m_vec[10] *= a_s;
0299 pr::m_vec[11] *= a_s;
0300 }
0301 void mul_translate(const T& a_x,const T& a_y,const T& a_z) {
0302 pr::m_vec[12] = pr::m_vec[0]*a_x+pr::m_vec[4]*a_y+pr::m_vec[ 8]*a_z+pr::m_vec[12];
0303 pr::m_vec[13] = pr::m_vec[1]*a_x+pr::m_vec[5]*a_y+pr::m_vec[ 9]*a_z+pr::m_vec[13];
0304 pr::m_vec[14] = pr::m_vec[2]*a_x+pr::m_vec[6]*a_y+pr::m_vec[10]*a_z+pr::m_vec[14];
0305 pr::m_vec[15] = pr::m_vec[3]*a_x+pr::m_vec[7]*a_y+pr::m_vec[11]*a_z+pr::m_vec[15];
0306 }
0307
0308 void mul_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T(*a_sin)(T),T(*a_cos)(T)) {
0309 T rot[16];
0310 _set_rotate(a_x,a_y,a_z,a_angle,rot,a_sin,a_cos);
0311 parent::_mul_mtx(rot);
0312 }
0313
0314 void left_mul_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T(*a_sin)(T),T(*a_cos)(T)) {
0315 T _m[16];
0316 _set_rotate(a_x,a_y,a_z,a_angle,_m,a_sin,a_cos);
0317 parent::_left_mul_mtx(_m);
0318 }
0319
0320 void left_mul_scale(const T& a_x,const T& a_y,const T& a_z) {
0321 T _m[16];
0322 _set_scale(a_x,a_y,a_z,_m);
0323 parent::_left_mul_mtx(_m);
0324 }
0325
0326 void left_mul_translate(const T& a_x,const T& a_y,const T& a_z) {
0327 T _m[16];
0328 _set_translate(a_x,a_y,a_z,_m);
0329 parent::_left_mul_mtx(_m);
0330 }
0331
0332 void v00(const T& a_value){pr::m_vec[0+0*4] = a_value;}
0333 void v10(const T& a_value){pr::m_vec[1+0*4] = a_value;}
0334 void v20(const T& a_value){pr::m_vec[2+0*4] = a_value;}
0335 void v30(const T& a_value){pr::m_vec[3+0*4] = a_value;}
0336
0337 void v01(const T& a_value){pr::m_vec[0+1*4] = a_value;}
0338 void v11(const T& a_value){pr::m_vec[1+1*4] = a_value;}
0339 void v21(const T& a_value){pr::m_vec[2+1*4] = a_value;}
0340 void v31(const T& a_value){pr::m_vec[3+1*4] = a_value;}
0341
0342 void v02(const T& a_value){pr::m_vec[0+2*4] = a_value;}
0343 void v12(const T& a_value){pr::m_vec[1+2*4] = a_value;}
0344 void v22(const T& a_value){pr::m_vec[2+2*4] = a_value;}
0345 void v32(const T& a_value){pr::m_vec[3+2*4] = a_value;}
0346
0347 void v03(const T& a_value){pr::m_vec[0+3*4] = a_value;}
0348 void v13(const T& a_value){pr::m_vec[1+3*4] = a_value;}
0349 void v23(const T& a_value){pr::m_vec[2+3*4] = a_value;}
0350 void v33(const T& a_value){pr::m_vec[3+3*4] = a_value;}
0351
0352 const T& v00() const {return pr::m_vec[0+0*4];}
0353 const T& v10() const {return pr::m_vec[1+0*4];}
0354 const T& v20() const {return pr::m_vec[2+0*4];}
0355 const T& v30() const {return pr::m_vec[3+0*4];}
0356
0357 const T& v01() const {return pr::m_vec[0+1*4];}
0358 const T& v11() const {return pr::m_vec[1+1*4];}
0359 const T& v21() const {return pr::m_vec[2+1*4];}
0360 const T& v31() const {return pr::m_vec[3+1*4];}
0361
0362 const T& v02() const {return pr::m_vec[0+2*4];}
0363 const T& v12() const {return pr::m_vec[1+2*4];}
0364 const T& v22() const {return pr::m_vec[2+2*4];}
0365 const T& v32() const {return pr::m_vec[3+2*4];}
0366
0367 const T& v03() const {return pr::m_vec[0+3*4];}
0368 const T& v13() const {return pr::m_vec[1+3*4];}
0369 const T& v23() const {return pr::m_vec[2+3*4];}
0370 const T& v33() const {return pr::m_vec[3+3*4];}
0371
0372 protected:
0373 static void _set_translate(const T& a_x,const T& a_y,const T& a_z,T v[]) {
0374 v[0] = T(1);v[4] = 0;v[ 8] = 0;v[12] = a_x;
0375 v[1] = 0;v[5] = T(1);v[ 9] = 0;v[13] = a_y;
0376 v[2] = 0;v[6] = 0;v[10] = T(1);v[14] = a_z;
0377 v[3] = 0;v[7] = 0;v[11] = 0;v[15] = T(1);
0378 }
0379
0380 static void _set_scale(const T& a_1,const T& a_2,const T& a_3,T v[]) {
0381 v[0] = a_1;v[4] = 0;v[ 8] = 0;v[12] = 0;
0382 v[1] = 0;v[5] = a_2;v[ 9] = 0;v[13] = 0;
0383 v[2] = 0;v[6] = 0;v[10] = a_3;v[14] = 0;
0384 v[3] = 0;v[7] = 0;v[11] = 0;v[15] = T(1);
0385 }
0386
0387 static void _set_rotate(const T& a_x,const T& a_y,const T& a_z,const T& a_angle,T v[],T(*a_sin)(T),T(*a_cos)(T)) {
0388 //WARNING : (a_x,a_y,a_z) must be a normalized vector.
0389 // v[] = exp(-a_angle*n(a_x,a_y,a_z)*Rs). It models the rotation of an object in the same coordinate system (active rotation).
0390 T si = a_sin(a_angle);
0391 T co = a_cos(a_angle);
0392 T x = a_x;
0393 T y = a_y;
0394 T z = a_z;
0395 T x2 = x*x;
0396 T y2 = y*y;
0397 T z2 = z*z;
0398 T xy = x*y;
0399 T xz = x*z;
0400 T yz = y*z;
0401 v[0] = x2+(1-x2)*co;v[4] = xy*(1-co)-z*si;v[ 8] = xz*(1-co)+y*si;v[12] = 0;
0402 v[1] = xy*(1-co)+z*si;v[5] = y2+(1-y2)*co;v[ 9] = yz*(1-co)-x*si;v[13] = 0;
0403 v[2] = xz*(1-co)-y*si;v[6] = yz*(1-co)+x*si;v[10] = z2+(1-z2)*co;v[14] = 0;
0404 v[3] = 0;v[7] = 0;v[11] = 0;v[15] = 1;
0405
0406 // If :
0407 // n =(x,y,z)
0408 // n2 = x2+y2+z2 = 1
0409 // n.E = x*E1+y*E2+z*E3
0410 // with :
0411 // E1 E2 E3
0412 // 0 0 0 0 0 -1 0 1 0
0413 // 0 0 1 0 0 0 -1 0 0
0414 // 0 -1 0 1 0 0 0 0 0
0415 //
0416 // R(r,c) = cos(theta)*Id(r,c)+(1-cos(theta))*nr*nc-sin(theta)*(n.E)(r,c)
0417 //
0418 // R = exp(-theta*(n.E)) // active rotation (it models the rotation of an object by theta along n).
0419
0420 }
0421
0422 public:
0423 void mul_mtx_rot_root(const T& a_00,const T& a_01,const T& a_02, //1 row
0424 const T& a_10,const T& a_11,const T& a_12, //2 row
0425 const T& a_20,const T& a_21,const T& a_22) //3 row
0426 {
0427 T* tv = pr::m_vec;
0428 //pr::m_vec[0] = 00;pr::m_vec[4] = 01;pr::m_vec[ 8] = 02;pr::m_vec[12] = 03;
0429 //pr::m_vec[1] = 10;pr::m_vec[5] = 11;pr::m_vec[ 9] = 12;pr::m_vec[13] = 13;
0430 //pr::m_vec[2] = 20;pr::m_vec[6] = 21;pr::m_vec[10] = 22;pr::m_vec[14] = 23;
0431 //pr::m_vec[3] = 30;pr::m_vec[7] = 31;pr::m_vec[11] = 32;pr::m_vec[15] = 33;
0432
0433 T tv_0 = tv[0];
0434 T tv_1 = tv[1];
0435 T tv_2 = tv[2];
0436 T tv_3 = tv[3];
0437 T tv_4 = tv[4];
0438 T tv_5 = tv[5];
0439 T tv_6 = tv[6];
0440 T tv_7 = tv[7];
0441 T tv_8 = tv[8];
0442 T tv_9 = tv[9];
0443 T tv_10 = tv[10];
0444 T tv_11 = tv[11];
0445 T tv_12 = tv[12];
0446 T tv_13 = tv[13];
0447 T tv_14 = tv[14];
0448 T tv_15 = tv[15];
0449
0450 T fv_0 = a_00;
0451 T fv_1 = a_10;
0452 T fv_2 = a_20;
0453 //T fv_3 = 0;
0454
0455 T fv_4 = a_01;
0456 T fv_5 = a_11;
0457 T fv_6 = a_21;
0458 //T fv_7 = 0;
0459
0460 T fv_8 = a_02;
0461 T fv_9 = a_12;
0462 T fv_10 = a_22;
0463 //T fv_11 = 0;
0464
0465 //T fv_12 = 0;
0466 //T fv_13 = 0;
0467 //T fv_14 = 0;
0468 //T fv_15 = 1;
0469
0470 tv[0] = tv_0*fv_0+tv_4*fv_1+ tv_8*fv_2;
0471 tv[1] = tv_1*fv_0+tv_5*fv_1+ tv_9*fv_2;
0472 tv[2] = tv_2*fv_0+tv_6*fv_1+tv_10*fv_2;
0473 tv[3] = tv_3*fv_0+tv_7*fv_1+tv_11*fv_2;
0474
0475 tv[4] = tv_0*fv_4+tv_4*fv_5+ tv_8*fv_6;
0476 tv[5] = tv_1*fv_4+tv_5*fv_5+ tv_9*fv_6;
0477 tv[6] = tv_2*fv_4+tv_6*fv_5+tv_10*fv_6;
0478 tv[7] = tv_3*fv_4+tv_7*fv_5+tv_11*fv_6;
0479
0480 tv[8] = tv_0*fv_8+tv_4*fv_9+ tv_8*fv_10;
0481 tv[9] = tv_1*fv_8+tv_5*fv_9+ tv_9*fv_10;
0482 tv[10] = tv_2*fv_8+tv_6*fv_9+tv_10*fv_10;
0483 tv[11] = tv_3*fv_8+tv_7*fv_9+tv_11*fv_10;
0484
0485 tv[12] = tv_12;
0486 tv[13] = tv_13;
0487 tv[14] = tv_14;
0488 tv[15] = tv_15;
0489 }
0490
0491 template <class MAT3>
0492 void set_mat3(MAT3& a_m3) {
0493 a_m3.set_matrix(pr::m_vec[0],pr::m_vec[4],pr::m_vec[ 8], //1 row
0494 pr::m_vec[1],pr::m_vec[5],pr::m_vec[ 9], //2 row
0495 pr::m_vec[2],pr::m_vec[6],pr::m_vec[10]); //3 row
0496 }
0497 private:static void check_instantiation() {mat4<float> dummy;}
0498 };
0499
0500 ////////////////////////////////////////////////
0501 /// common matrices : //////////////////////////
0502 ////////////////////////////////////////////////
0503
0504 template <class T> inline const mat4<T>& mat4_zero() {static const mat4<T> s_v;return s_v;}
0505
0506 //for sf, mf :
0507 template <class T>
0508 inline const T* get_data(const mat4<T>& a_v) {return a_v.data();}
0509
0510 }
0511
0512 #include <ostream>
0513
0514 namespace tools {
0515
0516 template <class T>
0517 inline std::ostream& operator<<(std::ostream& a_out,const mat4<T>& a_mtx){
0518 const T* v = a_mtx.data();
0519 a_out << v[0] << "," << v[4] << "," << v[ 8] << "," << v[12] << std::endl
0520 << v[1] << "," << v[5] << "," << v[ 9] << "," << v[13] << std::endl
0521 << v[2] << "," << v[6] << "," << v[10] << "," << v[14] << std::endl
0522 << v[3] << "," << v[7] << "," << v[11] << "," << v[15] << std::endl;
0523 return a_out;
0524 }
0525
0526 }
0527
0528 #endif