Implement perspective maths

This commit is contained in:
JackCarterSmith 2024-09-30 15:17:01 +02:00
parent 969ba7e94a
commit 55ff78ee50
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
12 changed files with 2208 additions and 8 deletions

View File

@ -0,0 +1,79 @@
#include "3DRenderer.hpp"
// Rendering order:
// model matrix (Object SRT) -> view matrix (camera matrix inverted) -> proj matrix -> clipping -> perspective divide -> viewport transformation -> Rasterizer (draw pixels inside projected triangles on 2D screen)
// object coordinate -> world coordinate -> camera coordinate -> clip/screen coordinate
//
// Rasterizer inputs elements:
// - texture-buffer (2D array of pixels color value)
// - z-buffer (2D array of float representing the nearest pixel's depth, all pixels beyond are ignored)
// - projected vertices-buffer on screen (using vertices-buffer and projection function)
//
// Refs:
// * https://en.wikipedia.org/wiki/3D_projection
// * https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/overview-rasterization-algorithm.html
Graphic3DRenderer::Graphic3DRenderer() {
if (mMainCamera == nullptr) {
mMainCamera = std::make_unique<Camera>();
mMainCamera->SetPosition(0.0f, 3.0f, -20.0f);
mMainCamera->SetFrustrum(90.0f, 1280.f/324.f, 1.0f, 100.f);
mMainCamera->UpdateCamView();
}
}
Graphic3DRenderer::~Graphic3DRenderer() {}
void Graphic3DRenderer::Draw(sf::RenderTexture& context) {
sf::BlendMode sBM = sf::BlendNone;
sf::RenderStates sRS(sBM);
sf::Color yep[] = {sf::Color::White, sf::Color::Blue, sf::Color::Green, sf::Color::Red, sf::Color::Magenta, sf::Color::Cyan, sf::Color::Yellow};
static float thetaAngle = 0.31f;
thetaAngle = thetaAngle >= 6.283185f ? -6.283185f : thetaAngle + 0.004f;
bool clipped = false;
M3D_MATRIX viewMat = mMainCamera->GetView();
M3D_MATRIX projMat = mMainCamera->GetProj();
M3D_MATRIX modelMat = M3D_MIdentity() * M3D_TransformMatrixScaling(10.0f, 10.0f, 10.0f) * M3D_TransformMatrixRotationX(thetaAngle) * M3D_TransformMatrixRotationZ(0.5f*thetaAngle) * M3D_TransformMatrixTranslate(0.0f, 0.0f, 5.0f);
M3D_MATRIX viewProjMat = (viewMat) * (projMat);
M3D_MATRIX MVPMat = modelMat * viewProjMat;
M3D_MATRIX viewportMat = M3D_TransformMatrixViewport(1280.0f, 324.f, 0.0f, 0.0f);
uint8_t v_cnt = 0, yep_cnt = 0;
sf::Vertex v_tri[4];
M3D_F3 _2dCoord;
for (const auto _v : testObj.mMesh) {
M3D_VECTOR _vV = M3D_V4LoadF3(&_v.pos);
M3D_VECTOR projV = M3D_V3Transform(_vV, MVPMat);
//projV = M3D_V3Transform(projV, viewProjMat);
// Clipping (simple)
if (M3D_V4GetZ(projV) <= 0)
clipped = true;
// Perspective divide
M3D_VECTOR _w = M3D_V4SplatW(projV);
projV = M3D_V4Divide(projV, _w);
// Viewport transform
projV = M3D_V3Transform(projV, (viewportMat));
M3D_V4StoreF3(&_2dCoord, projV);
v_tri[v_cnt].position.x = _2dCoord.x;
v_tri[v_cnt].position.y = _2dCoord.y;
//v_tri[v_cnt].position.z = ((far+near)/2)+((far-near)/2)*_2dCoord.z; //TODO: transform matrix is incomplete
v_tri[v_cnt].color = yep[yep_cnt % 5];
if (v_cnt++ >= 2) {
if (!clipped) {
v_tri[3] = v_tri[0];
context.draw(v_tri, 4, sf::LineStrip, sRS);
//context.draw(v_tri, 3, sf::Triangles, sRS);
}
v_cnt = 0;
yep_cnt++;
clipped = false;
}
}
}

