librw/tools/d3d9/camera.cpp

170 lines
2.7 KiB
C++

#include "math/math.h"
#include "camera.h"
using namespace std;
void
Camera::look(void)
{
projMat = Mat4::perspective(fov, aspectRatio, n, f);
viewMat = Mat4::lookat(position, target, up);
// state->mat4(PMAT,true)->val = Mat4::perspective(fov, aspectRatio, n, f);
// Mat4 mv = Mat4::lookat(position, target, up);
// state->mat4(MVMAT, true)->val = mv;
// state->mat3(NORMALMAT, true)->val = Mat3(mv);
}
void
Camera::setPosition(Vec3 q)
{
position = q;
}
Vec3
Camera::getPosition(void)
{
return position;
}
void
Camera::setTarget(Vec3 q)
{
position -= target - q;
target = q;
}
Vec3
Camera::getTarget(void)
{
return target;
}
float
Camera::getHeading(void)
{
Vec3 dir = target - position;
float a = atan2(dir.y, dir.x)-PI/2.0f;
return local_up.z < 0.0f ? a-PI : a;
}
void
Camera::turn(float yaw, float pitch)
{
yaw /= 2.0f;
pitch /= 2.0f;
Quat dir = Quat(target - position);
Quat r(cos(yaw), 0.0f, 0.0f, sin(yaw));
dir = r*dir*r.K();
local_up = Vec3(r*Quat(local_up)*r.K());
Quat right = dir.wedge(Quat(local_up)).U();
r = Quat(cos(pitch), right*sin(pitch));
dir = r*dir*r.K();
local_up = Vec3(right.wedge(dir).U());
if(local_up.z >=0) up.z = 1;
else up.z = -1;
target = position + Vec3(dir);
}
void
Camera::orbit(float yaw, float pitch)
{
yaw /= 2.0f;
pitch /= 2.0f;
Quat dir = Quat(target - position);
Quat r(cos(yaw), 0.0f, 0.0f, sin(yaw));
dir = r*dir*r.K();
local_up = Vec3(r*Quat(local_up)*r.K());
Quat right = dir.wedge(Quat(local_up)).U();
r = Quat(cos(-pitch), right*sin(-pitch));
dir = r*dir*r.K();
local_up = Vec3(right.wedge(dir).U());
if(local_up.z >=0) up.z = 1;
else up.z = -1;
position = target - Vec3(dir);
}
void
Camera::dolly(float dist)
{
Vec3 dir = (target - position).normalized()*dist;
position += dir;
target += dir;
}
void
Camera::zoom(float dist)
{
Vec3 dir = target - position;
float curdist = dir.norm();
if(dist >= curdist)
dist = curdist-0.01f;
dir = dir.normalized()*dist;
position += dir;
}
void
Camera::pan(float x, float y)
{
Vec3 dir = (target-position).normalized();
Vec3 right = dir.cross(up).normalized();
// Vec3 local_up = right.cross(dir).normalized();
dir = right*x + local_up*y;
position += dir;
target += dir;
}
float
Camera::sqDistanceTo(Vec3 q)
{
return (position - q).normsq();
}
float
Camera::distanceTo(Vec3 q)
{
return (position - q).norm();
}
void
Camera::setFov(float f)
{
fov = f;
}
float
Camera::getFov(void)
{
return fov;
}
void
Camera::setAspectRatio(float r)
{
aspectRatio = r;
}
void
Camera::setNearFar(float n, float f)
{
this->n = n;
this->f = f;
}
Camera::Camera()
{
position = Vec3(0.0f, 6.0f, 0.0f);
target = Vec3(0.0f, 0.0f, 0.0f);
local_up = up = Vec3(0.0f, 0.0f, 1.0f);
fov = 70.0f;
aspectRatio = 1.0f;
n = 0.1f;
f = 100.0f;
}