Commit 0da55730 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Fix scaling of x/y field of views

Prevously, the x field of view was computed by scaling the y field of
view by the aspect ratio of the canvas. However, this is wrong because
the field of view angles do not scale linearly with the aspect ratio.
Fix this issue by using trig functions to convert the angle to distance,
scale the distance, and then convert back to angle.
parent 39b347db
......@@ -530,7 +530,31 @@ void Camera::SetFieldOfView(const vtkm::Float32& degrees)
}
vtkm::Float32 newFOVY = degrees;
vtkm::Float32 newFOVX = (vtkm::Float32(this->Width) / vtkm::Float32(this->Height)) * degrees;
vtkm::Float32 newFOVX;
if (this->Width != this->Height)
{
vtkm::Float32 fovyRad = (newFOVY * static_cast<vtkm::Float32>(vtkm::Pi())) / 180.0f;
// Use the tan function to find the distance from the center of the image to the top (or
// bottom). (Actually, we are finding the ratio of this distance to the near plane distance,
// but since we scale everything by the near plane distance, we can use this ratio as a scaled
// proxy of the distances we need.)
vtkm::Float32 verticalDistance = vtkm::Tan(0.5f * fovyRad);
// Scale the vertical distance by the aspect ratio to get the horizontal distance.
vtkm::Float32 aspectRatio = vtkm::Float32(this->Width) / vtkm::Float32(this->Height);
vtkm::Float32 horizontalDistance = aspectRatio * verticalDistance;
// Now use the arctan function to get the proper field of view in the x direction.
vtkm::Float32 fovxRad = 2.0f * vtkm::ATan(horizontalDistance);
newFOVX = 180.0f * (fovxRad / static_cast<vtkm::Float32>(vtkm::Pi()));
}
else
{
newFOVX = newFOVY;
}
if (newFOVX != this->FovX)
{
this->IsViewDirty = true;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment