Final camera movements

This commit is contained in:
JackCarterSmith 2024-10-14 20:20:37 +02:00
parent 50b1a15589
commit a4e0f7459e
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
10 changed files with 183 additions and 13 deletions

View File

@ -59,6 +59,14 @@ void Graphic3DRenderer::UpdateCamera(CAMERA_MOVE type, const float value) {
case CAMERA_MOVE_FLY:
mMainCamera->Fly(value);
break;
case CAMERA_MOVE_PITCH:
mMainCamera->Pitch(value);
break;
case CAMERA_MOVE_YAW:
mMainCamera->Yaw(value);
break;
default:
break;

View File

@ -10,7 +10,9 @@
typedef enum eCameraMovementType {
CAMERA_MOVE_WALK,
CAMERA_MOVE_STRAFE,
CAMERA_MOVE_FLY
CAMERA_MOVE_FLY,
CAMERA_MOVE_PITCH,
CAMERA_MOVE_YAW
} CAMERA_MOVE;
class Graphic3DRenderer final {

View File

@ -60,4 +60,21 @@ void Camera::Fly(float d) {
M3D_VECTOR u = M3D_V4LoadF3(&mUp);
M3D_VECTOR p = M3D_V4LoadF3(&mPos);
M3D_V4StoreF3(&mPos, M3D_V4MultiplyAdd(s, u, p));
}
void Camera::Pitch(float angle) {
// Rotate up and look vector about the right vector.
M3D_MATRIX R = M3D_TransformMatrixRotationAxis(M3D_V4LoadF3(&mRight), angle);
M3D_V4StoreF3(&mUp, M3D_V3TransformNormal(M3D_V4LoadF3(&mUp), R));
M3D_V4StoreF3(&mLook, M3D_V3TransformNormal(M3D_V4LoadF3(&mLook), R));
}
void Camera::Yaw(float angle) {
// Rotate the basis vectors about the world y-axis.
M3D_MATRIX R = M3D_TransformMatrixRotationY(angle);
M3D_V4StoreF3(&mRight, M3D_V3TransformNormal(M3D_V4LoadF3(&mRight), R));
M3D_V4StoreF3(&mUp, M3D_V3TransformNormal(M3D_V4LoadF3(&mUp), R));
M3D_V4StoreF3(&mLook, M3D_V3TransformNormal(M3D_V4LoadF3(&mLook), R));
}

View File

@ -32,11 +32,14 @@ public:
void Walk(float d);
void Fly(float d);
void Pitch(float angle);
void Yaw(float angle);
private:
M3D_F4X4 mProjMat = M3D_MIdentity4x4();
M3D_F4X4 mViewMat = M3D_MIdentity4x4();
M3D_F3 mPos = {1.5f, 1.5f, 1.5f};
M3D_F3 mPos = {0.0f, 0.0f, 0.0f};
M3D_F3 mRight = {1.0f, 0.0f, 0.0f};
M3D_F3 mUp = {0.0f, 1.0f, 0.0f};
M3D_F3 mLook = {0.0f, 0.0f, 1.0f};

View File

@ -164,6 +164,23 @@ struct __attribute__((aligned(16))) M3D_V4I32 {
#endif
};
struct M3D_F2 {
float x;
float y;
M3D_F2() = default;
M3D_F2(const M3D_F2&) = default;
M3D_F2& operator=(const M3D_F2&) = default;
M3D_F2(M3D_F2&&) = default;
M3D_F2& operator=(M3D_F2&&) = default;
constexpr M3D_F2(float _x, float _y) noexcept : x(_x), y(_y) {}
};
struct __attribute__((aligned(16))) M3D_F2A : public M3D_F2 {
using M3D_F2::M3D_F2;
};
struct M3D_F3 {
float x;
float y;
@ -489,10 +506,11 @@ M3D_VECTOR M3D_QRotationMatrix(M3D_MATRIX M) noexcept;
M3D_VECTOR M3D_V3Rotate(M3D_VECTOR V, M3D_VECTOR RotationQuaternion) noexcept;
M3D_VECTOR M3D_V3Transform(M3D_VECTOR V, M3D_MATRIX M) noexcept;
void M3D_V3Transform(M3D_F4* pOutputStream, size_t OutputStride, const M3D_F3* pInputStream, size_t InputStride, size_t VectorCount, M3D_MATRIX M) noexcept;
M3D_VECTOR M3D_V3TransformNormal(M3D_VECTOR V, M3D_MATRIX M) noexcept;
M3D_VECTOR M3D_V3TransformPersDiv(M3D_VECTOR V, M3D_MATRIX M) noexcept;
void M3D_V3TransformPersDiv(M3D_F3* pOutputStream, size_t OutputStride, const M3D_F3* pInputStream, size_t InputStride, size_t VectorCount, M3D_MATRIX M) noexcept;
M3D_VECTOR M3D_V4Transform(M3D_VECTOR V, M3D_MATRIX M) noexcept;
void M3D_V4Transform(M3D_F4* pOutputStream, size_t OutputStride, const M3D_F3* pInputStream, size_t InputStride, size_t VectorCount, M3D_MATRIX M) noexcept;
void M3D_V4Transform(M3D_F4* pOutputStream, size_t OutputStride, const M3D_F4* pInputStream, size_t InputStride, size_t VectorCount, M3D_MATRIX M) noexcept;
M3D_VECTOR M3D_V3TransformNDCToViewport(M3D_VECTOR V, float vpX, float vpY, float vpW, float vpH, float vpMinZ, float vpMaxZ) noexcept;
@ -513,6 +531,8 @@ M3D_MATRIX M3D_TransformMatrixRotationX(float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationY(float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationZ(float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixRotation(M3D_VECTOR Angles) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationNormal(M3D_VECTOR NormalAxis, float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationAxis(M3D_VECTOR axis, float angle) noexcept;
M3D_MATRIX M3D_TransformMatrixViewport(float _w, float _h, float _wOffset, float _hOffset) noexcept;

View File

@ -972,6 +972,28 @@ inline void M3D_V3Transform(
#endif
}
inline M3D_VECTOR M3D_V3TransformNormal(M3D_VECTOR V, M3D_MATRIX M) noexcept {
#ifdef DISABLE_INTRINSICS
M3D_VECTOR Z = M3D_V4SplatZ(V);
M3D_VECTOR Y = M3D_V4SplatY(V);
M3D_VECTOR X = M3D_V4SplatX(V);
M3D_VECTOR Result = M3D_V4Multiply(Z, M.rows[2]);
Result = M3D_V4MultiplyAdd(Y, M.rows[1], Result);
Result = M3D_V4MultiplyAdd(X, M.rows[0], Result);
return Result;
#else
M3D_VECTOR vResult = M3D_PERMUTE_PS(V, _MM_SHUFFLE(2, 2, 2, 2)); // Z
vResult = _mm_mul_ps(vResult, M.rows[2]);
M3D_VECTOR vTemp = M3D_PERMUTE_PS(V, _MM_SHUFFLE(1, 1, 1, 1)); // Y
vResult = M3D_FMADD_PS(vTemp, M.rows[1], vResult);
vTemp = M3D_PERMUTE_PS(V, _MM_SHUFFLE(0, 0, 0, 0)); // X
vResult = M3D_FMADD_PS(vTemp, M.rows[0], vResult);
return vResult;
#endif
}
inline M3D_VECTOR M3D_V3TransformPersDiv(M3D_VECTOR V, M3D_MATRIX M) noexcept {
M3D_VECTOR Z = M3D_V4SplatZ(V);
M3D_VECTOR Y = M3D_V4SplatY(V);
@ -1324,7 +1346,7 @@ inline M3D_VECTOR M3D_V4Transform(M3D_VECTOR V, M3D_MATRIX M) noexcept {
#endif
}
inline void M3D_V4Transform(M3D_F4* pOutputStream, size_t OutputStride, const M3D_F3* pInputStream, size_t InputStride, size_t VectorCount, M3D_MATRIX M) noexcept {
inline void M3D_V4Transform(M3D_F4* pOutputStream, size_t OutputStride, const M3D_F4* pInputStream, size_t InputStride, size_t VectorCount, M3D_MATRIX M) noexcept {
auto pInputVector = reinterpret_cast<const uint8_t*>(pInputStream);
auto pOutputVector = reinterpret_cast<uint8_t*>(pOutputStream);
@ -1584,21 +1606,20 @@ inline M3D_MATRIX M3D_TransformMatrixCamLookAtRH(M3D_VECTOR viewPos, M3D_VECTOR
inline M3D_MATRIX M3D_TransformMatrixCamLookToLH(M3D_VECTOR viewPos, M3D_VECTOR viewDirection, M3D_VECTOR upDirection) noexcept {
// Keep viewer's axes orthogonal to each other and of unit length
M3D_VECTOR look_normal = M3D_V3Normalize(viewDirection);
M3D_VECTOR up_norm = M3D_V3Cross(upDirection, look_normal);
up_norm = M3D_V3Normalize(up_norm);
M3D_VECTOR up_norm = M3D_V3Normalize(M3D_V3Cross(upDirection, look_normal));
// U, L already ortho-normal, so no need to normalize cross product
M3D_VECTOR right_norm = M3D_V3Cross(look_normal, up_norm);
M3D_VECTOR viewPos_n = M3D_V4Negate(viewPos);
M3D_VECTOR right_vec = M3D_V3Dot(up_norm, viewPos_n);
M3D_VECTOR up_vec = M3D_V3Dot(right_norm, viewPos_n);
M3D_VECTOR up_vec = M3D_V3Dot(up_norm, viewPos_n);
M3D_VECTOR right_vec = M3D_V3Dot(right_norm, viewPos_n);
M3D_VECTOR look_vec = M3D_V3Dot(look_normal, viewPos_n);
M3D_MATRIX ret;
ret.rows[0] = M3D_V4Select(right_vec, up_norm, M3D_MSelect1110.v);
ret.rows[1] = M3D_V4Select(up_vec, right_norm, M3D_MSelect1110.v);
ret.rows[0] = M3D_V4Select(up_vec, up_norm, M3D_MSelect1110.v);
ret.rows[1] = M3D_V4Select(right_vec, right_norm, M3D_MSelect1110.v);
ret.rows[2] = M3D_V4Select(look_vec, look_normal, M3D_MSelect1110.v);
ret.rows[3] = M3D_MIdentityR3.v;
@ -2061,6 +2082,88 @@ inline M3D_MATRIX M3D_TransformMatrixRotation(M3D_VECTOR Angles) noexcept {
#endif
}
inline M3D_MATRIX M3D_TransformMatrixRotationNormal(M3D_VECTOR NormalAxis, float Angle) noexcept {
float fSinAngle;
float fCosAngle;
M3D_ScalarSinCos(&fSinAngle, &fCosAngle, Angle);
#ifdef DISABLE_INTRINSICS
M3D_VECTOR A = M3D_V4Set(fSinAngle, fCosAngle, 1.0f - fCosAngle, 0.0f);
M3D_VECTOR C2 = M3D_V4SplatZ(A);
M3D_VECTOR C1 = M3D_V4SplatY(A);
M3D_VECTOR C0 = M3D_V4SplatX(A);
M3D_VECTOR N0 = M3D_V4Swizzle<M3D_SWIZZLE_Y, M3D_SWIZZLE_Z, M3D_SWIZZLE_X, M3D_SWIZZLE_W>(NormalAxis);
M3D_VECTOR N1 = M3D_V4Swizzle<M3D_SWIZZLE_Z, M3D_SWIZZLE_X, M3D_SWIZZLE_Y, M3D_SWIZZLE_W>(NormalAxis);
M3D_VECTOR V0 = M3D_V4Multiply(C2, N0);
V0 = M3D_V4Multiply(V0, N1);
M3D_VECTOR R0 = M3D_V4Multiply(C2, NormalAxis);
R0 = M3D_V4MultiplyAdd(R0, NormalAxis, C1);
M3D_VECTOR R1 = M3D_V4MultiplyAdd(C0, NormalAxis, V0);
M3D_VECTOR R2 = M3D_V4NegativeMultiplySubtract(C0, NormalAxis, V0);
V0 = M3D_V4Select(A, R0, M3D_MSelect1110.v);
M3D_VECTOR V1 = M3D_V4Permute<M3D_PERMUTE_0Z, M3D_PERMUTE_1Y, M3D_PERMUTE_1Z, M3D_PERMUTE_0X>(R1, R2);
M3D_VECTOR V2 = M3D_V4Permute<M3D_PERMUTE_0Y, M3D_PERMUTE_1X, M3D_PERMUTE_0Y, M3D_PERMUTE_1X>(R1, R2);
M3D_MATRIX M;
M.rows[0] = M3D_V4Permute<M3D_PERMUTE_0X, M3D_PERMUTE_1X, M3D_PERMUTE_1Y, M3D_PERMUTE_0W>(V0, V1);
M.rows[1] = M3D_V4Permute<M3D_PERMUTE_1Z, M3D_PERMUTE_0Y, M3D_PERMUTE_1W, M3D_PERMUTE_0W>(V0, V1);
M.rows[2] = M3D_V4Permute<M3D_PERMUTE_1X, M3D_PERMUTE_1Y, M3D_PERMUTE_0Z, M3D_PERMUTE_0W>(V0, V2);
M.rows[3] = M3D_MIdentityR3.v;
return M;
#else
M3D_VECTOR C2 = _mm_set_ps1(1.0f - fCosAngle);
M3D_VECTOR C1 = _mm_set_ps1(fCosAngle);
M3D_VECTOR C0 = _mm_set_ps1(fSinAngle);
M3D_VECTOR N0 = M3D_PERMUTE_PS(NormalAxis, _MM_SHUFFLE(3, 0, 2, 1));
M3D_VECTOR N1 = M3D_PERMUTE_PS(NormalAxis, _MM_SHUFFLE(3, 1, 0, 2));
M3D_VECTOR V0 = _mm_mul_ps(C2, N0);
V0 = _mm_mul_ps(V0, N1);
M3D_VECTOR R0 = _mm_mul_ps(C2, NormalAxis);
R0 = _mm_mul_ps(R0, NormalAxis);
R0 = _mm_add_ps(R0, C1);
M3D_VECTOR R1 = _mm_mul_ps(C0, NormalAxis);
R1 = _mm_add_ps(R1, V0);
M3D_VECTOR R2 = _mm_mul_ps(C0, NormalAxis);
R2 = _mm_sub_ps(V0, R2);
V0 = _mm_and_ps(R0, M3D_MMask3);
M3D_VECTOR V1 = _mm_shuffle_ps(R1, R2, _MM_SHUFFLE(2, 1, 2, 0));
V1 = M3D_PERMUTE_PS(V1, _MM_SHUFFLE(0, 3, 2, 1));
M3D_VECTOR V2 = _mm_shuffle_ps(R1, R2, _MM_SHUFFLE(0, 0, 1, 1));
V2 = M3D_PERMUTE_PS(V2, _MM_SHUFFLE(2, 0, 2, 0));
R2 = _mm_shuffle_ps(V0, V1, _MM_SHUFFLE(1, 0, 3, 0));
R2 = M3D_PERMUTE_PS(R2, _MM_SHUFFLE(1, 3, 2, 0));
M3D_MATRIX M;
M.rows[0] = R2;
R2 = _mm_shuffle_ps(V0, V1, _MM_SHUFFLE(3, 2, 3, 1));
R2 = M3D_PERMUTE_PS(R2, _MM_SHUFFLE(1, 3, 0, 2));
M.rows[1] = R2;
V2 = _mm_shuffle_ps(V2, V0, _MM_SHUFFLE(3, 2, 1, 0));
M.rows[2] = V2;
M.rows[3] = M3D_MIdentityR3.v;
return M;
#endif
}
inline M3D_MATRIX M3D_TransformMatrixRotationAxis(M3D_VECTOR axis, float angle) noexcept {
M3D_VECTOR nv = M3D_V3Normalize(axis);
return M3D_TransformMatrixRotationNormal(nv, angle);
}
//TODO: transform matrix is incomplete
//v_tri[v_cnt].position.z = ((far+near)/2)+((far-near)/2)*_2dCoord.z;
inline M3D_MATRIX M3D_TransformMatrixViewport(float _w, float _h, float _wOffset, float _hOffset) noexcept {

View File

@ -1071,7 +1071,7 @@ inline M3D_VECTOR M3D_V3Cross(M3D_VECTOR V1, M3D_VECTOR V2) noexcept {
// y2,z2,x2,w2
vTemp2 = M3D_PERMUTE_PS(vTemp2, _MM_SHUFFLE(3, 1, 0, 2));
// Perform the right operation
vResult = M3D_FMADD_PS(vTemp1, vTemp2, vResult);
vResult = M3D_FNMADD_PS(vTemp1, vTemp2, vResult);
// Set w to zero
return _mm_and_ps(vResult, M3D_MMask3);
#endif

View File

@ -3,6 +3,7 @@
#include <numeric>
#include <SFML/System.hpp>
#include <SFML/Window/Keyboard.hpp>
#include <SFML/Window/Mouse.hpp>
#include "Engine/Utils/Perfs.hpp"
@ -77,6 +78,19 @@ GAME_STATUS Game::Tick() {
return GAME_QUIT;
}
void Game::EventMouseMoved(int _x, int _y) {
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
float dx = M3D_Deg2Rad(0.25f * static_cast<float>(_x - mPrevMousePos.x));
float dy = M3D_Deg2Rad(0.25f * static_cast<float>(_y - mPrevMousePos.y));
mWorld3D->UpdateCamera(CAMERA_MOVE_PITCH, dy);
mWorld3D->UpdateCamera(CAMERA_MOVE_YAW, dx);
}
mPrevMousePos.x = _x;
mPrevMousePos.y = _y;
}
void Game::Update() {
// Refresh keyboard inputs
KeyboardInputsCheck();

View File

@ -30,6 +30,7 @@ public:
Game& operator= (Game const&) = delete;
GAME_STATUS Tick();
void EventMouseMoved(int _x, int _y);
private:
Game(std::shared_ptr<sf::RenderWindow> mainWnd, bool dbgFlag) noexcept(false);
@ -51,4 +52,6 @@ private:
std::unique_ptr<CockpitUI> mCockpitUI;
std::unique_ptr<WorldUI> mWorldUI;
sf::Vector2i mPrevMousePos = {0, 0};
};

View File

@ -46,7 +46,7 @@ int main(int argc, char** argv) {
// pause();
// break;
//if (event.type == sf::Event::GainedFocus)
//case sf::Event::GainedFocus:
// resume();
// break;
@ -58,7 +58,7 @@ int main(int argc, char** argv) {
if (mainWindow->hasFocus()) {
switch (event.type) {
case sf::Event::MouseMoved:
//if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
arcadeGame.EventMouseMoved(event.mouseMove.x, event.mouseMove.y);
break;
default: