//============================================================================ // 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="< pm, vm; pm = CreateProjectionMatrix(512,512); vm = CreateViewMatrix(); std::cout<<" PM: "<