mirror of
https://github.com/aap/librw.git
synced 2024-11-25 21:25:42 +00:00
170 lines
2.7 KiB
C++
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;
|
|
}
|
|
|