view include/Transform.h @ 16:2ac83ae9129b

Added get_ortho_mat44()
author Eris Caffee <discordia@eldalin.com>
date Sun, 19 May 2013 23:30:28 -0500
parents ea32c94fc495
children f49d8ba063ca
line source
1 #ifndef TRANSFORM_H_
2 #define TRANSFORM_H_
4 // Needs Vector.h and Matrix.h, but this file is not intended to be included
5 // directly. Just include Math.h and everything will be set up correctly.
7 namespace arda
8 {
9 namespace Math
10 {
12 //////////////////////////////////////////////////////////////////////////
14 // Transformation by distance d
15 template <typename T>
16 void get_trans_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector4<T> d);
18 // Rotation by angle around vector v
19 template <typename T>
20 void get_rot_mat33(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v);
22 template <typename T>
23 void get_rot_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v);
25 // Uniform scaling by factor of s
26 template <typename T>
27 void get_scale_mat44(arda::Math::Matrix44<T> & M, float s);
29 // Non-uniform scaling
30 template <typename T>
31 void get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s);
33 // Non-uniform scaling along arbitrary axis
34 template <typename T>
35 void get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s,
36 arda::Math::Vector3<T> x, arda::Math::Vector3<T> y, arda::Math::Vector3<T> z);
38 // Shear ith coordinate with respect to jth coordinate by s. i and j are zero based column indexes.
39 // (x = 0, y = 1, z = 2)
40 template <typename T>
41 void get_shear_mat44(arda::Math::Matrix44<T> & M, int i, int j, float s);
43 // Transformation matrix for combination of translation by d and rotation by angle around v.
44 template <typename T>
45 void get_transform_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v, arda::Math::Vector3<T> d);
47 // Rotate by angle around v with center of rotation p.
48 template <typename T>
49 void get_rot_about_point_mat44(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v, arda::Math::Vector3<T> p);
51 ////////////////////////////////////////
52 // Projection matrices
54 template <typename T>
55 void get_ortho_mat44(arda::Math::Matrix44<T> & M, T near, T far, T left, T right, T bottom, T top);
57 } // namespace Math
59 } // namespace arda
62 ////////////////////////////////////////////////////////////////////////////////
63 template <typename T>
64 void arda::Math::get_trans_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> d)
65 {
66 M.setidentity();
67 M.setcol(3, d.x, d.y, d.z, 1);
68 }
70 ////////////////////////////////////////////////////////////////////////////////
71 template <typename T>
72 void arda::Math::get_rot_mat33(arda::Math::Matrix33<T> & M, float angle, arda::Math::Vector3<T> v)
73 {
74 // TODO Replace == comparision of floating point number!
75 if (0.0 == v.length()) {
76 M.setidentity();
77 return;
78 }
80 // TODO: I should also immediately return identity if angle is a multiple of 2*PI but I'm not
81 // yet sure how I should I check for that (taking into account floating point imprecision).
84 v.normalize();
86 float c = cos(angle);
87 float s = sin(angle);
88 float one_minus_c = 1.0f - c;
90 // Remember: the "rows" as written here are actually the columns of the matrix.
91 M.assign(
92 c + one_minus_c * v.x * v.x , one_minus_c * v.x * v.y + s * v.z , one_minus_c * v.x * v.z - s * v.y ,
93 one_minus_c * v.x * v.y - s * v.z , c + one_minus_c * v.y * v.y , one_minus_c * v.y * v.z + s * v.x ,
94 one_minus_c * v.x * v.z + s * v.y , one_minus_c * v.y * v.z - s * v.x , c + one_minus_c * v.z * v.z
95 );
96 }
98 ////////////////////////////////////////////////////////////////////////////////
99 template <typename T>
100 void arda::Math::get_rot_mat44(arda::Math::Matrix44<T> & M, float angle, arda::Math::Vector3<T> v)
101 {
102 arda::Math::Matrix33<T> M33;
103 arda::Math::get_rot_mat33(M33, angle, v);
104 M.assign(M33[0], M33[1], M33[2], 0, M33[3], M33[4], M33[5], 0, M33[6], M33[7], M33[8], 0, 0, 0, 0, 1);
105 }
107 ////////////////////////////////////////////////////////////////////////////////
108 template <typename T>
109 void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, float s)
110 {
111 M.setidentity();
112 M *= s;
113 M[15] = 1;
114 }
116 ////////////////////////////////////////////////////////////////////////////////
117 template <typename T>
118 void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s)
119 {
120 M.setidentity();
121 M[0] = s.x;
122 M[5] = s.y;
123 M[10] = s.z;
124 }
126 ////////////////////////////////////////////////////////////////////////////////
127 template <typename T>
128 void arda::Math::get_scale_mat44(arda::Math::Matrix44<T> & M, arda::Math::Vector3<T> s,
129 arda::Math::Vector3<T> x, arda::Math::Vector3<T> y, arda::Math::Vector3<T> z)
130 {
131 // TODO Replace == comparision of floating point number!
132 assert(0 == x.dot(y));
133 assert(0 == x.dot(z));
134 assert(0 == y.dot(z));
136 arda::Math::Matrix44<T> F, Ft, S;
137 F.setcol(0, x.x, x.y, x.z, 0);
138 F.setcol(1, y.x, y.y, y.z, 0);
139 F.setcol(2, z.x, z.y, z.z, 0);
140 F.setcol(3, 0, 0, 0, 1);
142 Ft = arda::Math::transpose(F);
143 arda::Math::get_scale_mat44(S, s);
145 M = F * S * Ft;
146 }
148 ////////////////////////////////////////////////////////////////////////////////
149 template <typename T>
150 void arda::Math::get_shear_mat44(arda::Math::Matrix44<T> & M, int i, int j, float s)
151 {
152 assert(i<3 && i>=0);
153 assert(j<3 && j>=0);
154 M.setidentity();
155 M[4*j + i] = s;
156 }
159 ////////////////////////////////////////////////////////////////////////////////
160 template <typename T>
161 void arda::Math::get_transform_mat44(arda::Math::Matrix44<T> & M,
162 float angle, arda::Math::Vector3<T> v,
163 arda::Math::Vector3<T> d)
164 {
165 arda::Math::Matrix33<T> M33;
166 arda::Math::get_rot_mat33(M33, angle, v);
167 M.assign(M33[0], M33[1], M33[2], 0, M33[3], M33[4], M33[5], 0, M33[6], M33[7], M33[8], 0, d.x, d.y, d.z, 1);
168 }
172 ////////////////////////////////////////////////////////////////////////////////
173 // I initially wrote this while trying to do a rotation about an arbitrary vector with the center of rotation at point p.
174 // It seems to work, but I'm not sure of it's generality.
176 template <typename T>
177 void arda::Math::get_rot_about_point_mat44(arda::Math::Matrix44<T> & M,
178 float angle, arda::Math::Vector3<T> v,
179 arda::Math::Vector3<T> p)
180 {
181 arda::Math::Matrix33f M33(0);
182 get_rot_mat33(M33, angle, v);
183 arda::Math::Vector3f p1 = M33 * p;
185 M[0] = M33[0];
186 M[1] = M33[1];
187 M[2] = M33[2];
188 M[3] = T(0);
190 M[4] = M33[3];
191 M[5] = M33[4];
192 M[6] = M33[5];
193 M[7] = T(0);
195 M[8] = M33[6];
196 M[9] = M33[7];
197 M[10] = M33[8];
198 M[11] = T(0);
200 M[12] = p.x - p1.x;
201 M[13] = p.y - p1.y;
202 M[14] = p.z - p1.z;
203 M[15] = T(1);
204 }
206 ////////////////////////////////////////////////////////////////////////////////
207 template <typename T>
208 void arda::Math::get_ortho_mat44(arda::Math::Matrix44<T> & M, T near, T far, T left, T right, T bottom, T top)
209 {
210 M.assign(
211 2 / (right - left), T(0), T(0), T(0),
212 T(0), 2 / (top - bottom), T(0), T(0),
213 T(0), T(0), - 2 / (far - near), T(0),
214 - (right + left) / (right - left), - (top + bottom) / (top - bottom), - (far + near) / (far - near), T(1) );
216 }
219 #endif