the Fiddler.'s picture

OpenTK 0.3.13 Matrix4 errata

JTalton has uncovered some errors in the OpenTK.Math.Matrix4 implementation. Specifically, the Frustrum, Perspective, Rotate, RotateX, and Multiply methods return incorrect results.

Attached is the program used to test these functions, kindly povided by JTalton. Note that the multiply test may be wrong, so don't rely on its results.

Please use the equivalent Glu methods until the OpenTK 0.3.14 release.

AttachmentSize
Program.cs14.96 KB

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
george's picture

Hello, sorry I havn't replied sooner, I was ill and then on holiday.
It's perfectly possible I've messed up somewhere, I did throw it all together rather quickly, what are the issues?

the Fiddler.'s picture

Hey, no problem! I haven't had time to look into this either. Here are the failing functions:

(Edit: attached the program used to check at the first post)

1) Frustum
 
OpenTK.Math.Matrix4.Frustum(10, Width, Height, 10, 2.0f, 4.0f)
(0.006349206, 0, 1.031746, 0)
(0, -0.008510638, -1.042553, 0)
(0, 0, -3, -1)
(0, 0, -8, 0) 
 
OpenTK.OpenGL.GL.Frustum (10, Width, Height, 10, 2.0d, 4.0d)
|0.00634920643642545, 0, 0, 0|
|0, -0.00851063802838326, 0, 0|
|1.03174602985382, -1.04255318641663, -3, -1|
|0, 0, -8, 0|
 
2) Perspective
 
OpenTK.Math.Matrix4.Perspective(70, 1, 1.0f, 4.0f)
(0.8183574, 0, 0, 0)
(0, 0.8183574, 0, 0)
(0, 0, -1.666667, -1)
(0, 0, -2.666667, 0)
 
OpenTK.OpenGL.Glu.Perspective(70, 1, 1.0d, 4.0d)
|1.42814803123474, 0, 0, 0| 
|0, 1.42814803123474, 0, 0|
|0, 0, -1.66666662693024, -1|
|0, 0, -2.66666674613953, 0|
 
3) LookAt
 
OpenTK.Math.Matrix4.LookAt(new Vector3(10, 0, 10), new Vector3(0, 1, 0), new Vector3(0, 1, 0)) 
(0.7071068, 0.04987547, 0.7053456, 0)
(0, 0.9975094, -0.07053456, 0)
(-0.7071068, 0.04987547, 0.7053456, 0)
(0, -0.9975094, -14.10691, 1)
 
OpenTK.OpenGL.Glu.LookAt(new Vector3D(10, 0, 10), new Vector3D(0, 1, 0), new Vector3D(0, 1, 0))
|0.70710676908493, 0.0498754680156708, 0.705345630645752, 0|
|0, 0.997509360313416, -0.0705345645546913, 0| 
|-0.70710676908493, 0.0498754680156708, 0.705345630645752, 0|
|0, -0.997509360313416, -14.106912612915, 1|
 
4) Rotate
 
OpenTK.Math.Matrix4.Rotate(new Vector3(1, 2, 3), 17)) 
(-0.1840803, -0.5886666, 0.7871378, 0)
(0.952999, 0.08916904, 0.2895543, 0)
(-0.2406393, 0.8034428, 0.5445845, 0)
(0, 0, 0, 1)
 
OpenTK.OpenGL.GL.Rotate(17, new Vector3(1, 2, 3)) 
|0.959425806999207, 0.240661039948463, -0.146915972232819, 0|
|-0.228176668286324, 0.968789100646973, 0.0968661606311798, 0|
|0.165642499923706, -0.0594130754470825, 0.984394550323486, 0|
|0, 0, 0, 1|
 
5) RotateX
 
OpenTK.Math.Matrix4.RotateX(17))
(1, 0, 0, 0)
(0, -0.2751634, -0.9613975, 0)
(0, 0.9613975, -0.2751634, 0)
(0, 0, 0, 1)
 
OpenTK.OpenGL.GL.Rotate(17, new Vector3(1, 0, 0))
|1, 0, 0, 0|
|0, 0.956304728984833 , 0.292371690273285, 0|
|0, -0.292371690273285, 0.956304728984833, 0|
|0, 0, 0, 1|
george's picture

Ok, I've had a quick look.
The LookAt output seems to be the same apart from precision differences.
Remember that all the OpenTK.Math functions take angles in radians not degrees. Changing the calls appropriately gives the correct results for the rotate functions. The Perspective function did have an error in the implementation, if you change the first line from:
float yMax = near * (float)System.Math.Tan(fovy);
to:
float yMax = near * (float)System.Math.Tan(0.5f * fovy);
then that should clear that one up (as long as you remember to use radians).

Frustum is curious, it's used by the Perspective function, so it's definitely doing something right. I've been using it for ages without any problem. A quick google for glFrustum brought me to this page: http://www.gambasdoc.org/help/comp/gb.opengl/gl/frustum
which implies that the OpenTK.Math result is the correct one.

The Math classes are meant as a general purpose maths library, not as a drop in equivalent to the gl/glu functions. Hence the row major matrices and angles in radians. With that in mind I'm not all that bothered if the results differ from the opengl implementations as long as they do what they say on the tin. As I said, I haven't noticed any problems with the Frustum function in practice (if you've had a different experience please let me know).

Hope that helps.

the Fiddler.'s picture

Alright then! I've commited the Perspective fix, and the rest isn't anything that cannot be handled by the documentation. Many thanks!