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

Revision 2953, 16.6 KB checked in by mattausch, 16 years ago (diff)

started different stuff

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