@@ -99,6 +99,111 @@ impl Matrix4 {
9999 m. m41 * self . m14 + m. m42 * self . m24 + m. m43 * self . m34 + m. m44 * self . m44 )
100100 }
101101
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+
102207 pub fn mul_s ( & self , x : f32 ) -> Matrix4 {
103208 Matrix4 :: new ( self . m11 * x, self . m12 * x, self . m13 * x, self . m14 * x,
104209 self . m21 * x, self . m22 * x, self . m23 * x, self . m24 * x,
@@ -226,3 +331,45 @@ pub fn test_ortho() {
226331 debug ! ( "result={:?} expected={:?}" , result, expected) ;
227332 assert ! ( result. approx_eq( & expected) ) ;
228333}
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