]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/mat44impl.hpp
Clouds3D crashes because there is no Light
[simgear.git] / simgear / scene / sky / clouds3d / mat44impl.hpp
1 //------------------------------------------------------------------------------
2 // File : mat44impl.hpp
3 //------------------------------------------------------------------------------
4 // GLVU : Copyright 1997 - 2002 
5 //        The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its 
8 // documentation for any purpose is hereby granted without fee, provided that 
9 // the above copyright notice appear in all copies and that both that copyright 
10 // notice and this permission notice appear in supporting documentation. 
11 // Binaries may be compiled with this software without any royalties or 
12 // restrictions. 
13 //
14 // The University of North Carolina at Chapel Hill makes no representations 
15 // about the suitability of this software for any purpose. It is provided 
16 // "as is" without express or implied warranty.
17
18 //============================================================================
19 // mat44.hpp : 4x4 OpenGL-style matrix template.
20 // This is the template implementation file. It is included by mat44.hpp.
21 //============================================================================
22
23 //---------------------------------------------------------------------------
24 // CONSTRUCTORS
25 //---------------------------------------------------------------------------
26 template<class Type>
27 Mat44<Type>::Mat44()
28
29   Identity(); 
30 }
31
32 template<class Type>
33 Mat44<Type>::Mat44(const Type *N)
34 {
35   M[0]=N[0]; M[4]=N[4];  M[8]=N[8];  M[12]=N[12];
36   M[1]=N[1]; M[5]=N[5];  M[9]=N[9];  M[13]=N[13];
37   M[2]=N[2]; M[6]=N[6]; M[10]=N[10]; M[14]=N[14];
38   M[3]=N[3]; M[7]=N[7]; M[11]=N[11]; M[15]=N[15];
39 }
40
41 template<class Type>
42 Mat44<Type>::Mat44(Type M0, Type M4, Type M8, Type M12,
43       Type M1, Type M5, Type M9, Type M13,
44       Type M2, Type M6, Type M10, Type M14,
45       Type M3, Type M7, Type M11, Type M15)
46 {
47   M[0]=M0; M[4]=M4;  M[8]=M8;  M[12]=M12;
48   M[1]=M1; M[5]=M5;  M[9]=M9;  M[13]=M13;
49   M[2]=M2; M[6]=M6; M[10]=M10; M[14]=M14;
50   M[3]=M3; M[7]=M7; M[11]=M11; M[15]=M15;
51 }
52
53 //---------------------------------------------------------------------------
54 // MATRIX/MATRIX AND MATRIX/VECTOR OPERATORS
55 //---------------------------------------------------------------------------
56 template<class Type>
57 Mat44<Type>& Mat44<Type>::operator = (const Mat44& A)      // ASSIGNMENT (=)
58 {
59   M[0]=A.M[0]; M[4]=A.M[4];  M[8]=A.M[8];  M[12]=A.M[12];
60   M[1]=A.M[1]; M[5]=A.M[5];  M[9]=A.M[9];  M[13]=A.M[13];
61   M[2]=A.M[2]; M[6]=A.M[6]; M[10]=A.M[10]; M[14]=A.M[14];
62   M[3]=A.M[3]; M[7]=A.M[7]; M[11]=A.M[11]; M[15]=A.M[15];
63   return(*this);
64 }
65
66 template<class Type>
67 Mat44<Type>& Mat44<Type>::operator = (const Type* a) {
68   for (int i=0;i<16;i++) {
69     M[i] = a[i];
70   }
71   return *this;
72 }
73
74 template<class Type>
75 Mat44<Type> Mat44<Type>::operator * (const Mat44& A) const  // MULTIPLICATION (*)
76 {
77   Mat44<Type> NewM( M[0]*A.M[0] + M[4]*A.M[1] + M[8]*A.M[2] + M[12]*A.M[3],      // ROW 1
78               M[0]*A.M[4] + M[4]*A.M[5] + M[8]*A.M[6] + M[12]*A.M[7],
79               M[0]*A.M[8] + M[4]*A.M[9] + M[8]*A.M[10] + M[12]*A.M[11],
80               M[0]*A.M[12] + M[4]*A.M[13] + M[8]*A.M[14] + M[12]*A.M[15],
81
82               M[1]*A.M[0] + M[5]*A.M[1] + M[9]*A.M[2] + M[13]*A.M[3],      // ROW 2
83               M[1]*A.M[4] + M[5]*A.M[5] + M[9]*A.M[6] + M[13]*A.M[7],
84               M[1]*A.M[8] + M[5]*A.M[9] + M[9]*A.M[10] + M[13]*A.M[11],
85               M[1]*A.M[12] + M[5]*A.M[13] + M[9]*A.M[14] + M[13]*A.M[15],
86
87               M[2]*A.M[0] + M[6]*A.M[1] + M[10]*A.M[2] + M[14]*A.M[3],     // ROW 3
88               M[2]*A.M[4] + M[6]*A.M[5] + M[10]*A.M[6] + M[14]*A.M[7],
89               M[2]*A.M[8] + M[6]*A.M[9] + M[10]*A.M[10] + M[14]*A.M[11],
90               M[2]*A.M[12] + M[6]*A.M[13] + M[10]*A.M[14] + M[14]*A.M[15],
91
92               M[3]*A.M[0] + M[7]*A.M[1] + M[11]*A.M[2] + M[15]*A.M[3],     // ROW 4
93               M[3]*A.M[4] + M[7]*A.M[5] + M[11]*A.M[6] + M[15]*A.M[7],
94               M[3]*A.M[8] + M[7]*A.M[9] + M[11]*A.M[10] + M[15]*A.M[11],
95               M[3]*A.M[12] + M[7]*A.M[13] + M[11]*A.M[14] + M[15]*A.M[15] );
96   return(NewM);
97 }
98
99 template<class Type>
100 Vec3<Type> Mat44<Type>::operator * (const Vec3<Type>& V) const  // MAT-VECTOR MULTIPLICATION (*) W/ PERSP DIV
101 {
102   Type       W = M[3]*V.x + M[7]*V.y + M[11]*V.z + M[15];
103   Vec3<Type> NewV( (M[0]*V.x + M[4]*V.y + M[8]*V.z  + M[12]) / W,
104               (M[1]*V.x + M[5]*V.y + M[9]*V.z  + M[13]) / W,
105               (M[2]*V.x + M[6]*V.y + M[10]*V.z + M[14]) / W );
106   return(NewV);
107 }
108
109
110 // MAT-VECTOR MULTIPLICATION _WITHOUT_ PERSP DIV
111 // For transforming normals or other pure vectors. 
112 // Assumes matrix is affine, i.e. bottom row is 0,0,0,1
113 template<class Type>
114 Vec3<Type> Mat44<Type>::multNormal(const Vec3<Type>& N) const
115 {
116   Vec3<Type> NewN( (M[0]*N.x + M[4]*N.y + M[8]*N.z ),
117                    (M[1]*N.x + M[5]*N.y + M[9]*N.z ),
118                    (M[2]*N.x + M[6]*N.y + M[10]*N.z) );
119   return (NewN);
120 }
121
122 // MAT-POINT MULTIPLICATION _WITHOUT_ PERSP DIV 
123 // (for transforming points in space)
124 // Assumes matrix is affine, i.e. bottom row is 0,0,0,1
125 template<class Type>
126 Vec3<Type> Mat44<Type>::multPoint(const Vec3<Type>& P) const
127 {
128   Vec3<Type> NewP( (M[0]*P.x + M[4]*P.y + M[8]*P.z  + M[12]),
129                    (M[1]*P.x + M[5]*P.y + M[9]*P.z  + M[13]),
130                    (M[2]*P.x + M[6]*P.y + M[10]*P.z + M[14]) );
131   return (NewP);
132 }
133
134
135 template<class Type>
136 Vec4<Type> Mat44<Type>::operator * (const Vec4<Type>& V) const  // MAT-VECTOR MULTIPLICATION (*)
137 {
138   Vec4<Type> NewV;
139   NewV.x = M[0]*V.x + M[4]*V.y + M[8]*V.z  + M[12]*V.w;
140   NewV.y = M[1]*V.x + M[5]*V.y + M[9]*V.z  + M[13]*V.w;
141   NewV.z = M[2]*V.x + M[6]*V.y + M[10]*V.z + M[14]*V.w;
142   NewV.w = M[3]*V.x + M[7]*V.y + M[11]*V.z + M[15]*V.w;
143   return(NewV);
144 }
145
146
147 template<class Type>
148 Mat44<Type> Mat44<Type>::operator * (Type a) const              // SCALAR POST-MULTIPLICATION
149 {
150   Mat44<Type> NewM( M[0] * a, M[1] * a, M[2] * a, M[3] * a, 
151                     M[4] * a, M[5] * a, M[6] * a, M[7] * a,
152                     M[8] * a, M[9] * a, M[10] * a, M[11] * a, 
153                     M[12] * a, M[13] * a, M[14] * a, M[15] * a);
154   return NewM;
155 }
156
157 template<class Type>
158 Mat44<Type>& Mat44<Type>::operator *= (Type a)                  // SCALAR ACCUMULATE POST-MULTIPLICATION
159 {
160   for (int i = 0; i < 16; i++)
161   {
162     M[i] *= a;
163   }
164
165   return *this;
166 }
167
168 template<class Type>
169 Mat44<Type>::operator const Type*() const
170 {
171   return M;
172 }
173
174 template<class Type>
175 Mat44<Type>::operator Type*()
176 {
177   return M;
178 }
179
180 template<class Type>
181 Type& Mat44<Type>::operator()(int col, int row)
182 {
183   return M[4*col+row];
184 }
185
186 template<class Type>
187 const Type& Mat44<Type>::operator()(int col, int row) const
188 {
189   return M[4*col+row];
190 }
191
192 template<class Type>
193 void Mat44<Type>::Set(const Type* a)
194 {
195   for (int i=0;i<16;i++) {
196     M[i] = a[i];
197   }
198   
199 }
200
201 template<class Type>
202 void Mat44<Type>::Set(Type M0, Type M4, Type M8, Type M12,
203                       Type M1, Type M5, Type M9, Type M13,
204                       Type M2, Type M6, Type M10, Type M14,
205                       Type M3, Type M7, Type M11, Type M15)
206 {
207   M[0]=M0; M[4]=M4;  M[8]=M8;  M[12]=M12;
208   M[1]=M1; M[5]=M5;  M[9]=M9;  M[13]=M13;
209   M[2]=M2; M[6]=M6; M[10]=M10; M[14]=M14;
210   M[3]=M3; M[7]=M7; M[11]=M11; M[15]=M15;
211 }
212
213
214 //---------------------------------------------------------------------------
215 // Standard Matrix Operations
216 //---------------------------------------------------------------------------
217 template<class Type>
218 void Mat44<Type>::Identity()
219 {
220   M[0]=M[5]=M[10]=M[15]=1;
221   M[1]=M[2]=M[3]=M[4]=M[6]=M[7]=M[8]=M[9]=M[11]=M[12]=M[13]=M[14]=0;
222 }
223
224 template<class Type>
225 void Mat44<Type>::Transpose()
226 {
227   SWAP(M[1],M[4]);
228   SWAP(M[2],M[8]);
229   SWAP(M[6],M[9]);
230   SWAP(M[3],M[12]);
231   SWAP(M[7],M[13]);
232   SWAP(M[11],M[14]);
233 }
234
235 //---------------------------------------------------------------------------
236 // Standard Matrix Affine Transformations
237 //---------------------------------------------------------------------------
238 template <class Type>
239 void Mat44<Type>::Translate(Type Tx, Type Ty, Type Tz)
240 {
241   M[0]=1; M[4]=0;  M[8]=0;  M[12]=Tx;
242   M[1]=0; M[5]=1;  M[9]=0;  M[13]=Ty;
243   M[2]=0; M[6]=0;  M[10]=1; M[14]=Tz;
244   M[3]=0; M[7]=0;  M[11]=0; M[15]=1;
245 }
246
247 template<class Type>
248 void Mat44<Type>::Translate(const Vec3<Type>& T)
249 {
250   M[0]=1; M[4]=0;  M[8]=0;  M[12]=T.x;
251   M[1]=0; M[5]=1;  M[9]=0;  M[13]=T.y;
252   M[2]=0; M[6]=0;  M[10]=1; M[14]=T.z;
253   M[3]=0; M[7]=0;  M[11]=0; M[15]=1;
254 }
255
256 template<class Type>
257 void Mat44<Type>::invTranslate(Type Tx, Type Ty, Type Tz)
258 {
259   M[0]=1; M[4]=0;  M[8]=0;  M[12]=-Tx;
260   M[1]=0; M[5]=1;  M[9]=0;  M[13]=-Ty;
261   M[2]=0; M[6]=0;  M[10]=1; M[14]=-Tz;
262   M[3]=0; M[7]=0;  M[11]=0; M[15]=1;
263 }
264
265 template<class Type>
266 void Mat44<Type>::invTranslate(const Vec3<Type>& T)
267 {
268   M[0]=1; M[4]=0;  M[8]=0;  M[12]=-T.x;
269   M[1]=0; M[5]=1;  M[9]=0;  M[13]=-T.y;
270   M[2]=0; M[6]=0;  M[10]=1; M[14]=-T.z;
271   M[3]=0; M[7]=0;  M[11]=0; M[15]=1;
272 }
273
274 template<class Type>
275 void Mat44<Type>::Scale(Type Sx, Type Sy, Type Sz)
276 {
277   M[0]=Sx; M[4]=0;  M[8]=0;   M[12]=0;
278   M[1]=0;  M[5]=Sy; M[9]=0;   M[13]=0;
279   M[2]=0;  M[6]=0;  M[10]=Sz; M[14]=0;
280   M[3]=0;  M[7]=0;  M[11]=0;  M[15]=1;
281 }
282
283 template<class Type>
284 void Mat44<Type>::Scale(const Vec3<Type>& S)
285 {
286   M[0]=S.x; M[4]=0;   M[8]=0;    M[12]=0;
287   M[1]=0;   M[5]=S.y; M[9]=0;    M[13]=0;
288   M[2]=0;   M[6]=0;   M[10]=S.z; M[14]=0;
289   M[3]=0;   M[7]=0;   M[11]=0;   M[15]=1;
290 }
291
292 template<class Type>
293 void Mat44<Type>::invScale(Type Sx, Type Sy, Type Sz)
294 {
295   M[0]=1/Sx; M[4]=0;    M[8]=0;     M[12]=0;
296   M[1]=0;    M[5]=1/Sy; M[9]=0;     M[13]=0;
297   M[2]=0;    M[6]=0;    M[10]=1/Sz; M[14]=0;
298   M[3]=0;    M[7]=0;    M[11]=0;    M[15]=1;
299 }
300
301 template<class Type>
302 void Mat44<Type>::invScale(const Vec3<Type>& S)
303 {
304   M[0]=1/S.x; M[4]=0;     M[8]=0;      M[12]=0;
305   M[1]=0;     M[5]=1/S.y; M[9]=0;      M[13]=0;
306   M[2]=0;     M[6]=0;     M[10]=1/S.z; M[14]=0;
307   M[3]=0;     M[7]=0;     M[11]=0;     M[15]=1;
308 }
309
310 template<class Type>
311 void Mat44<Type>::Rotate(Type DegAng, const Vec3<Type>& Axis)
312 {
313   Type RadAng = DegAng*Mat44TORADS;
314   Type ca=(Type)cos(RadAng),
315         sa=(Type)sin(RadAng);
316   if (Axis.x==1 && Axis.y==0 && Axis.z==0)  // ABOUT X-AXIS
317   {
318    M[0]=1; M[4]=0;  M[8]=0;   M[12]=0;
319    M[1]=0; M[5]=ca; M[9]=-sa; M[13]=0;
320    M[2]=0; M[6]=sa; M[10]=ca; M[14]=0;
321    M[3]=0; M[7]=0;  M[11]=0;  M[15]=1;
322   }
323   else if (Axis.x==0 && Axis.y==1 && Axis.z==0)  // ABOUT Y-AXIS
324   {
325    M[0]=ca;  M[4]=0; M[8]=sa;  M[12]=0;
326    M[1]=0;   M[5]=1; M[9]=0;   M[13]=0;
327    M[2]=-sa; M[6]=0; M[10]=ca; M[14]=0;
328    M[3]=0;   M[7]=0; M[11]=0;  M[15]=1;
329   }
330   else if (Axis.x==0 && Axis.y==0 && Axis.z==1)  // ABOUT Z-AXIS
331   {
332    M[0]=ca; M[4]=-sa; M[8]=0;  M[12]=0;
333    M[1]=sa; M[5]=ca;  M[9]=0;  M[13]=0;
334    M[2]=0;  M[6]=0;   M[10]=1; M[14]=0;
335    M[3]=0;  M[7]=0;   M[11]=0; M[15]=1;
336   }
337   else                                      // ARBITRARY AXIS
338   {
339    Type l = Axis.LengthSqr();
340    Type x, y, z;
341    x=Axis.x, y=Axis.y, z=Axis.z;
342    if (l > Type(1.0001) || l < Type(0.9999) && l!=0)
343    {
344      // needs normalization
345      l=Type(1.0)/sqrt(l);
346      x*=l; y*=l; z*=l;
347    }
348    Type x2=x*x, y2=y*y, z2=z*z;
349    M[0]=x2+ca*(1-x2); M[4]=(x*y)+ca*(-x*y)+sa*(-z); M[8]=(x*z)+ca*(-x*z)+sa*y;
350    M[1]=(x*y)+ca*(-x*y)+sa*z; M[5]=y2+ca*(1-y2); M[9]=(y*z)+ca*(-y*z)+sa*(-x);
351    M[2]=(x*z)+ca*(-x*z)+sa*(-y); M[6]=(y*z)+ca*(-y*z)+sa*x; M[10]=z2+ca*(1-z2);
352    M[12]=M[13]=M[14]=M[3]=M[7]=M[11]=0;
353    M[15]=1;
354   }
355 }
356
357 template<class Type>
358 void Mat44<Type>::invRotate(Type DegAng, const Vec3<Type>& Axis)
359 {
360   Rotate(DegAng,Axis);
361   Transpose();
362 }
363
364 template<class Type>
365 inline Type Mat44<Type>::Trace() const
366 {
367   return M[0] + M[5] + M[10] + M[15];
368 }
369
370 //---------------------------------------------------------------------------
371 // Same as glFrustum() : Perspective transformation matrix defined by a
372 //  truncated pyramid viewing frustum that starts at the origin (eye)
373 //  going in the -Z axis direction (viewer looks down -Z)
374 //  with the four pyramid sides passing through the sides of a window
375 //  defined through x=l, x=r, y=b, y=t on the viewplane at z=-n.
376 //  The top and bottom of the pyramid are truncated by the near and far
377 //  planes at z=-n and z=-f. A 4-vector (x,y,z,w) inside this frustum
378 //  transformed by this matrix will have x,y,z values in the range
379 //  [-w,w]. Homogeneous clipping is applied to restrict (x,y,z) to
380 //  this range. Later, a perspective divide by w will result in an NDC
381 //  coordinate 3-vector of the form (x/w,y/w,z/w,w/w)=(x',y',z',1) where
382 //  x', y', and z' all are in the range [-1,1]. Perspectively divided z'
383 //  will be in [-1,1] with -1 being the near plane and +1 being the far.
384 //---------------------------------------------------------------------------
385 template<class Type>
386 void Mat44<Type>::Frustum(Type l, Type r, Type b, Type t, Type n, Type f)
387 {
388   M[0]=(2*n)/(r-l); M[4]=0;           M[8]=(r+l)/(r-l);   M[12]=0;
389   M[1]=0;           M[5]=(2*n)/(t-b); M[9]=(t+b)/(t-b);   M[13]=0;
390   M[2]=0;           M[6]=0;           M[10]=-(f+n)/(f-n); M[14]=(-2*f*n)/(f-n);
391   M[3]=0;           M[7]=0;           M[11]=-1;           M[15]=0;
392 }
393
394 template<class Type>
395 void Mat44<Type>::invFrustum(Type l, Type r, Type b, Type t, Type n, Type f)
396 {
397   M[0]=(r-l)/(2*n); M[4]=0;           M[8]=0;               M[12]=(r+l)/(2*n);
398   M[1]=0;           M[5]=(t-b)/(2*n); M[9]=0;               M[13]=(t+b)/(2*n);
399   M[2]=0;           M[6]=0;           M[10]=0;              M[14]=-1;
400   M[3]=0;           M[7]=0;           M[11]=-(f-n)/(2*f*n); M[15]=(f+n)/(2*f*n);
401 }
402
403 //---------------------------------------------------------------------------
404 // Same as gluPerspective : calls Frustum()
405 //---------------------------------------------------------------------------
406 template<class Type>
407 void Mat44<Type>::Perspective(Type Yfov, Type Aspect, Type Ndist, Type Fdist)
408 {
409   Yfov *= 0.0174532f;  // CONVERT TO RADIANS
410   Type wT=tanf(Yfov*0.5f)*Ndist, wB=-wT;
411   Type wR=wT*Aspect, wL=-wR;
412   Frustum(wL,wR,wB,wT,Ndist,Fdist);
413 }
414
415 template<class Type>
416 void Mat44<Type>::invPerspective(Type Yfov, Type Aspect, Type Ndist, Type Fdist)
417 {
418   Yfov *= 0.0174532f;  // CONVERT TO RADIANS
419   Type wT=tanf(Yfov*0.5f)*Ndist, wB=-wT;
420   Type wR=wT*Aspect, wL=-wR;
421   invFrustum(wL,wR,wB,wT,Ndist,Fdist);
422 }
423
424 //---------------------------------------------------------------------------
425 // OpenGL VIEWPORT XFORM MATRIX : given Window width and height in pixels
426 // Transforms the x,y,z NDC values in [-1,1] to (x',y') pixel values and
427 // normalized z' in [0,1] (near and far respectively).
428 //---------------------------------------------------------------------------
429 template<class Type>
430 void Mat44<Type>::Viewport(int WW, int WH)
431 {
432   Type WW2=(Type)WW*0.5f, WH2=(Type)WH*0.5f;
433   M[0]=WW2;  M[4]=0;     M[8]=0;    M[12]=WW2;
434   M[1]=0;    M[5]=WH2;   M[9]=0;    M[13]=WH2;
435   M[2]=0;    M[6]=0;     M[10]=0.5; M[14]=0.5;
436   M[3]=0;    M[7]=0;     M[11]=0;   M[15]=1;
437 }
438
439 template<class Type>
440 void Mat44<Type>::invViewport(int WW, int WH)
441 {
442   Type WW2=2.0f/(Type)WW, WH2=2.0f/(Type)WH;
443   M[0]=WW2;  M[4]=0;     M[8]=0;    M[12]=-1.0;
444   M[1]=0;    M[5]=WH2;   M[9]=0;    M[13]=-1.0;
445   M[2]=0;    M[6]=0;     M[10]=2.0; M[14]=-1.0;
446   M[3]=0;    M[7]=0;     M[11]=0;   M[15]=1;
447 }
448
449 //---------------------------------------------------------------------------
450 // Same as gluLookAt()
451 //---------------------------------------------------------------------------
452 template<class Type>
453 void Mat44<Type>::LookAt(const Vec3<Type>& Eye, 
454                          const Vec3<Type>& LookAtPt, 
455                          const Vec3<Type>& ViewUp)
456 {
457   Vec3<Type> Z = Eye-LookAtPt;  Z.Normalize(); // CALC CAM AXES ("/" IS CROSS-PROD)
458   Vec3<Type> X = ViewUp/Z;      X.Normalize();
459   Vec3<Type> Y = Z/X;           Y.Normalize();
460   Vec3<Type> Tr = -Eye;
461   M[0]=X.x;  M[4]=X.y;   M[8]=X.z; M[12]=X*Tr;  // TRANS->ROT
462   M[1]=Y.x;  M[5]=Y.y;   M[9]=Y.z; M[13]=Y*Tr;
463   M[2]=Z.x;  M[6]=Z.y;  M[10]=Z.z; M[14]=Z*Tr;
464   M[3]=0;    M[7]=0;    M[11]=0;   M[15]=1;
465 }
466
467 template<class Type>
468 void Mat44<Type>::invLookAt(const Vec3<Type>& Eye, 
469                             const Vec3<Type>& LookAtPt,
470                             const Vec3<Type>& ViewUp)
471 {
472   Vec3<Type> Z = Eye-LookAtPt;  Z.Normalize(); // CALC CAM AXES ("/" IS CROSS-PROD)
473   Vec3<Type> X = ViewUp/Z;      X.Normalize();
474   Vec3<Type> Y = Z/X;           Y.Normalize();
475   M[0]=X.x;  M[4]=Y.x;   M[8]=Z.x; M[12]=Eye.x;  // ROT->TRANS
476   M[1]=X.y;  M[5]=Y.y;   M[9]=Z.y; M[13]=Eye.y;
477   M[2]=X.z;  M[6]=Y.z;  M[10]=Z.z; M[14]=Eye.z;
478   M[3]=0;    M[7]=0;    M[11]=0;   M[15]=1;
479 }
480
481 //---------------------------------------------------------------------------
482 // VIEWPORT TRANFORMATION MATRIX : given Window width and height in pixels
483 // FROM "JIM BLINN'S CORNER" JULY '91. This function transforms an
484 // 4-vector in homogeneous space of the form (x,y,z,w) where
485 // -w<=x,y,z<=w into (x',y',z',1) where (x',y') is the vectors
486 // projected pixel location in ([0,WW-1],[0,WH-1]) and z' is the
487 // normalized depth value mapped into [0,1]; 0 is the near plane
488 // and 1 is the far plane. Mat44VIEWPORT_TOL is introduced to have correct
489 // mappings. (-1,-1,?,?) in NDC refers to the bottom-left of the
490 // viewplane window and (0,0,?,?) in screen space refers to the
491 // bottom-left pixel.
492 //---------------------------------------------------------------------------
493 template<class Type>
494 void Mat44<Type>::Viewport2(int WW, int WH)
495 {
496   Type WW2=(WW-Mat44VIEWPORT_TOL)*0.5f, WH2=(WH-Mat44VIEWPORT_TOL)*0.5f;
497   M[0]=WW2;  M[4]=0;     M[8]=0;    M[12]=WW2;
498   M[1]=0;    M[5]=WH2;   M[9]=0;    M[13]=WH2;
499   M[2]=0;    M[6]=0;     M[10]=0.5; M[14]=0.5;
500   M[3]=0;    M[7]=0;     M[11]=0;   M[15]=1;
501 }
502
503 template<class Type>
504 void Mat44<Type>::invViewport2(int WW, int WH)
505 {
506   Type WW2=2.0f/(WW-Mat44VIEWPORT_TOL), WH2=2.0f/(WH-Mat44VIEWPORT_TOL);
507   M[0]=WW2;  M[4]=0;     M[8]=0;    M[12]=-1.0;
508   M[1]=0;    M[5]=WH2;   M[9]=0;    M[13]=-1.0;
509   M[2]=0;    M[6]=0;     M[10]=2.0; M[14]=-1.0;
510   M[3]=0;    M[7]=0;     M[11]=0;   M[15]=1;
511 }
512
513 //---------------------------------------------------------------------------
514 // Handy matrix printing routine.
515 //---------------------------------------------------------------------------
516 template<class Type>
517 void Mat44<Type>::Print() const
518 {
519   printf("\n%f %f %f %f\n",M[0],M[4],M[8],M[12]);
520   printf("%f %f %f %f\n",M[1],M[5],M[9],M[13]);
521   printf("%f %f %f %f\n",M[2],M[6],M[10],M[14]);
522   printf("%f %f %f %f\n\n",M[3],M[7],M[11],M[15]);
523 }
524
525 //---------------------------------------------------------------------------
526 // Copy contents of matrix into matrix array.
527 //---------------------------------------------------------------------------
528 template<class Type>
529 void Mat44<Type>::CopyInto(Type *Mat) const
530 {
531   Mat[0]=M[0]; Mat[4]=M[4];  Mat[8]=M[8];  Mat[12]=M[12];
532   Mat[1]=M[1]; Mat[5]=M[5];  Mat[9]=M[9];  Mat[13]=M[13];
533   Mat[2]=M[2]; Mat[6]=M[6]; Mat[10]=M[10]; Mat[14]=M[14];
534   Mat[3]=M[3]; Mat[7]=M[7]; Mat[11]=M[11]; Mat[15]=M[15];
535 }
536