Implement roll, elevation, and azimuth for 3D cameras

Also implement pan and zoom for 2D cameras.

Update the rendering tests to do these camera rotations. This matches
better the viewpoint used before the previous camera changes.
This commit is contained in:
Kenneth Moreland 2016-06-08 14:21:33 -06:00
parent cdeeda67bb
commit 9f3e0e5952
5 changed files with 114 additions and 14 deletions

@ -87,12 +87,12 @@ void mouseMove(int x, int y)
if (buttonStates[0] == GLUT_DOWN)
{
if (shiftKey)
view->GetCamera().Pan3D(x2-x1, y2-y1);
view->GetCamera().Pan(x2-x1, y2-y1);
else
view->GetCamera().TrackballRotate(x1,y1, x2,y2);
}
else if (buttonStates[1] == GLUT_DOWN)
view->GetCamera().Zoom3D(y2-y1);
view->GetCamera().Zoom(y2-y1);
}
lastx = x;

@ -101,7 +101,14 @@ class Camera
public:
VTKM_CONT_EXPORT
Camera2DStruct()
: Left(-1.0f), Right(1.0f), Bottom(-1.0f), Top(1.0f), XScale(1.0f)
: Left(-1.0f),
Right(1.0f),
Bottom(-1.0f),
Top(1.0f),
XScale(1.0f),
XPan(0.0f),
YPan(0.0f),
Zoom(1.0f)
{}
VTKM_CONT_EXPORT
@ -135,6 +142,11 @@ class Camera
matrix(1,3) = -(top+bottom)/(top-bottom);
matrix(2,3) = -(far+near)/(far-near);
matrix(3,3) = 1.f;
vtkm::Matrix<vtkm::Float32,4,4> T, Z;
T = vtkm::Transform3DTranslate(this->XPan, this->YPan, 0.f);
Z = vtkm::Transform3DScale(this->Zoom, this->Zoom, 1.f);
matrix = vtkm::MatrixMultiply(Z, vtkm::MatrixMultiply(T, matrix));
return matrix;
}
@ -143,6 +155,9 @@ class Camera
vtkm::Float32 Bottom;
vtkm::Float32 Top;
vtkm::Float32 XScale;
vtkm::Float32 XPan;
vtkm::Float32 YPan;
vtkm::Float32 Zoom;
};
public:
@ -429,21 +444,20 @@ public:
this->Camera3D.FieldOfView = fov;
}
/// \brief Pans the camera in 3D mode.
///
/// Panning the camera in this way changes the mode to 3D.
/// \brief Pans the camera
///
VTKM_CONT_EXPORT
void Pan3D(vtkm::Float32 dx, vtkm::Float32 dy)
void Pan(vtkm::Float32 dx, vtkm::Float32 dy)
{
this->SetModeTo3D();
this->Camera3D.XPan += dx;
this->Camera3D.YPan += dy;
this->Camera2D.XPan += dx;
this->Camera2D.YPan += dy;
}
VTKM_CONT_EXPORT
void Pan3D(vtkm::Vec<vtkm::Float32,2> direction)
void Pan(vtkm::Vec<vtkm::Float32,2> direction)
{
this->Pan3D(direction[0], direction[1]);
this->Pan(direction[0], direction[1]);
}
/// \brief Zooms the camera in or out
@ -452,16 +466,16 @@ public:
/// zoom makes the geometry look bigger or closer. Negative zoom has the
/// opposite effect. A zoom of 0 has no effect.
///
/// Zooming the camera changes the mode to 3D.
///
VTKM_CONT_EXPORT
void Zoom3D(vtkm::Float32 zoom)
void Zoom(vtkm::Float32 zoom)
{
this->SetModeTo3D();
vtkm::Float32 factor = vtkm::Pow(4.0f, zoom);
this->Camera3D.Zoom *= factor;
this->Camera3D.XPan *= factor;
this->Camera3D.YPan *= factor;
this->Camera2D.Zoom *= factor;
this->Camera2D.XPan *= factor;
this->Camera2D.YPan *= factor;
}
/// \brief Moves the camera as if a point was dragged along a sphere.
@ -523,6 +537,10 @@ public:
VTKM_CONT_EXPORT
void ResetToBounds(const vtkm::Bounds &dataBounds)
{
// Save camera mode
ModeEnum saveMode = this->GetMode();
// Reset for 3D camera
vtkm::Vec<vtkm::Float32,3> directionOfProjection =
this->GetPosition() - this->GetLookAt();
vtkm::Normalize(directionOfProjection);
@ -538,6 +556,82 @@ public:
this->SetPosition(center + directionOfProjection * diagonalLength * 1.0f);
this->SetFieldOfView(60.0f);
this->SetClippingRange(1.0f, diagonalLength*10.0f);
// Reset for 2D camera
this->SetViewRange2D(dataBounds);
// Restore camera mode
this->SetMode(saveMode);
}
/// \brief Roll the camera
///
/// Rotates the camera around the view direction by the given angle. The
/// angle is given in radians.
///
/// Roll is currently only supported for 3D cameras.
///
VTKM_CONT_EXPORT
void Roll(vtkm::Float32 angleRadians)
{
vtkm::Vec<vtkm::Float32,3> directionOfProjection =
this->GetLookAt() - this->GetPosition();
vtkm::Matrix<vtkm::Float32,4,4> rotateTransform =
vtkm::Transform3DRotate(angleRadians, directionOfProjection);
this->SetViewUp(vtkm::Transform3DVector(rotateTransform,this->GetViewUp()));
}
/// \brief Rotate the camera about the view up vector centered at the focal point.
///
/// Note that the view up vector is whatever was set via SetViewUp, and is
/// not necesarily perpendicular to the direction of projection. The angle is
/// given in radians.
///
/// Azimuth only makes sense for 3D cameras, so the camera mode will be set
/// to 3D when this method is called.
///
VTKM_CONT_EXPORT
void Azimuth(vtkm::Float32 angleRadians)
{
// Translate to the focal point (LookAt), rotate about view up, and
// translate back again.
vtkm::Matrix<vtkm::Float32,4,4> transform =
vtkm::Transform3DTranslate(this->GetLookAt());
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DRotate(angleRadians, this->GetViewUp()));
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DTranslate(-this->GetLookAt()));
this->SetPosition(vtkm::Transform3DPoint(transform, this->GetPosition()));
}
/// \brief Rotate the camera vertically around the focal point.
///
/// Specifically, this rotates the camera about the cross product of the
/// negative of the direction of projection and the view up vector, using the
/// focal point (LookAt) as the center of rotation. The angle is given
/// in radians.
///
/// Elevation only makes sense for 3D cameras, so the camera mode will be set
/// to 3D when this method is called.
///
VTKM_CONT_EXPORT
void Elevation(vtkm::Float32 angleRadians)
{
vtkm::Vec<vtkm::Float32,3> axisOfRotation =
vtkm::Cross(this->GetPosition() - this->GetLookAt(), this->GetViewUp());
// Translate to the focal point (LookAt), rotate about the defined axis,
// and translate back again.
vtkm::Matrix<vtkm::Float32,4,4> transform =
vtkm::Transform3DTranslate(this->GetLookAt());
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DRotate(angleRadians, axisOfRotation));
transform = vtkm::MatrixMultiply(
transform, vtkm::Transform3DTranslate(-this->GetLookAt()));
this->SetPosition(vtkm::Transform3DPoint(transform, this->GetPosition()));
}
/// \brief The viewable region in the x-y plane

