150 lines
3.9 KiB
C++

//
// Created by Epagris on 2020. 03. 16..
//
#include "Cam.h"
#include "utils.h"
eg3d::Cam::Cam() {
loadDefaults();
}
void eg3d::Cam::loadDefaults() {
mProjParams.loadDefaults();
mViewParams.loadDefaults();
constructViewMatrix();
constructProjMatrix();
}
const XMFLOAT4X4 &eg3d::Cam::getViewMatrix() const {
return mMView;
}
const XMFLOAT4X4 &eg3d::Cam::getProjMatrix() const {
return mMProj;
}
void eg3d::Cam::constructViewMatrix() {
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); // felfelé irány
XMMATRIX r = XMMatrixRotationX(mViewParams.pitch) * XMMatrixRotationY(mViewParams.yaw); // forgatások (yaw, pitch)
XMVECTOR dir = XMVectorSet(0.0f, 0.0f, 1.0, 1.0f); // (0,0,-1) irányba néz alapból a kamera
dir = XMVector3Transform(dir, r);
XMStoreFloat3(&mVViewDirection, dir); // forgatott vektor kiszámítása és letárolása
XMVECTOR position = XMLoadFloat3(&mViewParams.position);
XMMATRIX v = XMMatrixLookAtRH(position, position + dir, up);
XMStoreFloat4x4(&mMView, XMMatrixTranspose(v)); // view mátrix letárolása
XMVECTOR strafe = XMVector3Cross(dir, up); // oldalazás irányának kiszámítása
XMStoreFloat3(&mStrafeDirection, strafe);
//LOG(std::to_string(mViewParams.position.x) + ", " + std::to_string(mViewParams.position.y) + ", " + std::to_string(mViewParams.position.z));
//LOG(std::to_string(mViewParams.pitch));
}
void eg3d::Cam::constructProjMatrix() {
XMMATRIX p; // vetítés mátrixa
// vetítés mátrixának megadása
switch (mProjParams.projType)
{
case ProjectionType::PERSPECTIVE:
p = XMMatrixPerspectiveFovRH(mProjParams.FOV_ViewHeight, mProjParams.AspectRatio, mProjParams.NearPlane, mProjParams.FarPlane);
break;
case ProjectionType::ORTHOGRAPHIC:
p = XMMatrixOrthographicRH( mProjParams.FOV_ViewHeight * mProjParams.AspectRatio, mProjParams.FOV_ViewHeight, mProjParams.NearPlane, mProjParams.FarPlane);
break;
}
XMStoreFloat4x4(&mMProj, XMMatrixTranspose(p));
}
void eg3d::Cam::setProjParams(const eg3d::ProjParams &pp) {
mProjParams = pp;
constructProjMatrix(); // projekciós mátrix újragenerálása
}
eg3d::ProjParams eg3d::Cam::getProjParams() const {
return mProjParams;
}
void eg3d::Cam::setViewParams(const eg3d::ViewParams &vp) {
mViewParams = vp;
constructViewMatrix();
}
eg3d::ViewParams eg3d::Cam::getViewParams() const {
return mViewParams;
}
void eg3d::Cam::walk(float ds) {
XMVECTOR s = XMLoadFloat3(&mViewParams.position);
XMVECTOR dir = XMLoadFloat3(&mVViewDirection);
s = XMVectorAdd(s, XMVectorScale(dir, ds));
XMStoreFloat3(&mViewParams.position, s);
constructViewMatrix();
}
void eg3d::Cam::strafe(float ds)
{
XMVECTOR s = XMLoadFloat3(&mViewParams.position);
XMVECTOR strafe = XMLoadFloat3(&mStrafeDirection);
s = XMVectorAdd(s, XMVectorScale(strafe, ds));
XMStoreFloat3(&mViewParams.position, s);
constructViewMatrix();
}
void eg3d::Cam::yaw(float dphi) {
mViewParams.yaw -= dphi; // BALkezes koordináta-rendszer miatt
if (mViewParams.yaw < -XM_2PI)
{
mViewParams.yaw += XM_2PI;
} else if (mViewParams.yaw > XM_2PI)
{
mViewParams.yaw -= XM_2PI;
}
constructViewMatrix();
}
void eg3d::Cam::pitch(float drho) {
mViewParams.pitch = min(max(mViewParams.pitch + drho, -XM_PIDIV2 + 0.001f), XM_PIDIV2 - 0.001f);
constructViewMatrix();
}
const XMFLOAT3& eg3d::Cam::getViewDirection() const
{
return mVViewDirection;
}
// -----------------------------
eg3d::ProjParams::ProjParams() {
loadDefaults();
}
void eg3d::ProjParams::loadDefaults() {
FOV_ViewHeight = XM_PIDIV2; // 90 fokos látószög
AspectRatio = 1.0f; // 1:1-es képarány
NearPlane = 1.0f; // közeli sík
FarPlane = 10.0f; // távoli sík
projType = ProjectionType::PERSPECTIVE; // perspektivikus vetítés
}
eg3d::ViewParams::ViewParams()
{
loadDefaults();
}
void eg3d::ViewParams::loadDefaults() {
position.x = position.y = position.z = 0.0f; // (0,0,0), origó
yaw = 0.0f; // nincs forgatás
pitch = 0.0f; // nincs billentés
}