View File

@ -0,0 +1,66 @@
#pragma once
#include <memory>
#include <vector>
#include <SFML/Graphics/RenderTexture.hpp>
#include "Camera.hpp"
#include "../Utils/MeshHelper.hpp"
class MeshObjCube final {
public:
MeshObjCube() {
mMesh = {
// RIGHT
{0.5f, 0.5f, -0.5f}, {0.5f, -0.5f, 0.5f}, {0.5f, 0.5f, 0.5f},
{0.5f, 0.5f, -0.5f}, {0.5f, -0.5f, 0.5f}, {0.5f, -0.5f, -0.5f},
// FRONT
{0.5f, 0.5f, 0.5f}, {0.5f, -0.5f, 0.5f}, {-0.5f, -0.5f, 0.5f},
{0.5f, 0.5f, 0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f},
// LEFT
{-0.5f, 0.5f, 0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, 0.5f, -0.5f},
{-0.5f, 0.5f, -0.5f}, {-0.5f, -0.5f, 0.5f}, {-0.5f, -0.5f, -0.5f},
// BACK
{0.5f, 0.5f, -0.5f}, {-0.5f, 0.5f, -0.5f}, {0.5f, -0.5f, -0.5f},
{-0.5f, 0.5f, -0.5f}, {-0.5f, -0.5f, -0.5f}, {0.5f, -0.5f, -0.5f},
// TOP
{-0.5f, 0.5f, -0.5f}, {0.5f, 0.5f, -0.5f}, {-0.5f, 0.5f, 0.5f},
{0.5f, 0.5f, -0.5f}, {0.5f, 0.5f, 0.5f}, {-0.5f, 0.5f, 0.5f},
// BOTTOM
{-0.5f, -0.5f, -0.5f}, {-0.5f, -0.5f, 0.5f}, {0.5f, -0.5f, 0.5f},
{0.5f, -0.5f, 0.5f}, {0.5f, -0.5f, -0.5f}, {-0.5f, -0.5f, -0.5f},
};
}
std::vector<MeshVertex> mMesh;
private:
};
class Graphic3DRenderer final {
public:
Graphic3DRenderer();
~Graphic3DRenderer();
Graphic3DRenderer(Graphic3DRenderer&&) = default;
Graphic3DRenderer& operator= (Graphic3DRenderer&&) = default;
Graphic3DRenderer(Graphic3DRenderer const&) = delete;
Graphic3DRenderer& operator= (Graphic3DRenderer const&) = delete;
void Draw(sf::RenderTexture& context);
private:
sf::RenderTexture mWorldRender; // This is used to create the scene
std::unique_ptr<Camera> mMainCamera;
MeshObjCube testObj;
};

View File

@ -0,0 +1,39 @@
#include "Camera.hpp"
Camera::Camera() {
SetFrustrum(90.f, (1280.f/1024.f), 1.0f, 1000.f);
}
void Camera::SetFrustrum(float fov, float r, float zn, float zf) {
//if (!frameDirty)
M3D_MATRIX pMat = M3D_TransformMatrixFrustrumFovLH(M3D_Deg2Rad(fov), r, zn, zf);
M3D_V4StoreF4x4(&mProjMat, pMat);
}
void Camera::UpdateCamView() {
M3D_VECTOR P = M3D_V4LoadF3(&mPos);
M3D_VECTOR L = M3D_V4LoadF3(&mLook);
M3D_VECTOR U = M3D_V4LoadF3(&mUp);
M3D_V4StoreF4x4(&mViewMat, M3D_TransformMatrixCamLookAtLH(P, L, U));
}
void Camera::LookAt(M3D_VECTOR pos, M3D_VECTOR target, M3D_VECTOR worldUp) {
M3D_VECTOR L = M3D_V3Normalize(M3D_V4Subtract(target, pos));
M3D_VECTOR R = M3D_V3Normalize(M3D_V3Cross(worldUp, L));
M3D_VECTOR U = M3D_V3Cross(L, R);
M3D_V4StoreF3(&mPos, pos);
M3D_V4StoreF3(&mLook, L);
M3D_V4StoreF3(&mRight, R);
M3D_V4StoreF3(&mUp, U);
}
void Camera::LookAt(const M3D_F3& pos, const M3D_F3& target, const M3D_F3& up) {
M3D_VECTOR P = M3D_V4LoadF3(&pos);
M3D_VECTOR T = M3D_V4LoadF3(&target);
M3D_VECTOR U = M3D_V4LoadF3(&up);
LookAt(P, T, U);
}