@ -36,6 +36,8 @@ void Set3DView(vtkm::rendering::Camera &camera,
//set up a default view
camera = vtkm::rendering::Camera();
camera.ResetToBounds(coordsBounds);
camera.Azimuth(static_cast<vtkm::Float32>(vtkm::Pi_4()));
camera.Elevation(static_cast<vtkm::Float32>(vtkm::Pi_4()));
std::cout << "Camera3d: pos: " << camera.GetPosition() << std::endl;
std::cout << " lookAt: " << camera.GetLookAt() << std::endl;

@ -36,6 +36,8 @@ void Set3DView(vtkm::rendering::Camera &camera,
//set up a default view
camera = vtkm::rendering::Camera();
camera.ResetToBounds(coordsBounds);
camera.Azimuth(static_cast<vtkm::Float32>(vtkm::Pi_4()));
camera.Elevation(static_cast<vtkm::Float32>(vtkm::Pi_4()));
std::cout << "Camera3d: pos: " << camera.GetPosition() << std::endl;
std::cout << " lookAt: " << camera.GetLookAt() << std::endl;

@ -37,6 +37,8 @@ void Set3DView(vtkm::rendering::Camera &camera,
//set up a default view
camera = vtkm::rendering::Camera();
camera.ResetToBounds(coordsBounds);
camera.Azimuth(static_cast<vtkm::Float32>(vtkm::Pi_4()));
camera.Elevation(static_cast<vtkm::Float32>(vtkm::Pi_4()));
std::cout << "Camera3d: pos: " << camera.GetPosition() << std::endl;
std::cout << " lookAt: " << camera.GetLookAt() << std::endl;