1 | /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
---|
2 | /* |
---|
3 | * ---------------------------------------------------------------------- |
---|
4 | * Mat4x4.cpp: Mat4x4 class |
---|
5 | * |
---|
6 | * ====================================================================== |
---|
7 | * AUTHOR: Wei Qiao <qiaow@purdue.edu> |
---|
8 | * Purdue Rendering and Perceptualization Lab (PURPL) |
---|
9 | * |
---|
10 | * Copyright (c) 2004-2006 Purdue Research Foundation |
---|
11 | * |
---|
12 | * See the file "license.terms" for information on usage and |
---|
13 | * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
14 | * ====================================================================== |
---|
15 | */ |
---|
16 | #include <math.h> |
---|
17 | |
---|
18 | #include "Mat4x4.h" |
---|
19 | |
---|
20 | Mat4x4::Mat4x4(float *vals) |
---|
21 | { |
---|
22 | for (int i = 0; i < 16; i++) { |
---|
23 | m[i] = vals[i]; |
---|
24 | } |
---|
25 | } |
---|
26 | |
---|
27 | void |
---|
28 | Mat4x4::print() const |
---|
29 | { |
---|
30 | TRACE("%f %f %f %f\n", m[0], m[1], m[2], m[3]); |
---|
31 | TRACE("%f %f %f %f\n", m[4], m[5], m[6], m[7]); |
---|
32 | TRACE("%f %f %f %f\n", m[8], m[9], m[10], m[11]); |
---|
33 | TRACE("%f %f %f %f\n", m[12], m[13], m[14], m[15]); |
---|
34 | } |
---|
35 | |
---|
36 | Mat4x4 |
---|
37 | Mat4x4::inverse() const |
---|
38 | { |
---|
39 | Mat4x4 p; |
---|
40 | |
---|
41 | float m00 = m[0], m01 = m[4], m02 = m[8], m03 = m[12]; |
---|
42 | float m10 = m[1], m11 = m[5], m12 = m[9], m13 = m[13]; |
---|
43 | float m20 = m[2], m21 = m[6], m22 = m[10], m23 = m[14]; |
---|
44 | float m30 = m[3], m31 = m[7], m32 = m[11], m33 = m[15]; |
---|
45 | |
---|
46 | float det0, inv0; |
---|
47 | |
---|
48 | #define det33(a1,a2,a3,b1,b2,b3,c1,c2,c3) \ |
---|
49 | (a1*(b2*c3-b3*c2) + b1*(c2*a3-a2*c3) + c1*(a2*b3-a3*b2)) |
---|
50 | |
---|
51 | float cof00 = det33(m11, m12, m13, m21, m22, m23, m31, m32, m33); |
---|
52 | float cof01 = -det33(m12, m13, m10, m22, m23, m20, m32, m33, m30); |
---|
53 | float cof02 = det33(m13, m10, m11, m23, m20, m21, m33, m30, m31); |
---|
54 | float cof03 = -det33(m10, m11, m12, m20, m21, m22, m30, m31, m32); |
---|
55 | |
---|
56 | float cof10 = -det33(m21, m22, m23, m31, m32, m33, m01, m02, m03); |
---|
57 | float cof11 = det33(m22, m23, m20, m32, m33, m30, m02, m03, m00); |
---|
58 | float cof12 = -det33(m23, m20, m21, m33, m30, m31, m03, m00, m01); |
---|
59 | float cof13 = det33(m20, m21, m22, m30, m31, m32, m00, m01, m02); |
---|
60 | |
---|
61 | float cof20 = det33(m31, m32, m33, m01, m02, m03, m11, m12, m13); |
---|
62 | float cof21 = -det33(m32, m33, m30, m02, m03, m00, m12, m13, m10); |
---|
63 | float cof22 = det33(m33, m30, m31, m03, m00, m01, m13, m10, m11); |
---|
64 | float cof23 = -det33(m30, m31, m32, m00, m01, m02, m10, m11, m12); |
---|
65 | |
---|
66 | float cof30 = -det33(m01, m02, m03, m11, m12, m13, m21, m22, m23); |
---|
67 | float cof31 = det33(m02, m03, m00, m12, m13, m10, m22, m23, m20); |
---|
68 | float cof32 = -det33(m03, m00, m01, m13, m10, m11, m23, m20, m21); |
---|
69 | float cof33 = det33(m00, m01, m02, m10, m11, m12, m20, m21, m22); |
---|
70 | |
---|
71 | #undef det33 |
---|
72 | |
---|
73 | #if 0 |
---|
74 | TRACE("Invert:\n"); |
---|
75 | TRACE(" %12.9f %12.9f %12.9f %12.9f\n", m00, m01, m02, m03); |
---|
76 | TRACE(" %12.9f %12.9f %12.9f %12.9f\n", m10, m11, m12, m13); |
---|
77 | TRACE(" %12.9f %12.9f %12.9f %12.9f\n", m20, m21, m22, m23); |
---|
78 | TRACE(" %12.9f %12.9f %12.9f %12.9f\n", m30, m31, m32, m33); |
---|
79 | #endif |
---|
80 | |
---|
81 | #if 0 |
---|
82 | det0 = m00 * cof00 + m01 * cof01 + m02 * cof02 + m03 * cof03; |
---|
83 | #else |
---|
84 | det0 = m30 * cof30 + m31 * cof31 + m32 * cof32 + m33 * cof33; |
---|
85 | #endif |
---|
86 | inv0 = (det0 == 0.0f) ? 0.0f : 1.0f / det0; |
---|
87 | |
---|
88 | p.m[0] = cof00 * inv0; |
---|
89 | p.m[1] = cof01 * inv0; |
---|
90 | p.m[2] = cof02 * inv0; |
---|
91 | p.m[3] = cof03 * inv0; |
---|
92 | |
---|
93 | p.m[4] = cof10 * inv0; |
---|
94 | p.m[5] = cof11 * inv0; |
---|
95 | p.m[6] = cof12 * inv0; |
---|
96 | p.m[7] = cof13 * inv0; |
---|
97 | |
---|
98 | p.m[8] = cof20 * inv0; |
---|
99 | p.m[9] = cof21 * inv0; |
---|
100 | p.m[10] = cof22 * inv0; |
---|
101 | p.m[11] = cof23 * inv0; |
---|
102 | |
---|
103 | p.m[12] = cof30 * inv0; |
---|
104 | p.m[13] = cof31 * inv0; |
---|
105 | p.m[14] = cof32 * inv0; |
---|
106 | p.m[15]= cof33 * inv0; |
---|
107 | |
---|
108 | return p; |
---|
109 | } |
---|
110 | |
---|
111 | Vector4 |
---|
112 | Mat4x4::multiply_row_vector(const Vector4& v) const |
---|
113 | { |
---|
114 | Vector4 ret; |
---|
115 | ret.x = (m[0] * v.x) + (m[1] * v.y) + (m[2] * v.z) + (m[3] * v.w); |
---|
116 | ret.y = (m[4] * v.x) + (m[5] * v.y) + (m[6] * v.z) + (m[7] * v.w); |
---|
117 | ret.z = (m[8] * v.x) + (m[9] * v.y) + (m[10] * v.z) + (m[11] * v.w); |
---|
118 | ret.w = (m[12] * v.x) + (m[13] * v.y) + (m[14] * v.z) + (m[15] * v.w); |
---|
119 | return ret; |
---|
120 | } |
---|
121 | |
---|
122 | Vector4 |
---|
123 | Mat4x4::transform(const Vector4& v) const |
---|
124 | { |
---|
125 | Vector4 ret; |
---|
126 | ret.x = v.x*m[0]+v.y*m[4]+v.z*m[8]+v.w*m[12]; |
---|
127 | ret.y = v.x*m[1]+v.y*m[5]+v.z*m[9]+v.w*m[13]; |
---|
128 | ret.z = v.x*m[2]+v.y*m[6]+v.z*m[10]+v.w*m[14]; |
---|
129 | ret.w = v.x*m[3]+v.y*m[7]+v.z*m[11]+v.w*m[15]; |
---|
130 | return ret; |
---|
131 | } |
---|
132 | |
---|
133 | Mat4x4 |
---|
134 | Mat4x4::operator *(const Mat4x4& mat) const |
---|
135 | { |
---|
136 | Mat4x4 ret; |
---|
137 | |
---|
138 | ret.m[0] = m[0]*mat.m[0]+m[1]*mat.m[4]+m[2]*mat.m[8]+m[3]*mat.m[12]; |
---|
139 | ret.m[1] = m[0]*mat.m[1]+m[1]*mat.m[5]+m[2]*mat.m[9]+m[3]*mat.m[13]; |
---|
140 | ret.m[2] = m[0]*mat.m[2]+m[1]*mat.m[6]+m[2]*mat.m[10]+m[3]*mat.m[14]; |
---|
141 | ret.m[3] = m[0]*mat.m[3]+m[1]*mat.m[7]+m[2]*mat.m[11]+m[3]*mat.m[15]; |
---|
142 | |
---|
143 | ret.m[4] = m[4]*mat.m[0]+m[5]*mat.m[4]+m[6]*mat.m[8]+m[7]*mat.m[12]; |
---|
144 | ret.m[5] = m[4]*mat.m[1]+m[5]*mat.m[5]+m[6]*mat.m[9]+m[7]*mat.m[13]; |
---|
145 | ret.m[6] = m[4]*mat.m[2]+m[5]*mat.m[6]+m[6]*mat.m[10]+m[7]*mat.m[14]; |
---|
146 | ret.m[7] = m[4]*mat.m[3]+m[5]*mat.m[7]+m[6]*mat.m[11]+m[7]*mat.m[15]; |
---|
147 | |
---|
148 | ret.m[8] = m[8]*mat.m[0]+m[9]*mat.m[4]+m[10]*mat.m[8]+m[11]*mat.m[12]; |
---|
149 | ret.m[9] = m[8]*mat.m[1]+m[9]*mat.m[5]+m[10]*mat.m[9]+m[11]*mat.m[13]; |
---|
150 | ret.m[10] = m[8]*mat.m[2]+m[9]*mat.m[6]+m[10]*mat.m[10]+m[11]*mat.m[14]; |
---|
151 | ret.m[11] = m[8]*mat.m[3]+m[9]*mat.m[7]+m[10]*mat.m[11]+m[11]*mat.m[15]; |
---|
152 | |
---|
153 | ret.m[12] = m[12]*mat.m[0]+m[13]*mat.m[4]+m[14]*mat.m[8]+m[15]*mat.m[12]; |
---|
154 | ret.m[13] = m[12]*mat.m[1]+m[13]*mat.m[5]+m[14]*mat.m[9]+m[15]*mat.m[13]; |
---|
155 | ret.m[14] = m[12]*mat.m[2]+m[13]*mat.m[6]+m[14]*mat.m[10]+m[15]*mat.m[14]; |
---|
156 | ret.m[15] = m[12]*mat.m[3]+m[13]*mat.m[7]+m[14]*mat.m[11]+m[15]*mat.m[15]; |
---|
157 | |
---|
158 | return ret; |
---|
159 | } |
---|
160 | |
---|
161 | Mat4x4 |
---|
162 | Mat4x4::transpose() const |
---|
163 | { |
---|
164 | Mat4x4 ret; |
---|
165 | for (int i = 0; i < 4; i++) { |
---|
166 | for (int j = 0; j < 4; j++) { |
---|
167 | ret.m[j+4*i] = this->m[i+4*j]; |
---|
168 | } |
---|
169 | } |
---|
170 | return ret; |
---|
171 | } |
---|