2016-01-20 22:40:54 +00:00
|
|
|
//============================================================================
|
|
|
|
// 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.
|
|
|
|
//============================================================================
|
|
|
|
#ifndef vtk_m_rendering_raytracing_Camera_h
|
|
|
|
#define vtk_m_rendering_raytracing_Camera_h
|
|
|
|
#include <vtkm/VectorAnalysis.h>
|
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
|
|
|
#include <vtkm/cont/ErrorControlBadValue.h>
|
2016-06-02 19:04:01 +00:00
|
|
|
#include <vtkm/rendering/Camera.h>
|
2016-01-20 22:40:54 +00:00
|
|
|
#include <vtkm/rendering/raytracing/Ray.h>
|
2016-05-18 05:13:36 +00:00
|
|
|
#include <vtkm/rendering/raytracing/RayTracingTypeDefs.h>
|
2016-01-20 22:40:54 +00:00
|
|
|
#include <vtkm/rendering/raytracing/Worklets.h>
|
2016-05-18 05:13:36 +00:00
|
|
|
#include <vtkm/rendering/RenderSurfaceRayTracer.h>
|
2016-01-20 22:40:54 +00:00
|
|
|
#include <vtkm/worklet/DispatcherMapField.h>
|
|
|
|
#include <vtkm/worklet/WorkletMapField.h>
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
namespace vtkm {
|
|
|
|
namespace rendering {
|
|
|
|
namespace raytracing {
|
|
|
|
template< typename DeviceAdapter >
|
|
|
|
class Camera
|
|
|
|
{
|
|
|
|
public:
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
class SurfaceConverter : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
vtkm::Float32 Proj22;
|
|
|
|
vtkm::Float32 Proj23;
|
|
|
|
vtkm::Float32 Proj32;
|
|
|
|
vtkm::Int32 Width;
|
|
|
|
vtkm::Int32 SubsetWidth;
|
|
|
|
vtkm::Int32 Xmin;
|
|
|
|
vtkm::Int32 Ymin;
|
|
|
|
vtkm::Int32 NumPixels;
|
2016-05-19 22:37:37 +00:00
|
|
|
|
2016-05-18 05:13:36 +00:00
|
|
|
public:
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
SurfaceConverter(const vtkm::Int32 &width,
|
|
|
|
const vtkm::Int32 &subsetWidth,
|
|
|
|
const vtkm::Int32 &xmin,
|
|
|
|
const vtkm::Int32 &ymin,
|
|
|
|
const vtkm::Matrix<vtkm::Float32,4,4> projMat,
|
|
|
|
const vtkm::Int32 &numPixels)
|
|
|
|
{
|
|
|
|
Width = width;
|
|
|
|
SubsetWidth = subsetWidth;
|
|
|
|
Xmin = xmin;
|
|
|
|
Ymin = ymin;
|
|
|
|
Proj22 = projMat[2][2];
|
|
|
|
Proj23 = projMat[2][3];
|
|
|
|
Proj32 = projMat[3][2];
|
|
|
|
NumPixels = numPixels;
|
|
|
|
}
|
|
|
|
typedef void ControlSignature(FieldIn<>,
|
|
|
|
FieldIn<>,
|
|
|
|
ExecObject,
|
|
|
|
ExecObject);
|
|
|
|
typedef void ExecutionSignature(_1,
|
|
|
|
_2,
|
|
|
|
_3,
|
|
|
|
_4,
|
|
|
|
WorkIndex);
|
|
|
|
VTKM_EXEC_EXPORT
|
|
|
|
void operator()(const vtkm::Vec<vtkm::Float32,4> &inColor,
|
|
|
|
const vtkm::Float32 &inDepth,
|
|
|
|
vtkm::exec::ExecutionWholeArray<vtkm::Float32> &depthBuffer,
|
|
|
|
vtkm::exec::ExecutionWholeArray<vtkm::Float32> &colorBuffer,
|
|
|
|
const vtkm::Id &index) const
|
|
|
|
{
|
|
|
|
if(index >= NumPixels) return;
|
|
|
|
vtkm::Float32 depth = (Proj22 + Proj23 / (-inDepth)) / Proj32;
|
|
|
|
depth = 0.5f * depth + 0.5f;
|
2016-05-19 13:57:54 +00:00
|
|
|
vtkm::Int32 x = static_cast<vtkm::Int32>(index) % SubsetWidth;
|
|
|
|
vtkm::Int32 y = static_cast<vtkm::Int32>(index) / SubsetWidth;
|
2016-05-18 05:13:36 +00:00
|
|
|
x += Xmin;
|
|
|
|
y += Ymin;
|
2016-05-19 13:57:54 +00:00
|
|
|
vtkm::Id outIdx = static_cast<vtkm::Id>(y * Width + x);
|
2016-05-18 05:13:36 +00:00
|
|
|
//std::cout<<" "<<depth;
|
|
|
|
depthBuffer.Set(outIdx, depth);
|
|
|
|
|
|
|
|
outIdx = outIdx * 4;
|
|
|
|
colorBuffer.Set(outIdx + 0, inColor[0]);
|
|
|
|
colorBuffer.Set(outIdx + 1, inColor[1]);
|
|
|
|
colorBuffer.Set(outIdx + 2, inColor[2]);
|
|
|
|
colorBuffer.Set(outIdx + 3, inColor[3]);
|
|
|
|
}
|
|
|
|
}; //class SurfaceConverter
|
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
class PerspectiveRayGen : public vtkm::worklet::WorkletMapField
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
vtkm::Int32 w;
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::Int32 h;
|
2016-05-18 05:13:36 +00:00
|
|
|
vtkm::Int32 Minx;
|
|
|
|
vtkm::Int32 Miny;
|
|
|
|
vtkm::Int32 SubsetWidth;
|
2016-01-20 22:40:54 +00:00
|
|
|
vtkm::Vec< vtkm::Float32, 3> nlook;// normalized look
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> delta_x;
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> delta_y;
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
PerspectiveRayGen(vtkm::Int32 width,
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::Int32 height,
|
|
|
|
vtkm::Float32 fovX,
|
|
|
|
vtkm::Float32 fovY,
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> look,
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> up,
|
2016-05-18 05:13:36 +00:00
|
|
|
vtkm::Float32 _zoom,
|
|
|
|
vtkm::Int32 subsetWidth,
|
|
|
|
vtkm::Int32 minx,
|
|
|
|
vtkm::Int32 miny)
|
2016-05-19 22:37:37 +00:00
|
|
|
: w(width),
|
|
|
|
h(height),
|
2016-05-18 05:13:36 +00:00
|
|
|
Minx(minx),
|
2016-05-19 23:26:15 +00:00
|
|
|
Miny(miny),
|
|
|
|
SubsetWidth(subsetWidth)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-18 05:13:36 +00:00
|
|
|
vtkm::Float32 thx = tanf( (fovX*vtkm::Float32(vtkm::Pi())/180.f) *.5f);
|
|
|
|
vtkm::Float32 thy = tanf( (fovY*vtkm::Float32(vtkm::Pi())/180.f) *.5f);
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> ru = vtkm::Cross(look,up);
|
2016-01-20 22:40:54 +00:00
|
|
|
vtkm::Normalize(ru);
|
|
|
|
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> rv = vtkm::Cross(ru,look);
|
|
|
|
vtkm::Normalize(rv);
|
|
|
|
delta_x = ru*(2*thx/(float)w);
|
|
|
|
delta_y = rv*(2*thy/(float)h);
|
|
|
|
|
|
|
|
if(_zoom > 0)
|
|
|
|
{
|
|
|
|
delta_x[0] = delta_x[0] / _zoom;
|
|
|
|
delta_x[1] = delta_x[1] / _zoom;
|
|
|
|
delta_x[2] = delta_x[2] / _zoom;
|
|
|
|
delta_y[0] = delta_y[0] / _zoom;
|
|
|
|
delta_y[1] = delta_y[1] / _zoom;
|
|
|
|
delta_y[2] = delta_y[2] / _zoom;
|
|
|
|
}
|
|
|
|
nlook = look;
|
|
|
|
vtkm::Normalize(nlook);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef void ControlSignature(FieldOut<>,
|
|
|
|
FieldOut<>,
|
|
|
|
FieldOut<> );
|
|
|
|
|
2016-05-19 22:37:37 +00:00
|
|
|
typedef void ExecutionSignature(WorkIndex,
|
|
|
|
_1,
|
|
|
|
_2,
|
2016-01-20 22:40:54 +00:00
|
|
|
_3);
|
|
|
|
VTKM_EXEC_EXPORT
|
2016-05-19 22:37:37 +00:00
|
|
|
void operator()(vtkm::Id idx,
|
2016-01-20 22:40:54 +00:00
|
|
|
vtkm::Float32 &rayDirX,
|
|
|
|
vtkm::Float32 &rayDirY,
|
|
|
|
vtkm::Float32 &rayDirZ) const
|
|
|
|
{
|
|
|
|
vtkm::Vec<vtkm::Float32,3> ray_dir(rayDirX, rayDirY, rayDirZ);
|
2016-05-18 05:13:36 +00:00
|
|
|
int i = vtkm::Int32( idx ) % SubsetWidth;
|
|
|
|
int j = vtkm::Int32( idx ) / SubsetWidth;
|
|
|
|
i += Minx;
|
|
|
|
j += Miny;
|
2016-05-19 22:37:37 +00:00
|
|
|
ray_dir = nlook + delta_x * ((2.f * vtkm::Float32(i) - vtkm::Float32(w)) / 2.0f)
|
2016-01-20 22:40:54 +00:00
|
|
|
+ delta_y * ((2.f * vtkm::Float32(j) - vtkm::Float32(h)) / 2.0f);
|
|
|
|
vtkm::Normalize(ray_dir);
|
|
|
|
rayDirX = ray_dir[0];
|
|
|
|
rayDirY = ray_dir[1];
|
|
|
|
rayDirZ = ray_dir[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
};// class perspective ray gen
|
|
|
|
private:
|
|
|
|
vtkm::Int32 Height;
|
|
|
|
vtkm::Int32 Width;
|
2016-05-18 05:13:36 +00:00
|
|
|
vtkm::Int32 SubsetWidth;
|
|
|
|
vtkm::Int32 SubsetHeight;
|
|
|
|
vtkm::Int32 SubsetMinX;
|
|
|
|
vtkm::Int32 SubsetMinY;
|
2016-01-20 22:40:54 +00:00
|
|
|
vtkm::Float32 FovX;
|
|
|
|
vtkm::Float32 FovY;
|
|
|
|
vtkm::Float32 FOV;
|
|
|
|
vtkm::Float32 Zoom;
|
|
|
|
bool IsViewDirty;
|
|
|
|
bool IsResDirty;
|
|
|
|
bool MortonSort;
|
|
|
|
bool LookAtSet;
|
2016-05-18 05:13:36 +00:00
|
|
|
//bool ImageSubsetModeOn;
|
2016-01-20 22:40:54 +00:00
|
|
|
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> Look;
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> Up;
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> LookAt;
|
|
|
|
vtkm::Vec< vtkm::Float32, 3> Position;
|
2016-06-02 19:04:01 +00:00
|
|
|
vtkm::rendering::Camera CameraView;
|
2016-05-18 05:13:36 +00:00
|
|
|
vtkm::Matrix<vtkm::Float32,4,4> ViewProjectionMat;
|
|
|
|
|
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
public:
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
ColorBuffer4f FrameBuffer;
|
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
Camera()
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->Height = 500;
|
|
|
|
this->Width = 500;
|
|
|
|
this->SubsetWidth = 500;
|
|
|
|
this->SubsetHeight = 500;
|
|
|
|
this->SubsetMinX = 0;
|
|
|
|
this->SubsetMinY = 0;
|
|
|
|
this->FovY = 30.f;
|
|
|
|
this->FovX = 30.f;
|
|
|
|
this->Zoom = 1.f;
|
|
|
|
this->Look[0] = 0.f;
|
|
|
|
this->Look[1] = 0.f;
|
|
|
|
this->Look[2] = -1.f;
|
|
|
|
this->LookAt[0] = 0.f;
|
|
|
|
this->LookAt[1] = 0.f;
|
|
|
|
this->LookAt[2] = -1.f;
|
|
|
|
this->Up[0] = 0.f;
|
|
|
|
this->Up[1] = 1.f;
|
|
|
|
this->Up[2] = 0.f;
|
|
|
|
this->Position[0] = 0.f;
|
|
|
|
this->Position[1] = 0.f;
|
|
|
|
this->Position[2] = 0.f;
|
|
|
|
this->IsViewDirty = true;
|
|
|
|
this->IsResDirty = true;
|
|
|
|
this->MortonSort = false;
|
|
|
|
this->FrameBuffer.Allocate(Height * Width);
|
|
|
|
//this->ImageSubsetModeOn = true;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
2016-06-02 19:04:01 +00:00
|
|
|
void SetParameters(vtkm::rendering::Camera &camera)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-06-02 19:04:01 +00:00
|
|
|
this->SetUp(camera.Camera3d.Up);
|
|
|
|
this->SetLookAt(camera.Camera3d.LookAt);
|
|
|
|
this->SetPosition(camera.Camera3d.Position);
|
|
|
|
this->SetFieldOfView(camera.Camera3d.FieldOfView);
|
|
|
|
this->SetHeight(camera.Height);
|
|
|
|
this->SetWidth(camera.Width);
|
|
|
|
this->CameraView = camera;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetHeight(const vtkm::Int32 &height)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(height <= 0)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
|
|
"Camera height must be greater than zero.");
|
|
|
|
}
|
|
|
|
if(Height != height)
|
|
|
|
{
|
|
|
|
this->IsResDirty = true;
|
|
|
|
this->Height = height;
|
|
|
|
this->SetFieldOfView(this->FovX);
|
|
|
|
this->CameraView.Height = this->Height;
|
|
|
|
}
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Int32 GetHeight() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->Height;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetWidth(const vtkm::Int32 &width)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(width <= 0)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
|
|
"Camera width must be greater than zero.");
|
|
|
|
}
|
|
|
|
if(this->Width != width)
|
|
|
|
{
|
|
|
|
this->IsResDirty = true;
|
|
|
|
this->Width = width;
|
|
|
|
this->SetFieldOfView(this->FovX);
|
|
|
|
this->CameraView.Width = this->Width;
|
|
|
|
}
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
2016-05-19 22:37:37 +00:00
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Int32 GetWidth() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->Width;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
2016-05-19 22:37:37 +00:00
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetZoom(const vtkm::Float32 &zoom)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(zoom <= 0)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
|
|
"Camera zoom must be greater than zero.");
|
|
|
|
}
|
|
|
|
if(this->Zoom != zoom)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->IsViewDirty = true;
|
|
|
|
this->Zoom = zoom;
|
|
|
|
}
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Float32 GetZoom() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->Zoom;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetFieldOfView(const vtkm::Float32 °rees)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(degrees <= 0)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
|
|
"Camera feild of view must be greater than zero.");
|
|
|
|
}
|
|
|
|
if(degrees > 180)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
|
|
"Camera feild of view must be less than 180.");
|
|
|
|
}
|
|
|
|
// fov is stored as a half angle
|
2016-05-18 05:13:36 +00:00
|
|
|
// float fovx= 2.f*atan(tan(view.view3d.fov/2.f)*view.w/view.h);
|
|
|
|
// fovx*=180.f/M_PI;
|
|
|
|
// camera->setFOVY((view.view3d.fov*(180.f/M_PI))/2.f);
|
|
|
|
// camera->setFOVX( fovx/2.f );
|
2016-05-19 22:37:37 +00:00
|
|
|
|
|
|
|
vtkm::Float32 newFOVY =
|
|
|
|
(vtkm::Float32(this->Height) / vtkm::Float32(this->Width)) * degrees;
|
|
|
|
vtkm::Float32 newFOVX = degrees;
|
|
|
|
if(newFOVX != this->FovX) { this->IsViewDirty = true; }
|
|
|
|
if(newFOVY != this->FovY) { this->IsViewDirty = true; }
|
|
|
|
this->FovX = newFOVX;
|
|
|
|
this->FovY = newFOVY;
|
2016-06-02 19:04:01 +00:00
|
|
|
this->CameraView.Camera3d.FieldOfView = this->FovX;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Float32 GetFieldOfView() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->FovX;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetUp(const vtkm::Vec<vtkm::Float32, 3> &up)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(this->Up != up)
|
|
|
|
{
|
|
|
|
this->Up = up;
|
|
|
|
vtkm::Normalize(this->Up);
|
|
|
|
this->IsViewDirty = true;
|
|
|
|
}
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Vec<vtkm::Float32, 3> GetUp() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->Up;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetLookAt(const vtkm::Vec<vtkm::Float32, 3> &lookAt)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(this->LookAt != lookAt)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->LookAt = lookAt;
|
|
|
|
this->IsViewDirty = true;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Vec<vtkm::Float32, 3> GetLookAt() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->LookAt;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void SetPosition(const vtkm::Vec<vtkm::Float32, 3> &position)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(this->Position != position)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->Position = position;
|
|
|
|
this->IsViewDirty = true;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
vtkm::Vec<vtkm::Float32, 3> GetPosition() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->Position;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void ResetIsViewDirty()
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->IsViewDirty = false;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
bool GetIsViewDirty() const
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
return this->IsViewDirty;
|
2016-01-20 22:40:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
2016-05-18 05:13:36 +00:00
|
|
|
void WriteToSurface(RenderSurfaceRayTracer *surface,
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Float32> &distances)
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-18 05:13:36 +00:00
|
|
|
if(surface == NULL)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
throw vtkm::cont::ErrorControlBadValue(
|
|
|
|
"Camera can not write to NULL surface");
|
2016-05-18 05:13:36 +00:00
|
|
|
}
|
2016-05-19 22:44:41 +00:00
|
|
|
if(this->Height != vtkm::Int32(surface->Height) ||
|
|
|
|
this->Width != vtkm::Int32(surface->Width))
|
2016-05-19 22:37:37 +00:00
|
|
|
{
|
2016-05-18 05:13:36 +00:00
|
|
|
throw vtkm::cont::ErrorControlBadValue("Camera: suface-view mismatched dims");
|
2016-05-19 22:37:37 +00:00
|
|
|
}
|
|
|
|
vtkm::worklet::DispatcherMapField< SurfaceConverter >(
|
|
|
|
SurfaceConverter( this->Width,
|
|
|
|
this->SubsetWidth,
|
|
|
|
this->SubsetMinX,
|
|
|
|
this->SubsetMinY,
|
|
|
|
this->CameraView.CreateProjectionMatrix(),
|
|
|
|
this->SubsetWidth * this->SubsetHeight) )
|
|
|
|
.Invoke( this->FrameBuffer,
|
2016-05-18 05:13:36 +00:00
|
|
|
distances,
|
2016-05-19 22:44:41 +00:00
|
|
|
vtkm::exec::ExecutionWholeArray<vtkm::Float32>(surface->DepthArray),
|
|
|
|
vtkm::exec::ExecutionWholeArray<vtkm::Float32>(surface->ColorArray) );
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
//Force the transfer so the vectors contain data from device
|
2016-05-19 22:44:41 +00:00
|
|
|
surface->ColorArray.GetPortalControl().Get(0);
|
|
|
|
surface->DepthArray.GetPortalControl().Get(0);
|
2016-05-18 05:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void CreateRays(Ray<DeviceAdapter> &rays,
|
2016-05-26 23:04:35 +00:00
|
|
|
const vtkm::Bounds boundingBox = vtkm::Bounds())
|
2016-05-18 05:13:36 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->UpdateDimensions(&rays, boundingBox);
|
2016-01-20 22:40:54 +00:00
|
|
|
//Set the origin of the ray back to the camera position
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::worklet::DispatcherMapField< MemSet< vtkm::Float32 > >( MemSet< vtkm::Float32>( this->Position[0] ) )
|
2016-01-20 22:40:54 +00:00
|
|
|
.Invoke( rays.OriginX );
|
|
|
|
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::worklet::DispatcherMapField< MemSet< vtkm::Float32 > >( MemSet< vtkm::Float32>( this->Position[1] ) )
|
2016-01-20 22:40:54 +00:00
|
|
|
.Invoke( rays.OriginY );
|
|
|
|
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::worklet::DispatcherMapField< MemSet< vtkm::Float32 > >( MemSet< vtkm::Float32>( this->Position[2] ) )
|
2016-01-20 22:40:54 +00:00
|
|
|
.Invoke( rays.OriginZ );
|
|
|
|
|
|
|
|
//Reset the camera look vector
|
2016-05-19 22:37:37 +00:00
|
|
|
this->Look = this->LookAt - this->Position;
|
|
|
|
vtkm::Normalize(this->Look);
|
2016-01-20 22:40:54 +00:00
|
|
|
//Create the ray direction
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::worklet::DispatcherMapField< PerspectiveRayGen >(
|
|
|
|
PerspectiveRayGen(this->Width,
|
|
|
|
this->Height,
|
|
|
|
this->FovX,
|
|
|
|
this->FovY,
|
|
|
|
this->Look,
|
|
|
|
this->Up,
|
|
|
|
this->Zoom,
|
|
|
|
this->SubsetWidth,
|
|
|
|
this->SubsetMinX,
|
|
|
|
this->SubsetMinY) )
|
2016-01-20 22:40:54 +00:00
|
|
|
.Invoke(rays.DirX,
|
|
|
|
rays.DirY,
|
|
|
|
rays.DirZ); //X Y Z
|
|
|
|
|
|
|
|
vtkm::worklet::DispatcherMapField< MemSet< vtkm::Float32 > >( MemSet< vtkm::Float32 >( 1e12f ) )
|
|
|
|
.Invoke( rays.Distance );
|
|
|
|
|
|
|
|
//Reset the Rays Hit Index to -2
|
|
|
|
vtkm::worklet::DispatcherMapField< MemSet< vtkm::Id > >( MemSet< vtkm::Id >( -2 ) )
|
|
|
|
.Invoke( rays.HitIdx );
|
|
|
|
|
|
|
|
} //create rays
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
2016-05-18 05:13:36 +00:00
|
|
|
void CreateRays(VolumeRay<DeviceAdapter> &rays,
|
2016-05-26 23:04:35 +00:00
|
|
|
const vtkm::Bounds &boundingBox = vtkm::Bounds())
|
2016-01-20 22:40:54 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
|
|
|
|
this->UpdateDimensions(&rays, boundingBox);
|
2016-01-20 22:40:54 +00:00
|
|
|
|
|
|
|
//Reset the camera look vector
|
2016-05-19 22:37:37 +00:00
|
|
|
this->Look = this->LookAt - this->Position;
|
|
|
|
vtkm::Normalize(this->Look);
|
2016-01-20 22:40:54 +00:00
|
|
|
//Create the ray direction
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::worklet::DispatcherMapField< PerspectiveRayGen >(
|
|
|
|
PerspectiveRayGen(this->Width,
|
|
|
|
this->Height,
|
|
|
|
this->FovX,
|
|
|
|
this->FovY,
|
|
|
|
this->Look,
|
|
|
|
this->Up,
|
|
|
|
this->Zoom,
|
|
|
|
this->SubsetWidth,
|
|
|
|
this->SubsetMinX,
|
|
|
|
this->SubsetMinY) )
|
2016-01-20 22:40:54 +00:00
|
|
|
.Invoke(rays.DirX,
|
|
|
|
rays.DirY,
|
|
|
|
rays.DirZ); //X Y Z
|
|
|
|
|
|
|
|
} //create rays
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
VTKM_CONT_EXPORT
|
2016-05-26 23:04:35 +00:00
|
|
|
void FindSubset(const vtkm::Bounds &bounds)
|
2016-05-19 22:37:37 +00:00
|
|
|
{
|
2016-05-18 05:13:36 +00:00
|
|
|
vtkm::Float32 x[2], y[2], z[2];
|
2016-05-26 23:04:35 +00:00
|
|
|
x[0] = static_cast<vtkm::Float32>(bounds.X.Min);
|
|
|
|
x[1] = static_cast<vtkm::Float32>(bounds.X.Max);
|
|
|
|
y[0] = static_cast<vtkm::Float32>(bounds.Y.Min);
|
|
|
|
y[1] = static_cast<vtkm::Float32>(bounds.Y.Max);
|
|
|
|
z[0] = static_cast<vtkm::Float32>(bounds.Z.Min);
|
|
|
|
z[1] = static_cast<vtkm::Float32>(bounds.Z.Max);
|
2016-05-18 05:13:36 +00:00
|
|
|
//Inise the data bounds
|
2016-05-19 22:37:37 +00:00
|
|
|
if(this->Position[0] >=x[0] && this->Position[0] <=x[1] &&
|
|
|
|
this->Position[1] >=y[0] && this->Position[1] <=y[1] &&
|
|
|
|
this->Position[2] >=z[0] && this->Position[2] <=z[1] )
|
2016-05-18 05:13:36 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->SubsetWidth = this->Width;
|
|
|
|
this->SubsetHeight = this->Height;
|
|
|
|
this->SubsetMinY = 0;
|
|
|
|
this->SubsetMinX = 0;
|
2016-05-18 05:13:36 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-05-19 22:37:37 +00:00
|
|
|
|
2016-05-18 05:13:36 +00:00
|
|
|
//std::cout<<"Bounds ("<<x[0]<<","<<y[0]<<","<<z[0]<<")-("<<x[1]<<","<<y[1]<<","<<z[1]<<std::endl;
|
|
|
|
vtkm::Float32 xmin, ymin, xmax, ymax, zmin, zmax;
|
|
|
|
xmin = std::numeric_limits<vtkm::Float32>::max();
|
|
|
|
ymin = std::numeric_limits<vtkm::Float32>::max();
|
|
|
|
zmin = std::numeric_limits<vtkm::Float32>::max();
|
|
|
|
xmax = std::numeric_limits<vtkm::Float32>::min();
|
|
|
|
ymax = std::numeric_limits<vtkm::Float32>::min();
|
|
|
|
zmax = std::numeric_limits<vtkm::Float32>::min();
|
|
|
|
vtkm::Vec<vtkm::Float32,4> extentPoint;
|
|
|
|
for (vtkm::Int32 i = 0; i < 2; ++i)
|
|
|
|
for (vtkm::Int32 j = 0; j < 2; ++j)
|
|
|
|
for (vtkm::Int32 k = 0; k < 2; ++k)
|
|
|
|
{
|
|
|
|
extentPoint[0] = x[i];
|
|
|
|
extentPoint[1] = y[j];
|
|
|
|
extentPoint[2] = z[k];
|
|
|
|
extentPoint[3] = 1.f;
|
2016-05-19 22:37:37 +00:00
|
|
|
vtkm::Vec<vtkm::Float32,4> transformed =
|
|
|
|
vtkm::MatrixMultiply(this->ViewProjectionMat,extentPoint);
|
2016-05-18 05:13:36 +00:00
|
|
|
// perform the perspective divide
|
|
|
|
for (vtkm::Int32 a = 0; a < 3; ++a)
|
|
|
|
{
|
|
|
|
transformed[a] = transformed[a] / transformed[3];
|
|
|
|
}
|
|
|
|
|
2016-05-19 13:57:54 +00:00
|
|
|
transformed[0] = (transformed[0] * 0.5f + 0.5f) * static_cast<vtkm::Float32>(Width);
|
|
|
|
transformed[1] = (transformed[1] * 0.5f + 0.5f) * static_cast<vtkm::Float32>(Height);
|
2016-05-18 05:13:36 +00:00
|
|
|
transformed[2] = (transformed[2] * 0.5f + 0.5f);
|
|
|
|
zmin = vtkm::Min(zmin, transformed[2]);
|
|
|
|
zmax = vtkm::Max(zmax, transformed[2]);
|
2016-05-19 22:37:37 +00:00
|
|
|
if(transformed[2] < 0 || transformed[2] > 1) { continue; }
|
2016-05-18 05:13:36 +00:00
|
|
|
xmin = vtkm::Min(xmin, transformed[0]);
|
|
|
|
ymin = vtkm::Min(ymin, transformed[1]);
|
|
|
|
xmax = vtkm::Max(xmax, transformed[0]);
|
|
|
|
ymax = vtkm::Max(ymax, transformed[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
xmin -= .001f;
|
|
|
|
xmax += .001f;
|
|
|
|
ymin -= .001f;
|
|
|
|
ymax += .001f;
|
2016-05-19 13:57:54 +00:00
|
|
|
xmin = vtkm::Floor(vtkm::Min(vtkm::Max(0.f, xmin),vtkm::Float32(Width) ));
|
|
|
|
xmax = vtkm::Ceil(vtkm::Min(vtkm::Max(0.f, xmax),vtkm::Float32(Width) ));
|
|
|
|
ymin = vtkm::Floor(vtkm::Min(vtkm::Max(0.f, ymin),vtkm::Float32(Height) ));
|
|
|
|
ymax = vtkm::Ceil(vtkm::Min(vtkm::Max(0.f, ymax),vtkm::Float32(Height) ));
|
2016-05-20 14:04:37 +00:00
|
|
|
|
2016-05-18 05:13:36 +00:00
|
|
|
//printf("Pixel range = (%f,%f,%f), (%f,%f,%f)\n", xmin, ymin,zmin, xmax,ymax,zmax);
|
|
|
|
vtkm::Int32 dx = vtkm::Int32(xmax) - vtkm::Int32(xmin);
|
|
|
|
vtkm::Int32 dy = vtkm::Int32(ymax) - vtkm::Int32(ymin);
|
2016-05-19 22:37:37 +00:00
|
|
|
|
2016-05-18 05:13:36 +00:00
|
|
|
//
|
|
|
|
// scene is behind the camera
|
|
|
|
//
|
|
|
|
if(zmax < 0 || zmin > 1 ||
|
|
|
|
xmin >= xmax ||
|
|
|
|
ymin >= ymax)
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->SubsetWidth = 1;
|
|
|
|
this->SubsetHeight = 1;
|
|
|
|
this->SubsetMinX = 0;
|
|
|
|
this->SubsetMinY = 0;
|
2016-05-18 05:13:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->SubsetWidth = dx;
|
|
|
|
this->SubsetHeight = dy;
|
|
|
|
this->SubsetMinX = vtkm::Int32(xmin);
|
|
|
|
this->SubsetMinY = vtkm::Int32(ymin);
|
2016-05-18 05:13:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT_EXPORT
|
|
|
|
void UpdateDimensions(RayBase *rays,
|
2016-05-26 23:04:35 +00:00
|
|
|
const vtkm::Bounds &boundingBox = vtkm::Bounds())
|
2016-05-18 05:13:36 +00:00
|
|
|
{
|
|
|
|
// If bounds have been provided, only cast rays that could hit the data
|
2016-05-26 23:04:35 +00:00
|
|
|
bool imageSubsetModeOn = boundingBox.IsNonEmpty();
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
//Update our ViewProjection matrix
|
2016-05-19 22:37:37 +00:00
|
|
|
this->ViewProjectionMat
|
|
|
|
= vtkm::MatrixMultiply(this->CameraView.CreateProjectionMatrix(),
|
|
|
|
this->CameraView.CreateViewMatrix());
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
//Find the pixel footprint
|
2016-05-19 22:37:37 +00:00
|
|
|
if(imageSubsetModeOn)
|
|
|
|
{
|
|
|
|
this->FindSubset(boundingBox);
|
|
|
|
}
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
//Update the image dimensions
|
2016-05-19 22:37:37 +00:00
|
|
|
if(!imageSubsetModeOn)
|
2016-05-18 05:13:36 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
this->SubsetWidth = this->Width;
|
|
|
|
this->SubsetHeight = this->Height;
|
|
|
|
this->SubsetMinY = 0;
|
|
|
|
this->SubsetMinX = 0;
|
2016-05-18 05:13:36 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
if(this->SubsetWidth != this->Width) { this->IsResDirty = true; }
|
|
|
|
if(this->SubsetHeight != this->Height) { this->IsResDirty = true; }
|
2016-05-18 05:13:36 +00:00
|
|
|
}
|
|
|
|
// resize rays and buffers
|
2016-05-19 22:37:37 +00:00
|
|
|
if(this->IsResDirty)
|
2016-05-18 05:13:36 +00:00
|
|
|
{
|
2016-05-19 22:37:37 +00:00
|
|
|
rays->resize(this->SubsetHeight * this->SubsetWidth);
|
|
|
|
this->FrameBuffer.PrepareForOutput(this->SubsetHeight * this->SubsetWidth,
|
|
|
|
DeviceAdapter());
|
|
|
|
}
|
2016-05-18 05:13:36 +00:00
|
|
|
|
2016-05-19 22:37:37 +00:00
|
|
|
this->IsResDirty = false;
|
2016-05-18 05:13:36 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-01-20 22:40:54 +00:00
|
|
|
}; // class camera
|
|
|
|
}}}//namespace vtkm::rendering::raytracing
|
2016-04-18 20:42:59 +00:00
|
|
|
#endif //vtk_m_rendering_raytracing_Camera_h
|