source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Matrix4x4.cpp @ 3078

Revision 3078, 17.2 KB checked in by mattausch, 16 years ago (diff)
Line 
1#include "Matrix4x4.h"
2#include "Vector3.h"
3#include "AxisAlignedBox3.h"
4
5
6using namespace std;
7
8
9namespace CHCDemoEngine
10{
11
12Matrix4x4::Matrix4x4()
13{}
14
15
16Matrix4x4::Matrix4x4(const Vector3 &a, const Vector3 &b, const Vector3 &c)
17{
18        // first index is column [x], the second is row [y]
19        x[0][0] = a.x;
20        x[1][0] = b.x;
21        x[2][0] = c.x;
22        x[3][0] = 0.0f;
23
24        x[0][1] = a.y;
25        x[1][1] = b.y;
26        x[2][1] = c.y;
27        x[3][1] = 0.0f;
28
29        x[0][2] = a.z;
30        x[1][2] = b.z;
31        x[2][2] = c.z;
32        x[3][2] = 0.0f;
33
34        x[0][3] = 0.0f;
35        x[1][3] = 0.0f;
36        x[2][3] = 0.0f;
37        x[3][3] = 1.0f;
38}
39
40
41void Matrix4x4::SetColumns(const Vector3 &a, const Vector3 &b, const Vector3 &c)
42{
43        // first index is column [x], the second is row [y]
44        x[0][0] = a.x;
45        x[1][0] = a.y;
46        x[2][0] = a.z;
47        x[3][0] = 0.0f;
48
49        x[0][1] = b.x;
50        x[1][1] = b.y;
51        x[2][1] = b.z;
52        x[3][1] = 0.0f;
53
54        x[0][2] = c.x;
55        x[1][2] = c.y;
56        x[2][2] = c.z;
57        x[3][2] = 0.0f;
58
59        x[0][3] = 0.0f;
60        x[1][3] = 0.0f;
61        x[2][3] = 0.0f;
62        x[3][3] = 1.0f;
63}
64
65// full constructor
66Matrix4x4::Matrix4x4(float x11, float x12, float x13, float x14,
67                                         float x21, float x22, float x23, float x24,
68                                         float x31, float x32, float x33, float x34,
69                                         float x41, float x42, float x43, float x44)
70{
71        // first index is column [x], the second is row [y]
72        x[0][0] = x11;
73        x[1][0] = x12;
74        x[2][0] = x13;
75        x[3][0] = x14;
76
77        x[0][1] = x21;
78        x[1][1] = x22;
79        x[2][1] = x23;
80        x[3][1] = x24;
81
82        x[0][2] = x31;
83        x[1][2] = x32;
84        x[2][2] = x33;
85        x[3][2] = x34;
86
87        x[0][3] = x41;
88        x[1][3] = x42;
89        x[2][3] = x43;
90        x[3][3] = x44;
91}
92
93
94float Matrix4x4::Det3x3() const
95{
96        return (x[0][0]*x[1][1]*x[2][2] + \
97                x[1][0]*x[2][1]*x[0][2] + \
98                x[2][0]*x[0][1]*x[1][2] - \
99                x[2][0]*x[1][1]*x[0][2] - \
100                x[0][0]*x[2][1]*x[1][2] - \
101                x[1][0]*x[0][1]*x[2][2]);
102}
103
104
105
106// inverse matrix computation gauss_jacobiho method .. from N.R. in C
107// if matrix is regular = computatation successfull = returns 0
108// in case of singular matrix returns 1
109int Matrix4x4::Invert()
110{
111        int indxc[4],indxr[4],ipiv[4];
112        int i,icol,irow,j,k,l,ll,n;
113        float big,dum,pivinv,temp;
114        // satisfy the compiler
115        icol = irow = 0;
116
117        // the size of the matrix
118        n = 4;
119
120        for ( j = 0 ; j < n ; j++) /* zero pivots */
121                ipiv[j] = 0;
122
123        for ( i = 0; i < n; i++)
124        {
125                big = 0.0;
126                for (j = 0 ; j < n ; j++)
127                        if (ipiv[j] != 1)
128                                for ( k = 0 ; k<n ; k++)
129                                {
130                                        if (ipiv[k] == 0)
131                                        {
132                                                if (fabs(x[k][j]) >= big)
133                                                {
134                                                        big = fabs(x[k][j]);
135                                                        irow = j;
136                                                        icol = k;
137                                                }
138                                        }
139                                        else
140                                                if (ipiv[k] > 1)
141                                                        return 1; /* singular matrix */
142                                }
143                                ++(ipiv[icol]);
144                                if (irow != icol)
145                                {
146                                        for ( l = 0 ; l<n ; l++)
147                                        {
148                                                temp = x[l][icol];
149                                                x[l][icol] = x[l][irow];
150                                                x[l][irow] = temp;
151                                        }
152                                }
153                                indxr[i] = irow;
154                                indxc[i] = icol;
155                                if (x[icol][icol] == 0.0)
156                                        return 1; /* singular matrix */
157
158                                pivinv = 1.0f / x[icol][icol];
159                                x[icol][icol] = 1.0f ;
160                                for ( l = 0 ; l<n ; l++)
161                                        x[l][icol] = x[l][icol] * pivinv ;
162
163                                for (ll = 0 ; ll < n ; ll++)
164                                        if (ll != icol)
165                                        {
166                                                dum = x[icol][ll];
167                                                x[icol][ll] = 0.0;
168                                                for ( l = 0 ; l<n ; l++)
169                                                        x[l][ll] = x[l][ll] - x[l][icol] * dum ;
170                                        }
171        }
172        for ( l = n; l--; )
173        {
174                if (indxr[l] != indxc[l])
175                        for ( k = 0; k<n ; k++)
176                        {
177                                temp = x[indxr[l]][k];
178                                x[indxr[l]][k] = x[indxc[l]][k];
179                                x[indxc[l]][k] = temp;
180                        }
181        }
182
183        return 0 ; // matrix is regular .. inversion has been succesfull
184}
185
186
187// Invert the given matrix using the above inversion routine.
188Matrix4x4 Invert(const Matrix4x4& M)
189{
190        Matrix4x4 InvertMe = M;
191        InvertMe.Invert();
192        return InvertMe;
193}
194
195
196// Transpose the matrix.
197void Matrix4x4::Transpose()
198{
199        for (int i = 0; i < 4; i++)
200                for (int j = i; j < 4; j++)
201                        if (i != j) {
202                                float temp = x[i][j];
203                                x[i][j] = x[j][i];
204                                x[j][i] = temp;
205                        }
206}
207
208
209// Transpose the given matrix using the transpose routine above.
210Matrix4x4 Transpose(const Matrix4x4& M)
211{
212        Matrix4x4 TransposeMe = M;
213        TransposeMe.Transpose();
214        return TransposeMe;
215}
216
217
218// Construct an identity matrix.
219Matrix4x4 IdentityMatrix()
220{
221        Matrix4x4 M;
222
223        for (int i = 0; i < 4; i++)
224                for (int j = 0; j < 4; j++)
225                        M.x[i][j] = (i == j) ? 1.0f : 0.0f;
226        return M;
227}
228
229
230// Construct a zero matrix.
231Matrix4x4 ZeroMatrix()
232{
233        Matrix4x4 M;
234        for (int i = 0; i < 4; i++)
235                for (int j = 0; j < 4; j++)
236                        M.x[i][j] = 0;
237        return M;
238}
239
240// Construct a translation matrix given the location to translate to.
241Matrix4x4
242TranslationMatrix(const Vector3& Location)
243{
244        Matrix4x4 M = IdentityMatrix();
245        M.x[3][0] = Location.x;
246        M.x[3][1] = Location.y;
247        M.x[3][2] = Location.z;
248        return M;
249}
250
251// Construct a rotation matrix.  Rotates Angle radians about the
252// X axis.
253Matrix4x4
254RotationXMatrix(float Angle)
255{
256        Matrix4x4 M = IdentityMatrix();
257        float Cosine = cos(Angle);
258        float Sine = sin(Angle);
259        M.x[1][1] = Cosine;
260        M.x[2][1] = -Sine;
261        M.x[1][2] = Sine;
262        M.x[2][2] = Cosine;
263        return M;
264}
265
266// Construct a rotation matrix.  Rotates Angle radians about the
267// Y axis.
268Matrix4x4 RotationYMatrix(float angle)
269{
270        Matrix4x4 m = IdentityMatrix();
271
272        float cosine = cos(angle);
273        float sine = sin(angle);
274
275        m.x[0][0] = cosine;
276        m.x[2][0] = -sine;
277        m.x[0][2] = sine;
278        m.x[2][2] = cosine;
279
280        return m;
281}
282
283
284// Construct a rotation matrix.  Rotates Angle radians about the
285// Z axis.
286Matrix4x4 RotationZMatrix(float angle)
287{
288        Matrix4x4 m = IdentityMatrix();
289
290        float cosine = cos(angle);
291        float sine = sin(angle);
292       
293        m.x[0][0] = cosine;
294        m.x[1][0] = -sine;
295        m.x[0][1] = sine;
296        m.x[1][1] = cosine;
297
298        return m;
299}
300
301
302// Construct a yaw-pitch-roll rotation matrix.  Rotate Yaw
303// radians about the XY axis, rotate Pitch radians in the
304// plane defined by the Yaw rotation, and rotate Roll radians
305// about the axis defined by the previous two angles.
306Matrix4x4 RotationYPRMatrix(float Yaw, float Pitch, float Roll)
307{
308        Matrix4x4 M;
309        float ch = cos(Yaw);
310        float sh = sin(Yaw);
311        float cp = cos(Pitch);
312        float sp = sin(Pitch);
313        float cr = cos(Roll);
314        float sr = sin(Roll);
315
316        M.x[0][0] = ch * cr + sh * sp * sr;
317        M.x[1][0] = -ch * sr + sh * sp * cr;
318        M.x[2][0] = sh * cp;
319        M.x[0][1] = sr * cp;
320        M.x[1][1] = cr * cp;
321        M.x[2][1] = -sp;
322        M.x[0][2] = -sh * cr - ch * sp * sr;
323        M.x[1][2] = sr * sh + ch * sp * cr;
324        M.x[2][2] = ch * cp;
325        for (int i = 0; i < 4; i++)
326                M.x[3][i] = M.x[i][3] = 0;
327        M.x[3][3] = 1;
328
329        return M;
330}
331
332// Construct a rotation of a given angle about a given axis.
333// Derived from Eric Haines's SPD (Standard Procedural
334// Database).
335Matrix4x4 RotationAxisMatrix(const Vector3& axis, float angle)
336{
337        Matrix4x4 M;
338
339        float cosine = cos(angle);
340        float sine = sin(angle);
341        float one_minus_cosine = 1 - cosine;
342
343        M.x[0][0] = axis.x * axis.x + (1.0f - axis.x * axis.x) * cosine;
344        M.x[0][1] = axis.x * axis.y * one_minus_cosine + axis.z * sine;
345        M.x[0][2] = axis.x * axis.z * one_minus_cosine - axis.y * sine;
346        M.x[0][3] = 0;
347
348        M.x[1][0] = axis.x * axis.y * one_minus_cosine - axis.z * sine;
349        M.x[1][1] = axis.y * axis.y + (1.0f - axis.y * axis.y) * cosine;
350        M.x[1][2] = axis.y * axis.z * one_minus_cosine + axis.x * sine;
351        M.x[1][3] = 0;
352
353        M.x[2][0] = axis.x * axis.z * one_minus_cosine + axis.y * sine;
354        M.x[2][1] = axis.y * axis.z * one_minus_cosine - axis.x * sine;
355        M.x[2][2] = axis.z * axis.z + (1.0f - axis.z * axis.z) * cosine;
356        M.x[2][3] = 0;
357
358        M.x[3][0] = 0;
359        M.x[3][1] = 0;
360        M.x[3][2] = 0;
361        M.x[3][3] = 1;
362
363        return M;
364}
365
366
367// Constructs the rotation matrix that rotates 'vec1' to 'vec2'
368Matrix4x4 RotationVectorsMatrix(const Vector3 &vecStart, const Vector3 &vecTo)
369{
370        Vector3 vec = CrossProd(vecStart, vecTo);
371
372        if (Magnitude(vec) > Limits::Small) {
373                // vector exist, compute angle
374                float angle = acos(DotProd(vecStart, vecTo));
375                // normalize for sure
376                vec.Normalize();
377                return RotationAxisMatrix(vec, angle);
378        }
379
380        // opposite or colinear vectors
381        Matrix4x4 ret = IdentityMatrix();
382        if (DotProd(vecStart, vecTo) < 0.0f)
383                ret *= -1.0f; // opposite vectors
384
385        return ret;
386}
387
388
389// Construct a scale matrix given the X, Y, and Z parameters
390// to scale by.  To scale uniformly, let X==Y==Z.
391Matrix4x4 ScaleMatrix(float X, float Y, float Z)
392{
393        Matrix4x4 M = IdentityMatrix();
394
395        M.x[0][0] = X;
396        M.x[1][1] = Y;
397        M.x[2][2] = Z;
398
399        return M;
400}
401
402
403// Construct a rotation matrix that makes the x, y, z axes
404// correspond to the vectors given.
405Matrix4x4 GenRotation(const Vector3 &x, const Vector3 &y, const Vector3 &z)
406{
407        Matrix4x4 M = IdentityMatrix();
408
409        //  x  y
410        M.x[0][0] = x.x;
411        M.x[1][0] = x.y;
412        M.x[2][0] = x.z;
413
414        M.x[0][1] = y.x;
415        M.x[1][1] = y.y;
416        M.x[2][1] = y.z;
417
418        M.x[0][2] = z.x;
419        M.x[1][2] = z.y;
420        M.x[2][2] = z.z;
421
422        return M;
423}
424
425// Construct a quadric matrix.  After Foley et al. pp. 528-529.
426Matrix4x4
427QuadricMatrix(float a, float b, float c, float d, float e,
428                          float f, float g, float h, float j, float k)
429{
430        Matrix4x4 M;
431
432        M.x[0][0] = a;  M.x[0][1] = d;  M.x[0][2] = f;  M.x[0][3] = g;
433        M.x[1][0] = d;  M.x[1][1] = b;  M.x[1][2] = e;  M.x[1][3] = h;
434        M.x[2][0] = f;  M.x[2][1] = e;  M.x[2][2] = c;  M.x[2][3] = j;
435        M.x[3][0] = g;  M.x[3][1] = h;  M.x[3][2] = j;  M.x[3][3] = k;
436
437        return M;
438}
439
440// Construct various "mirror" matrices, which flip coordinate
441// signs in the various axes specified.
442Matrix4x4
443MirrorX()
444{
445        Matrix4x4 M = IdentityMatrix();
446        M.x[0][0] = -1;
447        return M;
448}
449
450Matrix4x4
451MirrorY()
452{
453        Matrix4x4 M = IdentityMatrix();
454        M.x[1][1] = -1;
455        return M;
456}
457
458Matrix4x4
459MirrorZ()
460{
461        Matrix4x4 M = IdentityMatrix();
462        M.x[2][2] = -1;
463        return M;
464}
465
466Matrix4x4
467RotationOnly(const Matrix4x4& x)
468{
469        Matrix4x4 M = x;
470        M.x[3][0] = M.x[3][1] = M.x[3][2] = 0;
471        return M;
472}
473
474// Add corresponding elements of the two matrices.
475Matrix4x4&
476Matrix4x4::operator+= (const Matrix4x4& A)
477{
478        for (int i = 0; i < 4; i++)
479                for (int j = 0; j < 4; j++)
480                        x[i][j] += A.x[i][j];
481        return *this;
482}
483
484// Subtract corresponding elements of the matrices.
485Matrix4x4&
486Matrix4x4::operator-= (const Matrix4x4& A)
487{
488        for (int i = 0; i < 4; i++)
489                for (int j = 0; j < 4; j++)
490                        x[i][j] -= A.x[i][j];
491        return *this;
492}
493
494// Scale each element of the matrix by A.
495Matrix4x4&
496Matrix4x4::operator*= (float A)
497{
498        for (int i = 0; i < 4; i++)
499                for (int j = 0; j < 4; j++)
500                        x[i][j] *= A;
501        return *this;
502}
503
504// Multiply two matrices.
505Matrix4x4&
506Matrix4x4::operator*= (const Matrix4x4& A)
507{
508        Matrix4x4 ret = *this;
509
510        for (int i = 0; i < 4; i++)
511                for (int j = 0; j < 4; j++) {
512                        float subt = 0;
513                        for (int k = 0; k < 4; k++)
514                                subt += ret.x[i][k] * A.x[k][j];
515                        x[i][j] = subt;
516                }
517                return *this;
518}
519
520// Add corresponding elements of the matrices.
521Matrix4x4
522operator+ (const Matrix4x4& A, const Matrix4x4& B)
523{
524        Matrix4x4 ret;
525
526        for (int i = 0; i < 4; i++)
527                for (int j = 0; j < 4; j++)
528                        ret.x[i][j] = A.x[i][j] + B.x[i][j];
529        return ret;
530}
531
532// Subtract corresponding elements of the matrices.
533Matrix4x4
534operator- (const Matrix4x4& A, const Matrix4x4& B)
535{
536        Matrix4x4 ret;
537
538        for (int i = 0; i < 4; i++)
539                for (int j = 0; j < 4; j++)
540                        ret.x[i][j] = A.x[i][j] - B.x[i][j];
541        return ret;
542}
543
544// Multiply matrices.
545Matrix4x4
546operator* (const Matrix4x4& A, const Matrix4x4& B)
547{
548        Matrix4x4 ret;
549
550        for (int i = 0; i < 4; i++)
551                for (int j = 0; j < 4; j++) {
552                        float subt = 0;
553                        for (int k = 0; k < 4; k++)
554                                subt += A.x[i][k] * B.x[k][j];
555                        ret.x[i][j] = subt;
556                }
557                return ret;
558}
559
560// Transform a vector by a matrix.
561Vector3
562operator* (const Matrix4x4& M, const Vector3& v)
563{
564        Vector3 ret;
565        float denom;
566
567        ret.x = v.x * M.x[0][0] + v.y * M.x[1][0] + v.z * M.x[2][0] + M.x[3][0];
568        ret.y = v.x * M.x[0][1] + v.y * M.x[1][1] + v.z * M.x[2][1] + M.x[3][1];
569        ret.z = v.x * M.x[0][2] + v.y * M.x[1][2] + v.z * M.x[2][2] + M.x[3][2];
570        denom = v.x * M.x[0][3] + v.y * M.x[1][3] + v.z * M.x[2][3] + M.x[3][3];
571
572        if (denom != 1.0)
573                ret /= denom;
574        return ret;
575}
576
577
578Vector3 Matrix4x4::Transform(float &w, const Vector3 &v, float h) const
579{
580        Vector3 ret;
581       
582        ret.x = v.x * x[0][0] + v.y * x[1][0] + v.z * x[2][0] + h * x[3][0];
583        ret.y = v.x * x[0][1] + v.y * x[1][1] + v.z * x[2][1] + h * x[3][1];
584        ret.z = v.x * x[0][2] + v.y * x[1][2] + v.z * x[2][2] + h * x[3][2];
585        w     = v.x * x[0][3] + v.y * x[1][3] + v.z * x[2][3] + h * x[3][3];
586
587        return ret;
588}
589
590
591// Apply the rotation portion of a matrix to a vector.
592Vector3
593RotateOnly(const Matrix4x4& M, const Vector3& v)
594{
595        Vector3 ret;
596        float denom;
597
598        ret.x = v.x * M.x[0][0] + v.y * M.x[1][0] + v.z * M.x[2][0];
599        ret.y = v.x * M.x[0][1] + v.y * M.x[1][1] + v.z * M.x[2][1];
600        ret.z = v.x * M.x[0][2] + v.y * M.x[1][2] + v.z * M.x[2][2];
601        denom = M.x[0][3] + M.x[1][3] + M.x[2][3] + M.x[3][3];
602        if (denom != 1.0)
603                ret /= denom;
604        return ret;
605}
606
607// Scale each element of the matrix by B.
608Matrix4x4
609operator* (const Matrix4x4& A, float B)
610{
611        Matrix4x4 ret;
612
613        for (int i = 0; i < 4; i++)
614                for (int j = 0; j < 4; j++)
615                        ret.x[i][j] = A.x[i][j] * B;
616        return ret;
617}
618
619// Overloaded << for C++-style output.
620ostream&
621operator<< (ostream& s, const Matrix4x4& M)
622{
623        for (int i = 0; i < 4; i++) { // y
624                for (int j = 0; j < 4; j++) { // x
625                        //  x  y
626                        s << M.x[j][i];
627                }
628                s << '\n';
629        }
630        return s;
631}
632
633
634Vector3 PlaneRotate(const Matrix4x4& tform, const Vector3& p)
635{
636        // I sure hope that matrix is invertible...
637        Matrix4x4 use = Transpose(Invert(tform));
638
639        return RotateOnly(use, p);
640}
641
642// Transform a normal
643Vector3 TransformNormal(const Matrix4x4& tform, const Vector3& n)
644{
645        Matrix4x4 use = NormalTransformMatrix(tform);
646
647        return RotateOnly(use, n);
648}
649
650
651Matrix4x4  NormalTransformMatrix(const Matrix4x4 &tform)
652{
653        Matrix4x4 m = tform;
654        // for normal translation vector must be zero!
655        m.x[3][0] = m.x[3][1] = m.x[3][2] = 0.0;
656        // I sure hope that matrix is invertible...
657        return Transpose(Invert(m));
658}
659
660
661Vector3 GetTranslation(const Matrix4x4 &M)
662{
663        return Vector3(M.x[3][0], M.x[3][1], M.x[3][2]);
664}
665
666
667Matrix4x4 GetFittingProjectionMatrix(const AxisAlignedBox3 &box)
668{
669        Matrix4x4 m;
670
671        m.x[0][0] = 2.0f / (box.Max()[0] - box.Min()[0]);
672        m.x[0][1] = .0f;
673        m.x[0][2] = .0f;
674        m.x[0][3] = .0f;
675
676        m.x[1][0] = .0f;
677        m.x[1][1] = 2.0f / (box.Max()[1] - box.Min()[1]);
678        m.x[1][2] = .0f;
679        m.x[1][3] = .0f;
680
681        m.x[2][0] = .0f;
682        m.x[2][1] = .0f;
683        m.x[2][2] = 2.0f / (box.Max()[2] - box.Min()[2]);
684        m.x[2][3] = .0f;
685
686        m.x[3][0] = -(box.Max()[0] + box.Min()[0]) / (box.Max()[0] - box.Min()[0]);
687        m.x[3][1] = -(box.Max()[1] + box.Min()[1]) / (box.Max()[1] - box.Min()[1]);
688        m.x[3][2] = -(box.Max()[2] + box.Min()[2]) / (box.Max()[2] - box.Min()[2]);
689        m.x[3][3] = 1.0f;
690
691        return m;
692}
693
694
695/** The resultig matrix that is equal to the result of glFrustum
696*/
697Matrix4x4 GetFrustum(float left, float right,
698                                         float bottom, float top,
699                                         float near, float far)
700{
701        Matrix4x4 m;
702
703        const float xDif = 1.0f / (right - left);
704        const float yDif = 1.0f / (top - bottom);
705        const float zDif = 1.0f / (near - far);
706
707        m.x[0][0] = 2.0f * near * xDif;
708        m.x[0][1] = .0f;
709        m.x[0][2] = .0f;
710        m.x[0][3] = .0f;
711
712        m.x[1][0] = .0f;
713        m.x[1][1] = 2.0f * near * yDif;
714        m.x[1][2] = .0f;
715        m.x[1][3] = .0f;
716
717        m.x[2][0] = (right + left) * xDif;
718        m.x[2][1] = (top + bottom)* yDif;
719        m.x[2][2] = (far + near) * zDif;
720        m.x[2][3] = -1.0f;
721
722        m.x[3][0] = .0f;
723        m.x[3][1] = .0f;
724        m.x[3][2] = 2.0f * near * far * zDif;
725        m.x[3][3] = .0f;
726
727        return m;
728}
729
730
731Matrix4x4 LookAt(const Vector3 &pos, const Vector3 &dir, const Vector3& up)
732{
733        const Vector3 nDir = Normalize(dir);
734        Vector3 nUp = Normalize(up);
735
736        Vector3 nRight = Normalize(CrossProd(nDir, nUp));
737        nUp = Normalize(CrossProd(nRight, nDir));
738
739        Matrix4x4 m(nRight.x, nRight.y, nRight.z, 0,
740                        nUp.x,    nUp.y,    nUp.z,    0,
741                                -nDir.x,  -nDir.y,   -nDir.z, 0,
742                                0,        0,        0,        1);
743
744        // note: left handed system => we go into positive z
745        m.x[3][0] = -DotProd(nRight, pos);
746        m.x[3][1] = -DotProd(nUp, pos);
747        m.x[3][2] = DotProd(nDir, pos);
748
749        return m;
750}
751
752
753/** The resultig matrix that is equal to the result of glOrtho
754*/
755Matrix4x4 GetOrtho(float left, float right, float bottom, float top, float far, float near)
756{
757        Matrix4x4 m;
758
759        const float xDif = 1.0f / (right - left);
760        const float yDif = 1.0f / (top - bottom);
761        const float zDif = 1.0f / (far - near);
762
763        m.x[0][0] = 2.0f * xDif;
764        m.x[0][1] = .0f;
765        m.x[0][2] = .0f;
766        m.x[0][3] = .0f;
767
768        m.x[1][0] = .0f;
769        m.x[1][1] = 2.0f * yDif;
770        m.x[1][2] = .0f;
771        m.x[1][3] = .0f;
772
773        m.x[2][0] = .0f;
774        m.x[2][1] = .0f;
775        m.x[2][2] = -2.0f * zDif;
776        m.x[2][3] = .0f;
777       
778        m.x[3][0] = (right + left) * xDif;
779        m.x[3][1] = (top + bottom) * yDif;
780        m.x[3][2] = (far + near) * zDif;
781        m.x[3][3] = 1.0f;
782
783        return m;
784}
785
786/** The resultig matrix that is equal to the result of gluPerspective
787*/
788Matrix4x4 GetPerspective(float fov, float aspect, float near, float far)
789{
790        Matrix4x4 m;
791
792        const float x = 1.0f / tan(fov * 0.5f);
793        const float zDif = 1.0f / (near - far);
794
795        m.x[0][0] = x / aspect;
796        m.x[0][1] = .0f;
797        m.x[0][2] = .0f;
798        m.x[0][3] = .0f;
799
800        m.x[1][0] = .0f;
801        m.x[1][1] = x;
802        m.x[1][2] = .0f;
803        m.x[1][3] = .0f;
804
805        m.x[2][0] = .0f;
806        m.x[2][1] = .0f;
807        m.x[2][2] = (far + near) * zDif;
808        m.x[2][3] = -1.0f;
809       
810        m.x[3][0] = .0f;
811        m.x[3][1] = .0f;
812        m.x[3][2] = 2.0f *(far * near) * zDif;
813        m.x[3][3] = 0.0f;
814
815        return m;
816}
817
818
819}
Note: See TracBrowser for help on using the repository browser.