Is there any way to retrieve the camera origin/position from the view projection matrix? (OpenGL)
I'm trying to draw the camera's frustum and I have no problems calculating corners for the Far and the Near planes.
But I can't figure out how to retrieve a point that would represent the camera origin.
I was expecting to retrieve this by multiplying the Homogeneous clip-space coordinates:
glm::vec4(0.f, 0.f, 0.f, 1.f)
But I'm getting somewhat that looks to be like ~inverted camera position. (Marked as X in the screenshot) Included all the source code below.
// Homogeneous points for source cube in clip-space.
std::array<glm::vec4, 9> corners =
{
// Far plane
glm::vec4(-1.f,-1.f, 1.f, 1.f), // bottom-left
glm::vec4( 1.f,-1.f, 1.f, 1.f), // bottom-right
glm::vec4( 1.f, 1.f, 1.f, 1.f), // top-right
glm::vec4(-1.f, 1.f, 1.f, 1.f), // top-left
// Near plane
glm::vec4(-1.f,-1.f,-1.f, 1.f), // bottom-left
glm::vec4( 1.f,-1.f,-1.f, 1.f), // bottom-right
glm::vec4( 1.f, 1.f,-1.f, 1.f), // top-right
glm::vec4(-1.f, 1.f,-1.f, 1.f), // top-left
// Camera/screen center position.
// glm::vec4(0.f, 0.f, 0.f, 1.f) // EDIT
glm::vec4(0.f, 0.f,-1.f, 0.f) // SOLVED
};
const auto invMatrix(glm::inverse(viewProjectionMatrix));
for (U32 i = 0; i < corners.size(); i++)
{
corners[i] = invMatrix * corners[i]; // 4x4 * 4x1 matrix/vector multiplication.
corners[i] /= corners[i].w; // Homogeneous to euclidean/cartesian conversion
}
// Far plane.
this->AddLine(corners[0], corners[1], rColor);
this->AddLine(corners[1], corners[2], rColor);
this->AddLine(corners[2], corners[3], rColor);
this->AddLine(corners[3], corners[0], rColor);
// Near plane.
this->AddLine(corners[4], corners[5], rColor);
this->AddLine(corners[5], corners[6], rColor);
this->AddLine(corners[6], corners[7], rColor);
this->AddLine(corners[7], corners[4], rColor);
// Connection from Near rectangle to the Far rectangle.
this->AddLine(corners[0], corners[4], rColor);
this->AddLine(corners[1], corners[5], rColor);
this->AddLine(corners[2], corners[6], rColor);
this->AddLine(corners[3], corners[7], rColor);
// X
this->AddLine(corners[4], corners[8], rColor);
this->AddLine(corners[5], corners[8], rColor);
this->AddLine(corners[6], corners[8], rColor);
this->AddLine(corners[7], corners[8], rColor);
[Solved]
The problem was that I needed to use glm::vec4(0.f, 0.f,-1.f, 0.f)
instead of glm::vec4(0.f, 0.f, 0.f, 1.f)
.