Subversion Repositories AndroidProjects

Rev

Rev 782 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
782 chris 1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Threading.Tasks;
6
 
7
namespace BauzoidNET.math
8
{
9
    class Matrix4
10
    {
784 chris 11
            public const int M11 = 0;
12
            public const int M21 = 1;
13
            public const int M31 = 2;
14
            public const int M41 = 3;
15
            public const int M12 = 4;
16
            public const int M22 = 5;
17
            public const int M32 = 6;
18
            public const int M42 = 7;
19
            public const int M13 = 8;
20
            public const int M23 = 9;
21
            public const int M33 = 10;
22
            public const int M43 = 11;
23
            public const int M14 = 12;
24
            public const int M24 = 13;
25
            public const int M34 = 14;
26
            public const int M44 = 15;
782 chris 27
 
784 chris 28
            public const int MATRIX_SIZE = 4;
782 chris 29
 
30
            public float[] values = new float[MATRIX_SIZE*MATRIX_SIZE];
31
 
32
            public Matrix4()
33
            {
34
            }
35
 
36
            /** Copy constructor. */
37
            public Matrix4(Matrix4 b)
38
            {
39
                    for (int i = 0; i < values.Length; i++)
40
                            this.values[i] = b.values[i];
41
            }
42
 
43
            public Matrix4(float[] m)
44
            {
45
            for (int i = 0; i < values.Length; i++)
46
                            this.values[i] = m[i];
47
            }
48
 
49
            public float get(int row, int col)
50
            {
51
                    return values[col*MATRIX_SIZE + row];
52
            }
53
 
54
            public void set(int row, int col, float value)
55
            {
56
                    values[col*MATRIX_SIZE + row] = value;
57
            }
58
 
59
            public void zero()
60
            {
61
            for (int i = 0; i < values.Length; i++)
62
                            values[i] = 0.0f;
63
        }
64
 
65
            public void identity()
66
            {
67
                    zero();
68
                    values[M11] = 1.0f; values[M22] = 1.0f; values[M33] = 1.0f; values[M44] = 1.0f;
69
            }
70
 
71
            public bool equals(Matrix4 other)
72
            {
73
            for (int i = 0; i < values.Length; i++)
74
                    {
75
                            if (this.values[i] != other.values[i])
76
                                    return false;
77
                    }
78
                    return true;
79
            }
80
 
81
            public bool isSingular()
82
        {
83
            float determinant = getDeterminant();
84
            return ((float)Math.Abs(determinant) < MathUtil.EPSILON);
85
        }
86
 
87
            public Matrix4 getTranspose()
88
            {
89
                    Matrix4 result = new Matrix4();
90
 
91
                    for (int row = 0; row < MATRIX_SIZE; row++)
92
                    {
93
                            for (int col = 0; col < MATRIX_SIZE; col++)
94
                            {
95
                                    float v = this.get(row, col);
96
                                    this.set(col, row, v);
97
                            }
98
                    }
99
 
100
                    return result;
101
            }
102
 
103
            public float getDeterminant()
104
            {
105
 
106
            float result =
107
                    values[M14] * values[M23] * values[M32] * values[M41] -
108
                    values[M13] * values[M24] * values[M32] * values[M41] -
109
                    values[M14] * values[M22] * values[M33] * values[M41] +
110
                    values[M12] * values[M24] * values[M33] * values[M41] +
111
                    values[M13] * values[M22] * values[M34] * values[M41] -
112
                    values[M12] * values[M23] * values[M34] * values[M41] -
113
                    values[M14] * values[M23] * values[M31] * values[M42] +
114
                    values[M13] * values[M24] * values[M31] * values[M42] +
115
                    values[M14] * values[M21] * values[M33] * values[M42] -
116
                    values[M11] * values[M24] * values[M33] * values[M42] -
117
                    values[M13] * values[M21] * values[M34] * values[M42] +
118
                    values[M11] * values[M23] * values[M34] * values[M42] +
119
                    values[M14] * values[M22] * values[M31] * values[M43] -
120
                    values[M12] * values[M24] * values[M31] * values[M43] -
121
                    values[M14] * values[M21] * values[M32] * values[M43] +
122
                    values[M11] * values[M24] * values[M32] * values[M43] +
123
                    values[M12] * values[M21] * values[M34] * values[M43] -
124
                    values[M11] * values[M22] * values[M34] * values[M43] -
125
                    values[M13] * values[M22] * values[M31] * values[M44] +
126
                    values[M12] * values[M23] * values[M31] * values[M44] +
127
                    values[M13] * values[M21] * values[M32] * values[M44] -
128
                    values[M11] * values[M23] * values[M32] * values[M44] -
129
                    values[M12] * values[M21] * values[M33] * values[M44] +
130
                    values[M11] * values[M22] * values[M33] * values[M44];
131
            return result;
132
            }
133
 
134
            public Matrix4 getInverse()
135
            {
136
                    Matrix4 result = new Matrix4();
137
 
138
                    float determinant = getDeterminant();
139
                    if (determinant == 0.0f)
140
                    {
141
                            // singular matrix cannot be inverted
142
                            return this;
143
                    }
144
 
145
            result.values[M11] = values[M23] * values[M34] * values[M42]
146
                            - values[M24] * values[M33] * values[M42]
147
                            + values[M24] * values[M32] * values[M43]
148
                            - values[M22] * values[M34] * values[M43]
149
                            - values[M23] * values[M32] * values[M44]
150
                            + values[M22] * values[M33] * values[M44];
151
                    result.values[M12] = values[M14] * values[M33] * values[M42]
152
                            - values[M13] * values[M34] * values[M42]
153
                            - values[M14] * values[M32] * values[M43]
154
                            + values[M12] * values[M34] * values[M43]
155
                            + values[M13] * values[M32] * values[M44]
156
                            - values[M12] * values[M33] * values[M44];
157
                    result.values[M13] = values[M13] * values[M24] * values[M42]
158
                            - values[M14] * values[M23] * values[M42]
159
                            + values[M14] * values[M22] * values[M43]
160
                            - values[M12] * values[M24] * values[M43]
161
                            - values[M13] * values[M22] * values[M44]
162
                            + values[M12] * values[M23] * values[M44];
163
                    result.values[M14] = values[M14] * values[M23] * values[M32]
164
                            - values[M13] * values[M24] * values[M32]
165
                            - values[M14] * values[M22] * values[M33]
166
                            + values[M12] * values[M24] * values[M33]
167
                            + values[M13] * values[M22] * values[M34]
168
                            - values[M12] * values[M23] * values[M34];
169
                    result.values[M21] = values[M24] * values[M33] * values[M41]
170
                            - values[M23] * values[M34] * values[M41]
171
                            - values[M24] * values[M31] * values[M43]
172
                            + values[M21] * values[M34] * values[M43]
173
                            + values[M23] * values[M31] * values[M44]
174
                            - values[M21] * values[M33] * values[M44];
175
                    result.values[M22] = values[M13] * values[M34] * values[M41]
176
                            - values[M14] * values[M33] * values[M41]
177
                            + values[M14] * values[M31] * values[M43]
178
                            - values[M11] * values[M34] * values[M43]
179
                            - values[M13] * values[M31] * values[M44]
180
                            + values[M11] * values[M33] * values[M44];
181
                    result.values[M23] = values[M14] * values[M23] * values[M41]
182
                            - values[M13] * values[M24] * values[M41]
183
                            - values[M14] * values[M21] * values[M43]
184
                            + values[M11] * values[M24] * values[M43]
185
                            + values[M13] * values[M21] * values[M44]
186
                            - values[M11] * values[M23] * values[M44];
187
                    result.values[M24] = values[M13] * values[M24] * values[M31]
188
                            - values[M14] * values[M23] * values[M31]
189
                            + values[M14] * values[M21] * values[M33]
190
                            - values[M11] * values[M24] * values[M33]
191
                            - values[M13] * values[M21] * values[M34]
192
                            + values[M11] * values[M23] * values[M34];
193
                    result.values[M31] = values[M22] * values[M34] * values[M41]
194
                            - values[M24] * values[M32] * values[M41]
195
                            + values[M24] * values[M31] * values[M42]
196
                            - values[M21] * values[M34] * values[M42]
197
                            - values[M22] * values[M31] * values[M44]
198
                            + values[M21] * values[M32] * values[M44];
199
                    result.values[M32] = values[M14] * values[M32] * values[M41]
200
                            - values[M12] * values[M34] * values[M41]
201
                            - values[M14] * values[M31] * values[M42]
202
                            + values[M11] * values[M34] * values[M42]
203
                            + values[M12] * values[M31] * values[M44]
204
                            - values[M11] * values[M32] * values[M44];
205
                    result.values[M33] = values[M12] * values[M24] * values[M41]
206
                            - values[M14] * values[M22] * values[M41]
207
                            + values[M14] * values[M21] * values[M42]
208
                            - values[M11] * values[M24] * values[M42]
209
                            - values[M12] * values[M21] * values[M44]
210
                            + values[M11] * values[M22] * values[M44];
211
                    result.values[M34] = values[M14] * values[M22] * values[M31]
212
                            - values[M12] * values[M24] * values[M31]
213
                            - values[M14] * values[M21] * values[M32]
214
                            + values[M11] * values[M24] * values[M32]
215
                            + values[M12] * values[M21] * values[M34]
216
                            - values[M11] * values[M22] * values[M34];
217
                    result.values[M41] = values[M23] * values[M32] * values[M41]
218
                            - values[M22] * values[M33] * values[M41]
219
                            - values[M23] * values[M31] * values[M42]
220
                            + values[M21] * values[M33] * values[M42]
221
                            + values[M22] * values[M31] * values[M43]
222
                            - values[M21] * values[M32] * values[M43];
223
                    result.values[M42] = values[M12] * values[M33] * values[M41]
224
                            - values[M13] * values[M32] * values[M41]
225
                            + values[M13] * values[M31] * values[M42]
226
                            - values[M11] * values[M33] * values[M42]
227
                            - values[M12] * values[M31] * values[M43]
228
                            + values[M11] * values[M32] * values[M43];
229
                    result.values[M43] = values[M13] * values[M22] * values[M41]
230
                            - values[M12] * values[M23] * values[M41]
231
                            - values[M13] * values[M21] * values[M42]
232
                            + values[M11] * values[M23] * values[M42]
233
                            + values[M12] * values[M21] * values[M43]
234
                            - values[M11] * values[M22] * values[M43];
235
                    result.values[M44] = values[M12] * values[M23] * values[M31]
236
                            - values[M13] * values[M22] * values[M31]
237
                            + values[M13] * values[M21] * values[M32]
238
                            - values[M11] * values[M23] * values[M32]
239
                            - values[M12] * values[M21] * values[M33]
240
                            + values[M11] * values[M22] * values[M33];
241
 
242
                    float multiply = 1.0f / determinant;
243
 
244
            for (int i = 0; i < values.Length; i++)
245
                            result.values[i] *= multiply;
246
 
247
                    return result;
248
            }
249
 
250
            public void copyTo(Matrix4 target)
251
            {
252
            for (int i = 0; i < values.Length; i++)
253
                            target.values[i] = this.values[i];
254
            }
255
 
256
            public void copyFrom(Matrix4 source)
257
            {
258
            for (int i = 0; i < values.Length; i++)
259
                            this.values[i] = source.values[i];
260
            }
261
 
262
            public void postMultiply(Matrix4 v)
263
            {
264
                    multiply(this, this, v);
265
            }
266
 
267
            public void preMultiply(Matrix4 v)
268
            {
269
                    multiply(this, v, this);
270
            }
271
 
272
            static public void multiply(Matrix4 result, Matrix4 a, Matrix4 b)
273
            {
274
            float result11 = a.values[M11] * b.values[M11] + a.values[M21] * b.values[M12] + a.values[M31] * b.values[M13] + a.values[M41] * b.values[M14];
275
            float result21 = a.values[M11] * b.values[M21] + a.values[M21] * b.values[M22] + a.values[M31] * b.values[M23] + a.values[M41] * b.values[M24];
276
            float result31 = a.values[M11] * b.values[M31] + a.values[M21] * b.values[M32] + a.values[M31] * b.values[M33] + a.values[M41] * b.values[M34];
277
            float result41 = a.values[M11] * b.values[M41] + a.values[M21] * b.values[M42] + a.values[M31] * b.values[M43] + a.values[M41] * b.values[M44];
278
            float result12 = a.values[M12] * b.values[M11] + a.values[M22] * b.values[M12] + a.values[M32] * b.values[M13] + a.values[M42] * b.values[M14];
279
            float result22 = a.values[M12] * b.values[M21] + a.values[M22] * b.values[M22] + a.values[M32] * b.values[M23] + a.values[M42] * b.values[M24];
280
            float result32 = a.values[M12] * b.values[M31] + a.values[M22] * b.values[M32] + a.values[M32] * b.values[M33] + a.values[M42] * b.values[M34];
281
            float result42 = a.values[M12] * b.values[M41] + a.values[M22] * b.values[M42] + a.values[M32] * b.values[M43] + a.values[M42] * b.values[M44];
282
            float result13 = a.values[M13] * b.values[M11] + a.values[M23] * b.values[M12] + a.values[M33] * b.values[M13] + a.values[M43] * b.values[M14];
283
            float result23 = a.values[M13] * b.values[M21] + a.values[M23] * b.values[M22] + a.values[M33] * b.values[M23] + a.values[M43] * b.values[M24];
284
                    float result33 = a.values[M13] * b.values[M31] + a.values[M23] * b.values[M32] + a.values[M33] * b.values[M33] + a.values[M43] * b.values[M34];
285
                    float result43 = a.values[M13] * b.values[M41] + a.values[M23] * b.values[M42] + a.values[M33] * b.values[M43] + a.values[M43] * b.values[M44];
286
                    float result14 = a.values[M14] * b.values[M11] + a.values[M24] * b.values[M12] + a.values[M34] * b.values[M13] + a.values[M44] * b.values[M14];
287
                    float result24 = a.values[M14] * b.values[M21] + a.values[M24] * b.values[M22] + a.values[M34] * b.values[M23] + a.values[M44] * b.values[M24];
288
                    float result34 = a.values[M14] * b.values[M31] + a.values[M24] * b.values[M32] + a.values[M34] * b.values[M33] + a.values[M44] * b.values[M34];
289
                    float result44 = a.values[M14] * b.values[M41] + a.values[M24] * b.values[M42] + a.values[M34] * b.values[M43] + a.values[M44] * b.values[M44];
290
                    result.values[M11] = result11;
291
                    result.values[M21] = result21;
292
                    result.values[M31] = result31;
293
                    result.values[M41] = result41;
294
                    result.values[M12] = result12;
295
                    result.values[M22] = result22;
296
                    result.values[M32] = result32;
297
                    result.values[M42] = result42;
298
                    result.values[M13] = result13;
299
                    result.values[M23] = result23;
300
                    result.values[M33] = result33;
301
                    result.values[M43] = result43;
302
                    result.values[M14] = result14;
303
                    result.values[M24] = result24;
304
                    result.values[M34] = result34;
305
                    result.values[M44] = result44;
306
            }
307
 
308
            static public Matrix4 multiply(Matrix4 a, Matrix4 b)
309
            {
310
                    Matrix4 result = new Matrix4();
311
                    multiply(result, a, b);
312
                    return result;
313
            }
314
 
315
            public void multiply(Matrix4 other)
316
            {
317
                    Matrix4.multiply(this, this, other);
318
            }
319
 
320
            static public Matrix4 createIdentity()
321
            {
322
                    return createScale(1.0f, 1.0f, 1.0f);
323
            }
324
 
325
            static public Matrix4 createScale(float sx, float sy, float sz)
326
            {
327
                    Matrix4 result = new Matrix4();
328
                    result.setScale(sx, sy, sz);
329
                    return result;             
330
            }
331
 
332
            static public Matrix4 createScale(Vector3 scale)
333
            {
334
                    return createScale(scale.x, scale.y, scale.z);
335
            }
336
 
337
            static public Matrix4 createScale(float s)
338
            {
339
                    return createScale(s, s, s);
340
            }
341
 
342
            public void setScale(float sx, float sy, float sz)
343
            {
344
                    zero();
345
                    this.values[M11] = sx;
346
                    this.values[M22] = sy;
347
                    this.values[M33] = sz;
348
                    this.values[M44] = 1.0f;
349
            }
350
 
351
            public void setScale(Vector3 scale)
352
            {
353
                    setScale(scale.x, scale.y, scale.z);
354
            }
355
 
356
            public void setScale(float s)
357
            {
358
                    setScale(s, s, s);
359
            }
360
 
361
            static public Matrix4 createRotationX(float degrees)
362
            {
363
            Matrix4 matrix = new Matrix4();
364
            matrix.setRotationX(degrees);
365
            return matrix;
366
            }
367
 
368
            public void setRotationX(float degrees)
369
            {
370
                    float degreesrad = MathUtil.degToRad(degrees);
371
            float sinvalue = (float)Math.Sin(degreesrad);
372
            float cosvalue = (float)Math.Cos(degreesrad);
373
 
374
                    this.identity();
375
            this.values[M22] = cosvalue;
376
            this.values[M32] = -sinvalue;
377
            this.values[M23] = sinvalue;
378
            this.values[M33] = cosvalue;
379
            }
380
 
381
            static public Matrix4 createRotationY(float degrees)
382
            {
383
                    Matrix4 matrix = new Matrix4();
384
                    matrix.setRotationY(degrees);
385
            return matrix;
386
            }
387
 
388
            public void setRotationY(float degrees)
389
            {
390
            float degreesrad = MathUtil.degToRad(degrees);
391
            float sinvalue = (float)Math.Sin(degreesrad);
392
            float cosvalue = (float)Math.Cos(degreesrad);
393
 
394
            this.identity();
395
            this.values[M11] = cosvalue;
396
            this.values[M31] = sinvalue;
397
            this.values[M13] = -sinvalue;
398
            this.values[M33] = cosvalue;
399
            }
400
 
401
            static public Matrix4 createRotationZ(float degrees)
402
            {
403
                    Matrix4 matrix = new Matrix4();
404
                    matrix.setRotationZ(degrees);
405
            return matrix;
406
            }
407
 
408
            public void setRotationZ(float degrees)
409
            {
410
            float degreesrad = MathUtil.degToRad(degrees);
411
            float sinvalue = (float)Math.Sin(degreesrad);
412
            float cosvalue = (float)Math.Cos(degreesrad);
413
 
414
            this.identity();
415
            this.values[M11] = cosvalue;
416
            this.values[M21] = -sinvalue;
417
            this.values[M12] = sinvalue;
418
            this.values[M22] = cosvalue;
419
            }
420
 
421
            static public Matrix4 createRotation(Vector3 axis, float degrees)
422
            {
423
                    Matrix4 matrix = new Matrix4();
424
                    matrix.setRotation(axis, degrees);
425
            return matrix;
426
            }
427
 
428
            public void setRotation(Vector3 axis, float degrees)
429
            {
430
            float radangle = MathUtil.degToRad(degrees);
431
            float radcos = (float)Math.Cos(radangle);
432
            float radsin = (float)Math.Sin(radangle);
433
 
434
            this.identity();
435
            this.values[M11] = radcos + axis.x * axis.x * (1 - radcos);
436
            this.values[M21] = axis.z * radsin + axis.y * axis.x * (1 - radcos);
437
            this.values[M31] = -axis.y * radsin + axis.z * axis.x * (1 - radcos);
438
            this.values[M12] = -axis.z * radsin + axis.x * axis.y * (1 - radcos);
439
            this.values[M22] = radcos + axis.y * axis.y * (1 - radcos);
440
            this.values[M32] = axis.x * radsin + axis.z * axis.y * (1 - radcos);
441
            this.values[M13] = axis.y * radsin + axis.x * axis.z * (1 - radcos);
442
            this.values[M23] = -axis.x * radsin + axis.y * axis.z * (1 - radcos);
443
            this.values[M33] = radcos + axis.z * axis.z * (1 - radcos);
444
            this.values[M44] = 1.0f;
445
            }
446
 
447
            static public Matrix4 createTranslation(float x, float y, float z)
448
            {
449
                    Matrix4 result = new Matrix4();
450
                    result.setTranslation(x, y, z);
451
            return result;
452
            }
453
 
454
            static public Matrix4 createTranslation(Vector3 translate)
455
            {
456
                    return createTranslation(translate.x, translate.y, translate.z);
457
            }
458
 
459
            public void setTranslation(float x, float y, float z)
460
            {          
461
                    this.values[M11] = 1.0f; this.values[M21] = 0.0f; this.values[M31] = 0.0f; this.values[M41] = 0.0f;
462
                    this.values[M12] = 0.0f; this.values[M22] = 1.0f; this.values[M32] = 0.0f; this.values[M42] = 0.0f;
463
                    this.values[M13] = 0.0f; this.values[M23] = 0.0f; this.values[M33] = 1.0f; this.values[M43] = 0.0f;
464
                    this.values[M14] = x;    this.values[M24] = y;    this.values[M34] = z;    this.values[M44] = 1.0f;
465
            }
466
 
467
            public void setTranslation(Vector3 translate)
468
            {
469
                    setTranslation(translate.x, translate.y, translate.z);
470
            }
471
 
472
            static public Matrix4 createFromVectors(Vector3 forward, Vector3 up, Vector3 right)
473
            {
474
            forward.normalize();
475
            up.normalize();
476
            right.normalize();
477
 
478
            Matrix4 result = new Matrix4();
479
            result.setFromVectors(forward, up, right);        
480
            return result;
481
            }
482
 
483
            public void setFromVectors(Vector3 forward, Vector3 up, Vector3 right)
484
            {
485
            forward.normalize();
486
            up.normalize();
487
            right.normalize();
488
 
489
            identity();
490
 
491
            this.values[M11] = right.x;
492
            this.values[M12] = right.y;
493
            this.values[M13] = right.z;
494
            this.values[M21] = up.x;
495
            this.values[M22] = up.y;
496
            this.values[M23] = up.z;
497
            this.values[M31] = -forward.x;
498
            this.values[M32] = -forward.y;
499
            this.values[M33] = -forward.z;
500
            this.values[M44] = 1.0f;
501
            }
502
 
503
            static public Matrix4 createPerspective(float fovDegreesY, float aspect, float zNear, float zFar)
504
            {
505
                    Matrix4 result = new Matrix4();
506
                    result.setPerspective(fovDegreesY, aspect, zNear, zFar);
507
                    return result;
508
            }
509
 
510
            public void setPerspective(float fovDegreesY, float aspect, float zNear, float zFar)
511
            {
512
            float f = 1.0f / (float) Math.Tan(fovDegreesY * (Math.PI / 360.0));
513
            float rangeReciprocal = 1.0f / (zNear - zFar);
514
 
515
                    this.values[M11] = f / aspect;
516
                    this.values[M21] = 0.0f;
517
                    this.values[M31] = 0.0f;
518
                    this.values[M41] = 0.0f;
519
 
520
                    this.values[M12] = 0.0f;
521
                    this.values[M22] = f;
522
                    this.values[M32] = 0.0f;
523
                    this.values[M42] = 0.0f;
524
 
525
                    this.values[M13] = 0.0f;
526
                    this.values[M23] = 0.0f;
527
                    this.values[M33] = (zFar + zNear) * rangeReciprocal;
528
                    this.values[M43] = -1.0f;
529
 
530
                    this.values[M14] = 0.0f;
531
                    this.values[M24] = 0.0f;
532
                    this.values[M34] = 2.0f * zFar * zNear * rangeReciprocal;
533
                    this.values[M44] = 0.0f;
534
            }
535
 
536
            static public Matrix4 createFrustum(float left, float right, float bottom, float top, float near, float far)
537
            {
538
                    Matrix4 matrix = new Matrix4();
539
                    matrix.setFrustum(left, right, bottom, top, near, far);
540
                    return matrix;
541
            }
542
 
543
            public void setFrustum(float left, float right, float bottom, float top, float near, float far)
544
            {
545
            if (left == right)
546
            {
547
                throw new ArgumentException("left == right");
548
            }
549
            if (top == bottom)
550
            {
551
                throw new ArgumentException("top == bottom");
552
            }
553
            if (near == far)
554
            {
555
                throw new ArgumentException("near == far");
556
            }
557
            if (near <= 0.0f)
558
            {
559
                throw new ArgumentException("near <= 0.0f");
560
            }
561
            if (far <= 0.0f)
562
            {
563
                throw new ArgumentException("far <= 0.0f");
564
            }
565
 
566
            float r_width  = 1.0f / (right - left);
567
            float r_height = 1.0f / (top - bottom);
568
            float r_depth  = 1.0f / (near - far);
569
            float x = 2.0f * (near * r_width);
570
            float y = 2.0f * (near * r_height);
571
            float A = 2.0f * ((right + left) * r_width);
572
            float B = (top + bottom) * r_height;
573
            float C = (far + near) * r_depth;
574
            float D = 2.0f * (far * near * r_depth);
575
 
576
            this.values[M11] = x;
577
            this.values[M21] = 0.0f;
578
            this.values[M31] = 0.0f;
579
            this.values[M41] = 0.0f;
580
 
581
            this.values[M12] = 0.0f;
582
            this.values[M22] = y;
583
            this.values[M32] = 0.0f;
584
            this.values[M42] = 0.0f;
585
 
586
            this.values[M13] = A;
587
            this.values[M23] = B;
588
            this.values[M33] = C;
589
            this.values[M43] = -1.0f;
590
 
591
            this.values[M14] = 0.0f;
592
            this.values[M24] = 0.0f;
593
            this.values[M34] = D;
594
            this.values[M44] = 0.0f;
595
            }
596
 
597
            static public Matrix4 createOrtho(float left, float right, float bottom, float top, float near, float far)
598
            {
599
                    Matrix4 matrix = new Matrix4();
600
                    matrix.setOrtho(left, right, bottom, top, near, far);
601
                    return matrix;
602
            }
603
 
604
            public void setOrtho(float left, float right, float bottom, float top, float near, float far)
605
            {
606
                    if (left == right)
607
                throw new ArgumentException("left and right must not be identical!");
608
 
609
                    if (bottom == top)
610
                throw new ArgumentException("bottom and top must not be identical!");
611
 
612
                    if (near == far)
613
                throw new ArgumentException("near and far must not be identical!");
614
 
615
                    float r_width  = 1.0f / (right - left);
616
                    float r_height = 1.0f / (top - bottom);
617
                    float r_depth  = 1.0f / (far - near);
618
                    float x =  2.0f * (r_width);
619
                    float y =  2.0f * (r_height);
620
                    float z = -2.0f * (r_depth);
621
                    float tx = -(right + left) * r_width;
622
                    float ty = -(top + bottom) * r_height;
623
                    float tz = -(far + near) * r_depth;
624
 
625
                    this.values[M11] = x;               this.values[M21] = 0.0f;        this.values[M31] = 0.0f;        this.values[M41] = 0.0f;
626
                    this.values[M12] = 0.0f;    this.values[M22] = y;           this.values[M32] = 0.0f;        this.values[M42] = 0.0f;
627
                    this.values[M13] = 0.0f;    this.values[M23] = 0.0f;        this.values[M33] = z;           this.values[M43] = 0.0f;
628
                    this.values[M14] = tx;              this.values[M24] = ty;          this.values[M34] = tz;          this.values[M44] = 1.0f;
629
            }          
630
 
631
            static public Matrix4 createLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
632
            {
633
                    Matrix4 matrix = new Matrix4();
634
                    matrix.setLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
635
                    return matrix;
636
            }
637
 
638
            public void setLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
639
            {
640
            float fx = centerX - eyeX;
641
            float fy = centerY - eyeY;
642
            float fz = centerZ - eyeZ;
643
 
644
            // Normalize f
645
            float rlf = 1.0f / Vector3.length(fx, fy, fz);
646
            fx *= rlf;
647
            fy *= rlf;
648
            fz *= rlf;
649
 
650
            // compute s = f x up (x means "cross product")
651
            float sx = fy * upZ - fz * upY;
652
            float sy = fz * upX - fx * upZ;
653
            float sz = fx * upY - fy * upX;
654
 
655
            // and normalize s
656
            float rls = 1.0f / Vector3.length(sx, sy, sz);
657
            sx *= rls;
658
            sy *= rls;
659
            sz *= rls;
660
 
661
            // compute u = s x f
662
            float ux = sy * fz - sz * fy;
663
            float uy = sz * fx - sx * fz;
664
            float uz = sx * fy - sy * fx;
665
 
666
            this.values[M11] = sx;
667
            this.values[M21] = ux;
668
            this.values[M31] = -fx;
669
            this.values[M41] = 0.0f;
670
 
671
            this.values[M12] = sy;
672
            this.values[M22] = uy;
673
            this.values[M32] = -fy;
674
            this.values[M42] = 0.0f;
675
 
676
            this.values[M13] = sz;
677
            this.values[M23] = uz;
678
            this.values[M33] = -fz;
679
            this.values[M43] = 0.0f;
680
 
681
            this.values[M14] = 0.0f;
682
            this.values[M24] = 0.0f;
683
            this.values[M34] = 0.0f;
684
            this.values[M44] = 1.0f;
685
 
686
            this.values[M14] = this.values[M11] * -eyeX + this.values[M12] * -eyeY + this.values[M13] * -eyeZ + this.values[M14];
687
            this.values[M24] = this.values[M21] * -eyeX + this.values[M22] * -eyeY + this.values[M23] * -eyeZ + this.values[M24];
688
            this.values[M34] = this.values[M31] * -eyeX + this.values[M32] * -eyeY + this.values[M33] * -eyeZ + this.values[M34];
689
            this.values[M44] = this.values[M41] * -eyeX + this.values[M42] * -eyeY + this.values[M43] * -eyeZ + this.values[M44];
690
            }
691
 
692
            public Vector3 transform(Vector3 vector)
693
            {
694
 
695
                    return new Vector3(
696
                    values[M11] * vector.x + values[M21] * vector.y + values[M31] * vector.z + values[M41],
697
                    values[M12] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M42],
698
                    values[M13] * vector.x + values[M23] * vector.y + values[M33] * vector.z + values[M43]);
699
            }
700
 
701
            public Vector4 transform(Vector4 vector)
702
            {
703
            return new Vector4(
704
                    values[M11] * vector.x + values[M21] * vector.y + values[M31] * vector.z + values[M41] * vector.w,
705
                    values[M12] * vector.x + values[M22] * vector.y + values[M32] * vector.z + values[M42] * vector.w,
706
                    values[M13] * vector.x + values[M23] * vector.y + values[M33] * vector.z + values[M43] * vector.w,
707
                    values[M14] * vector.x + values[M24] * vector.y + values[M34] * vector.z + values[M44] * vector.w);
708
            }
709
 
710
            static public void interpolate(Matrix4 result, Matrix4 a, Matrix4 b, float ratio)
711
            {
712
            result.values[M11] = a.values[M11] + (b.values[M11] - a.values[M11]) * ratio;
713
            result.values[M21] = a.values[M21] + (b.values[M21] - a.values[M21]) * ratio;
714
            result.values[M31] = a.values[M31] + (b.values[M31] - a.values[M31]) * ratio;
715
            result.values[M41] = a.values[M41] + (b.values[M41] - a.values[M41]) * ratio;
716
            result.values[M12] = a.values[M12] + (b.values[M12] - a.values[M12]) * ratio;
717
            result.values[M22] = a.values[M22] + (b.values[M22] - a.values[M22]) * ratio;
718
            result.values[M32] = a.values[M32] + (b.values[M32] - a.values[M32]) * ratio;
719
            result.values[M42] = a.values[M42] + (b.values[M42] - a.values[M42]) * ratio;
720
            result.values[M13] = a.values[M13] + (b.values[M13] - a.values[M13]) * ratio;
721
            result.values[M23] = a.values[M23] + (b.values[M23] - a.values[M23]) * ratio;
722
            result.values[M33] = a.values[M33] + (b.values[M33] - a.values[M33]) * ratio;
723
            result.values[M43] = a.values[M43] + (b.values[M43] - a.values[M43]) * ratio;
724
            result.values[M14] = a.values[M14] + (b.values[M14] - a.values[M14]) * ratio;
725
            result.values[M24] = a.values[M24] + (b.values[M24] - a.values[M24]) * ratio;
726
            result.values[M34] = a.values[M34] + (b.values[M34] - a.values[M34]) * ratio;
727
            result.values[M44] = a.values[M44] + (b.values[M44] - a.values[M44]) * ratio;
728
            }
729
 
730
            static public Matrix4 interpolate(Matrix4 a, Matrix4 b, float ratio)
731
            {
732
                    Matrix4 result = createIdentity();
733
                    interpolate(result, a, b, ratio);
734
                    return result;
735
            }
736
 
737
            public Vector3 getForwardVector()
738
            {
739
                    Vector3 forward = new Vector3(-values[M31], -values[M32], -values[M33]);
740
            forward.normalize();
741
            return forward;
742
            }
743
 
744
            public Vector3 getUpVector()
745
            {
746
            Vector3 up = new Vector3(values[M21], values[M22], values[M23]);
747
            up.normalize();
748
            return up;
749
            }
750
 
751
            public Vector3 getRightVector()
752
            {
753
            Vector3 right = new Vector3(values[M11], values[M12], values[M13]);
754
            right.normalize();
755
            return right;
756
            }
757
 
758
            public float[] toGLMatrix()
759
            {
760
                    return values;
761
            }
762
 
763
            public void fromGLMatrix(float[] m)
764
            {
765
                    //values = m;
766
            for (int i = 0; i < values.Length; i++)
767
                values[i] = m[i];
768
            }  
769
 
770
            // TODO: convert to C# equivalent
771
        /*
772
            public FloatBuffer toFloatBuffer()
773
            {
774
                    FloatBuffer buffer = BufferUtils.newFloatBuffer(16);
775
 
776
                    BufferUtils.copy(values, buffer, values.length, 0);
777
 
778
                    return buffer;
779
            }*/
780
    }
781
}