diff --git a/vtkm/rendering/CMakeLists.txt b/vtkm/rendering/CMakeLists.txt index a8cdf1e48..dd8add4dd 100644 --- a/vtkm/rendering/CMakeLists.txt +++ b/vtkm/rendering/CMakeLists.txt @@ -50,6 +50,7 @@ set(sources AxisAnnotation3D.cxx BitmapFont.cxx BitmapFontFactory.cxx + Camera.cxx DecodePNG.cxx ) diff --git a/vtkm/rendering/Camera.cxx b/vtkm/rendering/Camera.cxx new file mode 100644 index 000000000..503a8cc7c --- /dev/null +++ b/vtkm/rendering/Camera.cxx @@ -0,0 +1,349 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2015 Sandia Corporation. +// Copyright 2015 UT-Battelle, LLC. +// Copyright 2015 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#include + +namespace vtkm { +namespace rendering { + +vtkm::Matrix +Camera::Camera3DStruct::CreateViewMatrix() const +{ + return MatrixHelpers::ViewMatrix(this->Position, this->LookAt, this->ViewUp); +} + +vtkm::Matrix +Camera::Camera3DStruct::CreateProjectionMatrix(vtkm::Id width, + vtkm::Id height, + vtkm::Float32 nearPlane, + vtkm::Float32 farPlane) const +{ + vtkm::Matrix matrix; + vtkm::MatrixIdentity(matrix); + + vtkm::Float32 AspectRatio = vtkm::Float32(width) / vtkm::Float32(height); + vtkm::Float32 fovRad = (this->FieldOfView * 3.1415926f)/180.f; + fovRad = vtkm::Tan( fovRad * 0.5f); + vtkm::Float32 size = nearPlane * fovRad; + vtkm::Float32 left = -size * AspectRatio; + vtkm::Float32 right = size * AspectRatio; + vtkm::Float32 bottom = -size; + vtkm::Float32 top = size; + + matrix(0,0) = 2.f * nearPlane / (right - left); + matrix(1,1) = 2.f * nearPlane / (top - bottom); + matrix(0,2) = (right + left) / (right - left); + matrix(1,2) = (top + bottom) / (top - bottom); + matrix(2,2) = -(farPlane + nearPlane) / (farPlane - nearPlane); + matrix(3,2) = -1.f; + matrix(2,3) = -(2.f * farPlane * nearPlane) / (farPlane - nearPlane); + matrix(3,3) = 0.f; + + vtkm::Matrix 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; +} + +//--------------------------------------------------------------------------- + +vtkm::Matrix +Camera::Camera2DStruct::CreateViewMatrix() const +{ + vtkm::Vec lookAt((this->Left + this->Right)/2.f, + (this->Top + this->Bottom)/2.f, + 0.f); + vtkm::Vec position = lookAt; + position[2] = 1.f; + vtkm::Vec up(0,1,0); + return MatrixHelpers::ViewMatrix(position, lookAt, up); +} + +vtkm::Matrix +Camera::Camera2DStruct::CreateProjectionMatrix(vtkm::Float32 size, + vtkm::Float32 znear, + vtkm::Float32 zfar, + vtkm::Float32 aspect) const +{ + vtkm::Matrix matrix(0.f); + vtkm::Float32 left = -size/2.f * aspect; + vtkm::Float32 right = size/2.f * aspect; + vtkm::Float32 bottom = -size/2.f; + vtkm::Float32 top = size/2.f; + + matrix(0,0) = 2.f/(right-left); + matrix(1,1) = 2.f/(top-bottom); + matrix(2,2) = -2.f/(zfar-znear); + matrix(0,3) = -(right+left)/(right-left); + matrix(1,3) = -(top+bottom)/(top-bottom); + matrix(2,3) = -(zfar+znear)/(zfar-znear); + matrix(3,3) = 1.f; + + vtkm::Matrix 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; +} + +//--------------------------------------------------------------------------- + +vtkm::Matrix +Camera::CreateViewMatrix() const +{ + if (this->Mode == Camera::MODE_3D) + { + return this->Camera3D.CreateViewMatrix(); + } + else + { + return this->Camera2D.CreateViewMatrix(); + } +} + +vtkm::Matrix +Camera::CreateProjectionMatrix(vtkm::Id screenWidth, + vtkm::Id screenHeight) const +{ + if (this->Mode == Camera::MODE_3D) + { + return this->Camera3D.CreateProjectionMatrix( + screenWidth, screenHeight, this->NearPlane, this->FarPlane); + } + else + { + vtkm::Float32 size = vtkm::Abs(this->Camera2D.Top - this->Camera2D.Bottom); + vtkm::Float32 left,right,bottom,top; + this->GetRealViewport(screenWidth,screenHeight,left,right,bottom,top); + vtkm::Float32 aspect = + (static_cast(screenWidth)*(right-left)) / + (static_cast(screenHeight)*(top-bottom)); + + return this->Camera2D.CreateProjectionMatrix( + size, this->NearPlane, this->FarPlane, aspect); + } +} + +void Camera::GetRealViewport(vtkm::Id screenWidth, + vtkm::Id screenHeight, + vtkm::Float32 &left, + vtkm::Float32 &right, + vtkm::Float32 &bottom, + vtkm::Float32 &top) const +{ + if (this->Mode == Camera::MODE_3D) + { + left = this->ViewportLeft; + right = this->ViewportRight; + bottom = this->ViewportBottom; + top = this->ViewportTop; + } + else + { + vtkm::Float32 maxvw = (this->ViewportRight-this->ViewportLeft) * static_cast(screenWidth); + vtkm::Float32 maxvh = (this->ViewportTop-this->ViewportBottom) * static_cast(screenHeight); + vtkm::Float32 waspect = maxvw / maxvh; + vtkm::Float32 daspect = (this->Camera2D.Right - this->Camera2D.Left) / (this->Camera2D.Top - this->Camera2D.Bottom); + daspect *= this->Camera2D.XScale; + //cerr << "waspect="<