google / mathfu

C++ math library developed primarily for games focused on simplicity and efficiency.

Home Page:http://google.github.io/mathfu

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Projection function

rickomax opened this issue · comments

Hi. The library contains the "UnProjectHelper" to convert a 2D screen point to 3D world point. Would be hard to implement a "ProjectHelper" function, to convert from 3D to 2D screen point?

@billhsu you wrote the UnProjectHelper, what do you think?

I've tried to implement the "gluProject" source using MathFu matrices, but something is wrong, all the resulting points using a "mathfu::mat4::Ortho" matrix as "projMatrix" parameter are getting perspective-projected when calculated with my function:
https://pastebin.com/GRdBGm4E

Maybe the projection code is not suitable for MathFu, or I'm not creating the "ortho" matrix with right parameters.

@rickomax the implementation is a bit overly complicated I think..
Below is my implementation and I'm able to get correct results with Ortho matrix as input.

template <class T>
bool Project(T objx, T objy, T objz, const mathfu::Matrix<T, 4> projMatrix, const mathfu::Matrix<T, 4> modelMatrix, int* view, T* winx, T* winy, T* winz)
{
    mathfu::Vector<T, 4> in = projMatrix * modelMatrix* mathfu::Vector<T, 4>(objx, objy, objz, static_cast<T>(1));
    *winx = view[0] + (static_cast<T>(1) + in.x) * view[1] / static_cast<T>(2);
    *winy = view[2] + (static_cast<T>(1) + in.y) * view[3] / static_cast<T>(2);
    *winz = (in.z + static_cast<T>(1)) / static_cast<T>(2);
    return true;
}

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
    float winX,winY, winZ;
    int view[] = {0,800,0,600};
    Project(100.0f, 110.0f, 0.0f, mathfu::Matrix<float, 4, 4>::Ortho(0,800,0,600,-1,1), mathfu::Matrix<float, 4>::Identity(), view, &winX, &winY, &winZ);
    printf("%f %f %f\n", winX, winY, winZ);
    return 0;
}

@stewartmiles do you feel this is something we should include in mathfu? If it is, I can send a PR to add this in.

Thank you @billhsu and @stewartmiles !

I just discovered that I could not divide the input product by the z value, as this was causing the value to be "perspective divided".

Anyway, your function is well-written and I will use it.
In my opinion, would be awesome to have this function in Mathfu.

We already have helper functions to create projection matrices (e.g. Perspective()). So a projection function should simply be a question of multiplying with such a matrix, followed with perspective divide.

@rickomax sounds like a fair addition to the library fits within it's goals AFAIK. @gwvo / @aardappel thoughts?

I agree with @billhsu and @aardappel that the implementation could be simplified, wanna give it a shot and send a pull request?