@@ -99,6 +99,111 @@ impl Matrix4 {
99
99
m. m41 * self . m14 + m. m42 * self . m24 + m. m43 * self . m34 + m. m44 * self . m44 )
100
100
}
101
101
102
+ pub fn invert ( & self ) -> Matrix4 {
103
+ let det = self . determinant ( ) ;
104
+
105
+ if det == 0.0 {
106
+ return Matrix4 :: identity ( ) ;
107
+ }
108
+
109
+ // todo(gw): this could be made faster by special casing
110
+ // for simpler matrix types.
111
+ let m = Matrix4 :: new (
112
+ self . m23 * self . m34 * self . m42 - self . m24 * self . m33 * self . m42 +
113
+ self . m24 * self . m32 * self . m43 - self . m22 * self . m34 * self . m43 -
114
+ self . m23 * self . m32 * self . m44 + self . m22 * self . m33 * self . m44 ,
115
+
116
+ self . m14 * self . m33 * self . m42 - self . m13 * self . m34 * self . m42 -
117
+ self . m14 * self . m32 * self . m43 + self . m12 * self . m34 * self . m43 +
118
+ self . m13 * self . m32 * self . m44 - self . m12 * self . m33 * self . m44 ,
119
+
120
+ self . m13 * self . m24 * self . m42 - self . m14 * self . m23 * self . m42 +
121
+ self . m14 * self . m22 * self . m43 - self . m12 * self . m24 * self . m43 -
122
+ self . m13 * self . m22 * self . m44 + self . m12 * self . m23 * self . m44 ,
123
+
124
+ self . m14 * self . m23 * self . m32 - self . m13 * self . m24 * self . m32 -
125
+ self . m14 * self . m22 * self . m33 + self . m12 * self . m24 * self . m33 +
126
+ self . m13 * self . m22 * self . m34 - self . m12 * self . m23 * self . m34 ,
127
+
128
+ self . m24 * self . m33 * self . m41 - self . m23 * self . m34 * self . m41 -
129
+ self . m24 * self . m31 * self . m43 + self . m21 * self . m34 * self . m43 +
130
+ self . m23 * self . m31 * self . m44 - self . m21 * self . m33 * self . m44 ,
131
+
132
+ self . m13 * self . m34 * self . m41 - self . m14 * self . m33 * self . m41 +
133
+ self . m14 * self . m31 * self . m43 - self . m11 * self . m34 * self . m43 -
134
+ self . m13 * self . m31 * self . m44 + self . m11 * self . m33 * self . m44 ,
135
+
136
+ self . m14 * self . m23 * self . m41 - self . m13 * self . m24 * self . m41 -
137
+ self . m14 * self . m21 * self . m43 + self . m11 * self . m24 * self . m43 +
138
+ self . m13 * self . m21 * self . m44 - self . m11 * self . m23 * self . m44 ,
139
+
140
+ self . m13 * self . m24 * self . m31 - self . m14 * self . m23 * self . m31 +
141
+ self . m14 * self . m21 * self . m33 - self . m11 * self . m24 * self . m33 -
142
+ self . m13 * self . m21 * self . m34 + self . m11 * self . m23 * self . m34 ,
143
+
144
+ self . m22 * self . m34 * self . m41 - self . m24 * self . m32 * self . m41 +
145
+ self . m24 * self . m31 * self . m42 - self . m21 * self . m34 * self . m42 -
146
+ self . m22 * self . m31 * self . m44 + self . m21 * self . m32 * self . m44 ,
147
+
148
+ self . m14 * self . m32 * self . m41 - self . m12 * self . m34 * self . m41 -
149
+ self . m14 * self . m31 * self . m42 + self . m11 * self . m34 * self . m42 +
150
+ self . m12 * self . m31 * self . m44 - self . m11 * self . m32 * self . m44 ,
151
+
152
+ self . m12 * self . m24 * self . m41 - self . m14 * self . m22 * self . m41 +
153
+ self . m14 * self . m21 * self . m42 - self . m11 * self . m24 * self . m42 -
154
+ self . m12 * self . m21 * self . m44 + self . m11 * self . m22 * self . m44 ,
155
+
156
+ self . m14 * self . m22 * self . m31 - self . m12 * self . m24 * self . m31 -
157
+ self . m14 * self . m21 * self . m32 + self . m11 * self . m24 * self . m32 +
158
+ self . m12 * self . m21 * self . m34 - self . m11 * self . m22 * self . m34 ,
159
+
160
+ self . m23 * self . m32 * self . m41 - self . m22 * self . m33 * self . m41 -
161
+ self . m23 * self . m31 * self . m42 + self . m21 * self . m33 * self . m42 +
162
+ self . m22 * self . m31 * self . m43 - self . m21 * self . m32 * self . m43 ,
163
+
164
+ self . m12 * self . m33 * self . m41 - self . m13 * self . m32 * self . m41 +
165
+ self . m13 * self . m31 * self . m42 - self . m11 * self . m33 * self . m42 -
166
+ self . m12 * self . m31 * self . m43 + self . m11 * self . m32 * self . m43 ,
167
+
168
+ self . m13 * self . m22 * self . m41 - self . m12 * self . m23 * self . m41 -
169
+ self . m13 * self . m21 * self . m42 + self . m11 * self . m23 * self . m42 +
170
+ self . m12 * self . m21 * self . m43 - self . m11 * self . m22 * self . m43 ,
171
+
172
+ self . m12 * self . m23 * self . m31 - self . m13 * self . m22 * self . m31 +
173
+ self . m13 * self . m21 * self . m32 - self . m11 * self . m23 * self . m32 -
174
+ self . m12 * self . m21 * self . m33 + self . m11 * self . m22 * self . m33
175
+ ) ;
176
+
177
+ m. mul_s ( 1.0 / det)
178
+ }
179
+
180
+ pub fn determinant ( & self ) -> f32 {
181
+ self . m14 * self . m23 * self . m32 * self . m41 -
182
+ self . m13 * self . m24 * self . m32 * self . m41 -
183
+ self . m14 * self . m22 * self . m33 * self . m41 +
184
+ self . m12 * self . m24 * self . m33 * self . m41 +
185
+ self . m13 * self . m22 * self . m34 * self . m41 -
186
+ self . m12 * self . m23 * self . m34 * self . m41 -
187
+ self . m14 * self . m23 * self . m31 * self . m42 +
188
+ self . m13 * self . m24 * self . m31 * self . m42 +
189
+ self . m14 * self . m21 * self . m33 * self . m42 -
190
+ self . m11 * self . m24 * self . m33 * self . m42 -
191
+ self . m13 * self . m21 * self . m34 * self . m42 +
192
+ self . m11 * self . m23 * self . m34 * self . m42 +
193
+ self . m14 * self . m22 * self . m31 * self . m43 -
194
+ self . m12 * self . m24 * self . m31 * self . m43 -
195
+ self . m14 * self . m21 * self . m32 * self . m43 +
196
+ self . m11 * self . m24 * self . m32 * self . m43 +
197
+ self . m12 * self . m21 * self . m34 * self . m43 -
198
+ self . m11 * self . m22 * self . m34 * self . m43 -
199
+ self . m13 * self . m22 * self . m31 * self . m44 +
200
+ self . m12 * self . m23 * self . m31 * self . m44 +
201
+ self . m13 * self . m21 * self . m32 * self . m44 -
202
+ self . m11 * self . m23 * self . m32 * self . m44 -
203
+ self . m12 * self . m21 * self . m33 * self . m44 +
204
+ self . m11 * self . m22 * self . m33 * self . m44
205
+ }
206
+
102
207
pub fn mul_s ( & self , x : f32 ) -> Matrix4 {
103
208
Matrix4 :: new ( self . m11 * x, self . m12 * x, self . m13 * x, self . m14 * x,
104
209
self . m21 * x, self . m22 * x, self . m23 * x, self . m24 * x,
@@ -226,3 +331,45 @@ pub fn test_ortho() {
226
331
debug ! ( "result={:?} expected={:?}" , result, expected) ;
227
332
assert ! ( result. approx_eq( & expected) ) ;
228
333
}
334
+
335
+ #[ test]
336
+ pub fn test_invert_simple ( ) {
337
+ let m1 = Matrix4 :: identity ( ) ;
338
+ let m2 = m1. invert ( ) ;
339
+ assert ! ( m1. approx_eq( & m2) ) ;
340
+ }
341
+
342
+ #[ test]
343
+ pub fn test_invert_scale ( ) {
344
+ let m1 = Matrix4 :: create_scale ( 1.5 , 0.3 , 2.1 ) ;
345
+ let m2 = m1. invert ( ) ;
346
+ assert ! ( m1. mul( & m2) . approx_eq( & Matrix4 :: identity( ) ) ) ;
347
+ }
348
+
349
+ #[ test]
350
+ pub fn test_invert_translate ( ) {
351
+ let m1 = Matrix4 :: create_translation ( -132.0 , 0.3 , 493.0 ) ;
352
+ let m2 = m1. invert ( ) ;
353
+ assert ! ( m1. mul( & m2) . approx_eq( & Matrix4 :: identity( ) ) ) ;
354
+ }
355
+
356
+ #[ test]
357
+ pub fn test_invert_rotate ( ) {
358
+ let m1 = Matrix4 :: create_rotation ( 0.0 , 1.0 , 0.0 , 1.57 ) ;
359
+ let m2 = m1. invert ( ) ;
360
+ assert ! ( m1. mul( & m2) . approx_eq( & Matrix4 :: identity( ) ) ) ;
361
+ }
362
+
363
+ #[ test]
364
+ pub fn test_invert_transform_point_2d ( ) {
365
+ let m1 = Matrix4 :: create_translation ( 100.0 , 200.0 , 0.0 ) ;
366
+ let m2 = m1. invert ( ) ;
367
+ assert ! ( m1. mul( & m2) . approx_eq( & Matrix4 :: identity( ) ) ) ;
368
+
369
+ let p1 = Point2D :: new ( 1000.0 , 2000.0 ) ;
370
+ let p2 = m1. transform_point ( & p1) ;
371
+ assert ! ( p2. eq( & Point2D :: new( 1100.0 , 2200.0 ) ) ) ;
372
+
373
+ let p3 = m2. transform_point ( & p2) ;
374
+ assert ! ( p3. eq( & p1) ) ;
375
+ }
0 commit comments