150 lines
3.9 KiB
C++
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
|
|
}
|