//============================================================================ // 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. //============================================================================ #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 * vtkm::Pi_180f(); 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::Vec3f_32 lookAt((this->Left + this->Right) / 2.f, (this->Top + this->Bottom) / 2.f, 0.f); vtkm::Vec3f_32 position = lookAt; position[2] = 1.f; vtkm::Vec3f_32 up(0, 1, 0); vtkm::Matrix V = MatrixHelpers::ViewMatrix(position, lookAt, up); vtkm::Matrix scaleMatrix = MatrixHelpers::CreateScale(this->XScale, 1, 1); V = vtkm::MatrixMultiply(scaleMatrix, V); return V; } 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->ModeType == Camera::Mode::ThreeD) { return this->Camera3D.CreateViewMatrix(); } else { return this->Camera2D.CreateViewMatrix(); } } vtkm::Matrix Camera::CreateProjectionMatrix(vtkm::Id screenWidth, vtkm::Id screenHeight) const { if (this->ModeType == Camera::Mode::ThreeD) { 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->ModeType == Camera::Mode::ThreeD) { 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: " << std::endl; std::cout << pm[0][0] << " " << pm[0][1] << " " << pm[0][2] << " " << pm[0][3] << std::endl; std::cout << pm[1][0] << " " << pm[1][1] << " " << pm[1][2] << " " << pm[1][3] << std::endl; std::cout << pm[2][0] << " " << pm[2][1] << " " << pm[2][2] << " " << pm[2][3] << std::endl; std::cout << pm[3][0] << " " << pm[3][1] << " " << pm[3][2] << " " << pm[3][3] << std::endl; std::cout << " VM: " << std::endl; std::cout << vm[0][0] << " " << vm[0][1] << " " << vm[0][2] << " " << vm[0][3] << std::endl; std::cout << vm[1][0] << " " << vm[1][1] << " " << vm[1][2] << " " << vm[1][3] << std::endl; std::cout << vm[2][0] << " " << vm[2][1] << " " << vm[2][2] << " " << vm[2][3] << std::endl; std::cout << vm[3][0] << " " << vm[3][1] << " " << vm[3][2] << " " << vm[3][3] << std::endl; } else if (this->ModeType == Camera::Mode::TwoD) { std::cout << "Camera: 2D" << std::endl; std::cout << " LRBT: " << Camera2D.Left << " " << Camera2D.Right << " " << Camera2D.Bottom << " " << Camera2D.Top << std::endl; std::cout << " XY : " << Camera2D.XPan << " " << Camera2D.YPan << std::endl; std::cout << " SZ : " << Camera2D.XScale << " " << Camera2D.Zoom << std::endl; vtkm::Matrix pm, vm; pm = CreateProjectionMatrix(512, 512); vm = CreateViewMatrix(); std::cout << " PM: " << std::endl; std::cout << pm[0][0] << " " << pm[0][1] << " " << pm[0][2] << " " << pm[0][3] << std::endl; std::cout << pm[1][0] << " " << pm[1][1] << " " << pm[1][2] << " " << pm[1][3] << std::endl; std::cout << pm[2][0] << " " << pm[2][1] << " " << pm[2][2] << " " << pm[2][3] << std::endl; std::cout << pm[3][0] << " " << pm[3][1] << " " << pm[3][2] << " " << pm[3][3] << std::endl; std::cout << " VM: " << std::endl; std::cout << vm[0][0] << " " << vm[0][1] << " " << vm[0][2] << " " << vm[0][3] << std::endl; std::cout << vm[1][0] << " " << vm[1][1] << " " << vm[1][2] << " " << vm[1][3] << std::endl; std::cout << vm[2][0] << " " << vm[2][1] << " " << vm[2][2] << " " << vm[2][3] << std::endl; std::cout << vm[3][0] << " " << vm[3][1] << " " << vm[3][2] << " " << vm[3][3] << std::endl; } } } } // namespace vtkm::rendering