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

2020-09-04 Thread Guillaume Piolat via Digitalmars-d-learn

On Thursday, 3 September 2020 at 12:36:35 UTC, Thomas wrote:

-
import std.stdio;

int main()
{

import gfm.math.matrix;

const int width = 800;
const int height = 600;

auto projectionMatrix = mat4!(float).identity();


Note that instead of `mat4!(float)` you can just use `mat4f`.




auto ratio = cast(float)width / cast(float)height;

projectionMatrix = mat4!(float).perspective( 45.0f, ratio, 
0.0f, 100.0f );


As others said, zNear is zero so your matrix is not invertible.
I guess perspective should warn about that.


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

2020-09-03 Thread Thomas via Digitalmars-d-learn

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.3, 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!


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

2020-09-03 Thread Mike Parker via Digitalmars-d-learn

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.3, 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.






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

2020-09-03 Thread drug via Digitalmars-d-learn

On 9/3/20 3:36 PM, Thomas wrote:

Hi!

I am following some examples in C++ about how OpenGL is working. There 
are great tutorials out there and most of it works also with D.
For my code I am using gfm.math.matrix (Version 8.0.3) to be able to 
calculate the mouse position in a 3d world.

Now I have some problems with the projection matrix by inverting it.

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;
}

The projection matrix will be calculated correctly with
[1.3, 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)


So I looked a couple of hours for an answer, but did not find anything 
useful.


Is somebody out there who could help me out ? Maybe one developer of the 
d gfm library ?


Thank you for you time!

Thomas


1. zNear should not be equal to zero, this makes your matrix singular 
and inversion of singular matix is impossible so you get nans and infs. 
Make zNear a little bit more than zero and your code will work


2. FOV in perspective should be expressed in radians, not degrees

so this fixes your problem:
```
projectionMatrix = mat4!(float).perspective( 45.0f * 3.14 / 180., ratio, 
0.01f, 100.0f );

```