// // 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 }