Files
igl/external/embree/tutorials/common/tutorial/camera.h
T

98 lines
3.7 KiB
C++
Executable File

// ======================================================================== //
// Copyright 2009-2014 Intel Corporation //
// //
// Licensed under the Apache License, Version 2.0 (the "License"); //
// you may not use this file except in compliance with the License. //
// You may obtain a copy of the License at //
// //
// http://www.apache.org/licenses/LICENSE-2.0 //
// //
// Unless required by applicable law or agreed to in writing, software //
// distributed under the License is distributed on an "AS IS" BASIS, //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and //
// limitations under the License. //
// ======================================================================== //
#pragma once
#include "sys/platform.h"
#include "sys/ref.h"
#include "math/math.h"
#include "math/vec3.h"
//#include "math/color.h"
#include "math/affinespace.h"
namespace embree
{
/* camera settings */
struct Camera
{
public:
Camera ()
: from(0.0001f,0.0001f,-3.0f), to(0,0,0), up(0,1,0), fov(90) {}
Camera (Vec3fa& from, Vec3fa& to, Vec3fa& up, float fov)
: from(from), to(to), up(up), fov(fov) {}
AffineSpace3fa camera2world () { return AffineSpace3fa::lookat(from, to, up); }
AffineSpace3fa world2camera () { return rcp(AffineSpace3fa::lookat(from, to, up)); }
Vec3fa world2camera(const Vec3fa& p) { return xfmPoint(world2camera(),p); }
Vec3fa camera2world(const Vec3fa& p) { return xfmPoint(camera2world(),p); }
AffineSpace3fa pixel2world (size_t width, size_t height)
{
const float fovScale = 1.0f/tanf(deg2rad(0.5f*fov));
const AffineSpace3fa local2world = AffineSpace3fa::lookat(from, to, up);
return AffineSpace3fa(local2world.l.vx,
-local2world.l.vy,
-0.5f*width*local2world.l.vx + 0.5f*height*local2world.l.vy + 0.5f*height*fovScale*local2world.l.vz,
local2world.p);
}
void move (float dx, float dy, float dz)
{
AffineSpace3fa xfm = camera2world();
Vec3fa ds = xfmVector(xfm,Vec3fa(dx,dy,dz));
from += ds;
to += ds;
}
void rotate (float dtheta, float dphi)
{
Vec3fa view = xfmPoint(world2camera(),to);
float theta = atan2f(view.x, view.z); theta += dtheta;
float phi = asinf (view.y); phi += dphi;
float x = cosf(phi)*sinf(theta);
float y = sinf(phi);
float z = cosf(phi)*cosf(theta);
to = xfmPoint(camera2world(),length(view)*Vec3fa(x,y,z));
}
void rotateOrbit (float dtheta, float dphi)
{
Vec3fa view = normalize(xfmVector(world2camera(),to - from));
float theta = atan2f(view.x, view.z); theta += dtheta;
float phi = asinf (view.y); phi += dphi;
float x = cosf(phi)*sinf(theta);
float y = sinf(phi);
float z = cosf(phi)*cosf(theta);
Vec3fa view1 = xfmVector(camera2world(),Vec3fa(x,y,z));
from = to - length(to - from) * view1;
}
void dolly (float ds)
{
float dollySpeed = 0.01f;
float k = powf((1.0f-dollySpeed), ds);
from += length(to-from) * (1-k) * normalize(to-from);
}
public:
Vec3fa from; //!< position of camera
Vec3fa to; //!< look at point
Vec3fa up; //!< up vector
float fov; //!< field of view
};
}