source: trunk/src/matrix.cpp @ 708

Last change on this file since 708 was 708, checked in by sam, 10 years ago

Basic utility function to display matrices.

  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#ifdef ANDROID_NDK
16#   include <android/log.h>
17#endif
18
19#include <cstdio>
20#include <cstdlib> /* free() */
21#include <cstring> /* strdup() */
22
23#include "core.h"
24
25namespace lol
26{
27
28static inline float det3(float a, float b, float c,
29                         float d, float e, float f,
30                         float g, float h, float i)
31{
32    return a * (e * i - h * f)
33         + b * (f * g - i * d)
34         + c * (d * h - g * e);
35}
36
37static inline float cofact3(mat4 const &mat, int i, int j)
38{
39    return det3(mat[(i + 1) & 3][(j + 1) & 3],
40                mat[(i + 2) & 3][(j + 1) & 3],
41                mat[(i + 3) & 3][(j + 1) & 3],
42                mat[(i + 1) & 3][(j + 2) & 3],
43                mat[(i + 2) & 3][(j + 2) & 3],
44                mat[(i + 3) & 3][(j + 2) & 3],
45                mat[(i + 1) & 3][(j + 3) & 3],
46                mat[(i + 2) & 3][(j + 3) & 3],
47                mat[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f);
48}
49
50template<> float mat4::det() const
51{
52    float ret = 0;
53    for (int n = 0; n < 4; n++)
54        ret += (*this)[n][0] * cofact3(*this, n, 0);
55    return ret;
56}
57
58template<> mat4 mat4::invert() const
59{
60    mat4 ret;
61    float d = det();
62    if (d)
63    {
64        d = 1.0f / d;
65        for (int j = 0; j < 4; j++)
66            for (int i = 0; i < 4; i++)
67                ret[j][i] = cofact3(*this, i, j) * d;
68    }
69    return ret;
70}
71
72template<> void mat4::printf() const
73{
74    mat4 const &p = *this;
75
76#ifdef ANDROID_NDK
77    __android_log_print(ANDROID_LOG_INFO, "LOL",
78        "[ %6.6f %6.6f %6.6f %6.6f", p[0][0], p[1][0], p[2][0], p[3][0]);
79    __android_log_print(ANDROID_LOG_INFO, "LOL",
80        "  %6.6f %6.6f %6.6f %6.6f", p[0][1], p[1][1], p[2][1], p[3][1]);
81    __android_log_print(ANDROID_LOG_INFO, "LOL",
82        "  %6.6f %6.6f %6.6f %6.6f", p[0][2], p[1][2], p[2][2], p[3][2]);
83    __android_log_print(ANDROID_LOG_INFO, "LOL",
84        "  %6.6f %6.6f %6.6f %6.6f ]", p[0][3], p[1][3], p[2][3], p[3][3]);
85#else
86    fprintf(stderr, "[ %6.6f %6.6f %6.6f %6.6f\n",
87            p[0][0], p[1][0], p[2][0], p[3][0]);
88    fprintf(stderr, "  %6.6f %6.6f %6.6f %6.6f\n",
89            p[0][1], p[1][1], p[2][1], p[3][1]);
90    fprintf(stderr, "  %6.6f %6.6f %6.6f %6.6f\n",
91            p[0][2], p[1][2], p[2][2], p[3][2]);
92    fprintf(stderr, "  %6.6f %6.6f %6.6f %6.6f ]\n",
93            p[0][3], p[1][3], p[2][3], p[3][3]);
94#endif
95}
96
97template<> mat4 mat4::ortho(float left, float right, float bottom,
98                            float top, float near, float far)
99{
100    float invrl = (right != left) ? 1.0f / (right - left) : 0.0f;
101    float invtb = (top != bottom) ? 1.0f / (top - bottom) : 0.0f;
102    float invfn = (far != near) ? 1.0f / (far - near) : 0.0f;
103
104    mat4 ret(0.0f);
105    ret[0][0] = 2.0f * invrl;
106    ret[1][1] = 2.0f * invtb;
107    ret[2][2] = -2.0f * invfn;
108    ret[3][0] = - (right + left) * invrl;
109    ret[3][1] = - (top + bottom) * invtb;
110    ret[3][2] = - (far + near) * invfn;
111    ret[3][3] = 1.0f;
112    return ret;
113}
114
115template<> mat4 mat4::frustum(float left, float right, float bottom,
116                              float top, float near, float far)
117{
118    float invrl = (right != left) ? 1.0f / (right - left) : 0.0f;
119    float invtb = (top != bottom) ? 1.0f / (top - bottom) : 0.0f;
120    float invfn = (far != near) ? 1.0f / (far - near) : 0.0f;
121
122    mat4 ret(0.0f);
123    ret[0][0] = 2.0f * near * invrl;
124    ret[1][1] = 2.0f * near * invtb;
125    ret[2][0] = (right + left) * invrl;
126    ret[2][1] = (top + bottom) * invtb;
127    ret[2][2] = - (far + near) * invfn;
128    ret[2][3] = -1.0f;
129    ret[3][2] = -2.0f * far * near * invfn;
130    return ret;
131}
132
133template<> mat4 mat4::perspective(float theta, float width,
134                                  float height, float near, float far)
135{
136    float t1 = tanf(theta / 2.0f);
137    float t2 = t1 * height / width;
138
139    return frustum(-near * t1, near * t1, -near * t2, near * t2, near, far);
140}
141
142template<> mat4 mat4::translate(float x, float y, float z)
143{
144    mat4 ret(1.0f);
145    ret[3][0] = x;
146    ret[3][1] = y;
147    ret[3][2] = z;
148    return ret;
149}
150
151template<> mat4 mat4::rotate(float theta, float x, float y, float z)
152{
153    float st = sinf(theta);
154    float ct = cosf(theta);
155
156    float len = sqrtf(x * x + y * y + z * z);
157    float invlen = len ? 1.0f / len : 0.0f;
158    x *= invlen;
159    y *= invlen;
160    z *= invlen;
161
162    float mtx = (1.0f - ct) * x;
163    float mty = (1.0f - ct) * y;
164    float mtz = (1.0f - ct) * z;
165
166    mat4 ret(1.0f);
167
168    ret[0][0] = x * mtx + ct;
169    ret[0][1] = x * mty + st * z;
170    ret[0][2] = x * mtz - st * y;
171
172    ret[1][0] = y * mtx - st * z;
173    ret[1][1] = y * mty + ct;
174    ret[1][2] = y * mtz + st * x;
175
176    ret[2][0] = z * mtx + st * y;
177    ret[2][1] = z * mty - st * x;
178    ret[2][2] = z * mtz + ct;
179
180    return ret;
181}
182
183} /* namespace lol */
184
Note: See TracBrowser for help on using the repository browser.