Problem with gfm.math.matrix (some gamedevs out there ?)

Thomas earthwormjimmy at gmx.at
Thu Sep 3 13:49:21 UTC 2020


On Thursday, 3 September 2020 at 13:31:01 UTC, Mike Parker wrote:
> On Thursday, 3 September 2020 at 12:36:35 UTC, Thomas wrote:
>
>>
>> My example code:
>> ---------------------
>> import std.stdio;
>>
>> int main()
>> {
>>
>>     import gfm.math.matrix;
>>
>>     const int width = 800;
>>     const int height = 600;
>>
>>     auto projectionMatrix = mat4!(float).identity();
>>     auto ratio = cast(float)width / cast(float)height;
>>
>>     projectionMatrix = mat4!(float).perspective( 45.0f, ratio, 
>> 0.0f, 100.0f );
>>
>>     writeln("projectionMatrix: ", projectionMatrix );
>>
>>     auto inversedMatrix = mat4!(float).identity();
>>     inversedMatrix = projectionMatrix.inverse();  // <-- why 
>> this does not work ?
>>     writeln("inversedMatrix: ", inversedMatrix );
>>
>>     return 0;
>> }
>
> This is not the problem, but FYI these two lines are reduntant:
>
> auto projectionMatrix = mat4!(float).identity();
> auto inversedMatrix = mat4!(float).identity();
>
> This is all you need:
>
> auto projectionMatrix = mat4!(float).perspective( 45.0f, ratio, 
> 0.0f, 100.0f );
> auto inversedMatrix = projectionMatrix.inverse();
>
> `perspective` and `inverse` return new instances that overwrite 
> the two identity matrices you initialized, so you're doing work 
> you don't need to do.
>
>
>
>>
>> The projection matrix will be calculated correctly with
>> [1.34444, 0, 0, 0, 0, 1.79259, 0, 0, 0, 0, -1, -0, 0, 0, -1, 
>> 0] assuming that the screen size is 800x600.
>>
>> But using the .inverse() function in gfm returns only a matrix 
>> with following values:
>> [-nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, -nan, 
>> -nan, -nan, -nan, -nan, inf, -inf]
>>
>> I don't know what I am doing wrong here:
>>   - do I call the function wrong way ? (but there is no other 
>> way)
>>   - is there a bug in the function ? (I do not believe that 
>> because the library is battle proved)
>>
>
> My guess is the problem is in the `inverse` implementation:
>
> https://github.com/d-gamedev-team/gfm/blob/master/math/gfm/math/matrix.d#L448
>
> T invDet = 1 / det;
>
> It doesn't check if det is 0.
>
> This shows 1f / 0f results in `inf`:
>
> import std;
> void main()
> {
>     float f = 0;
>     float i = 1 / f;
>     writeln(i);
> }
>
> https://run.dlang.io/is/ZyggRg
>
> With all those zeroes in the perspective matrix and all the 
> multiplications in the `inverse` function, I guess things are 
> getting wonky.

Thank you very much! Both of you!


More information about the Digitalmars-d-learn mailing list