View File

@ -0,0 +1,40 @@
#pragma once
#include "../Utils/3DMaths.hpp"
class Camera final {
public:
Camera();
~Camera() {}
Camera(Camera&&) = default;
Camera& operator= (Camera&&) = default;
Camera(Camera const&) = delete;
Camera& operator= (Camera const&) = delete;
M3D_VECTOR GetPos() const { return M3D_V4LoadF3(&mPos); }
M3D_F3 GetPos3f() const { return mPos; }
M3D_MATRIX GetView() const { return M3D_V4LoadF4x4(&mViewMat); }
M3D_F4X4 GetView4x4f() const { return mViewMat; }
M3D_MATRIX GetProj() const { return M3D_V4LoadF4x4(&mProjMat); }
M3D_F4X4 GetProj4x4f() const { return mProjMat; }
void SetPosition(const float x, const float y, const float z) { mPos = M3D_F3(x, y, z); }
void SetPosition(const M3D_F3 v) { mPos = v; }
void SetFrustrum(float fov, float r, float zn, float zf);
void UpdateCamView();
void LookAt(M3D_VECTOR pos, M3D_VECTOR target, M3D_VECTOR worldUp);
void LookAt(const M3D_F3& pos, const M3D_F3& target, const M3D_F3& up);
private:
M3D_F4X4 mProjMat = M3D_MIdentity4x4();
M3D_F4X4 mViewMat = M3D_MIdentity4x4();
M3D_F3 mPos = {1.5f, 1.5f, 1.5f};
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

@ -34,8 +34,9 @@ CockpitUI::CockpitUI() : UI() {
mUIRender.setSmooth(true);
mUIRender.setRepeated(false);
mBoardTexture.setSrgb(true);
mBoardTexture.loadFromFile("cockpit_ui_empty_rescaled.png", sf::IntRect(0, 0, 1280, 780));
mStaticCockpitTexture.setSrgb(true);
if (!mStaticCockpitTexture.loadFromFile("cockpit_ui_empty_rescaled.png", sf::IntRect(0, 0, 1280, 780)))
throw std::runtime_error("Unable to load texture datas");
}
void CockpitUI::Update() {
@ -50,7 +51,7 @@ void CockpitUI::Draw(std::shared_ptr<sf::RenderWindow> context) {
mUIRender.clear(sf::Color::Transparent);
// Draw the static board
sf::Sprite staticBoardSprite(mBoardTexture);
sf::Sprite staticBoardSprite(mStaticCockpitTexture);
mUIRender.draw(staticBoardSprite, sRS);
// Draw the radar display
@ -87,4 +88,21 @@ WorldUI::WorldUI() : UI() {
void WorldUI::Update() {
}
void WorldUI::Draw(std::shared_ptr<sf::RenderWindow> context) {
sf::BlendMode sBM = sf::BlendNone;
sf::RenderStates sRS(sBM);
// Clear the UI screen
mUIRender.clear(sf::Color::Transparent);
// Draw the 3D view
m3DEngine.Draw(mUIRender);
// Do the final texture render
mUIRender.display();
// OnScreen rendering
DrawUIOnRenderWindow(context);
}

View File

@ -5,6 +5,8 @@
#include <SFML/Graphics/RenderTexture.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include "3DRenderer.hpp"
class UI {
public:
@ -14,7 +16,7 @@ public:
virtual inline void Draw(std::shared_ptr<sf::RenderWindow> c) { DrawUIOnRenderWindow(c); }
protected:
sf::RenderTexture mUIRender; // This is used to create the scene
sf::RenderTexture mUIRender; // The screen to draw onto
void DrawUIOnRenderWindow(std::shared_ptr<sf::RenderWindow> context);
@ -36,7 +38,7 @@ public:
void Draw(std::shared_ptr<sf::RenderWindow>) override;
private:
sf::Texture mBoardTexture;
sf::Texture mStaticCockpitTexture;
};
@ -51,6 +53,9 @@ public:
WorldUI& operator= (WorldUI const&) = delete;
void Update() override;
//void Draw(std::shared_ptr<sf::RenderWindow>) override;
void Draw(std::shared_ptr<sf::RenderWindow>) override;
private:
Graphic3DRenderer m3DEngine;
};

View File

@ -0,0 +1,399 @@
#pragma once
#include <cstdint>
#ifndef DISABLE_INTRINSICS
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#
// https://stackoverflow.com/tags/sse/info
// https://lowleveldev.substack.com/p/simd-a-practical-guide
# include <immintrin.h>
// If GNU-gcc => NO_XMVECTOR_OVERLOADS
#else
# include <cmath>
#endif
#ifndef __cplusplus
#error This header requires C++
#endif
#ifndef DISABLE_INTRINSICS
#ifdef NO_MOVNT
#define M3D_STREAM_PS( p, a ) _mm_store_ps((p), (a))
#define M3D_STREAM_256_PS( p, a ) _mm256_store_ps((p), (a))
#define M3D_SFENCE()
#else
#define M3D_STREAM_PS( p, a ) _mm_stream_ps((p), (a))
#define M3D_STREAM_256b_PS( p, a ) _mm256_stream_ps((p), (a))
#define M3D_SFENCE() _mm_sfence()
#endif
#ifdef FMA3_INTRINSICS
#define M3D_FMADD_PS( a, b, c ) _mm_fmadd_ps((a), (b), (c))
#define M3D_FNMADD_PS( a, b, c ) _mm_fnmadd_ps((a), (b), (c))
#else
#define M3D_FMADD_PS( a, b, c ) _mm_add_ps(_mm_mul_ps((a), (b)), (c))
#define M3D_FNMADD_PS( a, b, c ) _mm_sub_ps((c), _mm_mul_ps((a), (b)))
#endif
#if defined(AVX_INTRINSICS) && defined(FAVOR_INTEL)
#define M3D_PERMUTE_PS( v, c ) _mm_permute_ps((v), c )
#else
#define M3D_PERMUTE_PS( v, c ) _mm_shuffle_ps((v), (v), c )
#endif
#endif
//
// Math constants and helping functions
//
constexpr float M3D_PI = 3.141592654f;
constexpr float M3D_2PI = 6.283185307f;
constexpr float M3D_1DIVPI = 0.318309886f;
constexpr float M3D_1DIV2PI = 0.159154943f;
constexpr float M3D_PIDIV2 = 1.570796327f;
constexpr float M3D_PIDIV4 = 0.785398163f;
constexpr float M3D_Deg2Rad(float a) noexcept { return a * (M3D_PI / 180.0f); }
constexpr float M3D_Rad2Deg(float a) noexcept { return a * (180.0f / M3D_PI); }
//
// Generic SIMD vector implementation
//
// Call convention (x86_64):
// 1-3rd vector parameter should be M3D_VECTOR
// 4th+ vector parameter should be M3D_VECTOR&
//
#ifdef DISABLE_INTRINSICS
struct sM3DV4 {
union {
float v4f[4];
uint32_t v4u[4];
};
};
using M3D_VECTOR = sM3DV4;
#else
using M3D_VECTOR = __m128;
#endif
struct __attribute__((aligned(16))) M3D_V4F32 {
union {
float f[4];
M3D_VECTOR v;
};
inline operator M3D_VECTOR() const noexcept { return v; }
inline operator const float* () const noexcept { return f; }
#ifndef DISABLE_INTRINSICS
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
#endif
};
struct __attribute__((aligned(16))) M3D_V4U8 {
union {
uint8_t u[16];
M3D_VECTOR v;
};
inline operator M3D_VECTOR() const noexcept { return v; }
inline operator const uint8_t* () const noexcept { return u; }
#ifndef DISABLE_INTRINSICS
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
#endif
};
struct __attribute__((aligned(16))) M3D_V4U32 {
union {
uint32_t u[4];
M3D_VECTOR v;
};
inline operator M3D_VECTOR() const noexcept { return v; }
inline operator const uint32_t* () const noexcept { return u; }
#ifndef DISABLE_INTRINSICS
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
#endif
};
struct __attribute__((aligned(16))) M3D_V4I32 {
union {
int32_t i[4];
M3D_VECTOR v;
};
inline operator M3D_VECTOR() const noexcept { return v; }
inline operator const int32_t* () const noexcept { return i; }
#ifndef DISABLE_INTRINSICS
inline operator __m128i() const noexcept { return _mm_castps_si128(v); }
inline operator __m128d() const noexcept { return _mm_castps_pd(v); }
#endif
};
struct M3D_F3 {
float x;
float y;
float z;
M3D_F3() = default;
M3D_F3(const M3D_F3&) = default;
M3D_F3& operator=(const M3D_F3&) = default;
M3D_F3(M3D_F3&&) = default;
M3D_F3& operator=(M3D_F3&&) = default;
constexpr M3D_F3(float _x, float _y, float _z) noexcept : x(_x), y(_y), z(_z) {}
};
struct __attribute__((aligned(16))) M3D_F3A : public M3D_F3 {
using M3D_F3::M3D_F3;
};
struct M3D_F4 {
float x;
float y;
float z;
float w;
M3D_F4() = default;
M3D_F4(const M3D_F4&) = default;
M3D_F4& operator=(const M3D_F4&) = default;
M3D_F4(M3D_F4&&) = default;
M3D_F4& operator=(M3D_F4&&) = default;
constexpr M3D_F4(float _x, float _y, float _z, float _w) noexcept : x(_x), y(_y), z(_z), w(_w) {}
#if (__cplusplus >= 202002L)
bool operator == (const M3D_F4&) const = default;
auto operator <=> (const M3D_F4&) const = default;
#endif
};
struct __attribute__((aligned(16))) M3D_F4A : public M3D_F4 {
using M3D_F4::M3D_F4;
};
struct M3D_F4X4 {
union {
struct {
float _00, _01, _02, _03;
float _10, _11, _12, _13;
float _20, _21, _22, _23;
float _30, _31, _32, _33;
};
float mat[4][4];
};
M3D_F4X4() = default;
M3D_F4X4(const M3D_F4X4&) = default;
M3D_F4X4& operator=(const M3D_F4X4&) = default;
M3D_F4X4(M3D_F4X4&&) = default;
M3D_F4X4& operator=(M3D_F4X4&&) = default;
constexpr M3D_F4X4(float f00, float f01, float f02, float f03,
float f10, float f11, float f12, float f13,
float f20, float f21, float f22, float f23,
float f30, float f31, float f32, float f33) noexcept
: _00(f00), _01(f01), _02(f02), _03(f03),
_10(f10), _11(f11), _12(f12), _13(f13),
_20(f20), _21(f21), _22(f22), _23(f23),
_30(f30), _31(f31), _32(f32), _33(f33) {}
float operator() (size_t row, size_t column) const noexcept { return mat[row][column]; }
float& operator() (size_t row, size_t column) noexcept { return mat[row][column]; }
#if (__cplusplus >= 202002L)
bool operator == (const M3D_F4X4&) const = default;
auto operator <=> (const M3D_F4X4&) const = default;
#endif
};
struct __attribute__((aligned(16))) M3D_F4X4A : public M3D_F4X4
{
using M3D_F4X4::M3D_F4X4;
};
//
// Generic SIMD matrix implementation
//
// Call convention (x86_64):
// 1st matrix parameter should be M3D_MATRIX
// 2nd+ matrix parameter should be M3D_MATRIX&
//
#ifdef DISABLE_INTRINSICS
struct M3D_MATRIX {
union {
M3D_VECTOR rows[4];
struct {
float _00, _01, _02, _03;
float _10, _11, _12, _13;
float _20, _21, _22, _23;
float _30, _31, _32, _33;
};
float mat[4][4];
};
#else
struct __attribute__((aligned(16))) M3D_MATRIX {
M3D_VECTOR rows[4];
#endif
M3D_MATRIX() = default;
M3D_MATRIX(const M3D_MATRIX&) = default;
M3D_MATRIX& operator=(const M3D_MATRIX&) = default;
M3D_MATRIX(M3D_MATRIX&&) = default;
M3D_MATRIX& operator=(M3D_MATRIX&&) = default;
constexpr M3D_MATRIX(M3D_VECTOR v0, M3D_VECTOR v1, M3D_VECTOR v2, M3D_VECTOR& v3) noexcept : rows{ v0,v1,v2,v3 } {}
M3D_MATRIX(float f00, float f01, float f02, float f03,
float f10, float f11, float f12, float f13,
float f20, float f21, float f22, float f23,
float f30, float f31, float f32, float f33) noexcept;
#ifdef DISABLE_INTRINSICS
float operator() (size_t row, size_t column) const noexcept { return mat[row][column]; }
float& operator() (size_t row, size_t column) noexcept { return mat[row][column]; }
#endif
M3D_MATRIX operator+ () const noexcept { return *this; }
M3D_MATRIX operator- () const noexcept;
M3D_MATRIX& operator+= (M3D_MATRIX M) noexcept;
M3D_MATRIX& operator-= (M3D_MATRIX M) noexcept;
M3D_MATRIX& operator*= (M3D_MATRIX M) noexcept;
M3D_MATRIX& operator*= (float S) noexcept;
M3D_MATRIX& operator/= (float S) noexcept;
M3D_MATRIX operator+ (M3D_MATRIX M) const noexcept;
M3D_MATRIX operator- (M3D_MATRIX M) const noexcept;
M3D_MATRIX operator* (M3D_MATRIX M) const noexcept;
M3D_MATRIX operator* (float S) const noexcept;
M3D_MATRIX operator/ (float S) const noexcept;
friend M3D_MATRIX operator* (float S, M3D_MATRIX& M) noexcept;
};
//
// Load/Store functions
//
M3D_VECTOR M3D_V4LoadF3(const M3D_F3* src) noexcept;
M3D_VECTOR M3D_V4LoadF3A(const M3D_F3A* src) noexcept;
void M3D_V4StoreF3(M3D_F3* dst, M3D_VECTOR V) noexcept;
void M3D_V4StoreF3A(M3D_F3A* dst, M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4LoadF4(const M3D_F4* src) noexcept;
M3D_VECTOR M3D_V4LoadF4A(const M3D_F4A* src) noexcept;
void M3D_V4StoreF4(M3D_F4* dst, M3D_VECTOR V) noexcept;
void M3D_V4StoreF4A(M3D_F4A* dst, M3D_VECTOR V) noexcept;
M3D_MATRIX M3D_V4LoadF4x4(const M3D_F4X4* src) noexcept;
M3D_MATRIX M3D_V4LoadF4x4A(const M3D_F4X4A* src) noexcept;
void M3D_V4StoreF4x4(M3D_F4X4* dst, M3D_MATRIX M) noexcept;
void M3D_V4StoreF4x4A(M3D_F4X4A* dst, M3D_MATRIX M) noexcept;
//
// Vector operation
//
M3D_VECTOR M3D_V4Set(float x, float y, float z, float w) noexcept;
M3D_VECTOR M3D_V4Negate(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4Replicate(float val) noexcept;
float M3D_V4GetX(M3D_VECTOR V) noexcept;
float M3D_V4GetY(M3D_VECTOR V) noexcept;
float M3D_V4GetZ(M3D_VECTOR V) noexcept;
float M3D_V4GetW(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4SplatX(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4SplatY(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4SplatZ(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4SplatW(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V4Add(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V4Subtract(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V4MultiplyAdd(M3D_VECTOR V1, M3D_VECTOR V2, M3D_VECTOR V3) noexcept;
M3D_VECTOR M3D_V4Divide(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V4Scale(M3D_VECTOR V, float scale) noexcept;
M3D_VECTOR M3D_V4Select(M3D_VECTOR V1, M3D_VECTOR V2, M3D_VECTOR Control) noexcept;
M3D_VECTOR M3D_V4MergeXY(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V4MergeZW(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V4Sqrt(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V3Dot(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V3Cross(M3D_VECTOR V1, M3D_VECTOR V2) noexcept;
M3D_VECTOR M3D_V3LengthSq(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V3Length(M3D_VECTOR V) noexcept;
M3D_VECTOR M3D_V3Normalize(M3D_VECTOR V) noexcept;
//
// Matrix operation
//
M3D_MATRIX M3D_MIdentity() noexcept;
M3D_MATRIX M3D_MMultiply(M3D_MATRIX M1, M3D_MATRIX& M2) noexcept;
M3D_MATRIX M3D_MTranspose(M3D_MATRIX M) noexcept;
//
// Vector/Matrix operation
//
M3D_VECTOR M3D_V3Transform(M3D_VECTOR V, M3D_MATRIX M) noexcept;
//
// Common transformation matrix constructor functions
//
M3D_MATRIX M3D_TransformMatrixCamLookAtLH(M3D_VECTOR viewPos, M3D_VECTOR focusPos, M3D_VECTOR upDirection) noexcept;
M3D_MATRIX M3D_TransformMatrixCamLookAtRH(M3D_VECTOR viewPos, M3D_VECTOR focusPos, M3D_VECTOR upDirection) noexcept;
M3D_MATRIX M3D_TransformMatrixCamLookToLH(M3D_VECTOR viewPos, M3D_VECTOR viewDirection, M3D_VECTOR upDirection) noexcept;
M3D_MATRIX M3D_TransformMatrixCamLookToRH(M3D_VECTOR viewPos, M3D_VECTOR viewDirection, M3D_VECTOR upDirection) noexcept;
M3D_MATRIX M3D_TransformMatrixFrustrumFovLH(float fov, float ratio, float near, float far) noexcept;
M3D_MATRIX M3D_TransformMatrixFrustrumFovRH(float fov, float ratio, float near, float far) noexcept;
M3D_MATRIX M3D_TransformMatrixScaling(float ScaleX, float ScaleY, float ScaleZ) noexcept;
M3D_MATRIX M3D_TransformMatrixTranslate(float OffsetX, float OffsetY, float OffsetZ) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationX(float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationY(float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixRotationZ(float Angle) noexcept;
M3D_MATRIX M3D_TransformMatrixViewport(float _w, float _h, float _wOffset, float _hOffset) noexcept;
//
// Common values for vector/matrix manipulation
//
#ifndef M3D_GCONST
# if defined(__GNUC__) && !defined(__MINGW32__)
# define M3D_GCONST extern const __attribute__((weak))
# else
# define M3D_GCONST extern const __declspec(selectany)
# endif
#endif
M3D_GCONST M3D_V4F32 M3D_MIdentityR0 = {{{1.0f, 0.0f, 0.0f, 0.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR1 = {{{0.0f, 1.0f, 0.0f, 0.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR2 = {{{0.0f, 0.0f, 1.0f, 0.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR3 = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR0_n = {{{-1.0f, 0.0f, 0.0f, 0.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR1_n = {{{0.0f, -1.0f, 0.0f, 0.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR2_n = {{{0.0f, 0.0f, -1.0f, 0.0f}}};
M3D_GCONST M3D_V4F32 M3D_MIdentityR3_n = {{{0.0f, 0.0f, 0.0f, -1.0f}}};
M3D_GCONST M3D_V4F32 M3D_MNegateX = {{{-1.0f, 1.0f, 1.0f, 1.0f}}};
M3D_GCONST M3D_V4F32 M3D_MNegateY = {{{1.0f, -1.0f, 1.0f, 1.0f}}};
M3D_GCONST M3D_V4F32 M3D_MNegateZ = {{{1.0f, 1.0f, -1.0f, 1.0f}}};
M3D_GCONST M3D_V4F32 M3D_MNegateW = {{{1.0f, 1.0f, 1.0f, -1.0f}}};
M3D_GCONST M3D_V4I32 M3D_MInfinity = {{{0x7F800000, 0x7F800000, 0x7F800000, 0x7F800000}}};
M3D_GCONST M3D_V4I32 M3D_MQNaN = {{{0x7FC00000, 0x7FC00000, 0x7FC00000, 0x7FC00000}}};
M3D_GCONST M3D_V4U32 M3D_MMaskX = {{{0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000}}};
M3D_GCONST M3D_V4U32 M3D_MMaskY = {{{0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000}}};
M3D_GCONST M3D_V4U32 M3D_MMaskZ = {{{0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000}}};
M3D_GCONST M3D_V4U32 M3D_MMaskW = {{{0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF}}};
M3D_GCONST M3D_V4U32 M3D_MMask3 = {{{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000}}};
M3D_GCONST M3D_V4U32 M3D_MSelect1000 = {{{0xFFFFFFFF, 0x0, 0x0, 0x0}}};
M3D_GCONST M3D_V4U32 M3D_MSelect1100 = {{{0xFFFFFFFF, 0xFFFFFFFF, 0x0, 0x0}}};
M3D_GCONST M3D_V4U32 M3D_MSelect1110 = {{{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0}}};
M3D_GCONST M3D_V4U32 M3D_MSelect1011 = {{{0xFFFFFFFF, 0x0, 0xFFFFFFFF, 0xFFFFFFFF}}};
constexpr M3D_F4X4 M3D_MIdentity4x4() {
M3D_F4X4 I(
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
return I;
}
#include "3DMaths.inl"

1528
Engine/Utils/3DMaths.inl Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,23 @@
#pragma once
#include "../Utils/3DMaths.hpp"
struct MeshVertex {
MeshVertex() = default;
MeshVertex(const MeshVertex&) = default;
MeshVertex& operator=(const MeshVertex&) = default;
MeshVertex(MeshVertex&&) = default;
MeshVertex& operator=(MeshVertex&&) = default;
MeshVertex(M3D_F3 const& _pos) noexcept : pos(_pos) {}
MeshVertex(const float _x, const float _y, const float _z) noexcept : pos(M3D_F3(_x,_y,_z)) {}
MeshVertex(M3D_VECTOR const _pos) noexcept {
M3D_V4StoreF3(&this->pos, _pos);
}
M3D_F3 pos = {0.0f, 0.0f, 0.0f};
M3D_F4 color = {255.0f, 255.0f, 255.0f, 255.f};
};

View File

@ -5,8 +5,9 @@ set(MAIN_SCRS
icon.h
)
set(UTILS_SCRS
Engine/Utils/3DMaths.cpp
Engine/Utils/3DMaths.inl
Engine/Utils/3DMaths.hpp
Engine/Utils/MeshHelper.hpp
Engine/Utils/Timers.hpp
Engine/Utils/Perfs.cpp
Engine/Utils/Perfs.hpp
@ -24,8 +25,10 @@ set(GAME_SCRS
Engine/World/Tank.cpp
)
set(GRAPHS_SCRS
Engine/Graphics/3DGraphics.cpp
Engine/Graphics/3DRenderer.cpp
Engine/Graphics/3DRenderer.hpp
Engine/Graphics/Camera.cpp
Engine/Graphics/Camera.hpp
Engine/Graphics/UI.cpp
Engine/Graphics/UI.hpp
Engine/Graphics/DebugUI.cpp